/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
 */

#ifndef _COMPAT_LINUX_IOPOLL_H
#define _COMPAT_LINUX_IOPOLL_H

/* Include the autogenerated header file */
#include "../../compat/config.h"

#include_next <linux/iopoll.h>

#ifndef HAVE_POLL_TIMEOUT_US
#define poll_timeout_us(op, cond, sleep_us, timeout_us, sleep_before_op) \
({ \
	u64 __timeout_us = (timeout_us); \
	unsigned long __sleep_us = (sleep_us); \
	ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
	int ___ret; \
	might_sleep_if((__sleep_us) != 0); \
	if ((sleep_before_op) && __sleep_us) \
		usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
	for (;;) { \
		bool __expired = __timeout_us && \
			ktime_compare(ktime_get(), __timeout) > 0; \
		/* guarantee 'op' and 'cond' are evaluated after timeout expired */ \
		barrier(); \
		op; \
		if (cond) { \
			___ret = 0; \
			break; \
		} \
		if (__expired) { \
			___ret = -ETIMEDOUT; \
			break; \
		} \
		if (__sleep_us) \
			usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
		cpu_relax(); \
	} \
	___ret; \
})

#undef read_poll_timeout
#define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \
			  sleep_before_read, args...) \
	poll_timeout_us((val) = op(args), cond, sleep_us, timeout_us, sleep_before_read)

#endif

#endif /* _COMPAT_LINUX_IOPOLL_H */
