[PATCH V2 5/6] pinctrl: bcm: pinctrl-ns: supoprt DT specified pins, groups & functions

Rafał Miłecki zajec5 at gmail.com
Wed Nov 24 15:04:38 PST 2021


From: Rafał Miłecki <rafal at milecki.pl>

It's now possible to specify hardware pins, groups & functions in DT
instead of hardcoding that info in a driver. Use pinctrl subsystem
helpers to extract that info from DT.

Keep hardcoded data as fallback method.

Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 drivers/pinctrl/bcm/pinctrl-ns.c | 90 +++++++++++++++++++++-----------
 1 file changed, 60 insertions(+), 30 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-ns.c b/drivers/pinctrl/bcm/pinctrl-ns.c
index 0897041b5ef1..9036d62c806f 100644
--- a/drivers/pinctrl/bcm/pinctrl-ns.c
+++ b/drivers/pinctrl/bcm/pinctrl-ns.c
@@ -213,7 +213,11 @@ static int ns_pinctrl_probe(struct platform_device *pdev)
 	struct ns_pinctrl *ns_pinctrl;
 	struct pinctrl_desc *pctldesc;
 	struct pinctrl_pin_desc *pin;
+	struct device_node *functions;
+	struct device_node *groups;
+	struct device_node *pins;
 	struct resource *res;
+	int err;
 	int i;
 
 	ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL);
@@ -243,19 +247,27 @@ static int ns_pinctrl_probe(struct platform_device *pdev)
 
 	/* Set pinctrl properties */
 
-	pctldesc->pins = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_pins),
-				      sizeof(struct pinctrl_pin_desc),
-				      GFP_KERNEL);
-	if (!pctldesc->pins)
-		return -ENOMEM;
-	for (i = 0, pin = (struct pinctrl_pin_desc *)&pctldesc->pins[0];
-	     i < ARRAY_SIZE(ns_pinctrl_pins); i++) {
-		const struct pinctrl_pin_desc *src = &ns_pinctrl_pins[i];
-		unsigned int chipsets = (uintptr_t)src->drv_data;
-
-		if (chipsets & ns_pinctrl->chipset_flag) {
-			memcpy(pin++, src, sizeof(*src));
-			pctldesc->npins++;
+	pins = of_get_child_by_name(dev->of_node, "pins");
+	if (pins) {
+		err = pinctrl_generic_load_pins(pctldesc, dev);
+		of_node_put(pins);
+		if (err)
+			return err;
+	} else {
+		pctldesc->pins = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_pins),
+					sizeof(struct pinctrl_pin_desc),
+					GFP_KERNEL);
+		if (!pctldesc->pins)
+			return -ENOMEM;
+		for (i = 0, pin = (struct pinctrl_pin_desc *)&pctldesc->pins[0];
+		     i < ARRAY_SIZE(ns_pinctrl_pins); i++) {
+			const struct pinctrl_pin_desc *src = &ns_pinctrl_pins[i];
+			unsigned int chipsets = (uintptr_t)src->drv_data;
+
+			if (chipsets & ns_pinctrl->chipset_flag) {
+				memcpy(pin++, src, sizeof(*src));
+				pctldesc->npins++;
+			}
 		}
 	}
 
@@ -267,25 +279,43 @@ static int ns_pinctrl_probe(struct platform_device *pdev)
 		return PTR_ERR(ns_pinctrl->pctldev);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(ns_pinctrl_groups); i++) {
-		const struct ns_pinctrl_group *group = &ns_pinctrl_groups[i];
-
-		if (!(group->chipsets & ns_pinctrl->chipset_flag))
-			continue;
-
-		pinctrl_generic_add_group(ns_pinctrl->pctldev, group->name,
-					  group->pins, group->num_pins, NULL);
+	groups = of_get_child_by_name(dev->of_node, "groups");
+	if (groups) {
+		err = pinctrl_generic_load_groups(ns_pinctrl->pctldev);
+		of_node_put(groups);
+		if (err)
+			return err;
+	} else {
+		for (i = 0; i < ARRAY_SIZE(ns_pinctrl_groups); i++) {
+			const struct ns_pinctrl_group *group = &ns_pinctrl_groups[i];
+
+			if (!(group->chipsets & ns_pinctrl->chipset_flag))
+				continue;
+
+			pinctrl_generic_add_group(ns_pinctrl->pctldev,
+						  group->name, group->pins,
+						  group->num_pins, NULL);
+		}
 	}
 
-	for (i = 0; i < ARRAY_SIZE(ns_pinctrl_functions); i++) {
-		const struct ns_pinctrl_function *function = &ns_pinctrl_functions[i];
-
-		if (!(function->chipsets & ns_pinctrl->chipset_flag))
-			continue;
-
-		pinmux_generic_add_function(ns_pinctrl->pctldev, function->name,
-					    function->groups,
-					    function->num_groups, NULL);
+	functions = of_get_child_by_name(dev->of_node, "functions");
+	if (functions) {
+		err = pinmux_generic_load_functions(ns_pinctrl->pctldev);
+		of_node_put(functions);
+		if (err)
+			return err;
+	} else {
+		for (i = 0; i < ARRAY_SIZE(ns_pinctrl_functions); i++) {
+			const struct ns_pinctrl_function *function = &ns_pinctrl_functions[i];
+
+			if (!(function->chipsets & ns_pinctrl->chipset_flag))
+				continue;
+
+			pinmux_generic_add_function(ns_pinctrl->pctldev,
+						    function->name,
+						    function->groups,
+						    function->num_groups, NULL);
+		}
 	}
 
 	return 0;
-- 
2.31.1




More information about the linux-arm-kernel mailing list