diff mbox series

[for-3.18.y+] pinctrl: msm: fix gpio-hog related boot issues

Message ID 1550493012-5959-2-git-send-email-amit.pundir@linaro.org
State New
Headers show
Series [for-3.18.y+] pinctrl: msm: fix gpio-hog related boot issues | expand

Commit Message

Amit Pundir Feb. 18, 2019, 12:30 p.m. UTC
From: Christian Lamparter <chunkeey@gmail.com>


commit a86caa9ba5d70696ceb35d1d39caa20d8b641387 upstream.

Sven Eckelmann reported an issue with the current IPQ4019 pinctrl.
Setting up any gpio-hog in the device-tree for his device would
"kill the bootup completely":

| [    0.477838] msm_serial 78af000.serial: could not find pctldev for node /soc/pinctrl@1000000/serial_pinmux, deferring probe
| [    0.499828] spi_qup 78b5000.spi: could not find pctldev for node /soc/pinctrl@1000000/spi_0_pinmux, deferring probe
| [    1.298883] requesting hog GPIO enable USB2 power (chip 1000000.pinctrl, offset 58) failed, -517
| [    1.299609] gpiochip_add_data: GPIOs 0..99 (1000000.pinctrl) failed to register
| [    1.308589] ipq4019-pinctrl 1000000.pinctrl: Failed register gpiochip
| [    1.316586] msm_serial 78af000.serial: could not find pctldev for node /soc/pinctrl@1000000/serial_pinmux, deferring probe
| [    1.322415] spi_qup 78b5000.spi: could not find pctldev for node /soc/pinctrl@1000000/spi_0_pinmux, deferri

This was also verified on a RT-AC58U (IPQ4018) which would
no longer boot, if a gpio-hog was specified. (Tried forcing
the USB LED PIN (GPIO0) to high.).

The problem is that Pinctrl+GPIO registration is currently
peformed in the following order in pinctrl-msm.c:
	1. pinctrl_register()
	2. gpiochip_add()
	3. gpiochip_add_pin_range()

The actual error code -517 == -EPROBE_DEFER is coming from
pinctrl_get_device_gpio_range(), which is called through:
        gpiochip_add
            of_gpiochip_add
                of_gpiochip_scan_gpios
                    gpiod_hog
                        gpiochip_request_own_desc
                            __gpiod_request
                                chip->request
                                    gpiochip_generic_request
                                       pinctrl_gpio_request
                                          pinctrl_get_device_gpio_range

pinctrl_get_device_gpio_range() is unable to find any valid
pin ranges, since nothing has been added to the pinctrldev_list yet.
so the range can't be found, and the operation fails with -EPROBE_DEFER.

This patch fixes the issue by adding the "gpio-ranges" property to
the pinctrl device node of all upstream Qcom SoC. The pin ranges are
then added by the gpio core.

In order to remain compatible with older, existing DTs (and ACPI)
a check for the "gpio-ranges" property has been added to
msm_gpio_init(). This prevents the driver of adding the same entry
to the pinctrldev_list twice.

Reported-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com> [ipq4019]

Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

[AmitP: Minor rebasing for Stable]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>

---
Cherry-picked from lede tree https://git.lede-project.org/?p=source.git
and build tested for LTS trees up to v4.14.y for ARCH=arm/arm64 defconfig.

 drivers/pinctrl/qcom/pinctrl-msm.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

-- 
2.7.4

Comments

Greg Kroah-Hartman Feb. 18, 2019, 1:31 p.m. UTC | #1
On Mon, Feb 18, 2019 at 06:00:11PM +0530, Amit Pundir wrote:
> From: Christian Lamparter <chunkeey@gmail.com>

> 

> commit a86caa9ba5d70696ceb35d1d39caa20d8b641387 upstream.

> 

> Sven Eckelmann reported an issue with the current IPQ4019 pinctrl.

> Setting up any gpio-hog in the device-tree for his device would

> "kill the bootup completely":

> 

> | [    0.477838] msm_serial 78af000.serial: could not find pctldev for node /soc/pinctrl@1000000/serial_pinmux, deferring probe

