|
24 | 24 | #include <linux/regulator/consumer.h>
|
25 | 25 | #include <linux/regulator/machine.h>
|
26 | 26 | #include <linux/slab.h>
|
| 27 | +#include <linux/ktime.h> |
27 | 28 | #include <linux/platform_device.h>
|
28 | 29 |
|
29 | 30 | #include <linux/mfd/arizona/core.h>
|
@@ -236,22 +237,39 @@ static irqreturn_t arizona_overclocked(int irq, void *data)
|
236 | 237 |
|
237 | 238 | #define ARIZONA_REG_POLL_DELAY_US 7500
|
238 | 239 |
|
| 240 | +static inline bool arizona_poll_reg_delay(ktime_t timeout) |
| 241 | +{ |
| 242 | + if (ktime_compare(ktime_get(), timeout) > 0) |
| 243 | + return false; |
| 244 | + |
| 245 | + usleep_range(ARIZONA_REG_POLL_DELAY_US / 2, ARIZONA_REG_POLL_DELAY_US); |
| 246 | + |
| 247 | + return true; |
| 248 | +} |
| 249 | + |
239 | 250 | static int arizona_poll_reg(struct arizona *arizona,
|
240 | 251 | int timeout_ms, unsigned int reg,
|
241 | 252 | unsigned int mask, unsigned int target)
|
242 | 253 | {
|
| 254 | + ktime_t timeout = ktime_add_us(ktime_get(), timeout_ms * USEC_PER_MSEC); |
243 | 255 | unsigned int val = 0;
|
244 | 256 | int ret;
|
245 | 257 |
|
246 |
| - ret = regmap_read_poll_timeout(arizona->regmap, |
247 |
| - reg, val, ((val & mask) == target), |
248 |
| - ARIZONA_REG_POLL_DELAY_US, |
249 |
| - timeout_ms * 1000); |
250 |
| - if (ret) |
251 |
| - dev_err(arizona->dev, "Polling reg 0x%x timed out: %x\n", |
252 |
| - reg, val); |
| 258 | + do { |
| 259 | + ret = regmap_read(arizona->regmap, reg, &val); |
253 | 260 |
|
254 |
| - return ret; |
| 261 | + if ((val & mask) == target) |
| 262 | + return 0; |
| 263 | + } while (arizona_poll_reg_delay(timeout)); |
| 264 | + |
| 265 | + if (ret) { |
| 266 | + dev_err(arizona->dev, "Failed polling reg 0x%x: %d\n", |
| 267 | + reg, ret); |
| 268 | + return ret; |
| 269 | + } |
| 270 | + |
| 271 | + dev_err(arizona->dev, "Polling reg 0x%x timed out: %x\n", reg, val); |
| 272 | + return -ETIMEDOUT; |
255 | 273 | }
|
256 | 274 |
|
257 | 275 | static int arizona_wait_for_boot(struct arizona *arizona)
|
|
0 commit comments