aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChen-Yu Tsai <wens@csie.org>2017-09-29 04:23:01 -0400
committerMark Brown <broonie@kernel.org>2017-10-04 06:46:32 -0400
commit667063acb81931e2f8fd0cb91df9fcccad131d9a (patch)
treef1532a383fdecb60c40673771c29765562676d05
parent2bd6bf03f4c1c59381d62c61d03f6cc3fe71f66e (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.h39
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
144enum regmap_endian { 183enum regmap_endian {