diff options
author | Basavaraj Natikar <Basavaraj.Natikar@amd.com> | 2022-06-13 09:41:26 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-09-05 11:25:02 +0300 |
commit | d85f14a43f63360bc2cb741f6ad47bc6002381d6 (patch) | |
tree | fc2bbe97d74730a6ccb68eca7fd7608aee418a99 /drivers/pinctrl | |
parent | 8af84a31769e10970b73b613c15c31ff91bee3d2 (diff) | |
download | linux-d85f14a43f63360bc2cb741f6ad47bc6002381d6.tar.xz |
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.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 34d9148d2766..c57f91f48423 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -753,6 +753,7 @@ 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++) { @@ -761,7 +762,9 @@ 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; @@ -772,6 +775,7 @@ 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++) { @@ -780,7 +784,10 @@ 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; |