aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-01-20 15:46:46 -0500
committerLinus Walleij <linus.walleij@linaro.org>2014-02-13 05:20:55 -0500
commita183da637c52c74ae4634355187d3fbaa1ba9763 (patch)
tree277ab1ec855b4b4db09b7088b5ed83b671664578
parentbf6edb4bb1fabd73bebcd0ae85cdeb14c5893f3b (diff)
clk: versatile: respect parent rate in ICST clock
If the ICST clock has a parent, respect the rate of the parent when calculating the clock frequency. As this involves modifying the ICST parameter struct, make a cloned copy (the divisor arrays should be safe) so we can update the .ref field. Do not define the reference clock on the Integrator as we have the reference clock from the device tree. Keep it everywhere else. Cc: Mike Turquette <mturquette@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/clk/versatile/clk-icst.c20
-rw-r--r--drivers/clk/versatile/clk-integrator.c1
2 files changed, 16 insertions, 5 deletions
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index c98adbe62733..a820b0cfcf57 100644
--- a/drivers/clk/versatile/clk-icst.c
+++ b/drivers/clk/versatile/clk-icst.c
@@ -33,7 +33,7 @@ struct clk_icst {
33 struct clk_hw hw; 33 struct clk_hw hw;
34 void __iomem *vcoreg; 34 void __iomem *vcoreg;
35 void __iomem *lockreg; 35 void __iomem *lockreg;
36 const struct icst_params *params; 36 struct icst_params *params;
37 unsigned long rate; 37 unsigned long rate;
38}; 38};
39 39
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
84 struct clk_icst *icst = to_icst(hw); 84 struct clk_icst *icst = to_icst(hw);
85 struct icst_vco vco; 85 struct icst_vco vco;
86 86
87 if (parent_rate)
88 icst->params->ref = parent_rate;
87 vco = vco_get(icst->vcoreg); 89 vco = vco_get(icst->vcoreg);
88 icst->rate = icst_hz(icst->params, vco); 90 icst->rate = icst_hz(icst->params, vco);
89 return icst->rate; 91 return icst->rate;
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
105 struct clk_icst *icst = to_icst(hw); 107 struct clk_icst *icst = to_icst(hw);
106 struct icst_vco vco; 108 struct icst_vco vco;
107 109
110 if (parent_rate)
111 icst->params->ref = parent_rate;
108 vco = icst_hz_to_vco(icst->params, rate); 112 vco = icst_hz_to_vco(icst->params, rate);
109 icst->rate = icst_hz(icst->params, vco); 113 icst->rate = icst_hz(icst->params, vco);
110 vco_set(icst->lockreg, icst->vcoreg, vco); 114 vco_set(icst->lockreg, icst->vcoreg, vco);
@@ -126,19 +130,27 @@ struct clk *icst_clk_register(struct device *dev,
126 struct clk *clk; 130 struct clk *clk;
127 struct clk_icst *icst; 131 struct clk_icst *icst;
128 struct clk_init_data init; 132 struct clk_init_data init;
133 struct icst_params *pclone;
129 134
130 icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); 135 icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
131 if (!icst) { 136 if (!icst) {
132 pr_err("could not allocate ICST clock!\n"); 137 pr_err("could not allocate ICST clock!\n");
133 return ERR_PTR(-ENOMEM); 138 return ERR_PTR(-ENOMEM);
134 } 139 }
140
141 pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
142 if (!pclone) {
143 pr_err("could not clone ICST params\n");
144 return ERR_PTR(-ENOMEM);
145 }
146
135 init.name = name; 147 init.name = name;
136 init.ops = &icst_ops; 148 init.ops = &icst_ops;
137 init.flags = CLK_IS_ROOT; 149 init.flags = CLK_IS_ROOT;
138 init.parent_names = NULL; 150 init.parent_names = (parent_name ? &parent_name : NULL);
139 init.num_parents = 0; 151 init.num_parents = (parent_name ? 1 : 0);
140 icst->hw.init = &init; 152 icst->hw.init = &init;
141 icst->params = desc->params; 153 icst->params = pclone;
142 icst->vcoreg = base + desc->vco_offset; 154 icst->vcoreg = base + desc->vco_offset;
143 icst->lockreg = base + desc->lock_offset; 155 icst->lockreg = base + desc->lock_offset;
144 156
diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c
index 5d36a719fefb..734c4b8fe6ab 100644
--- a/drivers/clk/versatile/clk-integrator.c
+++ b/drivers/clk/versatile/clk-integrator.c
@@ -21,7 +21,6 @@
21static void __iomem *cm_base; 21static void __iomem *cm_base;
22 22
23static const struct icst_params cp_auxosc_params = { 23static const struct icst_params cp_auxosc_params = {
24 .ref = 24000000,
25 .vco_max = ICST525_VCO_MAX_5V, 24 .vco_max = ICST525_VCO_MAX_5V,
26 .vco_min = ICST525_VCO_MIN, 25 .vco_min = ICST525_VCO_MIN,
27 .vd_min = 8, 26 .vd_min = 8,