]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/6.4.8/pm-sleep-wakeirq-fix-wake-irq-arming.patch
6.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 6.4.8 / pm-sleep-wakeirq-fix-wake-irq-arming.patch
CommitLineData
67bda23a
GKH
1From 8527beb12087238d4387607597b4020bc393c4b4 Mon Sep 17 00:00:00 2001
2From: Johan Hovold <johan+linaro@kernel.org>
3Date: Thu, 13 Jul 2023 16:57:39 +0200
4Subject: PM: sleep: wakeirq: fix wake irq arming
5
6From: Johan Hovold <johan+linaro@kernel.org>
7
8commit 8527beb12087238d4387607597b4020bc393c4b4 upstream.
9
10The decision whether to enable a wake irq during suspend can not be done
11based on the runtime PM state directly as a driver may use wake irqs
12without implementing runtime PM. Such drivers specifically leave the
13state set to the default 'suspended' and the wake irq is thus never
14enabled at suspend.
15
16Add a new wake irq flag to track whether a dedicated wake irq has been
17enabled at runtime suspend and therefore must not be enabled at system
18suspend.
19
20Note that pm_runtime_enabled() can not be used as runtime PM is always
21disabled during late suspend.
22
23Fixes: 69728051f5bf ("PM / wakeirq: Fix unbalanced IRQ enable for wakeirq")
24Cc: 4.16+ <stable@vger.kernel.org> # 4.16+
25Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
26Reviewed-by: Tony Lindgren <tony@atomide.com>
27Tested-by: Tony Lindgren <tony@atomide.com>
28Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
29Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30---
31 drivers/base/power/power.h | 1 +
32 drivers/base/power/wakeirq.c | 12 ++++++++----
33 2 files changed, 9 insertions(+), 4 deletions(-)
34
35--- a/drivers/base/power/power.h
36+++ b/drivers/base/power/power.h
37@@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct
38 #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \
39 WAKE_IRQ_DEDICATED_MANAGED | \
40 WAKE_IRQ_DEDICATED_REVERSE)
41+#define WAKE_IRQ_DEDICATED_ENABLED BIT(3)
42
43 struct wake_irq {
44 struct device *dev;
45--- a/drivers/base/power/wakeirq.c
46+++ b/drivers/base/power/wakeirq.c
47@@ -314,8 +314,10 @@ void dev_pm_enable_wake_irq_check(struct
48 return;
49
50 enable:
51- if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
52+ if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) {
53 enable_irq(wirq->irq);
54+ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
55+ }
56 }
57
58 /**
59@@ -336,8 +338,10 @@ void dev_pm_disable_wake_irq_check(struc
60 if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE))
61 return;
62
63- if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED)
64+ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) {
65+ wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED;
66 disable_irq_nosync(wirq->irq);
67+ }
68 }
69
70 /**
71@@ -376,7 +380,7 @@ void dev_pm_arm_wake_irq(struct wake_irq
72
73 if (device_may_wakeup(wirq->dev)) {
74 if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
75- !pm_runtime_status_suspended(wirq->dev))
76+ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
77 enable_irq(wirq->irq);
78
79 enable_irq_wake(wirq->irq);
80@@ -399,7 +403,7 @@ void dev_pm_disarm_wake_irq(struct wake_
81 disable_irq_wake(wirq->irq);
82
83 if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED &&
84- !pm_runtime_status_suspended(wirq->dev))
85+ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED))
86 disable_irq_nosync(wirq->irq);
87 }
88 }