diff mbox series

[v2,1/2] pinctrl: bcm2835: Change init order for gpio hogs

Message ID 20211206092237.4105895-2-phil@raspberrypi.com
State Accepted
Commit 266423e60ea1b953fcc0cd97f3dad85857e434d1
Headers show
Series [v2,1/2] pinctrl: bcm2835: Change init order for gpio hogs | expand

Commit Message

Phil Elwell Dec. 6, 2021, 9:22 a.m. UTC
...and gpio-ranges

pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
side is registered first, but this breaks gpio hogs (which are
configured during gpiochip_add_data). Part of the hog initialisation
is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
yet been registered this results in an -EPROBE_DEFER from which it can
never recover.

Change the initialisation sequence to register the pinctrl driver
first.

This also solves a similar problem with the gpio-ranges property, which
is required in order for released pins to be returned to inputs.

Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 29 +++++++++++++++------------
 1 file changed, 16 insertions(+), 13 deletions(-)

Comments

Florian Fainelli Dec. 7, 2021, 6:32 p.m. UTC | #1
On 12/6/21 1:22 AM, Phil Elwell wrote:
> ...and gpio-ranges
> 
> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
> side is registered first, but this breaks gpio hogs (which are
> configured during gpiochip_add_data). Part of the hog initialisation
> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
> yet been registered this results in an -EPROBE_DEFER from which it can
> never recover.
> 
> Change the initialisation sequence to register the pinctrl driver
> first.
> 
> This also solves a similar problem with the gpio-ranges property, which
> is required in order for released pins to be returned to inputs.
> 
> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
> Signed-off-by: Phil Elwell <phil@raspberrypi.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Linus Walleij Dec. 9, 2021, 11:24 p.m. UTC | #2
On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:

> ...and gpio-ranges
>
> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
> side is registered first, but this breaks gpio hogs (which are
> configured during gpiochip_add_data). Part of the hog initialisation
> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
> yet been registered this results in an -EPROBE_DEFER from which it can
> never recover.
>
> Change the initialisation sequence to register the pinctrl driver
> first.
>
> This also solves a similar problem with the gpio-ranges property, which
> is required in order for released pins to be returned to inputs.
>
> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
> Signed-off-by: Phil Elwell <phil@raspberrypi.com>

This patch (1/2) applied for fixes.

Yours,
Linus Walleij
Florian Fainelli Dec. 29, 2021, 9:11 p.m. UTC | #3
On 12/29/2021 11:07 AM, Stefan Wahren wrote:
> Am 10.12.21 um 00:24 schrieb Linus Walleij:
>> On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:
>>
>>> ...and gpio-ranges
>>>
>>> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
>>> side is registered first, but this breaks gpio hogs (which are
>>> configured during gpiochip_add_data). Part of the hog initialisation
>>> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
>>> yet been registered this results in an -EPROBE_DEFER from which it can
>>> never recover.
>>>
>>> Change the initialisation sequence to register the pinctrl driver
>>> first.
>>>
>>> This also solves a similar problem with the gpio-ranges property, which
>>> is required in order for released pins to be returned to inputs.
>>>
>>> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
>>> Signed-off-by: Phil Elwell <phil@raspberrypi.com>
>> This patch (1/2) applied for fixes.
> 
> Unfortunately this change breaks all GPIO LEDs at least on the Raspberry
> Pi 3 Plus (Linux 5.16-rc7, multi_v7_defconfig). The ACT LED for instance
> stays in the last state instead of the configured heartbeat behavior.
> Also there are no GPIO LEDs in /sys/class/leds/ directory.
> 
> After reverting this change everything is back to normal.

And this patch has already been applied to the stable 5.15 and 5.10 
branches as well, FWIW.
Linus Walleij Jan. 2, 2022, 6:54 a.m. UTC | #4
On Wed, Dec 29, 2021 at 8:07 PM Stefan Wahren <stefan.wahren@i2se.com> wrote:
> Am 10.12.21 um 00:24 schrieb Linus Walleij:
> > On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:
> >
> >> ...and gpio-ranges
> >>
> >> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
> >> side is registered first, but this breaks gpio hogs (which are
> >> configured during gpiochip_add_data). Part of the hog initialisation
> >> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
> >> yet been registered this results in an -EPROBE_DEFER from which it can
> >> never recover.
> >>
> >> Change the initialisation sequence to register the pinctrl driver
> >> first.
> >>
> >> This also solves a similar problem with the gpio-ranges property, which
> >> is required in order for released pins to be returned to inputs.
> >>
> >> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
> >> Signed-off-by: Phil Elwell <phil@raspberrypi.com>
> > This patch (1/2) applied for fixes.
>
> Unfortunately this change breaks all GPIO LEDs at least on the Raspberry
> Pi 3 Plus (Linux 5.16-rc7, multi_v7_defconfig). The ACT LED for instance
> stays in the last state instead of the configured heartbeat behavior.
> Also there are no GPIO LEDs in /sys/class/leds/ directory.
>
> After reverting this change everything is back to normal.

