Commit | Line | Data |
---|---|---|
9afdf402 MK |
1 | /* |
2 | * Wait for bit with timeout and ctrlc | |
3 | * | |
4 | * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0+ | |
7 | */ | |
8 | ||
9 | #ifndef __WAIT_BIT_H | |
10 | #define __WAIT_BIT_H | |
11 | ||
12 | #include <common.h> | |
13 | #include <console.h> | |
3cd42180 | 14 | #include <watchdog.h> |
1221ce45 | 15 | #include <linux/errno.h> |
9afdf402 MK |
16 | #include <asm/io.h> |
17 | ||
18 | /** | |
19 | * wait_for_bit() waits for bit set/cleared in register | |
20 | * | |
21 | * Function polls register waiting for specific bit(s) change | |
22 | * (either 0->1 or 1->0). It can fail under two conditions: | |
23 | * - Timeout | |
24 | * - User interaction (CTRL-C) | |
25 | * Function succeeds only if all bits of masked register are set/cleared | |
26 | * (depending on set option). | |
27 | * | |
28 | * @param prefix Prefix added to timeout messagge (message visible only | |
29 | * with debug enabled) | |
30 | * @param reg Register that will be read (using readl()) | |
31 | * @param mask Bit(s) of register that must be active | |
32 | * @param set Selects wait condition (bit set or clear) | |
33 | * @param timeout_ms Timeout (in miliseconds) | |
34 | * @param breakable Enables CTRL-C interruption | |
35 | * @return 0 on success, -ETIMEDOUT or -EINTR on failure | |
36 | */ | |
37 | static inline int wait_for_bit(const char *prefix, const u32 *reg, | |
38 | const u32 mask, const bool set, | |
39 | const unsigned int timeout_ms, | |
40 | const bool breakable) | |
41 | { | |
42 | u32 val; | |
43 | unsigned long start = get_timer(0); | |
44 | ||
45 | while (1) { | |
46 | val = readl(reg); | |
47 | ||
48 | if (!set) | |
49 | val = ~val; | |
50 | ||
51 | if ((val & mask) == mask) | |
52 | return 0; | |
53 | ||
54 | if (get_timer(start) > timeout_ms) | |
55 | break; | |
56 | ||
57 | if (breakable && ctrlc()) { | |
58 | puts("Abort\n"); | |
59 | return -EINTR; | |
60 | } | |
61 | ||
62 | udelay(1); | |
3cd42180 | 63 | WATCHDOG_RESET(); |
9afdf402 MK |
64 | } |
65 | ||
66 | debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n", prefix, reg, mask, | |
67 | set); | |
68 | ||
69 | return -ETIMEDOUT; | |
70 | } | |
71 | ||
72 | ||
73 | #endif |