Commit | Line | Data |
---|---|---|
54c52312 MW |
1 | /* |
2 | * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License version 2 and | |
6 | * only version 2 as published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
13 | */ | |
14 | ||
15 | #ifndef _LINUX_IOPOLL_H | |
16 | #define _LINUX_IOPOLL_H | |
17 | ||
18 | #include <linux/kernel.h> | |
19 | #include <linux/types.h> | |
16f4e319 | 20 | #include <linux/ktime.h> |
54c52312 MW |
21 | #include <linux/delay.h> |
22 | #include <linux/errno.h> | |
23 | #include <linux/io.h> | |
24 | ||
25 | /** | |
26 | * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs | |
27 | * @op: accessor function (takes @addr as its only argument) | |
28 | * @addr: Address to poll | |
29 | * @val: Variable to read the value into | |
30 | * @cond: Break condition (usually involving @val) | |
31 | * @sleep_us: Maximum time to sleep between reads in us (0 | |
32 | * tight-loops). Should be less than ~20ms since usleep_range | |
33 | * is used (see Documentation/timers/timers-howto.txt). | |
34 | * @timeout_us: Timeout in us, 0 means never timeout | |
35 | * | |
36 | * Returns 0 on success and -ETIMEDOUT upon a timeout. In either | |
37 | * case, the last read value at @addr is stored in @val. Must not | |
38 | * be called from atomic context if sleep_us or timeout_us are used. | |
39 | * | |
40 | * When available, you'll probably want to use one of the specialized | |
41 | * macros defined below rather than this macro directly. | |
42 | */ | |
43 | #define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \ | |
44 | ({ \ | |
d15809f3 AB |
45 | u64 __timeout_us = (timeout_us); \ |
46 | unsigned long __sleep_us = (sleep_us); \ | |
47 | ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ | |
48 | might_sleep_if((__sleep_us) != 0); \ | |
54c52312 MW |
49 | for (;;) { \ |
50 | (val) = op(addr); \ | |
51 | if (cond) \ | |
52 | break; \ | |
d15809f3 AB |
53 | if (__timeout_us && \ |
54 | ktime_compare(ktime_get(), __timeout) > 0) { \ | |
54c52312 MW |
55 | (val) = op(addr); \ |
56 | break; \ | |
57 | } \ | |
d15809f3 AB |
58 | if (__sleep_us) \ |
59 | usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ | |
54c52312 MW |
60 | } \ |
61 | (cond) ? 0 : -ETIMEDOUT; \ | |
62 | }) | |
63 | ||
64 | /** | |
65 | * readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs | |
66 | * @op: accessor function (takes @addr as its only argument) | |
67 | * @addr: Address to poll | |
68 | * @val: Variable to read the value into | |
69 | * @cond: Break condition (usually involving @val) | |
70 | * @delay_us: Time to udelay between reads in us (0 tight-loops). Should | |
71 | * be less than ~10us since udelay is used (see | |
72 | * Documentation/timers/timers-howto.txt). | |
73 | * @timeout_us: Timeout in us, 0 means never timeout | |
74 | * | |
75 | * Returns 0 on success and -ETIMEDOUT upon a timeout. In either | |
76 | * case, the last read value at @addr is stored in @val. | |
77 | * | |
78 | * When available, you'll probably want to use one of the specialized | |
79 | * macros defined below rather than this macro directly. | |
80 | */ | |
81 | #define readx_poll_timeout_atomic(op, addr, val, cond, delay_us, timeout_us) \ | |
82 | ({ \ | |
d15809f3 AB |
83 | u64 __timeout_us = (timeout_us); \ |
84 | unsigned long __delay_us = (delay_us); \ | |
85 | ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ | |
54c52312 MW |
86 | for (;;) { \ |
87 | (val) = op(addr); \ | |
88 | if (cond) \ | |
89 | break; \ | |
d15809f3 AB |
90 | if (__timeout_us && \ |
91 | ktime_compare(ktime_get(), __timeout) > 0) { \ | |
54c52312 MW |
92 | (val) = op(addr); \ |
93 | break; \ | |
94 | } \ | |
d15809f3 AB |
95 | if (__delay_us) \ |
96 | udelay(__delay_us); \ | |
54c52312 MW |
97 | } \ |
98 | (cond) ? 0 : -ETIMEDOUT; \ | |
99 | }) | |
100 | ||
101 | ||
102 | #define readb_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
103 | readx_poll_timeout(readb, addr, val, cond, delay_us, timeout_us) | |
104 | ||
105 | #define readb_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
106 | readx_poll_timeout_atomic(readb, addr, val, cond, delay_us, timeout_us) | |
107 | ||
108 | #define readw_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
109 | readx_poll_timeout(readw, addr, val, cond, delay_us, timeout_us) | |
110 | ||
111 | #define readw_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
112 | readx_poll_timeout_atomic(readw, addr, val, cond, delay_us, timeout_us) | |
113 | ||
114 | #define readl_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
115 | readx_poll_timeout(readl, addr, val, cond, delay_us, timeout_us) | |
116 | ||
117 | #define readl_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
118 | readx_poll_timeout_atomic(readl, addr, val, cond, delay_us, timeout_us) | |
119 | ||
120 | #define readq_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
121 | readx_poll_timeout(readq, addr, val, cond, delay_us, timeout_us) | |
122 | ||
123 | #define readq_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
124 | readx_poll_timeout_atomic(readq, addr, val, cond, delay_us, timeout_us) | |
125 | ||
126 | #define readb_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
127 | readx_poll_timeout(readb_relaxed, addr, val, cond, delay_us, timeout_us) | |
128 | ||
129 | #define readb_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
130 | readx_poll_timeout_atomic(readb_relaxed, addr, val, cond, delay_us, timeout_us) | |
131 | ||
132 | #define readw_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
133 | readx_poll_timeout(readw_relaxed, addr, val, cond, delay_us, timeout_us) | |
134 | ||
135 | #define readw_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
136 | readx_poll_timeout_atomic(readw_relaxed, addr, val, cond, delay_us, timeout_us) | |
137 | ||
138 | #define readl_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
139 | readx_poll_timeout(readl_relaxed, addr, val, cond, delay_us, timeout_us) | |
140 | ||
141 | #define readl_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
142 | readx_poll_timeout_atomic(readl_relaxed, addr, val, cond, delay_us, timeout_us) | |
143 | ||
144 | #define readq_relaxed_poll_timeout(addr, val, cond, delay_us, timeout_us) \ | |
145 | readx_poll_timeout(readq_relaxed, addr, val, cond, delay_us, timeout_us) | |
146 | ||
147 | #define readq_relaxed_poll_timeout_atomic(addr, val, cond, delay_us, timeout_us) \ | |
148 | readx_poll_timeout_atomic(readq_relaxed, addr, val, cond, delay_us, timeout_us) | |
149 | ||
150 | #endif /* _LINUX_IOPOLL_H */ |