From 515fefa8a582d8705770e5b8d592fbaae5e7a4b8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 13 Jan 2015 07:33:09 +0100 Subject: regulator: allow to use it with non DT device this will use the device name as regulator name with the same Algo as clkdev for lookup Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Sascha Hauer --- drivers/regulator/Kconfig | 2 +- drivers/regulator/core.c | 98 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 83 insertions(+), 17 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 493b18a898..4085b3fd6e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -1,5 +1,4 @@ menuconfig REGULATOR - depends on OFDEVICE bool "voltage regulator support" if REGULATOR @@ -7,6 +6,7 @@ if REGULATOR config REGULATOR_FIXED bool "fixed/gpio regulator" depends on GENERIC_GPIO + depends on OFDEVICE help This enables a simple fixed regulator. It is used for regulators which are not software controllable or controllable via gpio. diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2808c27eba..a3c9e41abb 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -33,6 +33,7 @@ struct regulator_internal { int min_uv; int max_uv; char *name; + const char *supply; struct list_head consumer_list; }; @@ -42,6 +43,25 @@ struct regulator { struct device_d *dev; }; +static struct regulator_internal * __regulator_register(struct regulator_dev *rd, const char *name) +{ + struct regulator_internal *ri; + + ri = xzalloc(sizeof(*ri)); + ri->rdev = rd; + + INIT_LIST_HEAD(&ri->consumer_list); + + list_add_tail(&ri->list, ®ulator_list); + + if (name) + ri->name = xstrdup(name); + + return ri; +} + + +#ifdef CONFIG_OFDEVICE /* * of_regulator_register - register a regulator corresponding to a device_node * @rd: the regulator device providing the ops @@ -54,18 +74,10 @@ int of_regulator_register(struct regulator_dev *rd, struct device_node *node) struct regulator_internal *ri; const char *name; - ri = xzalloc(sizeof(*ri)); - ri->rdev = rd; - ri->node = node; - - INIT_LIST_HEAD(&ri->consumer_list); - - list_add_tail(&ri->list, ®ulator_list); - name = of_get_property(node, "regulator-name", NULL); - if (name) - ri->name = xstrdup(name); + ri = __regulator_register(rd, name); + ri->node = node; of_property_read_u32(node, "regulator-enable-ramp-delay", &ri->enable_time_us); @@ -127,6 +139,55 @@ out: return ri; } +#else +static struct regulator_internal *of_regulator_get(struct device_d *dev, const char *supply) +{ + return NULL; +} +#endif + +int dev_regulator_register(struct regulator_dev *rd, const char * name, const char* supply) +{ + struct regulator_internal *ri; + + ri = __regulator_register(rd, name); + + ri->supply = supply; + + return 0; +} + +static struct regulator_internal *dev_regulator_get(struct device_d *dev, const char *supply) +{ + struct regulator_internal *ri; + struct regulator_internal *ret = NULL; + int match, best = 0; + const char *dev_id = dev ? dev_name(dev) : NULL; + + list_for_each_entry(ri, ®ulator_list, list) { + match = 0; + if (ri->name) { + if (!dev_id || strcmp(ri->name, dev_id)) + continue; + match += 2; + } + if (ri->supply) { + if (!supply || strcmp(ri->supply, supply)) + continue; + match += 1; + } + + if (match > best) { + ret = ri; + if (match != 3) + best = match; + else + break; + } + } + + return ret; +} /* * regulator_get - get the supply for a device. @@ -140,15 +201,20 @@ out: */ struct regulator *regulator_get(struct device_d *dev, const char *supply) { - struct regulator_internal *ri; + struct regulator_internal *ri = NULL; struct regulator *r; - if (!dev->device_node) - return NULL; + if (dev->device_node) { + ri = of_regulator_get(dev, supply); + if (IS_ERR(ri)) + return ERR_CAST(ri); + } - ri = of_regulator_get(dev, supply); - if (IS_ERR(ri)) - return ERR_CAST(ri); + if (!ri) { + ri = dev_regulator_get(dev, supply); + if (IS_ERR(ri)) + return ERR_CAST(ri); + } if (!ri) return NULL; -- cgit v1.2.3