summaryrefslogtreecommitdiff
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorPhil Elwell <phil@raspberrypi.com>2021-12-06 12:22:36 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-12-29 14:28:47 +0300
commit79c6d4fa1be1fd0819c50ebb4dee101bbbc4d20e (patch)
treeb4cc228ba6f0966e81177f279443834f057f51c1 /drivers/pinctrl
parentdfd5b60b5342b6b505a104e48f08ad9b9bdbbd7b (diff)
downloadlinux-79c6d4fa1be1fd0819c50ebb4dee101bbbc4d20e.tar.xz
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: 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: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/bcm/pinctrl-bcm2835.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 6e6fefeb21ea..cc39c0e18b47 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1243,6 +1243,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;
@@ -1250,8 +1262,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,
@@ -1306,21 +1320,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;
}