diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-07-24 10:41:19 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-08-07 15:29:45 -0400 |
commit | 0c00c50b41a9a6ee83eb16fb5c6c22e5115391b8 (patch) | |
tree | 12a30d730032a46fac0793fea2ba30ef900b4d4f /drivers/base/regmap | |
parent | 40052ca0c243d101cfadd65936f60ef81df10b02 (diff) |
regmap: irq: Enable devices for runtime PM while handling interrupts
Some devices need to have a runtime PM reference while handling interrupts
to ensure that the register I/O is available. Support this with a flag in
the chip.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/base/regmap')
-rw-r--r-- | drivers/base/regmap/regmap-irq.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 6f8f0c1e550f..bb5e10305197 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/irqdomain.h> | 18 | #include <linux/irqdomain.h> |
19 | #include <linux/pm_runtime.h> | ||
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | 21 | ||
21 | #include "internal.h" | 22 | #include "internal.h" |
@@ -62,6 +63,13 @@ static void regmap_irq_sync_unlock(struct irq_data *data) | |||
62 | int i, ret; | 63 | int i, ret; |
63 | u32 reg; | 64 | u32 reg; |
64 | 65 | ||
66 | if (d->chip->runtime_pm) { | ||
67 | ret = pm_runtime_get_sync(map->dev); | ||
68 | if (ret < 0) | ||
69 | dev_err(map->dev, "IRQ sync failed to resume: %d\n", | ||
70 | ret); | ||
71 | } | ||
72 | |||
65 | /* | 73 | /* |
66 | * If there's been a change in the mask write it back to the | 74 | * If there's been a change in the mask write it back to the |
67 | * hardware. We rely on the use of the regmap core cache to | 75 | * hardware. We rely on the use of the regmap core cache to |
@@ -77,6 +85,9 @@ static void regmap_irq_sync_unlock(struct irq_data *data) | |||
77 | reg); | 85 | reg); |
78 | } | 86 | } |
79 | 87 | ||
88 | if (d->chip->runtime_pm) | ||
89 | pm_runtime_put(map->dev); | ||
90 | |||
80 | /* If we've changed our wakeup count propagate it to the parent */ | 91 | /* If we've changed our wakeup count propagate it to the parent */ |
81 | if (d->wake_count < 0) | 92 | if (d->wake_count < 0) |
82 | for (i = d->wake_count; i < 0; i++) | 93 | for (i = d->wake_count; i < 0; i++) |
@@ -147,6 +158,15 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
147 | bool handled = false; | 158 | bool handled = false; |
148 | u32 reg; | 159 | u32 reg; |
149 | 160 | ||
161 | if (chip->runtime_pm) { | ||
162 | ret = pm_runtime_get_sync(map->dev); | ||
163 | if (ret < 0) { | ||
164 | dev_err(map->dev, "IRQ thread failed to resume: %d\n", | ||
165 | ret); | ||
166 | return IRQ_NONE; | ||
167 | } | ||
168 | } | ||
169 | |||
150 | /* | 170 | /* |
151 | * Ignore masked IRQs and ack if we need to; we ack early so | 171 | * Ignore masked IRQs and ack if we need to; we ack early so |
152 | * there is no race between handling and acknowleding the | 172 | * there is no race between handling and acknowleding the |
@@ -162,6 +182,8 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
162 | if (ret != 0) { | 182 | if (ret != 0) { |
163 | dev_err(map->dev, "Failed to read IRQ status: %d\n", | 183 | dev_err(map->dev, "Failed to read IRQ status: %d\n", |
164 | ret); | 184 | ret); |
185 | if (chip->runtime_pm) | ||
186 | pm_runtime_put(map->dev); | ||
165 | return IRQ_NONE; | 187 | return IRQ_NONE; |
166 | } | 188 | } |
167 | 189 | ||
@@ -185,6 +207,9 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) | |||
185 | } | 207 | } |
186 | } | 208 | } |
187 | 209 | ||
210 | if (chip->runtime_pm) | ||
211 | pm_runtime_put(map->dev); | ||
212 | |||
188 | if (handled) | 213 | if (handled) |
189 | return IRQ_HANDLED; | 214 | return IRQ_HANDLED; |
190 | else | 215 | else |