diff options
| author | Ingo Molnar <mingo@kernel.org> | 2017-11-29 01:11:24 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2017-11-29 01:11:24 -0500 |
| commit | 4fc31ba13d052c2933bf91095c063cf9a39effd0 (patch) | |
| tree | beabb73c2fe245e6541126732895da62e55bc8ee /include/linux/regmap.h | |
| parent | 0e18dd12064e07519f7cbff4149ca7fff620cbed (diff) | |
| parent | b29c6ef7bb1257853c1e31616d84f55e561cf631 (diff) | |
Merge branch 'linus' into perf/urgent, to pick up dependent commits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'include/linux/regmap.h')
| -rw-r--r-- | include/linux/regmap.h | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 978abfbac617..15eddc1353ba 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
| @@ -120,21 +120,65 @@ struct reg_sequence { | |||
| 120 | */ | 120 | */ |
| 121 | #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \ | 121 | #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \ |
| 122 | ({ \ | 122 | ({ \ |
| 123 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | 123 | u64 __timeout_us = (timeout_us); \ |
| 124 | unsigned long __sleep_us = (sleep_us); \ | ||
| 125 | ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ | ||
| 126 | int __ret; \ | ||
| 127 | might_sleep_if(__sleep_us); \ | ||
| 128 | for (;;) { \ | ||
| 129 | __ret = regmap_read((map), (addr), &(val)); \ | ||
| 130 | if (__ret) \ | ||
| 131 | break; \ | ||
| 132 | if (cond) \ | ||
| 133 | break; \ | ||
| 134 | if ((__timeout_us) && \ | ||
| 135 | ktime_compare(ktime_get(), __timeout) > 0) { \ | ||
| 136 | __ret = regmap_read((map), (addr), &(val)); \ | ||
| 137 | break; \ | ||
| 138 | } \ | ||
| 139 | if (__sleep_us) \ | ||
| 140 | usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ | ||
| 141 | } \ | ||
| 142 | __ret ?: ((cond) ? 0 : -ETIMEDOUT); \ | ||
| 143 | }) | ||
| 144 | |||
| 145 | /** | ||
| 146 | * regmap_field_read_poll_timeout - Poll until a condition is met or timeout | ||
| 147 | * | ||
| 148 | * @field: Regmap field to read from | ||
| 149 | * @val: Unsigned integer variable to read the value into | ||
| 150 | * @cond: Break condition (usually involving @val) | ||
| 151 | * @sleep_us: Maximum time to sleep between reads in us (0 | ||
| 152 | * tight-loops). Should be less than ~20ms since usleep_range | ||
| 153 | * is used (see Documentation/timers/timers-howto.txt). | ||
| 154 | * @timeout_us: Timeout in us, 0 means never timeout | ||
| 155 | * | ||
| 156 | * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_field_read | ||
| 157 | * error return value in case of a error read. In the two former cases, | ||
| 158 | * the last read value at @addr is stored in @val. Must not be called | ||
| 159 | * from atomic context if sleep_us or timeout_us are used. | ||
| 160 | * | ||
| 161 | * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. | ||
| 162 | */ | ||
| 163 | #define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \ | ||
| 164 | ({ \ | ||
| 165 | u64 __timeout_us = (timeout_us); \ | ||
| 166 | unsigned long __sleep_us = (sleep_us); \ | ||
| 167 | ktime_t timeout = ktime_add_us(ktime_get(), __timeout_us); \ | ||
| 124 | int pollret; \ | 168 | int pollret; \ |
| 125 | might_sleep_if(sleep_us); \ | 169 | might_sleep_if(__sleep_us); \ |
| 126 | for (;;) { \ | 170 | for (;;) { \ |
| 127 | pollret = regmap_read((map), (addr), &(val)); \ | 171 | pollret = regmap_field_read((field), &(val)); \ |
| 128 | if (pollret) \ | 172 | if (pollret) \ |
| 129 | break; \ | 173 | break; \ |
| 130 | if (cond) \ | 174 | if (cond) \ |
| 131 | break; \ | 175 | break; \ |
| 132 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | 176 | if (__timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ |
| 133 | pollret = regmap_read((map), (addr), &(val)); \ | 177 | pollret = regmap_field_read((field), &(val)); \ |
| 134 | break; \ | 178 | break; \ |
| 135 | } \ | 179 | } \ |
| 136 | if (sleep_us) \ | 180 | if (__sleep_us) \ |
| 137 | usleep_range((sleep_us >> 2) + 1, sleep_us); \ | 181 | usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ |
| 138 | } \ | 182 | } \ |
| 139 | pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ | 183 | pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ |
| 140 | }) | 184 | }) |
| @@ -273,6 +317,9 @@ typedef void (*regmap_unlock)(void *); | |||
| 273 | * | 317 | * |
| 274 | * @ranges: Array of configuration entries for virtual address ranges. | 318 | * @ranges: Array of configuration entries for virtual address ranges. |
| 275 | * @num_ranges: Number of range configuration entries. | 319 | * @num_ranges: Number of range configuration entries. |
| 320 | * @hwlock_id: Specify the hardware spinlock id. | ||
| 321 | * @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE, | ||
| 322 | * HWLOCK_IRQ or 0. | ||
| 276 | */ | 323 | */ |
| 277 | struct regmap_config { | 324 | struct regmap_config { |
| 278 | const char *name; | 325 | const char *name; |
| @@ -317,6 +364,9 @@ struct regmap_config { | |||
| 317 | 364 | ||
| 318 | const struct regmap_range_cfg *ranges; | 365 | const struct regmap_range_cfg *ranges; |
| 319 | unsigned int num_ranges; | 366 | unsigned int num_ranges; |
| 367 | |||
| 368 | unsigned int hwlock_id; | ||
| 369 | unsigned int hwlock_mode; | ||
| 320 | }; | 370 | }; |
| 321 | 371 | ||
| 322 | /** | 372 | /** |
