1*6569c0d3SMasahiro Yamada /* 2*6569c0d3SMasahiro Yamada * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. 3*6569c0d3SMasahiro Yamada * 4*6569c0d3SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0 5*6569c0d3SMasahiro Yamada */ 6*6569c0d3SMasahiro Yamada 7*6569c0d3SMasahiro Yamada #ifndef _LINUX_IOPOLL_H 8*6569c0d3SMasahiro Yamada #define _LINUX_IOPOLL_H 9*6569c0d3SMasahiro Yamada 10*6569c0d3SMasahiro Yamada #include <linux/errno.h> 11*6569c0d3SMasahiro Yamada #include <linux/io.h> 12*6569c0d3SMasahiro Yamada #include <time.h> 13*6569c0d3SMasahiro Yamada 14*6569c0d3SMasahiro Yamada /** 15*6569c0d3SMasahiro Yamada * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs 16*6569c0d3SMasahiro Yamada * @op: accessor function (takes @addr as its only argument) 17*6569c0d3SMasahiro Yamada * @addr: Address to poll 18*6569c0d3SMasahiro Yamada * @val: Variable to read the value into 19*6569c0d3SMasahiro Yamada * @cond: Break condition (usually involving @val) 20*6569c0d3SMasahiro Yamada * @timeout_us: Timeout in us, 0 means never timeout 21*6569c0d3SMasahiro Yamada * 22*6569c0d3SMasahiro Yamada * Returns 0 on success and -ETIMEDOUT upon a timeout. In either 23*6569c0d3SMasahiro Yamada * case, the last read value at @addr is stored in @val. 24*6569c0d3SMasahiro Yamada * 25*6569c0d3SMasahiro Yamada * When available, you'll probably want to use one of the specialized 26*6569c0d3SMasahiro Yamada * macros defined below rather than this macro directly. 27*6569c0d3SMasahiro Yamada */ 28*6569c0d3SMasahiro Yamada #define readx_poll_timeout(op, addr, val, cond, timeout_us) \ 29*6569c0d3SMasahiro Yamada ({ \ 30*6569c0d3SMasahiro Yamada unsigned long timeout = timer_get_us() + timeout_us; \ 31*6569c0d3SMasahiro Yamada for (;;) { \ 32*6569c0d3SMasahiro Yamada (val) = op(addr); \ 33*6569c0d3SMasahiro Yamada if (cond) \ 34*6569c0d3SMasahiro Yamada break; \ 35*6569c0d3SMasahiro Yamada if (timeout_us && time_after(timer_get_us(), timeout)) { \ 36*6569c0d3SMasahiro Yamada (val) = op(addr); \ 37*6569c0d3SMasahiro Yamada break; \ 38*6569c0d3SMasahiro Yamada } \ 39*6569c0d3SMasahiro Yamada } \ 40*6569c0d3SMasahiro Yamada (cond) ? 0 : -ETIMEDOUT; \ 41*6569c0d3SMasahiro Yamada }) 42*6569c0d3SMasahiro Yamada 43*6569c0d3SMasahiro Yamada 44*6569c0d3SMasahiro Yamada #define readb_poll_timeout(addr, val, cond, timeout_us) \ 45*6569c0d3SMasahiro Yamada readx_poll_timeout(readb, addr, val, cond, timeout_us) 46*6569c0d3SMasahiro Yamada 47*6569c0d3SMasahiro Yamada #define readw_poll_timeout(addr, val, cond, timeout_us) \ 48*6569c0d3SMasahiro Yamada readx_poll_timeout(readw, addr, val, cond, timeout_us) 49*6569c0d3SMasahiro Yamada 50*6569c0d3SMasahiro Yamada #define readl_poll_timeout(addr, val, cond, timeout_us) \ 51*6569c0d3SMasahiro Yamada readx_poll_timeout(readl, addr, val, cond, timeout_us) 52*6569c0d3SMasahiro Yamada 53*6569c0d3SMasahiro Yamada #define readq_poll_timeout(addr, val, cond, timeout_us) \ 54*6569c0d3SMasahiro Yamada readx_poll_timeout(readq, addr, val, cond, timeout_us) 55*6569c0d3SMasahiro Yamada 56*6569c0d3SMasahiro Yamada #define readb_relaxed_poll_timeout(addr, val, cond, timeout_us) \ 57*6569c0d3SMasahiro Yamada readx_poll_timeout(readb_relaxed, addr, val, cond, timeout_us) 58*6569c0d3SMasahiro Yamada 59*6569c0d3SMasahiro Yamada #define readw_relaxed_poll_timeout(addr, val, cond, timeout_us) \ 60*6569c0d3SMasahiro Yamada readx_poll_timeout(readw_relaxed, addr, val, cond, timeout_us) 61*6569c0d3SMasahiro Yamada 62*6569c0d3SMasahiro Yamada #define readl_relaxed_poll_timeout(addr, val, cond, timeout_us) \ 63*6569c0d3SMasahiro Yamada readx_poll_timeout(readl_relaxed, addr, val, cond, timeout_us) 64*6569c0d3SMasahiro Yamada 65*6569c0d3SMasahiro Yamada #define readq_relaxed_poll_timeout(addr, val, cond, timeout_us) \ 66*6569c0d3SMasahiro Yamada readx_poll_timeout(readq_relaxed, addr, val, cond, timeout_us) 67*6569c0d3SMasahiro Yamada 68*6569c0d3SMasahiro Yamada #endif /* _LINUX_IOPOLL_H */ 69