diff options
Diffstat (limited to 'drivers/clk/at91/sckc.c')
-rw-r--r-- | drivers/clk/at91/sckc.c | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index fdc9b669f8a7..7741d8f3dbee 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -117,17 +117,17 @@ static const struct clk_ops slow_osc_ops = { static struct clk_hw * __init at91_clk_register_slow_osc(void __iomem *sckcr, const char *name, - const char *parent_name, + const struct clk_parent_data *parent_data, unsigned long startup, bool bypass, const struct clk_slow_bits *bits) { struct clk_slow_osc *osc; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; - if (!sckcr || !name || !parent_name) + if (!sckcr || !name || !parent_data) return ERR_PTR(-EINVAL); osc = kzalloc(sizeof(*osc), GFP_KERNEL); @@ -136,7 +136,7 @@ at91_clk_register_slow_osc(void __iomem *sckcr, init.name = name; init.ops = &slow_osc_ops; - init.parent_names = &parent_name; + init.parent_data = parent_data; init.num_parents = 1; init.flags = CLK_IGNORE_UNUSED; @@ -310,6 +310,7 @@ static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) } static const struct clk_ops sam9x5_slow_ops = { + .determine_rate = clk_hw_determine_rate_no_reparent, .set_parent = clk_sam9x5_slow_set_parent, .get_parent = clk_sam9x5_slow_get_parent, }; @@ -317,16 +318,16 @@ static const struct clk_ops sam9x5_slow_ops = { static struct clk_hw * __init at91_clk_register_sam9x5_slow(void __iomem *sckcr, const char *name, - const char **parent_names, + const struct clk_hw **parent_hws, int num_parents, const struct clk_slow_bits *bits) { struct clk_sam9x5_slow *slowck; struct clk_hw *hw; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; - if (!sckcr || !name || !parent_names || !num_parents) + if (!sckcr || !name || !parent_hws || !num_parents) return ERR_PTR(-EINVAL); slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); @@ -335,7 +336,7 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, init.name = name; init.ops = &sam9x5_slow_ops; - init.parent_names = parent_names; + init.parent_hws = parent_hws; init.num_parents = num_parents; init.flags = 0; @@ -366,18 +367,21 @@ static void __init at91sam9x5_sckc_register(struct device_node *np, unsigned int rc_osc_startup_us, const struct clk_slow_bits *bits) { - const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; void __iomem *regbase = of_iomap(np, 0); struct device_node *child = NULL; const char *xtal_name; struct clk_hw *slow_rc, *slow_osc, *slowck; + static struct clk_parent_data parent_data = { + .name = "slow_xtal", + }; + const struct clk_hw *parent_hws[2]; bool bypass; int ret; if (!regbase) return; - slow_rc = at91_clk_register_slow_rc_osc(regbase, parent_names[0], + slow_rc = at91_clk_register_slow_rc_osc(regbase, "slow_rc_osc", 32768, 50000000, rc_osc_startup_us, bits); if (IS_ERR(slow_rc)) @@ -401,12 +405,16 @@ static void __init at91sam9x5_sckc_register(struct device_node *np, if (!xtal_name) goto unregister_slow_rc; - slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1], - xtal_name, 1200000, bypass, bits); + parent_data.fw_name = xtal_name; + + slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc", + &parent_data, 1200000, bypass, bits); if (IS_ERR(slow_osc)) goto unregister_slow_rc; - slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_names, + parent_hws[0] = slow_rc; + parent_hws[1] = slow_osc; + slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", parent_hws, 2, bits); if (IS_ERR(slowck)) goto unregister_slow_osc; @@ -464,14 +472,17 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) struct clk_hw_onecell_data *clk_data; struct clk_hw *slow_rc, *slow_osc; const char *xtal_name; - const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; + const struct clk_hw *parent_hws[2]; + static struct clk_parent_data parent_data = { + .name = "slow_xtal", + }; bool bypass; int ret; if (!regbase) return; - slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, parent_names[0], + slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, "slow_rc_osc", NULL, 0, 32768, 93750000); if (IS_ERR(slow_rc)) @@ -481,9 +492,10 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) if (!xtal_name) goto unregister_slow_rc; + parent_data.fw_name = xtal_name; bypass = of_property_read_bool(np, "atmel,osc-bypass"); - slow_osc = at91_clk_register_slow_osc(regbase, parent_names[1], - xtal_name, 5000000, bypass, + slow_osc = at91_clk_register_slow_osc(regbase, "slow_osc", + &parent_data, 5000000, bypass, &at91sam9x60_bits); if (IS_ERR(slow_osc)) goto unregister_slow_rc; @@ -494,14 +506,16 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) /* MD_SLCK and TD_SLCK. */ clk_data->num = 2; - clk_data->hws[0] = clk_hw_register_fixed_rate(NULL, "md_slck", - parent_names[0], - 0, 32768); + clk_data->hws[0] = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", + slow_rc, + 0, 32768); if (IS_ERR(clk_data->hws[0])) goto clk_data_free; + parent_hws[0] = slow_rc; + parent_hws[1] = slow_osc; clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck", - parent_names, 2, + parent_hws, 2, &at91sam9x60_bits); if (IS_ERR(clk_data->hws[1])) goto unregister_md_slck; @@ -572,30 +586,36 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np) void __iomem *regbase = of_iomap(np, 0); struct clk_hw *slow_rc, *slowck; struct clk_sama5d4_slow_osc *osc; - struct clk_init_data init; + struct clk_init_data init = {}; const char *xtal_name; - const char *parent_names[2] = { "slow_rc_osc", "slow_osc" }; + const struct clk_hw *parent_hws[2]; + static struct clk_parent_data parent_data = { + .name = "slow_xtal", + }; int ret; if (!regbase) return; slow_rc = clk_hw_register_fixed_rate_with_accuracy(NULL, - parent_names[0], + "slow_rc_osc", NULL, 0, 32768, 250000000); if (IS_ERR(slow_rc)) return; xtal_name = of_clk_get_parent_name(np, 0); + if (!xtal_name) + goto unregister_slow_rc; + parent_data.fw_name = xtal_name; osc = kzalloc(sizeof(*osc), GFP_KERNEL); if (!osc) goto unregister_slow_rc; - init.name = parent_names[1]; + init.name = "slow_osc"; init.ops = &sama5d4_slow_osc_ops; - init.parent_names = &xtal_name; + init.parent_data = &parent_data; init.num_parents = 1; init.flags = CLK_IGNORE_UNUSED; @@ -608,8 +628,10 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np) if (ret) goto free_slow_osc_data; + parent_hws[0] = slow_rc; + parent_hws[1] = &osc->hw; slowck = at91_clk_register_sam9x5_slow(regbase, "slowck", - parent_names, 2, + parent_hws, 2, &at91sama5d4_bits); if (IS_ERR(slowck)) goto unregister_slow_osc; |