Commit 266423e6 authored by Phil Elwell's avatar Phil Elwell Committed by Linus Walleij

pinctrl: bcm2835: Change init order for gpio hogs

...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: 73345a18 ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
Signed-off-by: default avatarPhil Elwell <phil@raspberrypi.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Link: https://lore.kernel.org/r/20211206092237.4105895-2-phil@raspberrypi.comSigned-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 2d5446da
...@@ -1244,6 +1244,18 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) ...@@ -1244,6 +1244,18 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
raw_spin_lock_init(&pc->irq_lock[i]); 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 = &pc->gpio_chip.irq;
girq->chip = &bcm2835_gpio_irq_chip; girq->chip = &bcm2835_gpio_irq_chip;
girq->parent_handler = bcm2835_gpio_irq_handler; girq->parent_handler = bcm2835_gpio_irq_handler;
...@@ -1251,8 +1263,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) ...@@ -1251,8 +1263,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS, girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
sizeof(*girq->parents), sizeof(*girq->parents),
GFP_KERNEL); GFP_KERNEL);
if (!girq->parents) if (!girq->parents) {
pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
return -ENOMEM; return -ENOMEM;
}
if (is_7211) { if (is_7211) {
pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS, pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
...@@ -1307,21 +1321,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev) ...@@ -1307,21 +1321,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
err = gpiochip_add_data(&pc->gpio_chip, pc); err = gpiochip_add_data(&pc->gpio_chip, pc);
if (err) { if (err) {
dev_err(dev, "could not add GPIO chip\n"); dev_err(dev, "could not add GPIO chip\n");
pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
return err; 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; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment