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 |
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 --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,