diff options
Diffstat (limited to 'drivers/clk/at91/clk-generated.c')
-rw-r--r-- | drivers/clk/at91/clk-generated.c | 87 |
1 files changed, 51 insertions, 36 deletions
diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index f6164cc8ca..d36f64ffdf 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -17,15 +17,41 @@ DECLARE_GLOBAL_DATA_PTR; #define GENERATED_SOURCE_MAX 6 #define GENERATED_MAX_DIV 255 -struct generated_clk_priv { +/** + * generated_clk_bind() - for the generated clock driver + * Recursively bind its children as clk devices. + * + * @return: 0 on success, or negative error code on failure + */ +static int generated_clk_bind(struct udevice *dev) +{ + return at91_clk_sub_device_bind(dev, "generic-clk"); +} + +static const struct udevice_id generated_clk_match[] = { + { .compatible = "atmel,sama5d2-clk-generated" }, + {} +}; + +U_BOOT_DRIVER(generated_clk) = { + .name = "generated-clk", + .id = UCLASS_MISC, + .of_match = generated_clk_match, + .bind = generated_clk_bind, +}; + +/*-------------------------------------------------------------*/ + +struct generic_clk_priv { u32 num_parents; }; -static ulong generated_clk_get_rate(struct clk *clk) +static ulong generic_clk_get_rate(struct clk *clk) { struct pmc_platdata *plat = dev_get_platdata(clk->dev); struct at91_pmc *pmc = plat->reg_base; struct clk parent; + ulong clk_rate; u32 tmp, gckdiv; u8 parent_id; int ret; @@ -36,18 +62,22 @@ static ulong generated_clk_get_rate(struct clk *clk) AT91_PMC_PCR_GCKCSS_MASK; gckdiv = (tmp >> AT91_PMC_PCR_GCKDIV_OFFSET) & AT91_PMC_PCR_GCKDIV_MASK; - ret = clk_get_by_index(clk->dev, parent_id, &parent); + ret = clk_get_by_index(dev_get_parent(clk->dev), parent_id, &parent); if (ret) return 0; - return clk_get_rate(&parent) / (gckdiv + 1); + clk_rate = clk_get_rate(&parent) / (gckdiv + 1); + + clk_free(&parent); + + return clk_rate; } -static ulong generated_clk_set_rate(struct clk *clk, ulong rate) +static ulong generic_clk_set_rate(struct clk *clk, ulong rate) { struct pmc_platdata *plat = dev_get_platdata(clk->dev); struct at91_pmc *pmc = plat->reg_base; - struct generated_clk_priv *priv = dev_get_priv(clk->dev); + struct generic_clk_priv *priv = dev_get_priv(clk->dev); struct clk parent, best_parent; ulong tmp_rate, best_rate = rate, parent_rate; int tmp_diff, best_diff = -1; @@ -58,7 +88,7 @@ static ulong generated_clk_set_rate(struct clk *clk, ulong rate) int ret; for (i = 0; i < priv->num_parents; i++) { - ret = clk_get_by_index(clk->dev, i, &parent); + ret = clk_get_by_index(dev_get_parent(clk->dev), i, &parent); if (ret) return ret; @@ -111,18 +141,20 @@ static ulong generated_clk_set_rate(struct clk *clk, ulong rate) return 0; } -static struct clk_ops generated_clk_ops = { - .get_rate = generated_clk_get_rate, - .set_rate = generated_clk_set_rate, +static struct clk_ops generic_clk_ops = { + .of_xlate = at91_clk_of_xlate, + .get_rate = generic_clk_get_rate, + .set_rate = generic_clk_set_rate, }; -static int generated_clk_ofdata_to_platdata(struct udevice *dev) +static int generic_clk_ofdata_to_platdata(struct udevice *dev) { - struct generated_clk_priv *priv = dev_get_priv(dev); + struct generic_clk_priv *priv = dev_get_priv(dev); u32 cells[GENERATED_SOURCE_MAX]; u32 num_parents; - num_parents = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset, + num_parents = fdtdec_get_int_array_count(gd->fdt_blob, + dev_get_parent(dev)->of_offset, "clocks", cells, GENERATED_SOURCE_MAX); @@ -134,29 +166,12 @@ static int generated_clk_ofdata_to_platdata(struct udevice *dev) return 0; } -static int generated_clk_bind(struct udevice *dev) -{ - return at91_pmc_clk_node_bind(dev); -} - -static int generated_clk_probe(struct udevice *dev) -{ - return at91_pmc_core_probe(dev); -} - -static const struct udevice_id generated_clk_match[] = { - { .compatible = "atmel,sama5d2-clk-generated" }, - {} -}; - -U_BOOT_DRIVER(generated_clk) = { - .name = "generated-clk", +U_BOOT_DRIVER(generic_clk) = { + .name = "generic-clk", .id = UCLASS_CLK, - .of_match = generated_clk_match, - .bind = generated_clk_bind, - .probe = generated_clk_probe, - .ofdata_to_platdata = generated_clk_ofdata_to_platdata, - .priv_auto_alloc_size = sizeof(struct generated_clk_priv), + .probe = at91_clk_probe, + .ofdata_to_platdata = generic_clk_ofdata_to_platdata, + .priv_auto_alloc_size = sizeof(struct generic_clk_priv), .platdata_auto_alloc_size = sizeof(struct pmc_platdata), - .ops = &generated_clk_ops, + .ops = &generic_clk_ops, }; |