1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * Wait for bit with timeout and ctrlc 4 * 5 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> 6 */ 7 8 #ifndef __WAIT_BIT_H 9 #define __WAIT_BIT_H 10 11 #include <console.h> 12 #include <log.h> 13 #include <time.h> 14 #include <watchdog.h> 15 #include <linux/delay.h> 16 #include <linux/errno.h> 17 #include <asm/io.h> 18 19 /** 20 * wait_for_bit_x() waits for bit set/cleared in register 21 * 22 * Function polls register waiting for specific bit(s) change 23 * (either 0->1 or 1->0). It can fail under two conditions: 24 * - Timeout 25 * - User interaction (CTRL-C) 26 * Function succeeds only if all bits of masked register are set/cleared 27 * (depending on set option). 28 * 29 * @param reg Register that will be read (using read_x()) 30 * @param mask Bit(s) of register that must be active 31 * @param set Selects wait condition (bit set or clear) 32 * @param timeout_ms Timeout (in milliseconds) 33 * @param breakable Enables CTRL-C interruption 34 * @return 0 on success, -ETIMEDOUT or -EINTR on failure 35 */ 36 37 #define BUILD_WAIT_FOR_BIT(sfx, type, read) \ 38 \ 39 static inline int wait_for_bit_##sfx(const void *reg, \ 40 const type mask, \ 41 const bool set, \ 42 const unsigned int timeout_ms, \ 43 const bool breakable) \ 44 { \ 45 type val; \ 46 unsigned long start = get_timer(0); \ 47 \ 48 while (1) { \ 49 val = read(reg); \ 50 \ 51 if (!set) \ 52 val = ~val; \ 53 \ 54 if ((val & mask) == mask) \ 55 return 0; \ 56 \ 57 if (get_timer(start) > timeout_ms) \ 58 break; \ 59 \ 60 if (breakable && ctrlc()) { \ 61 puts("Abort\n"); \ 62 return -EINTR; \ 63 } \ 64 \ 65 udelay(1); \ 66 WATCHDOG_RESET(); \ 67 } \ 68 \ 69 debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__, \ 70 reg, mask, set); \ 71 \ 72 return -ETIMEDOUT; \ 73 } 74 75 BUILD_WAIT_FOR_BIT(8, u8, readb) 76 BUILD_WAIT_FOR_BIT(le16, u16, readw) 77 BUILD_WAIT_FOR_BIT(16, u16, readw) 78 #ifdef readw_be 79 BUILD_WAIT_FOR_BIT(be16, u16, readw_be) 80 #endif 81 BUILD_WAIT_FOR_BIT(le32, u32, readl) 82 BUILD_WAIT_FOR_BIT(32, u32, readl) 83 #ifdef readl_be 84 BUILD_WAIT_FOR_BIT(be32, u32, readl_be) 85 #endif 86 87 #endif 88