pinctrl: fix pinctrl_gpio_get_pinctrl_and_offset for gpio-ranges array
authorQuanyang Wang <quanyang.wang@windriver.com>
Thu, 16 Mar 2023 06:11:46 +0000 (14:11 +0800)
committerSimon Glass <sjg@chromium.org>
Sun, 2 Apr 2023 18:53:53 +0000 (06:53 +1200)
Sometimes a multi-element array is used for "gpio-ranges" property in
dts file:

    qe_pio_e: gpio-controller@1460 {
        ......
        gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>;
        ......
    };

But the function pinctrl_gpio_get_pinctrl_and_offset can't handle this
case because the "index" argument passed to dev_read_phandle_with_args
is fixed to be "0". Use a loop to traverse the array to fix it.

Signed-off-by: Quanyang Wang <quanyang.wang@windriver.com>
drivers/pinctrl/pinctrl-uclass.c

index 8837726..73dd7b1 100644 (file)
@@ -169,34 +169,33 @@ pinctrl_gpio_get_pinctrl_and_offset(struct udevice *dev, unsigned offset,
 {
        struct ofnode_phandle_args args;
        unsigned gpio_offset, pfc_base, pfc_pins;
-       int ret;
+       int ret = 0;
+       int i = 0;
 
-       ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
-                                        0, &args);
-       if (ret) {
-               dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n",
-                       __func__, ret);
-               return ret;
-       }
+       while (ret == 0) {
+               ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
+                                                i++, &args);
+               if (ret) {
+                       dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n",
+                               __func__, ret);
+                       return ret;
+               }
 
-       ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL,
-                                         args.node, pctldev);
-       if (ret) {
-               dev_dbg(dev,
-                       "%s: uclass_get_device_by_of_offset failed: err=%d\n",
-                       __func__, ret);
-               return ret;
-       }
+               ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL,
+                                                 args.node, pctldev);
+               if (ret) {
+                       dev_dbg(dev,
+                               "%s: uclass_get_device_by_of_offset failed: err=%d\n",
+                               __func__, ret);
+                       return ret;
+               }
 
-       gpio_offset = args.args[0];
-       pfc_base = args.args[1];
-       pfc_pins = args.args[2];
+               gpio_offset = args.args[0];
+               pfc_base = args.args[1];
+               pfc_pins = args.args[2];
 
-       if (offset < gpio_offset || offset > gpio_offset + pfc_pins) {
-               dev_dbg(dev,
-                       "%s: GPIO can not be mapped to pincontrol pin\n",
-                       __func__);
-               return -EINVAL;
+               if (offset >= gpio_offset && offset <= gpio_offset + pfc_pins)
+                       break;
        }
 
        offset -= gpio_offset;