diff options
| author | Stephen Boyd <sboyd@kernel.org> | 2023-06-09 14:59:14 -0700 |
|---|---|---|
| committer | Stephen Boyd <sboyd@kernel.org> | 2023-06-09 14:59:14 -0700 |
| commit | e90f15be2447d95d6b56068ad03c5ec73730103d (patch) | |
| tree | f35a17cdb584cefe1e5d9615ff9ec67a87bc2d0e /include/linux/iopoll.h | |
| parent | f73b836edfef23054c227712bbdb9d4c23e00440 (diff) | |
| parent | 7df8eea64a417f1db6777cddc1d7eda3634b7175 (diff) | |
| download | linux-e90f15be2447d95d6b56068ad03c5ec73730103d.tar.gz linux-e90f15be2447d95d6b56068ad03c5ec73730103d.tar.bz2 linux-e90f15be2447d95d6b56068ad03c5ec73730103d.zip | |
Merge tag 'renesas-clk-for-v6.5-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers into clk-renesas
Pull more Renesas clk driver updates from Geert Uytterhoeven:
- Convert the Renesas clock drivers to readl_poll_timeout_atomic()
* tag 'renesas-clk-for-v6.5-tag2' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers:
clk: renesas: rzg2l: Convert to readl_poll_timeout_atomic()
clk: renesas: mstp: Convert to readl_poll_timeout_atomic()
clk: renesas: cpg-mssr: Convert to readl_poll_timeout_atomic()
iopoll: Do not use timekeeping in read_poll_timeout_atomic()
iopoll: Call cpu_relax() in busy loops
Diffstat (limited to 'include/linux/iopoll.h')
| -rw-r--r-- | include/linux/iopoll.h | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h index 2c8860e406bd..19a7b00baff4 100644 --- a/include/linux/iopoll.h +++ b/include/linux/iopoll.h @@ -53,6 +53,7 @@ } \ if (__sleep_us) \ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ + cpu_relax(); \ } \ (cond) ? 0 : -ETIMEDOUT; \ }) @@ -73,6 +74,10 @@ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either * case, the last read value at @args is stored in @val. * + * This macro does not rely on timekeeping. Hence it is safe to call even when + * timekeeping is suspended, at the expense of an underestimation of wall clock + * time, which is rather minimal with a non-zero delay_us. + * * When available, you'll probably want to use one of the specialized * macros defined below rather than this macro directly. */ @@ -80,21 +85,30 @@ delay_before_read, args...) \ ({ \ u64 __timeout_us = (timeout_us); \ + s64 __left_ns = __timeout_us * NSEC_PER_USEC; \ unsigned long __delay_us = (delay_us); \ - ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ - if (delay_before_read && __delay_us) \ + u64 __delay_ns = __delay_us * NSEC_PER_USEC; \ + if (delay_before_read && __delay_us) { \ udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ for (;;) { \ (val) = op(args); \ if (cond) \ break; \ - if (__timeout_us && \ - ktime_compare(ktime_get(), __timeout) > 0) { \ + if (__timeout_us && __left_ns < 0) { \ (val) = op(args); \ break; \ } \ - if (__delay_us) \ + if (__delay_us) { \ udelay(__delay_us); \ + if (__timeout_us) \ + __left_ns -= __delay_ns; \ + } \ + cpu_relax(); \ + if (__timeout_us) \ + __left_ns--; \ } \ (cond) ? 0 : -ETIMEDOUT; \ }) |
