Commit 43864519 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents e2ae0d4a b67210cc
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -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;
}

+6 −2
Original line number Diff line number Diff line
@@ -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);
+4 −4
Original line number Diff line number Diff line
@@ -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;