diff options
author | Chen-Yu Tsai <wens@csie.org> | 2017-09-29 04:23:01 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-10-04 06:46:32 -0400 |
commit | 667063acb81931e2f8fd0cb91df9fcccad131d9a (patch) | |
tree | f1532a383fdecb60c40673771c29765562676d05 | |
parent | 2bd6bf03f4c1c59381d62c61d03f6cc3fe71f66e (diff) |
regmap: add iopoll-like polling macro for regmap_field
This patch adds a macro regmap_field_read_poll_timeout that works
similar to the readx_poll_timeout defined in linux/iopoll.h, except
that this can also return the error value returned by a failed
regmap_field_read.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | include/linux/regmap.h | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index 978abfbac617..93a4663d7acb 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -139,6 +139,45 @@ struct reg_sequence { | |||
139 | pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ | 139 | pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ |
140 | }) | 140 | }) |
141 | 141 | ||
142 | /** | ||
143 | * regmap_field_read_poll_timeout - Poll until a condition is met or timeout | ||
144 | * | ||
145 | * @field: Regmap field to read from | ||
146 | * @val: Unsigned integer variable to read the value into | ||
147 | * @cond: Break condition (usually involving @val) | ||
148 | * @sleep_us: Maximum time to sleep between reads in us (0 | ||
149 | * tight-loops). Should be less than ~20ms since usleep_range | ||
150 | * is used (see Documentation/timers/timers-howto.txt). | ||
151 | * @timeout_us: Timeout in us, 0 means never timeout | ||
152 | * | ||
153 | * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_field_read | ||
154 | * error return value in case of a error read. In the two former cases, | ||
155 | * the last read value at @addr is stored in @val. Must not be called | ||
156 | * from atomic context if sleep_us or timeout_us are used. | ||
157 | * | ||
158 | * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. | ||
159 | */ | ||
160 | #define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \ | ||
161 | ({ \ | ||
162 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | ||
163 | int pollret; \ | ||
164 | might_sleep_if(sleep_us); \ | ||
165 | for (;;) { \ | ||
166 | pollret = regmap_field_read((field), &(val)); \ | ||
167 | if (pollret) \ | ||
168 | break; \ | ||
169 | if (cond) \ | ||
170 | break; \ | ||
171 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | ||
172 | pollret = regmap_field_read((field), &(val)); \ | ||
173 | break; \ | ||
174 | } \ | ||
175 | if (sleep_us) \ | ||
176 | usleep_range((sleep_us >> 2) + 1, sleep_us); \ | ||
177 | } \ | ||
178 | pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ | ||
179 | }) | ||
180 | |||
142 | #ifdef CONFIG_REGMAP | 181 | #ifdef CONFIG_REGMAP |
143 | 182 | ||
144 | enum regmap_endian { | 183 | enum regmap_endian { |