Oh what a mess. OK I reverted the fix.

Yours,
Linus Walleij
Jan Kiszka Jan. 2, 2022, 11:02 a.m. UTC | #5
On 02.01.22 07:54, Linus Walleij wrote:
> On Wed, Dec 29, 2021 at 8:07 PM Stefan Wahren <stefan.wahren@i2se.com> wrote:
>> Am 10.12.21 um 00:24 schrieb Linus Walleij:
>>> On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:
>>>
>>>> ...and gpio-ranges
>>>>
>>>> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
>>>> side is registered first, but this breaks gpio hogs (which are
>>>> configured during gpiochip_add_data). Part of the hog initialisation
>>>> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
>>>> yet been registered this results in an -EPROBE_DEFER from which it can
>>>> never recover.
>>>>
>>>> Change the initialisation sequence to register the pinctrl driver
>>>> first.
>>>>
>>>> This also solves a similar problem with the gpio-ranges property, which
>>>> is required in order for released pins to be returned to inputs.
>>>>
>>>> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
>>>> Signed-off-by: Phil Elwell <phil@raspberrypi.com>
>>> This patch (1/2) applied for fixes.
>>
>> Unfortunately this change breaks all GPIO LEDs at least on the Raspberry
>> Pi 3 Plus (Linux 5.16-rc7, multi_v7_defconfig). The ACT LED for instance
>> stays in the last state instead of the configured heartbeat behavior.
>> Also there are no GPIO LEDs in /sys/class/leds/ directory.
>>
>> After reverting this change everything is back to normal.
>
> Oh what a mess. OK I reverted the fix.
>

I happened to debug this regression as well: The issue of the patch
seems to be that it initializes gpio_range.base with -1, because
gpio_chip.base is not yet set at this point. Maybe that can be achieved
differently, to please all cases.

Jan
Stefan Wahren Jan. 2, 2022, 12:33 p.m. UTC | #6
Hi Jan,

Am 02.01.22 um 12:02 schrieb Jan Kiszka:
> On 02.01.22 07:54, Linus Walleij wrote:
>> On Wed, Dec 29, 2021 at 8:07 PM Stefan Wahren <stefan.wahren@i2se.com> wrote:
>>> Am 10.12.21 um 00:24 schrieb Linus Walleij:
>>>> On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:
>>>>
>>>>> ...and gpio-ranges
>>>>>
>>>>> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
>>>>> side is registered first, but this breaks gpio hogs (which are
>>>>> configured during gpiochip_add_data). Part of the hog initialisation
>>>>> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
>>>>> yet been registered this results in an -EPROBE_DEFER from which it can
>>>>> never recover.
>>>>>
>>>>> Change the initialisation sequence to register the pinctrl driver
>>>>> first.
>>>>>
>>>>> This also solves a similar problem with the gpio-ranges property, which
>>>>> is required in order for released pins to be returned to inputs.
>>>>>
>>>>> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
>>>>> Signed-off-by: Phil Elwell <phil@raspberrypi.com>
>>>> This patch (1/2) applied for fixes.
>>> Unfortunately this change breaks all GPIO LEDs at least on the Raspberry
>>> Pi 3 Plus (Linux 5.16-rc7, multi_v7_defconfig). The ACT LED for instance
>>> stays in the last state instead of the configured heartbeat behavior.
>>> Also there are no GPIO LEDs in /sys/class/leds/ directory.
>>>
>>> After reverting this change everything is back to normal.
>> Oh what a mess. OK I reverted the fix.
>>
> I happened to debug this regression as well: The issue of the patch
> seems to be that it initializes gpio_range.base with -1, because
> gpio_chip.base is not yet set at this point. Maybe that can be achieved
> differently, to please all cases.

