Some hopefully final pin control fixes for the v5.16 kernel:

- Fix an out-of-bounds bug in the Mediatek driver
 - Fix an init order bug in the Broadcom BCM2835 driver
 - Fix a GPIO offset bug in the STM32 driver
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEElDRnuGcz/wPCXQWMQRCzN7AZXXMFAmHH3VUACgkQQRCzN7AZ
 XXNIOBAAmPYOpFC7UrQ5dr6RU2X9/sG1NjyMRcl0fsuTi+vv0BmBWUj3lC64Epjm
 CubPen+UpEkcME2t7h7XNT2qgtHraHdnQ7muCwriClq6qZiOJVmMIflGTONEbrcG
 wGEIRBH/1EMFr/5oYdF2caJ7VQzSR6d6JwKzLr/P4NJxPOoMxQL27Pw1C1umud2z
 ailoYrtRYqN71aAMFBl0v0pgiiFffYN6ey4CNEwZ1Vj5UodsYP4tNtMSkky+a31L
 AHoqu1f4hNiTAfa0C/UxuOhlQyak4iw8PKcQErwhJ1a06BKHT9xA9QYa7l7FuH7i
 DoDmuKoR96LJnEotVYwHpwWLUv3LwhSk+uZl58xLhmDovk8yo9V3vmNAwAS1Ckf8
 i8kVZyTRXGXrChAmwEZz48w++8B2+xQB1y8LnkfhG7fx9izwsDXouTd/ilnofNdA
 sWbd+lB2Bfn1qjKu+SFnXvXOwt7ji8FuCp3hMvZE2ANh6NV6boYro4isSrcXHvCV
 Tw1qDuEHqIKZimz/PwJPryHLTs3T3GkXqejh9ciFY7x4JVkhIhtTCXITRgsPasBm
 gt7eBD7HvkaXbbLdIRU56VbKgD4aIjtyQ27d3V4bZMA/8S8ynI1d/FDN5FQcLxlW
 IQbTvF63UxOWCEcY1S+J+NSE1twuaY0ZE2b4ElmNTOQkfxYi20I=
 =9jNV
 -----END PGP SIGNATURE-----

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

Pull pin control fixes from Linus Walleij:
 "Some hopefully final pin control fixes for the v5.16 kernel:

   - Fix an out-of-bounds bug in the Mediatek driver

   - Fix an init order bug in the Broadcom BCM2835 driver

   - Fix a GPIO offset bug in the STM32 driver"

* tag 'pinctrl-v5.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines
  pinctrl: bcm2835: Change init order for gpio hogs
  pinctrl: mediatek: fix global-out-of-bounds issue
This commit is contained in:
Linus Torvalds 2021-12-25 20:00:09 -08:00
commit 438645193e
3 changed files with 26 additions and 19 deletions

View file

@ -1244,6 +1244,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;
@ -1251,8 +1263,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,
@ -1307,21 +1321,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;
}

View file

@ -285,8 +285,12 @@ static int mtk_xt_get_gpio_n(void *data, unsigned long eint_n,
desc = (const struct mtk_pin_desc *)hw->soc->pins;
*gpio_chip = &hw->chip;
/* Be greedy to guess first gpio_n is equal to eint_n */
if (desc[eint_n].eint.eint_n == eint_n)
/*
* Be greedy to guess first gpio_n is equal to eint_n.
* Only eint virtual eint number is greater than gpio number.
*/
if (hw->soc->npins > eint_n &&
desc[eint_n].eint.eint_n == eint_n)
*gpio_n = eint_n;
else
*gpio_n = mtk_xt_find_eint_num(hw, eint_n);

View file

@ -1251,10 +1251,10 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl,
bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK;
bank->gpio_chip.base = args.args[1];
npins = args.args[2];
while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3,
++i, &args))
npins += args.args[2];
/* get the last defined gpio line (offset + nb of pins) */
npins = args.args[0] + args.args[2];
while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, ++i, &args))
npins = max(npins, (int)(args.args[0] + args.args[2]));
} else {
bank_nr = pctl->nbanks;
bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK;