
El 11/01/2018 a las 18:17, Jagan Teki escribió:
On Thu, Jan 11, 2018 at 10:41 PM, Álvaro Fernández Rojas noltari@gmail.com wrote:
Add 8/16/32 bits and BE/LE versions of wait_for_bit. This is needed for reading registers that are not aligned to 32 bits, and for Big Endian platforms.
Signed-off-by: Álvaro Fernández Rojas noltari@gmail.com Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com Reviewed-by: Jagan Teki jagan@openedev.com
v8: no changes. v7: Introduce changes suggested by Daniel Schwierzeck:
- Use const void* reg for compatibility with 64 bit systems.
- Remove prefix and use __func__ instead.
v6: Introduce changes suggested by Jagan Teki:
- Switch to wait_for_bit instead of infinite loop.
include/wait_bit.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+)
diff --git a/include/wait_bit.h b/include/wait_bit.h index 06ad43a122..bde6d2cfc3 100644 --- a/include/wait_bit.h +++ b/include/wait_bit.h @@ -69,5 +69,66 @@ static inline int wait_for_bit(const char *prefix, const u32 *reg, return -ETIMEDOUT; }
+/**
- wait_for_bit_x() waits for bit set/cleared in register
- Function polls register waiting for specific bit(s) change
- (either 0->1 or 1->0). It can fail under two conditions:
- Timeout
- User interaction (CTRL-C)
- Function succeeds only if all bits of masked register are set/cleared
- (depending on set option).
- @param reg Register that will be read (using read_x())
- @param mask Bit(s) of register that must be active
- @param set Selects wait condition (bit set or clear)
- @param timeout_ms Timeout (in milliseconds)
- @param breakable Enables CTRL-C interruption
- @return 0 on success, -ETIMEDOUT or -EINTR on failure
- */
+#define BUILD_WAIT_FOR_BIT(sfx, type, read) \
\
+static inline int wait_for_bit_##sfx(const void *reg, \
const type mask, \
const bool set, \
const unsigned int timeout_ms, \
const bool breakable) \
+{ \
type val; \
unsigned long start = get_timer(0); \
\
while (1) { \
val = read(reg); \
\
if (!set) \
val = ~val; \
\
if ((val & mask) == mask) \
return 0; \
\
if (get_timer(start) > timeout_ms) \
break; \
\
if (breakable && ctrlc()) { \
puts("Abort\n"); \
return -EINTR; \
} \
\
udelay(1); \
WATCHDOG_RESET(); \
} \
\
debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__, \
reg, mask, set); \
\
return -ETIMEDOUT; \
+}
+BUILD_WAIT_FOR_BIT(8, u8, readb) +BUILD_WAIT_FOR_BIT(le16, u16, readw) +BUILD_WAIT_FOR_BIT(be16, u16, readw_be) +BUILD_WAIT_FOR_BIT(le32, u32, readl) +BUILD_WAIT_FOR_BIT(be32, u32, readl_be)
I'm still thinking here, can't we try to use typeof and get rid of these endianess and macros? did you tried that?
No, I didn't try that. Can you provide an example of that?