thanks for the hint.

I tried to reproduce the original issue with the gpio hog by adding one
to the RPi Zero W. Here are my test results of this series based on
Linux 5.16:

1. - Patch 1 & 2 not applied: boot hangs caused by gpio hog
2. - Patch 1 applied, Patch 2 not applied: boot hangs caused by gpio hog
3. - Patch 1 not applied, Patch 2 applied: boot hangs caused by gpio hog
4. - Patch 1 & 2 applied: boot ok, LEDs okay, hog okay

So both patches must be applied at the same time. In general this is
done via immutable branch. But this requires caution while backporting.

Best regards

>
> Jan
Jan Kiszka Jan. 2, 2022, 3:12 p.m. UTC | #7
On 02.01.22 13:33, Stefan Wahren wrote:
> Hi Jan,
>
> Am 02.01.22 um 12:02 schrieb Jan Kiszka:
>> On 02.01.22 07:54, Linus Walleij wrote:
>>> On Wed, Dec 29, 2021 at 8:07 PM Stefan Wahren <stefan.wahren@i2se.com> wrote:
>>>> Am 10.12.21 um 00:24 schrieb Linus Walleij:
>>>>> On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:
>>>>>
>>>>>> ...and gpio-ranges
>>>>>>
>>>>>> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
>>>>>> side is registered first, but this breaks gpio hogs (which are
>>>>>> configured during gpiochip_add_data). Part of the hog initialisation
>>>>>> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
>>>>>> yet been registered this results in an -EPROBE_DEFER from which it can
>>>>>> never recover.
>>>>>>
>>>>>> Change the initialisation sequence to register the pinctrl driver
>>>>>> first.
>>>>>>
>>>>>> This also solves a similar problem with the gpio-ranges property, which
>>>>>> is required in order for released pins to be returned to inputs.
>>>>>>
>>>>>> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
>>>>>> Signed-off-by: Phil Elwell <phil@raspberrypi.com>
>>>>> This patch (1/2) applied for fixes.
>>>> Unfortunately this change breaks all GPIO LEDs at least on the Raspberry
>>>> Pi 3 Plus (Linux 5.16-rc7, multi_v7_defconfig). The ACT LED for instance
>>>> stays in the last state instead of the configured heartbeat behavior.
>>>> Also there are no GPIO LEDs in /sys/class/leds/ directory.
>>>>
>>>> After reverting this change everything is back to normal.
>>> Oh what a mess. OK I reverted the fix.
>>>
>> I happened to debug this regression as well: The issue of the patch
>> seems to be that it initializes gpio_range.base with -1, because
>> gpio_chip.base is not yet set at this point. Maybe that can be achieved
>> differently, to please all cases.
>
> thanks for the hint.
>
> I tried to reproduce the original issue with the gpio hog by adding one
> to the RPi Zero W. Here are my test results of this series based on
> Linux 5.16:
>
> 1. - Patch 1 & 2 not applied: boot hangs caused by gpio hog
> 2. - Patch 1 applied, Patch 2 not applied: boot hangs caused by gpio hog
> 3. - Patch 1 not applied, Patch 2 applied: boot hangs caused by gpio hog
> 4. - Patch 1 & 2 applied: boot ok, LEDs okay, hog okay
>
> So both patches must be applied at the same time. In general this is
> done via immutable branch. But this requires caution while backporting.
>

Indeed - upstream and stable are missing patch 2, and that fixes the
issue as well. Too bad that this series was split during merge.

