Skip to content

Commit

Permalink
PM: sleep: wakeirq: fix wake irq arming
Browse files Browse the repository at this point in the history
The decision whether to enable a wake irq during suspend can not be done
based on the runtime PM state directly as a driver may use wake irqs
without implementing runtime PM. Such drivers specifically leave the
state set to the default 'suspended' and the wake irq is thus never
enabled at suspend.

Add a new wake irq flag to track whether a dedicated wake irq has been
enabled at runtime suspend and therefore must not be enabled at system
suspend.

Note that pm_runtime_enabled() can not be used as runtime PM is always
disabled during late suspend.

Fixes: 6972805 ("PM / wakeirq: Fix unbalanced IRQ enable for wakeirq")
Cc: 4.16+ <[email protected]> # 4.16+
Signed-off-by: Johan Hovold <[email protected]>
Reviewed-by: Tony Lindgren <[email protected]>
Tested-by: Tony Lindgren <[email protected]>
Signed-off-by: Rafael J. Wysocki <[email protected]>
  • Loading branch information
jhovold authored and rafaeljw committed Jul 24, 2023
1 parent 6eaae19 commit 8527beb
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 4 deletions.
1 change: 1 addition & 0 deletions drivers/base/power/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct device *dev);
#define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \
WAKE_IRQ_DEDICATED_MANAGED | \
WAKE_IRQ_DEDICATED_REVERSE)
#define WAKE_IRQ_DEDICATED_ENABLED BIT(3)

struct wake_irq {
struct device *dev;
Expand Down
12 changes: 8 additions & 4 deletions drivers/base/power/wakeirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,10 @@ void dev_pm_enable_wake_irq_check(struct device *dev,
return;

enable:
if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
enable_irq(wirq->irq);
wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
}
}

/**
Expand All @@ -336,8 +338,10 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable)
if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
return;

if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
disable_irq_nosync(wirq->irq);
}
}

/**
Expand Down Expand Up @@ -376,7 +380,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq)

if (device_may_wakeup(wirq->dev)) {
if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
!pm_runtime_status_suspended(wirq->dev))
!(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
enable_irq(wirq->irq);

enable_irq_wake(wirq->irq);
Expand All @@ -399,7 +403,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq)
disable_irq_wake(wirq->irq);

if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
!pm_runtime_status_suspended(wirq->dev))
!(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
disable_irq_nosync(wirq->irq);
}
}

0 comments on commit 8527beb

Please sign in to comment.