diff options
author | Charles Keepax <ckeepax@opensource.wolfsonmicro.com> | 2013-03-26 13:38:45 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2013-04-08 09:21:01 -0400 |
commit | 9d53dfdc82503b819f7b854e627a555cc65224e3 (patch) | |
tree | 2f998c3f2d1dfda42b6d90fc26afe41366e9f9be | |
parent | 4c9bb8bc352a14c9613c77bc3f1e9038cd086b9b (diff) |
mfd: arizona: Factor out register polling
Factor out the polling of the interrupt status register whilst we wait
for boot done to allow the polling to be reused in other situations.
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/arizona-core.c | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index b71bf7ba4cfa..b09b119d4966 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -196,42 +196,50 @@ static irqreturn_t arizona_overclocked(int irq, void *data) | |||
196 | return IRQ_HANDLED; | 196 | return IRQ_HANDLED; |
197 | } | 197 | } |
198 | 198 | ||
199 | static int arizona_wait_for_boot(struct arizona *arizona) | 199 | static int arizona_poll_reg(struct arizona *arizona, |
200 | int timeout, unsigned int reg, | ||
201 | unsigned int mask, unsigned int target) | ||
200 | { | 202 | { |
201 | unsigned int reg; | 203 | unsigned int val = 0; |
202 | int ret, i; | 204 | int ret, i; |
203 | 205 | ||
204 | /* | 206 | for (i = 0; i < timeout; i++) { |
205 | * We can't use an interrupt as we need to runtime resume to do so, | 207 | ret = regmap_read(arizona->regmap, reg, &val); |
206 | * we won't race with the interrupt handler as it'll be blocked on | ||
207 | * runtime resume. | ||
208 | */ | ||
209 | for (i = 0; i < 5; i++) { | ||
210 | msleep(1); | ||
211 | |||
212 | ret = regmap_read(arizona->regmap, | ||
213 | ARIZONA_INTERRUPT_RAW_STATUS_5, ®); | ||
214 | if (ret != 0) { | 208 | if (ret != 0) { |
215 | dev_err(arizona->dev, "Failed to read boot state: %d\n", | 209 | dev_err(arizona->dev, "Failed to read reg %u: %d\n", |
216 | ret); | 210 | reg, ret); |
217 | continue; | 211 | continue; |
218 | } | 212 | } |
219 | 213 | ||
220 | if (reg & ARIZONA_BOOT_DONE_STS) | 214 | if ((val & mask) == target) |
221 | break; | 215 | return 0; |
216 | |||
217 | msleep(1); | ||
222 | } | 218 | } |
223 | 219 | ||
224 | if (reg & ARIZONA_BOOT_DONE_STS) { | 220 | dev_err(arizona->dev, "Polling reg %u timed out: %x\n", reg, val); |
221 | return -ETIMEDOUT; | ||
222 | } | ||
223 | |||
224 | static int arizona_wait_for_boot(struct arizona *arizona) | ||
225 | { | ||
226 | int ret; | ||
227 | |||
228 | /* | ||
229 | * We can't use an interrupt as we need to runtime resume to do so, | ||
230 | * we won't race with the interrupt handler as it'll be blocked on | ||
231 | * runtime resume. | ||
232 | */ | ||
233 | ret = arizona_poll_reg(arizona, 5, ARIZONA_INTERRUPT_RAW_STATUS_5, | ||
234 | ARIZONA_BOOT_DONE_STS, ARIZONA_BOOT_DONE_STS); | ||
235 | |||
236 | if (!ret) | ||
225 | regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5, | 237 | regmap_write(arizona->regmap, ARIZONA_INTERRUPT_STATUS_5, |
226 | ARIZONA_BOOT_DONE_STS); | 238 | ARIZONA_BOOT_DONE_STS); |
227 | } else { | ||
228 | dev_err(arizona->dev, "Device boot timed out: %x\n", reg); | ||
229 | return -ETIMEDOUT; | ||
230 | } | ||
231 | 239 | ||
232 | pm_runtime_mark_last_busy(arizona->dev); | 240 | pm_runtime_mark_last_busy(arizona->dev); |
233 | 241 | ||
234 | return 0; | 242 | return ret; |
235 | } | 243 | } |
236 | 244 | ||
237 | #ifdef CONFIG_PM_RUNTIME | 245 | #ifdef CONFIG_PM_RUNTIME |