diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 493b18a..4085b3f 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 @@ 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 2808c27..a3c9e41 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -33,6 +33,7 @@ int min_uv; int max_uv; char *name; + const char *supply; struct list_head consumer_list; }; @@ -42,6 +43,25 @@ 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 @@ 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 @@ 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 @@ */ 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; diff --git a/include/regulator.h b/include/regulator.h index 26a5e56..a43d3df 100644 --- a/include/regulator.h +++ b/include/regulator.h @@ -15,7 +15,17 @@ int (*is_enabled) (struct regulator_dev *); }; +#ifdef CONFIG_OFDEVICE int of_regulator_register(struct regulator_dev *rd, struct device_node *node); +#else +static inline int of_regulator_register(struct regulator_dev *rd, + struct device_node *node) +{ + return -ENOSYS; +} +#endif +int dev_regulator_register(struct regulator_dev *rd, const char * name, + const char* supply); void regulators_print(void);