1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */ 29afdf402SMateusz Kulikowski /* 39afdf402SMateusz Kulikowski * Wait for bit with timeout and ctrlc 49afdf402SMateusz Kulikowski * 59afdf402SMateusz Kulikowski * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> 69afdf402SMateusz Kulikowski */ 79afdf402SMateusz Kulikowski 89afdf402SMateusz Kulikowski #ifndef __WAIT_BIT_H 99afdf402SMateusz Kulikowski #define __WAIT_BIT_H 109afdf402SMateusz Kulikowski 119afdf402SMateusz Kulikowski #include <common.h> 129afdf402SMateusz Kulikowski #include <console.h> 133cd42180SMichal Simek #include <watchdog.h> 141221ce45SMasahiro Yamada #include <linux/errno.h> 159afdf402SMateusz Kulikowski #include <asm/io.h> 169afdf402SMateusz Kulikowski 179afdf402SMateusz Kulikowski /** 1891fe458bSÁlvaro Fernández Rojas * wait_for_bit_x() waits for bit set/cleared in register 1991fe458bSÁlvaro Fernández Rojas * 2091fe458bSÁlvaro Fernández Rojas * Function polls register waiting for specific bit(s) change 2191fe458bSÁlvaro Fernández Rojas * (either 0->1 or 1->0). It can fail under two conditions: 2291fe458bSÁlvaro Fernández Rojas * - Timeout 2391fe458bSÁlvaro Fernández Rojas * - User interaction (CTRL-C) 2491fe458bSÁlvaro Fernández Rojas * Function succeeds only if all bits of masked register are set/cleared 2591fe458bSÁlvaro Fernández Rojas * (depending on set option). 2691fe458bSÁlvaro Fernández Rojas * 2791fe458bSÁlvaro Fernández Rojas * @param reg Register that will be read (using read_x()) 2891fe458bSÁlvaro Fernández Rojas * @param mask Bit(s) of register that must be active 2991fe458bSÁlvaro Fernández Rojas * @param set Selects wait condition (bit set or clear) 3091fe458bSÁlvaro Fernández Rojas * @param timeout_ms Timeout (in milliseconds) 3191fe458bSÁlvaro Fernández Rojas * @param breakable Enables CTRL-C interruption 3291fe458bSÁlvaro Fernández Rojas * @return 0 on success, -ETIMEDOUT or -EINTR on failure 3391fe458bSÁlvaro Fernández Rojas */ 3491fe458bSÁlvaro Fernández Rojas 3591fe458bSÁlvaro Fernández Rojas #define BUILD_WAIT_FOR_BIT(sfx, type, read) \ 3691fe458bSÁlvaro Fernández Rojas \ 3791fe458bSÁlvaro Fernández Rojas static inline int wait_for_bit_##sfx(const void *reg, \ 3891fe458bSÁlvaro Fernández Rojas const type mask, \ 3991fe458bSÁlvaro Fernández Rojas const bool set, \ 4091fe458bSÁlvaro Fernández Rojas const unsigned int timeout_ms, \ 4191fe458bSÁlvaro Fernández Rojas const bool breakable) \ 4291fe458bSÁlvaro Fernández Rojas { \ 4391fe458bSÁlvaro Fernández Rojas type val; \ 4491fe458bSÁlvaro Fernández Rojas unsigned long start = get_timer(0); \ 4591fe458bSÁlvaro Fernández Rojas \ 4691fe458bSÁlvaro Fernández Rojas while (1) { \ 4791fe458bSÁlvaro Fernández Rojas val = read(reg); \ 4891fe458bSÁlvaro Fernández Rojas \ 4991fe458bSÁlvaro Fernández Rojas if (!set) \ 5091fe458bSÁlvaro Fernández Rojas val = ~val; \ 5191fe458bSÁlvaro Fernández Rojas \ 5291fe458bSÁlvaro Fernández Rojas if ((val & mask) == mask) \ 5391fe458bSÁlvaro Fernández Rojas return 0; \ 5491fe458bSÁlvaro Fernández Rojas \ 5591fe458bSÁlvaro Fernández Rojas if (get_timer(start) > timeout_ms) \ 5691fe458bSÁlvaro Fernández Rojas break; \ 5791fe458bSÁlvaro Fernández Rojas \ 5891fe458bSÁlvaro Fernández Rojas if (breakable && ctrlc()) { \ 5991fe458bSÁlvaro Fernández Rojas puts("Abort\n"); \ 6091fe458bSÁlvaro Fernández Rojas return -EINTR; \ 6191fe458bSÁlvaro Fernández Rojas } \ 6291fe458bSÁlvaro Fernández Rojas \ 6391fe458bSÁlvaro Fernández Rojas udelay(1); \ 6491fe458bSÁlvaro Fernández Rojas WATCHDOG_RESET(); \ 6591fe458bSÁlvaro Fernández Rojas } \ 6691fe458bSÁlvaro Fernández Rojas \ 6791fe458bSÁlvaro Fernández Rojas debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__, \ 6891fe458bSÁlvaro Fernández Rojas reg, mask, set); \ 6991fe458bSÁlvaro Fernández Rojas \ 7091fe458bSÁlvaro Fernández Rojas return -ETIMEDOUT; \ 7191fe458bSÁlvaro Fernández Rojas } 7291fe458bSÁlvaro Fernández Rojas 7391fe458bSÁlvaro Fernández Rojas BUILD_WAIT_FOR_BIT(8, u8, readb) 7491fe458bSÁlvaro Fernández Rojas BUILD_WAIT_FOR_BIT(le16, u16, readw) 7591fe458bSÁlvaro Fernández Rojas #ifdef readw_be 7691fe458bSÁlvaro Fernández Rojas BUILD_WAIT_FOR_BIT(be16, u16, readw_be) 7791fe458bSÁlvaro Fernández Rojas #endif 7891fe458bSÁlvaro Fernández Rojas BUILD_WAIT_FOR_BIT(le32, u32, readl) 7991fe458bSÁlvaro Fernández Rojas #ifdef readl_be 8091fe458bSÁlvaro Fernández Rojas BUILD_WAIT_FOR_BIT(be32, u32, readl_be) 8191fe458bSÁlvaro Fernández Rojas #endif 829afdf402SMateusz Kulikowski 839afdf402SMateusz Kulikowski #endif 84