ipq806x: r7800: add missing wifi definition for pcie
[oweals/openwrt.git] / target / linux / ipq806x / patches-4.14 / 0044-clk-Add-safe-switch-hook.patch
1 From patchwork Fri Dec  8 09:42:28 2017
2 Content-Type: text/plain; charset="utf-8"
3 MIME-Version: 1.0
4 Content-Transfer-Encoding: 7bit
5 Subject: [v4,10/12] clk: qcom: Add safe switch hook for krait mux clocks
6 From: Sricharan R <sricharan@codeaurora.org>
7 X-Patchwork-Id: 10102057
8 Message-Id: <1512726150-7204-11-git-send-email-sricharan@codeaurora.org>
9 To: mturquette@baylibre.com, sboyd@codeaurora.org,
10  devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
11  linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org,
12  viresh.kumar@linaro.org, linux-arm-kernel@lists.infradead.org
13 Cc: sricharan@codeaurora.org
14 Date: Fri,  8 Dec 2017 15:12:28 +0530
15
16 When the Hfplls are reprogrammed during the rate change,
17 the primary muxes which are sourced from the same hfpll
18 for higher frequencies, needs to be switched to the 'safe
19 secondary mux' as the parent for that small window. This
20 is done by registering a clk notifier for the muxes and
21 switching to the safe parent in the PRE_RATE_CHANGE notifier
22 and back to the original parent in the POST_RATE_CHANGE notifier.
23
24 Signed-off-by: Sricharan R <sricharan@codeaurora.org>
25 ---
26  drivers/clk/qcom/clk-krait.c |  2 ++
27  drivers/clk/qcom/clk-krait.h |  3 +++
28  drivers/clk/qcom/krait-cc.c  | 56 ++++++++++++++++++++++++++++++++++++++++++++
29  3 files changed, 61 insertions(+)
30
31 --- a/drivers/clk/qcom/clk-krait.c
32 +++ b/drivers/clk/qcom/clk-krait.c
33 @@ -60,6 +60,8 @@ static int krait_mux_set_parent(struct c
34         if (__clk_is_enabled(hw->clk))
35                 __krait_mux_set_sel(mux, sel);
36  
37 +       mux->reparent = true;
38 +
39         return 0;
40  }
41  
42 --- a/drivers/clk/qcom/clk-krait.h
43 +++ b/drivers/clk/qcom/clk-krait.h
44 @@ -23,6 +23,9 @@ struct krait_mux_clk {
45         u32             shift;
46         u32             en_mask;
47         bool            lpl;
48 +       u8              safe_sel;
49 +       u8              old_index;
50 +       bool            reparent;
51  
52         struct clk_hw   hw;
53         struct notifier_block   clk_nb;
54 --- a/drivers/clk/qcom/krait-cc.c
55 +++ b/drivers/clk/qcom/krait-cc.c
56 @@ -35,6 +35,49 @@ static unsigned int pri_mux_map[] = {
57         0,
58  };
59  
60 +/*
61 + * Notifier function for switching the muxes to safe parent
62 + * while the hfpll is getting reprogrammed.
63 + */
64 +static int krait_notifier_cb(struct notifier_block *nb,
65 +                            unsigned long event,
66 +                            void *data)
67 +{
68 +       int ret = 0;
69 +       struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk,
70 +                                                clk_nb);
71 +       /* Switch to safe parent */
72 +       if (event == PRE_RATE_CHANGE) {
73 +               mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw);
74 +               ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel);
75 +               mux->reparent = false;
76 +       /*
77 +        * By the time POST_RATE_CHANGE notifier is called,
78 +        * clk framework itself would have changed the parent for the new rate.
79 +        * Only otherwise, put back to the old parent.
80 +        */
81 +       } else if (event == POST_RATE_CHANGE) {
82 +               if (!mux->reparent)
83 +                       ret = krait_mux_clk_ops.set_parent(&mux->hw,
84 +                                                          mux->old_index);
85 +       }
86 +
87 +       return notifier_from_errno(ret);
88 +}
89 +
90 +static int krait_notifier_register(struct device *dev, struct clk *clk,
91 +                                  struct krait_mux_clk *mux)
92 +{
93 +       int ret = 0;
94 +
95 +       mux->clk_nb.notifier_call = krait_notifier_cb;
96 +       ret = clk_notifier_register(clk, &mux->clk_nb);
97 +       if (ret)
98 +               dev_err(dev, "failed to register clock notifier: %d\n", ret);
99 +
100 +       return ret;
101 +}
102 +
103  static int
104  krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
105  {
106 @@ -79,6 +122,7 @@ static int
107  krait_add_sec_mux(struct device *dev, int id, const char *s,
108                   unsigned int offset, bool unique_aux)
109  {
110 +       int ret;
111         struct krait_mux_clk *mux;
112         static const char *sec_mux_list[] = {
113                 "acpu_aux",
114 @@ -102,6 +146,7 @@ krait_add_sec_mux(struct device *dev, in
115         mux->shift = 2;
116         mux->parent_map = sec_mux_map;
117         mux->hw.init = &init;
118 +       mux->safe_sel = 0;
119  
120         init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
121         if (!init.name)
122 @@ -117,6 +162,11 @@ krait_add_sec_mux(struct device *dev, in
123  
124         clk = devm_clk_register(dev, &mux->hw);
125  
126 +       ret = krait_notifier_register(dev, clk, mux);
127 +       if (ret)
128 +               goto unique_aux;
129 +
130 +unique_aux:
131         if (unique_aux)
132                 kfree(sec_mux_list[0]);
133  err_aux:
134 @@ -128,6 +178,7 @@ static struct clk *
135  krait_add_pri_mux(struct device *dev, int id, const char *s,
136                   unsigned int offset)
137  {
138 +       int ret;
139         struct krait_mux_clk *mux;
140         const char *p_names[3];
141         struct clk_init_data init = {
142 @@ -148,6 +199,7 @@ krait_add_pri_mux(struct device *dev, in
143         mux->lpl = id >= 0;
144         mux->parent_map = pri_mux_map;
145         mux->hw.init = &init;
146 +       mux->safe_sel = 2;
147  
148         init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
149         if (!init.name)
150 @@ -173,6 +225,10 @@ krait_add_pri_mux(struct device *dev, in
151  
152         clk = devm_clk_register(dev, &mux->hw);
153  
154 +       ret = krait_notifier_register(dev, clk, mux);
155 +       if (ret)
156 +               goto err_p3;
157 +err_p3:
158         kfree(p_names[2]);
159  err_p2:
160         kfree(p_names[1]);