aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/versatile/clk-icst.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/versatile/clk-icst.c')
-rw-r--r--drivers/clk/versatile/clk-icst.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c
index 8cbfcf88fae3..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);
@@ -120,24 +124,33 @@ static const struct clk_ops icst_ops = {
120struct clk *icst_clk_register(struct device *dev, 124struct clk *icst_clk_register(struct device *dev,
121 const struct clk_icst_desc *desc, 125 const struct clk_icst_desc *desc,
122 const char *name, 126 const char *name,
127 const char *parent_name,
123 void __iomem *base) 128 void __iomem *base)
124{ 129{
125 struct clk *clk; 130 struct clk *clk;
126 struct clk_icst *icst; 131 struct clk_icst *icst;
127 struct clk_init_data init; 132 struct clk_init_data init;
133 struct icst_params *pclone;
128 134
129 icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL); 135 icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
130 if (!icst) { 136 if (!icst) {
131 pr_err("could not allocate ICST clock!\n"); 137 pr_err("could not allocate ICST clock!\n");
132 return ERR_PTR(-ENOMEM); 138 return ERR_PTR(-ENOMEM);
133 } 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
134 init.name = name; 147 init.name = name;
135 init.ops = &icst_ops; 148 init.ops = &icst_ops;
136 init.flags = CLK_IS_ROOT; 149 init.flags = CLK_IS_ROOT;
137 init.parent_names = NULL; 150 init.parent_names = (parent_name ? &parent_name : NULL);
138 init.num_parents = 0; 151 init.num_parents = (parent_name ? 1 : 0);
139 icst->hw.init = &init; 152 icst->hw.init = &init;
140 icst->params = desc->params; 153 icst->params = pclone;
141 icst->vcoreg = base + desc->vco_offset; 154 icst->vcoreg = base + desc->vco_offset;
142 icst->lockreg = base + desc->lock_offset; 155 icst->lockreg = base + desc->lock_offset;
143 156