> | [    0.499828] spi_qup 78b5000.spi: could not find pctldev for node /soc/pinctrl@1000000/spi_0_pinmux, deferring probe

> | [    1.298883] requesting hog GPIO enable USB2 power (chip 1000000.pinctrl, offset 58) failed, -517

> | [    1.299609] gpiochip_add_data: GPIOs 0..99 (1000000.pinctrl) failed to register

> | [    1.308589] ipq4019-pinctrl 1000000.pinctrl: Failed register gpiochip

> | [    1.316586] msm_serial 78af000.serial: could not find pctldev for node /soc/pinctrl@1000000/serial_pinmux, deferring probe

> | [    1.322415] spi_qup 78b5000.spi: could not find pctldev for node /soc/pinctrl@1000000/spi_0_pinmux, deferri

> 

> This was also verified on a RT-AC58U (IPQ4018) which would

> no longer boot, if a gpio-hog was specified. (Tried forcing

> the USB LED PIN (GPIO0) to high.).

> 

> The problem is that Pinctrl+GPIO registration is currently

> peformed in the following order in pinctrl-msm.c:

> 	1. pinctrl_register()

> 	2. gpiochip_add()

> 	3. gpiochip_add_pin_range()

> 

> The actual error code -517 == -EPROBE_DEFER is coming from

> pinctrl_get_device_gpio_range(), which is called through:

>         gpiochip_add

>             of_gpiochip_add

>                 of_gpiochip_scan_gpios

>                     gpiod_hog

>                         gpiochip_request_own_desc

>                             __gpiod_request

>                                 chip->request

>                                     gpiochip_generic_request

>                                        pinctrl_gpio_request

>                                           pinctrl_get_device_gpio_range

> 

> pinctrl_get_device_gpio_range() is unable to find any valid

> pin ranges, since nothing has been added to the pinctrldev_list yet.

> so the range can't be found, and the operation fails with -EPROBE_DEFER.

> 

> This patch fixes the issue by adding the "gpio-ranges" property to

> the pinctrl device node of all upstream Qcom SoC. The pin ranges are

> then added by the gpio core.

> 

> In order to remain compatible with older, existing DTs (and ACPI)

> a check for the "gpio-ranges" property has been added to

> msm_gpio_init(). This prevents the driver of adding the same entry

> to the pinctrldev_list twice.

> 

> Reported-by: Sven Eckelmann <sven.eckelmann@openmesh.com>

> Tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com> [ipq4019]

> Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>

> Signed-off-by: Christian Lamparter <chunkeey@gmail.com>

> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

> [AmitP: Minor rebasing for Stable]

> Signed-off-by: Amit Pundir <amit.pundir@linaro.org>

> ---

> Cherry-picked from lede tree https://git.lede-project.org/?p=source.git

> and build tested for LTS trees up to v4.14.y for ARCH=arm/arm64 defconfig.


Now applied, thanks.

greg k-h
diff mbox series

Patch

diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 31632c087504..8f0368330a04 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -839,11 +839,24 @@  static int msm_gpio_init(struct msm_pinctrl *pctrl)
 		return ret;
 	}
 
-	ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);
-	if (ret) {
-		dev_err(pctrl->dev, "Failed to add pin range\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.
+	 * If it is present, it takes care of adding the pin ranges
+	 * for the driver. In this case the driver can skip ahead.
+	 *
+	 * In order to remain compatible with older, existing DeviceTree
+	 * files which don't set the "gpio-ranges" property or systems that
+	 * utilize ACPI the driver has to call gpiochip_add_pin_range().
+	 */
+	if (!of_property_read_bool(pctrl->dev->of_node, "gpio-ranges")) {
+		ret = gpiochip_add_pin_range(&pctrl->chip,
+			dev_name(pctrl->dev), 0, 0, chip->ngpio);
+		if (ret) {
+			dev_err(pctrl->dev, "Failed to add pin range\n");
+			gpiochip_remove(&pctrl->chip);
+			return ret;
+		}
 	}
 
 	ret = gpiochip_irqchip_add(chip,