[PATCH v2 09/14] mfd: zl3073x: Add macro to wait for register value bits to be cleared

Ivan Vecera
2025-04-09T14:43:48Z

Sometimes in communication with the device is necessary to set
certain bit(s) in certain register and then the driver has to
wait until these bits are cleared by the device.

Add the macro for this functionality, it will be used by later
commits.

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
v1->v2:
* fixed macro documentation
---
include/linux/mfd/zl3073x.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)

diff --git a/include/linux/mfd/zl3073x.h b/include/linux/mfd/zl3073x.h
index 405a66a7b3e78..7ccb796f7b9aa 100644
--- a/include/linux/mfd/zl3073x.h
+++ b/include/linux/mfd/zl3073x.h
@@ -5,6 +5,8 @@

#include <linux/bug.h>
#include <linux/cleanup.h>
+#include <linux/errno.h>
+#include <linux/iopoll.h>
#include <linux/mutex.h>

struct device;
@@ -153,4 +155,34 @@ int zl3073x_write_##_name(struct zl3073x_dev *zldev, unsigned int idx, \
#define ZL3073X_REG48_IDX_DEF(_name, _addr, _num, _stride) \
__ZL3073X_REG_IDX_DEF(_name, _addr, 6, u64, _num, _stride)

+#define READ_SLEEP_US 10
+#define READ_TIMEOUT_US 2000000
+
+/**
+ * zl3073x_wait_clear_bits - wait for specific bits to be cleared
+ * @_zldev: pointer to zl3073x device
+ * @_reg: register name
+ * @_bits: bits that should be cleared
+ * @_index: optional index for indexed register
+ *
+ * The macro waits up to @READ_TIMEOUT_US microseconds for @_bits in @_reg
+ * to be cleared.
+ *
+ * Return:
+ * -ETIMEDOUT: if timeout occurred
+ * <0: for other errors occurred during communication
+ * 0: success
+ */
+#define zl3073x_wait_clear_bits(_zldev, _reg, _bits, _index...) \
+({ \
+ zl3073x_##_reg##_t __val; \
+ int __rc; \
+ if (read_poll_timeout(zl3073x_read_##_reg, __rc, \
+ __rc || !((_bits) & __val), \
+ READ_SLEEP_US, READ_TIMEOUT_US, false, \
+ _zldev, ##_index, &__val)) \
+ __rc = -ETIMEDOUT; \
+ __rc; \
+})
+
#endif /* __LINUX_MFD_ZL3073X_H */
--
2.48.1