Takashi Iwai 494ff3
From 6989ea4881c8944fbf04378418bb1af63d875ef8 Mon Sep 17 00:00:00 2001
Takashi Iwai 494ff3
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Takashi Iwai 494ff3
Date: Fri, 25 Nov 2022 00:29:26 +0200
Takashi Iwai 494ff3
Subject: [PATCH] pinctrl: intel: Save and restore pins in "direct IRQ" mode
Takashi Iwai 494ff3
Git-commit: 6989ea4881c8944fbf04378418bb1af63d875ef8
Takashi Iwai 494ff3
Patch-mainline: v6.1-rc8
Takashi Iwai 494ff3
References: git-fixes
Takashi Iwai 494ff3
Takashi Iwai 494ff3
The firmware on some systems may configure GPIO pins to be
Takashi Iwai 494ff3
an interrupt source in so called "direct IRQ" mode. In such
Takashi Iwai 494ff3
cases the GPIO controller driver has no idea if those pins
Takashi Iwai 494ff3
are being used or not. At the same time, there is a known bug
Takashi Iwai 494ff3
in the firmwares that don't restore the pin settings correctly
Takashi Iwai 494ff3
after suspend, i.e. by an unknown reason the Rx value becomes
Takashi Iwai 494ff3
inverted.
Takashi Iwai 494ff3
Takashi Iwai 494ff3
Hence, let's save and restore the pins that are configured
Takashi Iwai 494ff3
as GPIOs in the input mode with GPIROUTIOXAPIC bit set.
Takashi Iwai 494ff3
Takashi Iwai 494ff3
Cc: stable@vger.kernel.org
Takashi Iwai 494ff3
Reported-and-tested-by: Dale Smith <dalepsmith@gmail.com>
Takashi Iwai 494ff3
Reported-and-tested-by: John Harris <jmharris@gmail.com>
Takashi Iwai 494ff3
Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=214749
Takashi Iwai 494ff3
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Takashi Iwai 494ff3
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Takashi Iwai 494ff3
Link: https://lore.kernel.org/r/20221124222926.72326-1-andriy.shevchenko@linux.intel.com
Takashi Iwai 494ff3
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Takashi Iwai 494ff3
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 494ff3
Takashi Iwai 494ff3
---
Takashi Iwai 494ff3
 drivers/pinctrl/intel/pinctrl-intel.c | 27 ++++++++++++++++++++++++++-
Takashi Iwai 494ff3
 1 file changed, 26 insertions(+), 1 deletion(-)
Takashi Iwai 494ff3
Takashi Iwai 494ff3
diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
Takashi Iwai 494ff3
index 52ecd66ce357..047a8374b4fd 100644
Takashi Iwai 494ff3
--- a/drivers/pinctrl/intel/pinctrl-intel.c
Takashi Iwai 494ff3
+++ b/drivers/pinctrl/intel/pinctrl-intel.c
Takashi Iwai 494ff3
@@ -436,9 +436,14 @@ static void __intel_gpio_set_direction(void __iomem *padcfg0, bool input)
Takashi Iwai 494ff3
 	writel(value, padcfg0);
Takashi Iwai 494ff3
 }
Takashi Iwai 494ff3
 
Takashi Iwai 494ff3
+static int __intel_gpio_get_gpio_mode(u32 value)
Takashi Iwai 494ff3
+{
Takashi Iwai 494ff3
+	return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
Takashi Iwai 494ff3
+}
Takashi Iwai 494ff3
+
Takashi Iwai 494ff3
 static int intel_gpio_get_gpio_mode(void __iomem *padcfg0)
Takashi Iwai 494ff3
 {
Takashi Iwai 494ff3
-	return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT;
Takashi Iwai 494ff3
+	return __intel_gpio_get_gpio_mode(readl(padcfg0));
Takashi Iwai 494ff3
 }
Takashi Iwai 494ff3
 
Takashi Iwai 494ff3
 static void intel_gpio_set_gpio_mode(void __iomem *padcfg0)
Takashi Iwai 494ff3
@@ -1674,6 +1679,7 @@ EXPORT_SYMBOL_GPL(intel_pinctrl_get_soc_data);
Takashi Iwai 494ff3
 static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
Takashi Iwai 494ff3
 {
Takashi Iwai 494ff3
 	const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
Takashi Iwai 494ff3
+	u32 value;
Takashi Iwai 494ff3
 
Takashi Iwai 494ff3
 	if (!pd || !intel_pad_usable(pctrl, pin))
Takashi Iwai 494ff3
 		return false;
Takashi Iwai 494ff3
@@ -1688,6 +1694,25 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
Takashi Iwai 494ff3
 	    gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin)))
Takashi Iwai 494ff3
 		return true;
Takashi Iwai 494ff3
 
Takashi Iwai 494ff3
+	/*
Takashi Iwai 494ff3
+	 * The firmware on some systems may configure GPIO pins to be
Takashi Iwai 494ff3
+	 * an interrupt source in so called "direct IRQ" mode. In such
Takashi Iwai 494ff3
+	 * cases the GPIO controller driver has no idea if those pins
Takashi Iwai 494ff3
+	 * are being used or not. At the same time, there is a known bug
Takashi Iwai 494ff3
+	 * in the firmwares that don't restore the pin settings correctly
Takashi Iwai 494ff3
+	 * after suspend, i.e. by an unknown reason the Rx value becomes
Takashi Iwai 494ff3
+	 * inverted.
Takashi Iwai 494ff3
+	 *
Takashi Iwai 494ff3
+	 * Hence, let's save and restore the pins that are configured
Takashi Iwai 494ff3
+	 * as GPIOs in the input mode with GPIROUTIOXAPIC bit set.
Takashi Iwai 494ff3
+	 *
Takashi Iwai 494ff3
+	 * See https://bugzilla.kernel.org/show_bug.cgi?id=214749.
Takashi Iwai 494ff3
+	 */
Takashi Iwai 494ff3
+	value = readl(intel_get_padcfg(pctrl, pin, PADCFG0));
Takashi Iwai 494ff3
+	if ((value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
Takashi Iwai 494ff3
+	    (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO))
Takashi Iwai 494ff3
+		return true;
Takashi Iwai 494ff3
+
Takashi Iwai 494ff3
 	return false;
Takashi Iwai 494ff3
 }
Takashi Iwai 494ff3
 
Takashi Iwai 494ff3
-- 
Takashi Iwai 494ff3
2.35.3
Takashi Iwai 494ff3