Skip to content

Commit b26cd93

Browse files
Kornel Dulębalinusw
authored andcommitted
pinctrl: amd: Disable and mask interrupts on resume
This fixes a similar problem to the one observed in: commit 4e5a04b ("pinctrl: amd: disable and mask interrupts on probe"). On some systems, during suspend/resume cycle firmware leaves an interrupt enabled on a pin that is not used by the kernel. This confuses the AMD pinctrl driver and causes spurious interrupts. The driver already has logic to detect if a pin is used by the kernel. Leverage it to re-initialize interrupt fields of a pin only if it's not used by us. Cc: [email protected] Fixes: dbad75d ("pinctrl: add AMD GPIO driver support.") Signed-off-by: Kornel Dulęba <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Linus Walleij <[email protected]>
1 parent 913a956 commit b26cd93

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

drivers/pinctrl/pinctrl-amd.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -872,32 +872,34 @@ static const struct pinconf_ops amd_pinconf_ops = {
872872
.pin_config_group_set = amd_pinconf_group_set,
873873
};
874874

875-
static void amd_gpio_irq_init(struct amd_gpio *gpio_dev)
875+
static void amd_gpio_irq_init_pin(struct amd_gpio *gpio_dev, int pin)
876876
{
877-
struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
877+
const struct pin_desc *pd;
878878
unsigned long flags;
879879
u32 pin_reg, mask;
880-
int i;
881880

882881
mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3) |
883882
BIT(INTERRUPT_MASK_OFF) | BIT(INTERRUPT_ENABLE_OFF) |
884883
BIT(WAKE_CNTRL_OFF_S4);
885884

886-
for (i = 0; i < desc->npins; i++) {
887-
int pin = desc->pins[i].number;
888-
const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin);
889-
890-
if (!pd)
891-
continue;
885+
pd = pin_desc_get(gpio_dev->pctrl, pin);
886+
if (!pd)
887+
return;
892888

893-
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
889+
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
890+
pin_reg = readl(gpio_dev->base + pin * 4);
891+
pin_reg &= ~mask;
892+
writel(pin_reg, gpio_dev->base + pin * 4);
893+
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
894+
}
894895

895-
pin_reg = readl(gpio_dev->base + i * 4);
896-
pin_reg &= ~mask;
897-
writel(pin_reg, gpio_dev->base + i * 4);
896+
static void amd_gpio_irq_init(struct amd_gpio *gpio_dev)
897+
{
898+
struct pinctrl_desc *desc = gpio_dev->pctrl->desc;
899+
int i;
898900

899-
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
900-
}
901+
for (i = 0; i < desc->npins; i++)
902+
amd_gpio_irq_init_pin(gpio_dev, i);
901903
}
902904

903905
#ifdef CONFIG_PM_SLEEP
@@ -950,8 +952,10 @@ static int amd_gpio_resume(struct device *dev)
950952
for (i = 0; i < desc->npins; i++) {
951953
int pin = desc->pins[i].number;
952954

953-
if (!amd_gpio_should_save(gpio_dev, pin))
955+
if (!amd_gpio_should_save(gpio_dev, pin)) {
956+
amd_gpio_irq_init_pin(gpio_dev, pin);
954957
continue;
958+
}
955959

956960
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
957961
gpio_dev->saved_regs[i] |= readl(gpio_dev->base + pin * 4) & PIN_IRQ_PENDING;

0 commit comments

Comments
 (0)