Skip to contentSkip to conversation

Allow regulator nodes to hold their own init data

PATCH New Charles Keepax 1 participant 3 messages Nov 29, 2018 Voltage and current regulator framework

lore
Share & tools
lore
#0 lore raw

cover Allow regulator nodes to hold their own init data

Unfortunately due to a rather large testing oversight on my part the recently merged Lochnagar regulator binding does not actually work. The binding looks like this:

lochnagar {
        compatible = "cirrus,lochnagar1";

        ...

        lochnagar-micvdd: MICVDD {
                compatible = "cirrus,lochnagar2-micvdd";

                SYSVDD-supply = <&wallvdd>;

                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
        };
        lochnagar-vddcore: VDDCORE {
                compatible = "cirrus,lochnagar2-vddcore";

                SYSVDD-supply = <&wallvdd>;

                regulator-min-microvolt = <1200000>;
                regulator-max-microvolt = <1200000>;
        };
};

The trouble is that each regulator node individually binds in a driver and contains the init data. The regulator core appears to require the init data to be a sub-node of the node that bound in the regulator driver. As the above binding seems reasonable I opted to try and update the core to support the current binding, although as the rest of the Lochnagar driver isn't merged yet we could still update the binding if that comes out of the review as a preferred option. Apologies for missing such a glaring issue in my testing.

Thanks,
Charles

Charles Keepax (2):
regulator: Factor out location of init data OF node
regulator: Allow regulator nodes to contain their own init data

 drivers/regulator/of_regulator.c | 72 ++++++++++++++++++++++++----------------
 1 file changed, 43 insertions(+), 29 deletions(-)
Signature · 1 line
2.11.0
#1 lore raw

PATCH 1/2 regulator: Factor out location of init data OF node

To support future additions factor out the location of the OF node containing the init data for the regulator from the code that parses the init data.

---
 drivers/regulator/of_regulator.c | 64 +++++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 27 deletions(-)
drivers/regulator/of_regulator.c +37 -27
index c711a0a2bc4b..4bb8928bdb3f 100644
@@ -371,13 +371,10 @@ int of_regulator_match(struct device *dev, struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(of_regulator_match);
 
-struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
-					    const struct regulator_desc *desc,
-					    struct regulator_config *config,
-					    struct device_node **node)
+struct device_node *regulator_of_get_init_node(struct device *dev,
+					       const struct regulator_desc *desc)
 {
 	struct device_node *search, *child;
-	struct regulator_init_data *init_data = NULL;
 	const char *name;
 
 	if (!dev->of_node || !desc->of_match)
@@ -400,35 +397,48 @@ struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
 		if (!name)
 			name = child->name;
 
-		if (strcmp(desc->of_match, name))
-			continue;
+		if (!strcmp(desc->of_match, name))
+			return of_node_get(child);
+	}
 
-		init_data = of_get_regulator_init_data(dev, child, desc);
-		if (!init_data) {
-			dev_err(dev,
-				"failed to parse DT for regulator %pOFn\n",
-				child);
-			break;
-		}
+	of_node_put(search);
 
-		if (desc->of_parse_cb) {
-			if (desc->of_parse_cb(child, desc, config)) {
-				dev_err(dev,
-					"driver callback failed to parse DT for regulator %pOFn\n",
-					child);
-				init_data = NULL;
-				break;
-			}
-		}
+	return NULL;
+}
 
-		of_node_get(child);
-		*node = child;
-		break;
+struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
+					    const struct regulator_desc *desc,
+					    struct regulator_config *config,
+					    struct device_node **node)
+{
+	struct device_node *child;
+	struct regulator_init_data *init_data = NULL;
+
+	child = regulator_of_get_init_node(dev, desc);
+	if (!child)
+		return NULL;
+
+	init_data = of_get_regulator_init_data(dev, child, desc);
+	if (!init_data) {
+		dev_err(dev, "failed to parse DT for regulator %pOFn\n", child);
+		goto error;
 	}
 
-	of_node_put(search);
+	if (desc->of_parse_cb && desc->of_parse_cb(child, desc, config)) {
+		dev_err(dev,
+			"driver callback failed to parse DT for regulator %pOFn\n",
+			child);
+		goto error;
+	}
+
+	*node = child;
 
 	return init_data;
+
+error:
+	of_node_put(child);
+
+	return NULL;
 }
 
 static int of_node_match(struct device *dev, const void *data)
Signature · 1 line
2.11.0
#2 lore raw

PATCH 2/2 regulator: Allow regulator nodes to contain their own init data

In reply to Charles Keepax

Currently it is expected that regulator init data will be defined as a series of sub-nodes from the node that bound in the driver. Add support for a node to both bind in a driver and contain init data for that regulator.

---
 drivers/regulator/of_regulator.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/regulator/of_regulator.c +6 -2
index 4bb8928bdb3f..ffa5fc3724e4 100644
@@ -380,12 +380,16 @@ struct device_node *regulator_of_get_init_node(struct device *dev,
 	if (!dev->of_node || !desc->of_match)
 		return NULL;
 
-	if (desc->regulators_node)
+	if (desc->regulators_node) {
 		search = of_get_child_by_name(dev->of_node,
 					      desc->regulators_node);
-	else
+	} else {
 		search = of_node_get(dev->of_node);
 
+		if (!strcmp(desc->of_match, search->name))
+			return search;
+	}
+
 	if (!search) {
 		dev_dbg(dev, "Failed to find regulator container node '%s'\n",
 			desc->regulators_node);
Signature · 1 line
2.11.0