]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pinctrl: intel: Restore the pins that used to be in Direct IRQ mode
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Mon, 6 Feb 2023 14:15:59 +0000 (16:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Feb 2023 11:47:18 +0000 (12:47 +0100)
[ Upstream commit a8520be3ffef3d25b53bf171a7ebe17ee0154175 ]

If the firmware mangled the register contents too much,
check the saved value for the Direct IRQ mode. If it
matches, we will restore the pin state.

Reported-by: Jim Minter <jimminter@microsoft.com>
Fixes: 6989ea4881c8 ("pinctrl: intel: Save and restore pins in "direct IRQ" mode")
Tested-by: Jim Minter <jimminter@microsoft.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Link: https://lore.kernel.org/r/20230206141558.20916-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/pinctrl/intel/pinctrl-intel.c

index 198121bd89bbf5a10118209d707c60dca627f589..b786d9797f4046475ddc8929fcb779b2844f1867 100644 (file)
@@ -1432,6 +1432,12 @@ int intel_pinctrl_probe(struct platform_device *pdev,
 EXPORT_SYMBOL_GPL(intel_pinctrl_probe);
 
 #ifdef CONFIG_PM_SLEEP
+static bool __intel_gpio_is_direct_irq(u32 value)
+{
+       return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) &&
+              (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO);
+}
+
 static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin)
 {
        const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
@@ -1465,8 +1471,7 @@ static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int
         * 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))
+       if (__intel_gpio_is_direct_irq(value))
                return true;
 
        return false;
@@ -1551,7 +1556,12 @@ int intel_pinctrl_resume(struct device *dev)
                void __iomem *padcfg;
                u32 val;
 
-               if (!intel_pinctrl_should_save(pctrl, desc->number))
+               if (!(intel_pinctrl_should_save(pctrl, desc->number) ||
+                     /*
+                      * If the firmware mangled the register contents too much,
+                      * check the saved value for the Direct IRQ mode.
+                      */
+                     __intel_gpio_is_direct_irq(pads[i].padcfg0)))
                        continue;
 
                padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);