Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: cherryview: fix issues caused by dynamic gpio irqs mapping

New GPIO IRQs are allocated and mapped dynamically by default when
GPIO IRQ infrastructure is used by cherryview-pinctrl driver.
This causes issues on some Intel platforms [1][2] with broken BIOS which
hardcodes Linux IRQ numbers in their ACPI tables.

On such platforms cherryview-pinctrl driver should allocate and map all
GPIO IRQs at probe time.
Side effect - "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n"
can be seen at boot log.

NOTE. It still may fail if boot sequence will changed and some interrupt
controller will be probed before cherryview-pinctrl which will shift Linux IRQ
numbering (expected with CONFIG_SPARCE_IRQ enabled).

[1] https://bugzilla.kernel.org/show_bug.cgi?id=194945
[2] https://lkml.org/lkml/2017/9/28/153
Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
Cc: Chris Gorman <chrisjohgorman@gmail.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Reported-by: Chris Gorman <chrisjohgorman@gmail.com>
Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Chris Gorman <chrisjohgorman@gmail.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Grygorii Strashko and committed by
Linus Walleij
845e405e 83b31c2a

+13 -1
+13 -1
drivers/pinctrl/intel/pinctrl-cherryview.c
··· 1577 1577 struct gpio_chip *chip = &pctrl->chip; 1578 1578 bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); 1579 1579 int ret, i, offset; 1580 + int irq_base; 1580 1581 1581 1582 *chip = chv_gpio_chip; 1582 1583 ··· 1623 1622 /* Clear all interrupts */ 1624 1623 chv_writel(0xffff, pctrl->regs + CHV_INTSTAT); 1625 1624 1626 - ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, 0, 1625 + if (!need_valid_mask) { 1626 + irq_base = devm_irq_alloc_descs(pctrl->dev, -1, 0, 1627 + chip->ngpio, NUMA_NO_NODE); 1628 + if (irq_base < 0) { 1629 + dev_err(pctrl->dev, "Failed to allocate IRQ numbers\n"); 1630 + return irq_base; 1631 + } 1632 + } else { 1633 + irq_base = 0; 1634 + } 1635 + 1636 + ret = gpiochip_irqchip_add(chip, &chv_gpio_irqchip, irq_base, 1627 1637 handle_bad_irq, IRQ_TYPE_NONE); 1628 1638 if (ret) { 1629 1639 dev_err(pctrl->dev, "failed to add IRQ chip\n");