Jan
Jan Kiszka Jan. 2, 2022, 3:16 p.m. UTC | #8
On 02.01.22 16:12, Jan Kiszka wrote:
> On 02.01.22 13:33, Stefan Wahren wrote:
>> Hi Jan,
>>
>> Am 02.01.22 um 12:02 schrieb Jan Kiszka:
>>> On 02.01.22 07:54, Linus Walleij wrote:
>>>> On Wed, Dec 29, 2021 at 8:07 PM Stefan Wahren <stefan.wahren@i2se.com> wrote:
>>>>> Am 10.12.21 um 00:24 schrieb Linus Walleij:
>>>>>> On Mon, Dec 6, 2021 at 10:22 AM Phil Elwell <phil@raspberrypi.com> wrote:
>>>>>>
>>>>>>> ...and gpio-ranges
>>>>>>>
>>>>>>> pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
>>>>>>> side is registered first, but this breaks gpio hogs (which are
>>>>>>> configured during gpiochip_add_data). Part of the hog initialisation
>>>>>>> is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
>>>>>>> yet been registered this results in an -EPROBE_DEFER from which it can
>>>>>>> never recover.
>>>>>>>
>>>>>>> Change the initialisation sequence to register the pinctrl driver
>>>>>>> first.
>>>>>>>
>>>>>>> This also solves a similar problem with the gpio-ranges property, which
>>>>>>> is required in order for released pins to be returned to inputs.
>>>>>>>
>>>>>>> Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
>>>>>>> Signed-off-by: Phil Elwell <phil@raspberrypi.com>
>>>>>> This patch (1/2) applied for fixes.
>>>>> Unfortunately this change breaks all GPIO LEDs at least on the Raspberry
>>>>> Pi 3 Plus (Linux 5.16-rc7, multi_v7_defconfig). The ACT LED for instance
>>>>> stays in the last state instead of the configured heartbeat behavior.
>>>>> Also there are no GPIO LEDs in /sys/class/leds/ directory.
>>>>>
>>>>> After reverting this change everything is back to normal.
>>>> Oh what a mess. OK I reverted the fix.
>>>>
>>> I happened to debug this regression as well: The issue of the patch
>>> seems to be that it initializes gpio_range.base with -1, because
>>> gpio_chip.base is not yet set at this point. Maybe that can be achieved
>>> differently, to please all cases.
>>
>> thanks for the hint.
>>
>> I tried to reproduce the original issue with the gpio hog by adding one
>> to the RPi Zero W. Here are my test results of this series based on
>> Linux 5.16:
>>
>> 1. - Patch 1 & 2 not applied: boot hangs caused by gpio hog
>> 2. - Patch 1 applied, Patch 2 not applied: boot hangs caused by gpio hog
>> 3. - Patch 1 not applied, Patch 2 applied: boot hangs caused by gpio hog
>> 4. - Patch 1 & 2 applied: boot ok, LEDs okay, hog okay
>>
>> So both patches must be applied at the same time. In general this is
>> done via immutable branch. But this requires caution while backporting.
>>
>
> Indeed - upstream and stable are missing patch 2, and that fixes the
> issue as well. Too bad that this series was split during merge.
>

But, in fact, this series was misordered then, suggesting that patch 1
was independent of patch 2, but it actually depended on patch 2 to avoid
even temporary regressions.

Jan
diff mbox series

Patch

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 2abcc6ce4eba3..b607d10e4cbd8 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1244,6 +1244,18 @@  static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 		raw_spin_lock_init(&pc->irq_lock[i]);
 	}
 
+	pc->pctl_desc = *pdata->pctl_desc;
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+	if (IS_ERR(pc->pctl_dev)) {
+		gpiochip_remove(&pc->gpio_chip);
+		return PTR_ERR(pc->pctl_dev);
+	}
+
+	pc->gpio_range = *pdata->gpio_range;
+	pc->gpio_range.base = pc->gpio_chip.base;
+	pc->gpio_range.gc = &pc->gpio_chip;
+	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
 	girq = &pc->gpio_chip.irq;
 	girq->chip = &bcm2835_gpio_irq_chip;
 	girq->parent_handler = bcm2835_gpio_irq_handler;
@@ -1251,8 +1263,10 @@  static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
 				     sizeof(*girq->parents),
 				     GFP_KERNEL);
-	if (!girq->parents)
+	if (!girq->parents) {
+		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
 		return -ENOMEM;
+	}
 
 	if (is_7211) {
 		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
@@ -1307,21 +1321,10 @@  static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	err = gpiochip_add_data(&pc->gpio_chip, pc);
 	if (err) {
 		dev_err(dev, "could not add GPIO chip\n");
+		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
 		return err;
 	}
 
-	pc->pctl_desc = *pdata->pctl_desc;
-	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
-	if (IS_ERR(pc->pctl_dev)) {
-		gpiochip_remove(&pc->gpio_chip);
-		return PTR_ERR(pc->pctl_dev);
-	}
-
-	pc->gpio_range = *pdata->gpio_range;
-	pc->gpio_range.base = pc->gpio_chip.base;
-	pc->gpio_range.gc = &pc->gpio_chip;
-	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
-
 	return 0;
 }