pinctrl: renesas: rzg2l: Handle non-unique subnode names
authorBiju Das <biju.das.jz@bp.renesas.com>
Tue, 4 Jul 2023 11:18:58 +0000 (12:18 +0100)
committerGeert Uytterhoeven <geert+renesas@glider.be>
Mon, 10 Jul 2023 08:00:27 +0000 (10:00 +0200)
Currently, sd1 and sd0 have unique subnode names 'sd1_mux' and 'sd0_mux'.
If we change these to non-unique subnode names such as 'mux' this can
lead to the below conflict as the RZ/G2L pin control driver considers
only the names of the subnodes.

   pinctrl-rzg2l 11030000.pinctrl: pin P47_0 already requested by 11c00000.mmc; cannot claim for 11c10000.mmc
   pinctrl-rzg2l 11030000.pinctrl: pin-376 (11c10000.mmc) status -22
   pinctrl-rzg2l 11030000.pinctrl: could not request pin 376 (P47_0) from group mux  on device pinctrl-rzg2l
   renesas_sdhi_internal_dmac 11c10000.mmc: Error applying setting, reverse things back

Fix this by constructing unique names from the node names of both the
pin control configuration node and its child node, where appropriate.

Based on the work done by Geert for the RZ/V2M pinctrl driver.

Fixes: c4c4637eb57f ("pinctrl: renesas: Add RZ/G2L pin and gpio controller driver")
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20230704111858.215278-1-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
drivers/pinctrl/renesas/pinctrl-rzg2l.c

index 9511d92..b53d261 100644 (file)
@@ -249,6 +249,7 @@ static int rzg2l_map_add_config(struct pinctrl_map *map,
 
 static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
                                   struct device_node *np,
+                                  struct device_node *parent,
                                   struct pinctrl_map **map,
                                   unsigned int *num_maps,
                                   unsigned int *index)
@@ -266,6 +267,7 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
        struct property *prop;
        int ret, gsel, fsel;
        const char **pin_fn;
+       const char *name;
        const char *pin;
 
        pinmux = of_find_property(np, "pinmux", NULL);
@@ -349,8 +351,19 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
                psel_val[i] = MUX_FUNC(value);
        }
 
+       if (parent) {
+               name = devm_kasprintf(pctrl->dev, GFP_KERNEL, "%pOFn.%pOFn",
+                                     parent, np);
+               if (!name) {
+                       ret = -ENOMEM;
+                       goto done;
+               }
+       } else {
+               name = np->name;
+       }
+
        /* Register a single pin group listing all the pins we read from DT */
-       gsel = pinctrl_generic_add_group(pctldev, np->name, pins, num_pinmux, NULL);
+       gsel = pinctrl_generic_add_group(pctldev, name, pins, num_pinmux, NULL);
        if (gsel < 0) {
                ret = gsel;
                goto done;
@@ -360,17 +373,16 @@ static int rzg2l_dt_subnode_to_map(struct pinctrl_dev *pctldev,
         * Register a single group function where the 'data' is an array PSEL
         * register values read from DT.
         */
-       pin_fn[0] = np->name;
-       fsel = pinmux_generic_add_function(pctldev, np->name, pin_fn, 1,
-                                          psel_val);
+       pin_fn[0] = name;
+       fsel = pinmux_generic_add_function(pctldev, name, pin_fn, 1, psel_val);
        if (fsel < 0) {
                ret = fsel;
                goto remove_group;
        }
 
        maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
-       maps[idx].data.mux.group = np->name;
-       maps[idx].data.mux.function = np->name;
+       maps[idx].data.mux.group = name;
+       maps[idx].data.mux.function = name;
        idx++;
 
        dev_dbg(pctrl->dev, "Parsed %pOF with %d pins\n", np, num_pinmux);
@@ -417,7 +429,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev,
        index = 0;
 
        for_each_child_of_node(np, child) {
-               ret = rzg2l_dt_subnode_to_map(pctldev, child, map,
+               ret = rzg2l_dt_subnode_to_map(pctldev, child, np, map,
                                              num_maps, &index);
                if (ret < 0) {
                        of_node_put(child);
@@ -426,7 +438,7 @@ static int rzg2l_dt_node_to_map(struct pinctrl_dev *pctldev,
        }
 
        if (*num_maps == 0) {
-               ret = rzg2l_dt_subnode_to_map(pctldev, np, map,
+               ret = rzg2l_dt_subnode_to_map(pctldev, np, NULL, map,
                                              num_maps, &index);
                if (ret < 0)
                        goto done;