pinctrl: msm: Use init_valid_mask exported function
authorRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Fri, 5 Oct 2018 06:52:59 +0000 (08:52 +0200)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 10 Oct 2018 08:31:57 +0000 (10:31 +0200)
The current code produces XPU violation if get_direction is called just
after the initialization.

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Acked-by: Timur Tabi <timur@kernel.org>
Tested-by: Jeffrey Hugo <jhugo@codeaurora.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/pinctrl/qcom/pinctrl-msm.c

index 2155a30c282b24e20ba440e1398e8d71b308647e..8366b41ea609da7bb557482a7df2aa7371016c4e 100644 (file)
@@ -566,6 +566,42 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 #define msm_gpio_dbg_show NULL
 #endif
 
+static int msm_gpio_init_valid_mask(struct gpio_chip *chip)
+{
+       struct msm_pinctrl *pctrl = gpiochip_get_data(chip);
+       int ret;
+       unsigned int len, i;
+       unsigned int max_gpios = pctrl->soc->ngpios;
+       u16 *tmp;
+
+       /* The number of GPIOs in the ACPI tables */
+       len = ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL,
+                                                  0);
+       if (ret < 0)
+               return 0;
+
+       if (ret > max_gpios)
+               return -EINVAL;
+
+       tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL);
+       if (!tmp)
+               return -ENOMEM;
+
+       ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp, len);
+       if (ret < 0) {
+               dev_err(pctrl->dev, "could not read list of GPIOs\n");
+               goto out;
+       }
+
+       bitmap_zero(chip->valid_mask, max_gpios);
+       for (i = 0; i < len; i++)
+               set_bit(tmp[i], chip->valid_mask);
+
+out:
+       kfree(tmp);
+       return ret;
+}
+
 static const struct gpio_chip msm_gpio_template = {
        .direction_input  = msm_gpio_direction_input,
        .direction_output = msm_gpio_direction_output,
@@ -575,6 +611,7 @@ static const struct gpio_chip msm_gpio_template = {
        .request          = gpiochip_generic_request,
        .free             = gpiochip_generic_free,
        .dbg_show         = msm_gpio_dbg_show,
+       .init_valid_mask  = msm_gpio_init_valid_mask,
 };
 
 /* For dual-edge interrupts in software, since some hardware has no
@@ -831,41 +868,6 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)
        chained_irq_exit(chip, desc);
 }
 
-static int msm_gpio_init_valid_mask(struct gpio_chip *chip,
-                                   struct msm_pinctrl *pctrl)
-{
-       int ret;
-       unsigned int len, i;
-       unsigned int max_gpios = pctrl->soc->ngpios;
-       u16 *tmp;
-
-       /* The number of GPIOs in the ACPI tables */
-       len = ret = device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0);
-       if (ret < 0)
-               return 0;
-
-       if (ret > max_gpios)
-               return -EINVAL;
-
-       tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL);
-       if (!tmp)
-               return -ENOMEM;
-
-       ret = device_property_read_u16_array(pctrl->dev, "gpios", tmp, len);
-       if (ret < 0) {
-               dev_err(pctrl->dev, "could not read list of GPIOs\n");
-               goto out;
-       }
-
-       bitmap_zero(chip->valid_mask, max_gpios);
-       for (i = 0; i < len; i++)
-               set_bit(tmp[i], chip->valid_mask);
-
-out:
-       kfree(tmp);
-       return ret;
-}
-
 static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
 {
        return device_property_read_u16_array(pctrl->dev, "gpios", NULL, 0) > 0;
@@ -902,13 +904,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
                return ret;
        }
 
-       ret = msm_gpio_init_valid_mask(chip, pctrl);
-       if (ret) {
-               dev_err(pctrl->dev, "Failed to setup irq valid bits\n");
-               gpiochip_remove(&pctrl->chip);
-               return ret;
-       }
-
        /*
         * For DeviceTree-supported systems, the gpio core checks the
         * pinctrl's device node for the "gpio-ranges" property.