clk clkdev: Add clkdev matching based on physbase
Most clock/device associations can be done based on the physical base address of the corresponding device. So instead of depending on string matching add an optional possibility to associate a clock lookups with physical addresses. This also has the advantage that the lookups for devicetree based devices can be identical to the platform based devices. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
6f4dd1b204
commit
89b710e509
|
@ -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);
|
||||
|
|
|
@ -19,6 +19,7 @@ struct device_d;
|
|||
|
||||
struct clk_lookup {
|
||||
struct list_head node;
|
||||
unsigned long physbase;
|
||||
const char *dev_id;
|
||||
const char *con_id;
|
||||
struct clk *clk;
|
||||
|
@ -33,6 +34,8 @@ void clkdev_drop(struct clk_lookup *cl);
|
|||
void clkdev_add_table(struct clk_lookup *, size_t);
|
||||
int clk_add_alias(const char *, const char *, char *, struct device_d *);
|
||||
|
||||
int clkdev_add_physbase(struct clk *clk, unsigned long base, const char *id);
|
||||
|
||||
#define CLKDEV_DEV_ID(_id, _clk) \
|
||||
{ \
|
||||
.dev_id = _id, \
|
||||
|
|
Loading…
Reference in New Issue