gpio fixes for v7.1

- fix NULL pointer dereference in gpio-mvebu
 - fix runtime PM leak in remove path in gpio-zynq
 - reject invalid module params in gpio-mockup
 - fix generic IRQ chip leak in remove parh in gpio-rockchip
 - fix resource leaks in GPIO chip cleanup path on hog failure
 - fix a regression in how GPIO hogging code handles multiple GPIO chips
   reusing the same OF node
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEkeUTLeW1Rh17omX8BZ0uy/82hMMFAmoqZbYACgkQBZ0uy/82
 hMN+DhAAqntOaHqRks5PqwZlE8jRCFtx1EkvABTnnNHW5t+HXVF+GpBvzRw43aQG
 uppIsusTVnxIojDeuBAzueC6UYjhos5/u2UY8jfaE3HQ7bEksUKS5Ba7b+MzlPo4
 AsPIZey0zuoj1EJNTUZekii7xDcApFu9l+CV9xKqEH+MIySelREJj5sqprJbdF9y
 9hpraeVAn+x333o4zrhWm/mauX/DnFrveqU3nSF+dYQtLwNEJyYntoQZUxrf6I0g
 AHTWRpUMXeUk3aMfmeuaNXrXnfQksanPDYIWT5LmvWoOWkka+iqX0nbUeA51myhZ
 soGzfQ7flYQTZRalu4tqjz7YnVpZC1u9xmgaQlOIwVmEyeW1YPOI6yDjIPWZwUFi
 3DupOvBf98wpIU8wCLVUN/vul496dLw793S4TOnaSGlaMQnz9mop0Qq6Ffb0hgS+
 V5M3cRA2K/aivjtU7r5921M/0NamozIPRadl+1L8USvL1pw8atHjndFIVXgxygln
 Qi3nxEiqWNRk+45YYM7HFdxGZB4bJefq5qwiB9l4Bmz2FczrpMgFMgvdO/jp6HAN
 e3YKhfoDrQBd2tf2V3WodmMHhmkR+SLjLfCPZ9rZiueh1NuU/GOzRwN2sD/tABac
 rV7DSamrrRZzsagHKpyCxTi/Dd0shDh5kVWCtcLggaEO8m7sFEQ=
 =ov9g
 -----END PGP SIGNATURE-----

Merge tag 'gpio-fixes-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - fix NULL pointer dereference in gpio-mvebu

 - fix runtime PM leak in remove path in gpio-zynq

 - reject invalid module params in gpio-mockup

 - fix generic IRQ chip leak in remove parh in gpio-rockchip

 - fix resource leaks in GPIO chip cleanup path on hog failure

 - fix a regression in how GPIO hogging code handles multiple GPIO chips
   reusing the same OF node

* tag 'gpio-fixes-for-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpiolib: handle gpio-hogs only once
  gpio: fix cleanup path on hog failure
  gpio: rockchip: fix generic IRQ chip leak on remove
  gpio: mockup: reject invalid gpio_mockup_ranges widths
  gpio: zynq: fix runtime PM leak on remove
  gpio: mvebu: fix NULL pointer dereference in suspend/resume
This commit is contained in:
Linus Torvalds 2026-06-11 09:15:57 -07:00
commit 6e9e0dfc7f
6 changed files with 29 additions and 11 deletions

View File

@ -17,6 +17,7 @@
#include <linux/irq.h>
#include <linux/irq_sim.h>
#include <linux/irqdomain.h>
#include <linux/limits.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@ -578,7 +579,7 @@ static int __init gpio_mockup_register_chip(int idx)
static int __init gpio_mockup_init(void)
{
int i, num_chips, err;
int i, num_chips, err, base, ngpio;
if ((gpio_mockup_num_ranges % 2) ||
(gpio_mockup_num_ranges > GPIO_MOCKUP_MAX_RANGES))
@ -592,8 +593,19 @@ static int __init gpio_mockup_init(void)
* always be greater than 0.
*/
for (i = 0; i < num_chips; i++) {
if (gpio_mockup_range_ngpio(i) < 0)
base = gpio_mockup_range_base(i);
ngpio = gpio_mockup_range_ngpio(i);
if (ngpio <= 0)
return -EINVAL;
if (base < 0) {
if (ngpio > U16_MAX)
return -EINVAL;
} else {
if (ngpio <= base || ngpio - base > U16_MAX)
return -EINVAL;
}
}
gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup", NULL);

View File

@ -996,7 +996,7 @@ static int mvebu_gpio_suspend(struct platform_device *pdev, pm_message_t state)
BUG();
}
if (IS_REACHABLE(CONFIG_PWM))
if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
mvebu_pwm_suspend(mvchip);
return 0;
@ -1048,7 +1048,7 @@ static int mvebu_gpio_resume(struct platform_device *pdev)
BUG();
}
if (IS_REACHABLE(CONFIG_PWM))
if (IS_REACHABLE(CONFIG_PWM) && mvchip->mvpwm)
mvebu_pwm_resume(mvchip);
return 0;

View File

@ -802,8 +802,10 @@ static void rockchip_gpio_remove(struct platform_device *pdev)
struct rockchip_pin_bank *bank = platform_get_drvdata(pdev);
irq_set_chained_handler_and_data(bank->irq, NULL, NULL);
if (bank->domain)
if (bank->domain) {
irq_domain_remove_generic_chips(bank->domain);
irq_domain_remove(bank->domain);
}
gpiochip_remove(&bank->gpio_chip);
}

View File

@ -1014,6 +1014,7 @@ static void zynq_gpio_remove(struct platform_device *pdev)
gpiochip_remove(&gpio->chip);
device_set_wakeup_capable(&pdev->dev, 0);
pm_runtime_disable(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
}
static struct platform_driver zynq_gpio_driver = {

View File

@ -1066,11 +1066,6 @@ int of_gpiochip_add(struct gpio_chip *chip)
of_node_get(np);
for_each_available_child_of_node_scoped(np, child) {
if (of_property_read_bool(child, "gpio-hog"))
of_node_set_flag(child, OF_POPULATED);
}
return ret;
}

View File

@ -1031,9 +1031,17 @@ static int gpiochip_hog_lines(struct gpio_chip *gc)
if (!fwnode_property_present(fwnode, "gpio-hog"))
continue;
/* The hog may have been handled by another gpio_chip on the same fwnode */
if (is_of_node(fwnode) &&
of_node_check_flag(to_of_node(fwnode), OF_POPULATED))
continue;
ret = gpiochip_add_hog(gc, fwnode);
if (ret)
return ret;
if (is_of_node(fwnode))
of_node_set_flag(to_of_node(fwnode), OF_POPULATED);
}
return 0;
@ -1291,7 +1299,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiochip_hog_lines(gc);
if (ret)
goto err_remove_of_chip;
goto err_free_hogs;
ret = gpiochip_irqchip_init_valid_mask(gc);
if (ret)