|
@@ -33,7 +33,7 @@ struct clk_icst {
|
|
struct clk_hw hw;
|
|
struct clk_hw hw;
|
|
void __iomem *vcoreg;
|
|
void __iomem *vcoreg;
|
|
void __iomem *lockreg;
|
|
void __iomem *lockreg;
|
|
- const struct icst_params *params;
|
|
|
|
|
|
+ struct icst_params *params;
|
|
unsigned long rate;
|
|
unsigned long rate;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -84,6 +84,8 @@ static unsigned long icst_recalc_rate(struct clk_hw *hw,
|
|
struct clk_icst *icst = to_icst(hw);
|
|
struct clk_icst *icst = to_icst(hw);
|
|
struct icst_vco vco;
|
|
struct icst_vco vco;
|
|
|
|
|
|
|
|
+ if (parent_rate)
|
|
|
|
+ icst->params->ref = parent_rate;
|
|
vco = vco_get(icst->vcoreg);
|
|
vco = vco_get(icst->vcoreg);
|
|
icst->rate = icst_hz(icst->params, vco);
|
|
icst->rate = icst_hz(icst->params, vco);
|
|
return icst->rate;
|
|
return icst->rate;
|
|
@@ -105,6 +107,8 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate,
|
|
struct clk_icst *icst = to_icst(hw);
|
|
struct clk_icst *icst = to_icst(hw);
|
|
struct icst_vco vco;
|
|
struct icst_vco vco;
|
|
|
|
|
|
|
|
+ if (parent_rate)
|
|
|
|
+ icst->params->ref = parent_rate;
|
|
vco = icst_hz_to_vco(icst->params, rate);
|
|
vco = icst_hz_to_vco(icst->params, rate);
|
|
icst->rate = icst_hz(icst->params, vco);
|
|
icst->rate = icst_hz(icst->params, vco);
|
|
vco_set(icst->lockreg, icst->vcoreg, vco);
|
|
vco_set(icst->lockreg, icst->vcoreg, vco);
|
|
@@ -126,19 +130,27 @@ struct clk *icst_clk_register(struct device *dev,
|
|
struct clk *clk;
|
|
struct clk *clk;
|
|
struct clk_icst *icst;
|
|
struct clk_icst *icst;
|
|
struct clk_init_data init;
|
|
struct clk_init_data init;
|
|
|
|
+ struct icst_params *pclone;
|
|
|
|
|
|
icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
|
|
icst = kzalloc(sizeof(struct clk_icst), GFP_KERNEL);
|
|
if (!icst) {
|
|
if (!icst) {
|
|
pr_err("could not allocate ICST clock!\n");
|
|
pr_err("could not allocate ICST clock!\n");
|
|
return ERR_PTR(-ENOMEM);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ pclone = kmemdup(desc->params, sizeof(*pclone), GFP_KERNEL);
|
|
|
|
+ if (!pclone) {
|
|
|
|
+ pr_err("could not clone ICST params\n");
|
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
|
+ }
|
|
|
|
+
|
|
init.name = name;
|
|
init.name = name;
|
|
init.ops = &icst_ops;
|
|
init.ops = &icst_ops;
|
|
init.flags = CLK_IS_ROOT;
|
|
init.flags = CLK_IS_ROOT;
|
|
- init.parent_names = NULL;
|
|
|
|
- init.num_parents = 0;
|
|
|
|
|
|
+ init.parent_names = (parent_name ? &parent_name : NULL);
|
|
|
|
+ init.num_parents = (parent_name ? 1 : 0);
|
|
icst->hw.init = &init;
|
|
icst->hw.init = &init;
|
|
- icst->params = desc->params;
|
|
|
|
|
|
+ icst->params = pclone;
|
|
icst->vcoreg = base + desc->vco_offset;
|
|
icst->vcoreg = base + desc->vco_offset;
|
|
icst->lockreg = base + desc->lock_offset;
|
|
icst->lockreg = base + desc->lock_offset;
|
|
|
|
|