diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-27 11:13:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2020-01-27 11:13:02 -0800 |
commit | e83a0ed2a6a3f6e67630d1580f1ade97a54c524f (patch) | |
tree | 2b8538b16921cd6afe650183fa2813185b6d010a /include/linux | |
parent | a5b871c91d470326eed3ae0ebd2fc07f3aee9050 (diff) | |
parent | ea87683909bcda665527a828505c5e9c6a625429 (diff) |
Merge tag 'regmap-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap
Pull regmap updates from Mark Brown:
"This is quite a busy release for a subsystem that's usually very
quiet, though still a small set of updates in the grand scheme of
things:
- A fix for writes to non-incrementing registers.
- An iopoll() style helper for use with atomic safe regmaps, making
it easier to transition from raw memory mapped I/O.
- Some constification"
* tag 'regmap-v5.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
regmap: fix writes to non incrementing registers
regmap: add iopoll-like atomic polling macro
regmap-i2c: constify regmap_bus structures
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/regmap.h | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/include/linux/regmap.h b/include/linux/regmap.h index dfe493ac692d..f0a092a1a96d 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -145,6 +145,51 @@ struct reg_sequence { }) /** + * regmap_read_poll_timeout_atomic - Poll until a condition is met or a timeout occurs + * + * @map: Regmap to read from + * @addr: Address to poll + * @val: Unsigned integer variable to read the value into + * @cond: Break condition (usually involving @val) + * @delay_us: Time to udelay between reads in us (0 tight-loops). + * Should be less than ~10us since udelay is used + * (see Documentation/timers/timers-howto.rst). + * @timeout_us: Timeout in us, 0 means never timeout + * + * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read + * error return value in case of a error read. In the two former cases, + * the last read value at @addr is stored in @val. + * + * This is modelled after the readx_poll_timeout_atomic macros in linux/iopoll.h. + * + * Note: In general regmap cannot be used in atomic context. If you want to use + * this macro then first setup your regmap for atomic use (flat or no cache + * and MMIO regmap). + */ +#define regmap_read_poll_timeout_atomic(map, addr, val, cond, delay_us, timeout_us) \ +({ \ + u64 __timeout_us = (timeout_us); \ + unsigned long __delay_us = (delay_us); \ + ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ + int __ret; \ + for (;;) { \ + __ret = regmap_read((map), (addr), &(val)); \ + if (__ret) \ + break; \ + if (cond) \ + break; \ + if ((__timeout_us) && \ + ktime_compare(ktime_get(), __timeout) > 0) { \ + __ret = regmap_read((map), (addr), &(val)); \ + break; \ + } \ + if (__delay_us) \ + udelay(__delay_us); \ + } \ + __ret ?: ((cond) ? 0 : -ETIMEDOUT); \ +}) + +/** * regmap_field_read_poll_timeout - Poll until a condition is met or timeout * * @field: Regmap field to read from |