summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorBasavaraj Natikar <Basavaraj.Natikar@amd.com>2022-06-13 12:11:26 +0530
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-09-05 10:26:28 +0200
commitd64f71d8d6f67300bac4abdb09700406fb2d0985 (patch)
tree3709e8518c93e0957fe8919e788ecd4b4e1278db /drivers/pinctrl
parent964a8171267df6a54d4cabc06cbd7c88b0b2daad (diff)
downloadlinux-stable-d64f71d8d6f67300bac4abdb09700406fb2d0985.tar.gz
linux-stable-d64f71d8d6f67300bac4abdb09700406fb2d0985.tar.bz2
linux-stable-d64f71d8d6f67300bac4abdb09700406fb2d0985.zip
pinctrl: amd: Don't save/restore interrupt status and wake status bits
commit b8c824a869f220c6b46df724f85794349bafbf23 upstream. Saving/restoring interrupt and wake status bits across suspend can cause the suspend to fail if an IRQ is serviced across the suspend cycle. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com> Fixes: 79d2c8bede2c ("pinctrl/amd: save pin registers over suspend/resume") Link: https://lore.kernel.org/r/20220613064127.220416-3-Basavaraj.Natikar@amd.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/pinctrl-amd.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index 8d2dbf607bd1..66b9c5826ec0 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -798,6 +798,7 @@ static int amd_gpio_suspend(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+ unsigned long flags;
int i;
for (i = 0; i < desc->npins; i++) {
@@ -806,7 +807,9 @@ static int amd_gpio_suspend(struct device *dev)
if (!amd_gpio_should_save(gpio_dev, pin))
continue;
- gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin*4);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+ gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin * 4) & ~PIN_IRQ_PENDING;
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
return 0;
@@ -817,6 +820,7 @@ static int amd_gpio_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct amd_gpio *gpio_dev = platform_get_drvdata(pdev);
struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
+ unsigned long flags;
int i;
for (i = 0; i < desc->npins; i++) {
@@ -825,7 +829,10 @@ static int amd_gpio_resume(struct device *dev)
if (!amd_gpio_should_save(gpio_dev, pin))
continue;
- writel(gpio_dev->saved_regs[i], gpio_dev->base + pin*4);
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+ gpio_dev->saved_regs[i] |= readl(gpio_dev->base + pin * 4) & PIN_IRQ_PENDING;
+ writel(gpio_dev->saved_regs[i], gpio_dev->base + pin * 4);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
}
return 0;