diff options
Diffstat (limited to 'drivers/clk/clkdev.c')
-rw-r--r-- | drivers/clk/clkdev.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 717fea5689..1ae822ffa6 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -62,6 +62,34 @@ static struct clk *clk_find(const char *dev_id, const char *con_id) return clk; } +static struct clk *clk_find_physbase(struct device_d *dev, const char *con_id) +{ + struct clk_lookup *p; + unsigned long start; + struct clk *clk = ERR_PTR(-ENOSYS); + + if (!dev || !dev->resource) + return ERR_PTR(-ENOSYS); + + start = dev->resource[0].start; + + list_for_each_entry(p, &clocks, node) { + if (p->physbase == ~0) + continue; + if (p->physbase != start) + continue; + if (p->con_id) { + if (!con_id || strcmp(p->con_id, con_id)) + continue; + return p->clk; + } + clk = p->clk; + } + + return clk; + +} + struct clk *clk_get_sys(const char *dev_id, const char *con_id) { struct clk *clk; @@ -77,6 +105,11 @@ EXPORT_SYMBOL(clk_get_sys); struct clk *clk_get(struct device_d *dev, const char *con_id) { const char *dev_id = dev ? dev_name(dev) : NULL; + struct clk *clk; + + clk = clk_find_physbase(dev, con_id); + if (!IS_ERR(clk)) + return clk; return clk_get_sys(dev_id, con_id); } @@ -90,6 +123,9 @@ EXPORT_SYMBOL(clk_put); void clkdev_add(struct clk_lookup *cl) { + if (cl->dev_id) + cl->physbase = ~0; + list_add_tail(&cl->node, &clocks); } EXPORT_SYMBOL(clkdev_add); @@ -97,6 +133,8 @@ EXPORT_SYMBOL(clkdev_add); void __init clkdev_add_table(struct clk_lookup *cl, size_t num) { while (num--) { + if (cl->dev_id) + cl->physbase = ~0; list_add_tail(&cl->node, &clocks); cl++; } @@ -120,6 +158,7 @@ struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, if (!cla) return NULL; + cla->cl.physbase = ~0; cla->cl.clk = clk; if (con_id) { strlcpy(cla->con_id, con_id, sizeof(cla->con_id)); @@ -166,3 +205,19 @@ void clkdev_drop(struct clk_lookup *cl) kfree(cl); } EXPORT_SYMBOL(clkdev_drop); + +int clkdev_add_physbase(struct clk *clk, unsigned long base, const char *id) +{ + struct clk_lookup *cl; + + cl = xzalloc(sizeof(*cl)); + + cl->clk = clk; + cl->con_id = id; + cl->physbase = base; + + clkdev_add(cl); + + return 0; +} +EXPORT_SYMBOL(clkdev_add_physbase); |