#ifndef _COMPAT_LINUX_DEVICE_H
#define _COMPAT_LINUX_DEVICE_H

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

#include_next <linux/device.h>
#include <linux/overflow.h>
#include <linux/ratelimit.h>

#ifndef dev_fmt
#define dev_fmt(fmt) fmt
#endif

#ifndef dev_dbg_ratelimited
#if defined(CONFIG_DYNAMIC_DEBUG)
/* descriptor check is first to prevent flooding with "callbacks suppressed" */
#define dev_dbg_ratelimited(dev, fmt, ...)                              \
	do {                                                                    \
		static DEFINE_RATELIMIT_STATE(_rs,                              \
				DEFAULT_RATELIMIT_INTERVAL,       \
				DEFAULT_RATELIMIT_BURST);         \
		DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);                 \
		if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) &&        \
				__ratelimit(&_rs))                                          \
		__dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt),       \
##__VA_ARGS__);                       \
	} while (0)
#elif defined(DEBUG)
#define dev_dbg_ratelimited(dev, fmt, ...)                              \
	do {                                                                    \
		static DEFINE_RATELIMIT_STATE(_rs,                              \
				DEFAULT_RATELIMIT_INTERVAL,       \
				DEFAULT_RATELIMIT_BURST);         \
		if (__ratelimit(&_rs))                                          \
		dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
	} while (0)
#else
#define dev_dbg_ratelimited(dev, fmt, ...)                              \
	do {                                                                    \
		if (0)                                                          \
		dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \
	} while (0)
#endif
#endif

#ifndef DEVICE_ATTR_RO
#define DEVICE_ATTR_RO(_name) \
	struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
#endif
#ifndef DEVICE_ATTR_RW
#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)
#define DEVICE_ATTR_RW(_name) \
	struct device_attribute dev_attr_##_name = __ATTR_RW(_name)
#endif

#ifndef dev_warn_ratelimited
#define dev_warn_ratelimited(dev, fmt, ...)
#endif

#ifndef dev_level_ratelimited
#define dev_level_ratelimited(dev_level, dev, fmt, ...)                 \
	do {                                                                    \
		static DEFINE_RATELIMIT_STATE(_rs,                              \
				DEFAULT_RATELIMIT_INTERVAL,       \
				DEFAULT_RATELIMIT_BURST);         \
		if (__ratelimit(&_rs))                                          \
		dev_level(dev, fmt, ##__VA_ARGS__);                     \
	} while (0)
#endif

#ifndef dev_info_ratelimited
#define dev_info_ratelimited(dev, fmt, ...)                             \
        dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__)
#endif

#ifndef dev_warn_once
#ifdef CONFIG_PRINTK
#define dev_level_once(dev_level, dev, fmt, ...)                       \
	do {                                                                   \
		static bool __print_once __read_mostly;                         \
		\
		if (!__print_once) {                                            \
			__print_once = true;                                    \
			dev_level(dev, fmt, ##__VA_ARGS__);                     \
		}                                                               \
	} while (0)
#else
#define dev_level_once(dev_level, dev, fmt, ...)                       \
	do {                                                                   \
		if (0)                                                          \
		dev_level(dev, fmt, ##__VA_ARGS__);                     \
	} while (0)
#endif

#define dev_emerg_once(dev, fmt, ...)                                  \
	dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__)
#define dev_alert_once(dev, fmt, ...)                                  \
	dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__)
#define dev_crit_once(dev, fmt, ...)                                   \
	dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__)
#define dev_err_once(dev, fmt, ...)                                    \
	dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__)
#define dev_warn_once(dev, fmt, ...)                                   \
	dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__)
#define dev_notice_once(dev, fmt, ...)                                 \
	dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__)
#define dev_info_once(dev, fmt, ...)                                   \
	dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__)
#define dev_dbg_once(dev, fmt, ...)                                    \
	dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__)
#endif /* dev_warn_once */

#endif /* _COMPAT_LINUX_DEVICE_H */
