Messages in this thread Patch in this message | | | Date | Wed, 4 Feb 2015 15:19:57 -0800 | From | Tim Bird <> | Subject | [PATCH] regulator: Support different config and dev of_nodes in regulator_register |
| |
Support calling regulator_register with a dev node and a config node with different of_nodes. This is useful when a single driver wishes to register multiple child regulators.
Without this you get silent failures allocating a supply for a regulator which is registered using the device node of the regulator's DT parent (but it's own DT node).
Signed-off-by: Tim Bird <tim.bird@sonymobile.com> --- I encountered a problem where I did a devm_regulator_register with a dev (for a charger driver) and a config (for the regulator child of the driver) that had different of_nodes. In this case, inside regulator_dev_lookup the code did not find the supply that I had specified in the child regulator's DT node. The DT setup looked as follows:
charger@1000 { compatible = "qcom,pm8941-charger"; reg = <0x1000 0x700>; .... chg_otg { regulator_name = "chg_otg"; otg-supply = <&pm8941_mvs1>; ... } }
This code checks the of_node of specified in the struct regulator_config if the supply is not found in the dev.of_node. This code has no effect if dev.of_node and config.of_node are the same, so it shouldn't affect any existing (working) code.
drivers/regulator/core.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 128b432..36c5d78 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -128,13 +128,16 @@ static bool have_full_constraints(void) /** * of_get_regulator - get a regulator device node based on supply name * @dev: Device pointer for the consumer (of regulator) device + * @config: pointer to config for regulator registration * @supply: regulator supply name * * Extract the regulator device node corresponding to the supply name. * returns the device node corresponding to the regulator if found, else * returns NULL. */ -static struct device_node *of_get_regulator(struct device *dev, const char *supply) +static struct device_node *of_get_regulator(struct device *dev, + const struct regulator_config *config, + const char *supply) { struct device_node *regnode = NULL; char prop_name[32]; /* 32 is max size of property name */ @@ -147,7 +150,15 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp if (!regnode) { dev_dbg(dev, "Looking up %s property in node %s failed", prop_name, dev->of_node->full_name); - return NULL; + if (!config || !config->of_node || + config->of_node == dev->of_node) + return NULL; + regnode = of_parse_phandle(config->of_node, prop_name, 0); + if (!regnode) { + dev_dbg(dev, "Looking up %s property in node %s failed", + prop_name, dev->of_node->full_name); + return NULL; + } } return regnode; } @@ -1284,9 +1295,10 @@ static void regulator_supply_alias(struct device **dev, const char **supply) } } -static struct regulator_dev *regulator_dev_lookup(struct device *dev, - const char *supply, - int *ret) +static struct regulator_dev *regulator_dev_config_lookup(struct device *dev, + const struct regulator_config *config, + const char *supply, + int *ret) { struct regulator_dev *r; struct device_node *node; @@ -1297,7 +1309,7 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, /* first do a dt based lookup */ if (dev && dev->of_node) { - node = of_get_regulator(dev, supply); + node = of_get_regulator(dev, config, supply); if (node) { list_for_each_entry(r, ®ulator_list, list) if (r->dev.parent && @@ -1334,7 +1346,6 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, return map->regulator; } - return NULL; } @@ -1362,7 +1373,7 @@ static struct regulator *_regulator_get(struct device *dev, const char *id, mutex_lock(®ulator_list_mutex); - rdev = regulator_dev_lookup(dev, id, &ret); + rdev = regulator_dev_config_lookup(dev, NULL, id, &ret); if (rdev) goto found; @@ -3642,7 +3653,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (supply) { struct regulator_dev *r; - r = regulator_dev_lookup(dev, supply, &ret); + r = regulator_dev_config_lookup(dev, config, supply, &ret); if (ret == -ENODEV) { /* -- 1.8.2.2
| |