lkml.org 
[lkml]   [2022]   [Jan]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH stable 5.4 6/7] pinctrl: bcm2835: Change init order for gpio hogs
    Date
    From: Phil Elwell <phil@raspberrypi.com>

    commit 266423e60ea1b953fcc0cd97f3dad85857e434d1 upstream

    ...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>
    Link: https://lore.kernel.org/r/20211206092237.4105895-2-phil@raspberrypi.com
    Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
    Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
    ---
    drivers/pinctrl/bcm/pinctrl-bcm2835.c | 29 +++++++++++++++------------
    1 file changed, 16 insertions(+), 13 deletions(-)

    diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
    index 436184ebd2ef..fa742535f679 100644
    --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
    +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
    @@ -1241,6 +1241,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;
    @@ -1248,8 +1260,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,
    @@ -1300,21 +1314,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;
    }

    --
    2.25.1
    \
     
     \ /
      Last update: 2022-01-25 20:45    [W:3.639 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site