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: stable@vger.kernel.org Reported-and-tested-by: Dale Smith dalepsmith@gmail.com Reported-and-tested-by: John Harris jmharris@gmail.com BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214749 Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com ---
Linus, I hope that this can still make v6.1 release. I'm not going to send a PR for this change unless you insist.
drivers/pinctrl/intel/pinctrl-intel.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 739030e24093..57553ac77518 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -446,9 +446,14 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input) writel(value, padcfg0); }
+static int __intel_gpio_get_gpio_mode(u32 value) +{ + return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; +} + static int intel_gpio_get_gpio_mode(void __iomem *padcfg0) { - return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; + return __intel_gpio_get_gpio_mode(readl(padcfg0)); }
static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) @@ -1705,6 +1710,7 @@ EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data); static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) { const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); + u32 value;
if (!pd || !intel_pad_usable(pctrl, pin)) return false; @@ -1719,6 +1725,25 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin))) return true;
+ /* + * 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. + * + * See https://bugzilla.kernel.org/show_bug.cgi?id=214749. + */ + value = readl(intel_get_padcfg(pctrl, pin, PADCFG0)); + if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && + (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO)) + return true; + return false; }
On Fri, Nov 25, 2022 at 12:29:26AM +0200, Andy Shevchenko wrote:
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: stable@vger.kernel.org Reported-and-tested-by: Dale Smith dalepsmith@gmail.com Reported-and-tested-by: John Harris jmharris@gmail.com BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214749 Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com
Thanks Andy!
Acked-by: Mika Westerberg mika.westerberg@linux.intel.com
On Fri, Nov 25, 2022 at 08:11:14AM +0200, Mika Westerberg wrote:
On Fri, Nov 25, 2022 at 12:29:26AM +0200, Andy Shevchenko wrote:
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: stable@vger.kernel.org Reported-and-tested-by: Dale Smith dalepsmith@gmail.com Reported-and-tested-by: John Harris jmharris@gmail.com BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214749 Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com
Thanks Andy!
Acked-by: Mika Westerberg mika.westerberg@linux.intel.com
Thank you!
Linus, this would be nice to have in v6.1 release, if possible.
On Thu, Nov 24, 2022 at 11:29 PM Andy Shevchenko andriy.shevchenko@linux.intel.com wrote:
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: stable@vger.kernel.org Reported-and-tested-by: Dale Smith dalepsmith@gmail.com Reported-and-tested-by: John Harris jmharris@gmail.com BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214749 Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com
Linus, I hope that this can still make v6.1 release. I'm not going to send a PR for this change unless you insist.
Patch applied for fixes, plan is to get it to Torvalds ASAP!
Yours, Linus Walleij
linux-stable-mirror@lists.linaro.org