1/* 2 * @TAG(OTHER_GPL) 3 */ 4/* SPDX-License-Identifier: GPL-2.0+ */ 5/* 6 * Wait for bit with timeout and ctrlc 7 * 8 * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com> 9 */ 10 11#pragma once 12 13#include "../unimplemented.h" 14#include "../io.h" 15#include "tx2_configs.h" 16 17#define ETIMEDOUT 110 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 \ 39static 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 volatile unsigned long count = 0; \ 47 \ 48 while (count != timeout_ms) { \ 49 val = *((type *)reg); \ 50 \ 51 if (!set) \ 52 val = ~val; \ 53 \ 54 if ((val & mask) == mask) \ 55 return 0; \ 56 \ 57 \ 58 udelay(1000); \ 59 count++; \ 60 } \ 61 \ 62 \ 63 return -ETIMEDOUT; \ 64} 65 66BUILD_WAIT_FOR_BIT(8, u8, readb) 67BUILD_WAIT_FOR_BIT(le16, u16, readw) 68#ifdef readw_be 69BUILD_WAIT_FOR_BIT(be16, u16, readw_be) 70#endif 71BUILD_WAIT_FOR_BIT(le32, u32, readl) 72#ifdef readl_be 73BUILD_WAIT_FOR_BIT(be32, u32, readl_be) 74#endif 75