Skip to content

Commit 6989ea4

Browse files
andy-shevlinusw
authored andcommitted
pinctrl: intel: Save and restore pins in "direct IRQ" mode
The firmware on some systems may configure GPIO pins to be an interrupt source in so called "direct IRQ" mode. In such cases the GPIO controller driver has no idea if those pins are being used or not. At the same time, there is a known bug in the firmwares that don't restore the pin settings correctly after suspend, i.e. by an unknown reason the Rx value becomes inverted. Hence, let's save and restore the pins that are configured as GPIOs in the input mode with GPIROUTIOXAPIC bit set. Cc: [email protected] Reported-and-tested-by: Dale Smith <[email protected]> Reported-and-tested-by: John Harris <[email protected]> BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214749 Signed-off-by: Andy Shevchenko <[email protected]> Acked-by: Mika Westerberg <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Linus Walleij <[email protected]>
1 parent 11780e3 commit 6989ea4

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

drivers/pinctrl/intel/pinctrl-intel.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,14 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
436436
writel(value, padcfg0);
437437
}
438438

439+
static int __intel_gpio_get_gpio_mode(u32 value)
440+
{
441+
return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
442+
}
443+
439444
static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
440445
{
441-
return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
446+
return __intel_gpio_get_gpio_mode(readl(padcfg0));
442447
}
443448

444449
static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
@@ -1674,6 +1679,7 @@ EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data);
16741679
static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
16751680
{
16761681
const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
1682+
u32 value;
16771683

16781684
if (!pd || !intel_pad_usable(pctrl, pin))
16791685
return false;
@@ -1688,6 +1694,25 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
16881694
gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
16891695
return true;
16901696

1697+
/*
1698+
* The firmware on some systems may configure GPIO pins to be
1699+
* an interrupt source in so called "direct IRQ" mode. In such
1700+
* cases the GPIO controller driver has no idea if those pins
1701+
* are being used or not. At the same time, there is a known bug
1702+
* in the firmwares that don't restore the pin settings correctly
1703+
* after suspend, i.e. by an unknown reason the Rx value becomes
1704+
* inverted.
1705+
*
1706+
* Hence, let's save and restore the pins that are configured
1707+
* as GPIOs in the input mode with GPIROUTIOXAPIC bit set.
1708+
*
1709+
* See https://bugzilla.kernel.org/show_bug.cgi?id=214749.
1710+
*/
1711+
value = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
1712+
if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
1713+
(__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO))
1714+
return true;
1715+
16911716
return false;
16921717
}
16931718

0 commit comments

Comments
 (0)