summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinctrl-amd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-amd.c')
-rw-r--r--drivers/pinctrl/pinctrl-amd.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index bae9d429b813..1a7d686494ff 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -598,14 +598,14 @@ static struct irq_chip amd_gpio_irqchip = {
#define PIN_IRQ_PENDING (BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
-static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
+static bool do_amd_gpio_irq_handler(int irq, void *dev_id)
{
struct amd_gpio *gpio_dev = dev_id;
struct gpio_chip *gc = &gpio_dev->gc;
- irqreturn_t ret = IRQ_NONE;
unsigned int i, irqnr;
unsigned long flags;
u32 __iomem *regs;
+ bool ret = false;
u32 regval;
u64 status, mask;
@@ -627,6 +627,14 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
/* Each status bit covers four pins */
for (i = 0; i < 4; i++) {
regval = readl(regs + i);
+ /* caused wake on resume context for shared IRQ */
+ if (irq < 0 && (regval & BIT(WAKE_STS_OFF))) {
+ dev_dbg(&gpio_dev->pdev->dev,
+ "Waking due to GPIO %d: 0x%x",
+ irqnr + i, regval);
+ return true;
+ }
+
if (!(regval & PIN_IRQ_PENDING) ||
!(regval & BIT(INTERRUPT_MASK_OFF)))
continue;
@@ -650,9 +658,12 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
}
writel(regval, regs + i);
raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
- ret = IRQ_HANDLED;
+ ret = true;
}
}
+ /* did not cause wake on resume context for shared IRQ */
+ if (irq < 0)
+ return false;
/* Signal EOI to the GPIO unit */
raw_spin_lock_irqsave(&gpio_dev->lock, flags);
@@ -664,6 +675,16 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
return ret;
}
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
+{
+ return IRQ_RETVAL(do_amd_gpio_irq_handler(irq, dev_id));
+}
+
+static bool __maybe_unused amd_gpio_check_wake(void *dev_id)
+{
+ return do_amd_gpio_irq_handler(-1, dev_id);
+}
+
static int amd_get_groups_count(struct pinctrl_dev *pctldev)
{
struct amd_gpio *gpio_dev = pinctrl_dev_get_drvdata(pctldev);
@@ -988,9 +1009,6 @@ static int amd_gpio_probe(struct platform_device *pdev)
gpio_dev->gc.owner = THIS_MODULE;
gpio_dev->gc.parent = &pdev->dev;
gpio_dev->gc.ngpio = resource_size(res) / 4;
-#if defined(CONFIG_OF_GPIO)
- gpio_dev->gc.of_node = pdev->dev.of_node;
-#endif
gpio_dev->hwbank_num = gpio_dev->gc.ngpio / 64;
gpio_dev->groups = kerncz_groups;
@@ -1033,6 +1051,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
goto out2;
platform_set_drvdata(pdev, gpio_dev);
+ acpi_register_wakeup_handler(gpio_dev->irq, amd_gpio_check_wake, gpio_dev);
dev_dbg(&pdev->dev, "amd gpio driver loaded\n");
return ret;
@@ -1050,6 +1069,7 @@ static int amd_gpio_remove(struct platform_device *pdev)
gpio_dev = platform_get_drvdata(pdev);
gpiochip_remove(&gpio_dev->gc);
+ acpi_unregister_wakeup_handler(amd_gpio_check_wake, gpio_dev);
return 0;
}