|
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 |
|