wait_bit.h 2.1 KB

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