diff options
-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 3dc08ce15426..26914dfcc9fc 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h | |||
@@ -95,6 +95,45 @@ struct reg_sequence { | |||
95 | #define regmap_fields_force_update_bits(field, id, mask, val) \ | 95 | #define regmap_fields_force_update_bits(field, id, mask, val) \ |
96 | regmap_fields_update_bits_base(field, id, mask, val, NULL, false, true) | 96 | regmap_fields_update_bits_base(field, id, mask, val, NULL, false, true) |
97 | 97 | ||
98 | /** | ||
99 | * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs | ||
100 | * @map: Regmap to read from | ||
101 | * @addr: Address to poll | ||
102 | * @val: Unsigned integer variable to read the value into | ||
103 | * @cond: Break condition (usually involving @val) | ||
104 | * @sleep_us: Maximum time to sleep between reads in us (0 | ||
105 | * tight-loops). Should be less than ~20ms since usleep_range | ||
106 | * is used (see Documentation/timers/timers-howto.txt). | ||
107 | * @timeout_us: Timeout in us, 0 means never timeout | ||
108 | * | ||
109 | * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read | ||
110 | * error return value in case of a error read. In the two former cases, | ||
111 | * the last read value at @addr is stored in @val. Must not be called | ||
112 | * from atomic context if sleep_us or timeout_us are used. | ||
113 | * | ||
114 | * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. | ||
115 | */ | ||
116 | #define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \ | ||
117 | ({ \ | ||
118 | ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ | ||
119 | int ret; \ | ||
120 | might_sleep_if(sleep_us); \ | ||
121 | for (;;) { \ | ||
122 | ret = regmap_read((map), (addr), &(val)); \ | ||
123 | if (ret) \ | ||
124 | break; \ | ||
125 | if (cond) \ | ||
126 | break; \ | ||
127 | if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ | ||
128 | ret = regmap_read((map), (addr), &(val)); \ | ||
129 | break; \ | ||
130 | } \ | ||
131 | if (sleep_us) \ | ||
132 | usleep_range((sleep_us >> 2) + 1, sleep_us); \ | ||
133 | } \ | ||
134 | ret ?: ((cond) ? 0 : -ETIMEDOUT); \ | ||
135 | }) | ||
136 | |||
98 | #ifdef CONFIG_REGMAP | 137 | #ifdef CONFIG_REGMAP |
99 | 138 | ||
100 | enum regmap_endian { | 139 | enum regmap_endian { |