Commit 6d47cdec authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'v5.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio

Pull GPIO fixes from Linus Walleij:
 "These are hopefully the last GPIO fixes for this cycle.

  All are driver fixes except a small resource leak for pin ranges in
  the gpiolib. Two are PM related, which is nice because when developers
  start to find PM bugs it is usually because they have smoked out the
  bugs of more severe nature.

  Summary:

   - Fix runtime PM balancing on the errorpath of the Arizona driver

   - Fix a suspend NULL pointer reference in the dwapb driver

   - Balance free:ing in gpiochip_generic_free()

   - Fix runtime PM balancing on the errorpath of the zynq driver

   - Fix irqdomain use-after-free in the mvebu driver

   - Break an eternal loop in the spreadtrum EIC driver"

* tag 'v5.10-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio:
  gpio: eic-sprd: break loop when getting NULL device resource
  gpio: mvebu: fix potential user-after-free on probe
  gpio: zynq: fix reference leak in zynq_gpio functions
  gpiolib: Don't free if pin ranges are not defined
  gpio: dwapb: fix NULL pointer dereference at dwapb_gpio_suspend()
  gpio: arizona: disable pm_runtime in case of failure
parents c1cea112 263ade71
...@@ -192,6 +192,7 @@ static int arizona_gpio_probe(struct platform_device *pdev) ...@@ -192,6 +192,7 @@ static int arizona_gpio_probe(struct platform_device *pdev)
ret = devm_gpiochip_add_data(&pdev->dev, &arizona_gpio->gpio_chip, ret = devm_gpiochip_add_data(&pdev->dev, &arizona_gpio->gpio_chip,
arizona_gpio); arizona_gpio);
if (ret < 0) { if (ret < 0) {
pm_runtime_disable(&pdev->dev);
dev_err(&pdev->dev, "Could not register gpiochip, %d\n", dev_err(&pdev->dev, "Could not register gpiochip, %d\n",
ret); ret);
return ret; return ret;
......
...@@ -724,6 +724,8 @@ static int dwapb_gpio_probe(struct platform_device *pdev) ...@@ -724,6 +724,8 @@ static int dwapb_gpio_probe(struct platform_device *pdev)
return err; return err;
} }
platform_set_drvdata(pdev, gpio);
return 0; return 0;
} }
......
...@@ -598,7 +598,7 @@ static int sprd_eic_probe(struct platform_device *pdev) ...@@ -598,7 +598,7 @@ static int sprd_eic_probe(struct platform_device *pdev)
*/ */
res = platform_get_resource(pdev, IORESOURCE_MEM, i); res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res) if (!res)
continue; break;
sprd_eic->base[i] = devm_ioremap_resource(&pdev->dev, res); sprd_eic->base[i] = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(sprd_eic->base[i])) if (IS_ERR(sprd_eic->base[i]))
......
...@@ -1197,6 +1197,13 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1197,6 +1197,13 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip);
/* Some MVEBU SoCs have simple PWM support for GPIO lines */
if (IS_ENABLED(CONFIG_PWM)) {
err = mvebu_pwm_probe(pdev, mvchip, id);
if (err)
return err;
}
/* Some gpio controllers do not provide irq support */ /* Some gpio controllers do not provide irq support */
if (!have_irqs) if (!have_irqs)
return 0; return 0;
...@@ -1206,7 +1213,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1206,7 +1213,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
if (!mvchip->domain) { if (!mvchip->domain) {
dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
mvchip->chip.label); mvchip->chip.label);
return -ENODEV; err = -ENODEV;
goto err_pwm;
} }
err = irq_alloc_domain_generic_chips( err = irq_alloc_domain_generic_chips(
...@@ -1254,14 +1262,12 @@ static int mvebu_gpio_probe(struct platform_device *pdev) ...@@ -1254,14 +1262,12 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
mvchip); mvchip);
} }
/* Some MVEBU SoCs have simple PWM support for GPIO lines */
if (IS_ENABLED(CONFIG_PWM))
return mvebu_pwm_probe(pdev, mvchip, id);
return 0; return 0;
err_domain: err_domain:
irq_domain_remove(mvchip->domain); irq_domain_remove(mvchip->domain);
err_pwm:
pwmchip_remove(&mvchip->mvpwm->chip);
return err; return err;
} }
......
...@@ -574,7 +574,7 @@ static int zynq_gpio_irq_reqres(struct irq_data *d) ...@@ -574,7 +574,7 @@ static int zynq_gpio_irq_reqres(struct irq_data *d)
struct gpio_chip *chip = irq_data_get_irq_chip_data(d); struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
int ret; int ret;
ret = pm_runtime_get_sync(chip->parent); ret = pm_runtime_resume_and_get(chip->parent);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -942,7 +942,7 @@ static int zynq_gpio_probe(struct platform_device *pdev) ...@@ -942,7 +942,7 @@ static int zynq_gpio_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev); pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev); ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) if (ret < 0)
goto err_pm_dis; goto err_pm_dis;
......
...@@ -1806,6 +1806,11 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request); ...@@ -1806,6 +1806,11 @@ EXPORT_SYMBOL_GPL(gpiochip_generic_request);
*/ */
void gpiochip_generic_free(struct gpio_chip *gc, unsigned offset) void gpiochip_generic_free(struct gpio_chip *gc, unsigned offset)
{ {
#ifdef CONFIG_PINCTRL
if (list_empty(&gc->gpiodev->pin_ranges))
return;
#endif
pinctrl_gpio_free(gc->gpiodev->base + offset); pinctrl_gpio_free(gc->gpiodev->base + offset);
} }
EXPORT_SYMBOL_GPL(gpiochip_generic_free); EXPORT_SYMBOL_GPL(gpiochip_generic_free);
......
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