pinctrl: bcm2835: Change init order for gpio hogs
[ Upstream commit 266423e60ea1b953fcc0cd97f3dad85857e434d1 ]
...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: 73345a18d4
("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: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
676c572439
commit
ba696b4708
@@ -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)
|
|||||||
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,
|
||||||
@@ -1303,21 +1317,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user