1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2020 Sean Anderson <seanga2@gmail.com>
4  * Copyright (c) 2013 Google, Inc
5  *
6  * (C) Copyright 2012
7  * Pavel Herrmann <morpheus.ibis@gmail.com>
8  * Marek Vasut <marex@denx.de>
9  */
10 
11 #ifndef _DM_DEVICE_COMPAT_H
12 #define _DM_DEVICE_COMPAT_H
13 
14 #include <log.h>
15 #include <linux/build_bug.h>
16 #include <linux/compat.h>
17 #include <linux/printk.h>
18 
19 /*
20  * Define a new identifier which can be tested on by C code. A similar
21  * definition is made for DEBUG in <log.h>.
22  */
23 #ifdef VERBOSE_DEBUG
24 #define _VERBOSE_DEBUG 1
25 #else
26 #define _VERBOSE_DEBUG 0
27 #endif
28 
29 /**
30  * dev_printk_emit() - Emit a formatted log message
31  * @cat: Category of the message
32  * @level: Log level of the message
33  * @fmt: Format string
34  * @...: Arguments for @fmt
35  *
36  * This macro logs a message through the appropriate channel. It is a macro so
37  * the if statements can be optimized out (as @level should be a constant known
38  * at compile-time).
39  *
40  * If DEBUG or VERBOSE_DEBUG is defined, then some messages are always printed
41  * (through printf()). This is to match the historical behavior of the dev_xxx
42  * functions.
43  *
44  * If LOG is enabled, use log() to emit the message, otherwise print it based on
45  * the console loglevel.
46  */
47 #define dev_printk_emit(cat, level, fmt, ...) \
48 ({ \
49 	if ((_DEBUG && level == LOGL_DEBUG) || \
50 	    (_VERBOSE_DEBUG && level == LOGL_DEBUG_CONTENT)) \
51 		printf(fmt, ##__VA_ARGS__); \
52 	else if (CONFIG_IS_ENABLED(LOG)) \
53 		log(cat, level, fmt, ##__VA_ARGS__); \
54 	else if (level < CONFIG_VAL(LOGLEVEL)) \
55 		printf(fmt, ##__VA_ARGS__); \
56 })
57 
58 /**
59  * __dev_printk() - Log a message for a device
60  * @level: Log level of the message
61  * @dev: A &struct udevice or &struct device
62  * @fmt: Format string
63  * @...: Arguments for @fmt
64  *
65  * This macro formats and prints dev_xxx log messages. It is done as a macro
66  * because working with variadic argument is much easier this way, we can
67  * interrogate the type of device we are passed (and whether it *is* a &struct
68  * udevice or &struct device), and dev_printk_emit() can optimize out unused if
69  * branches.
70  *
71  * Because this is a macro, we must enforce type checks ourselves. Ideally, we
72  * would only accept udevices, but there is a significant amount of code (mostly
73  * USB) which calls dev_xxx with &struct device. When assigning ``__dev``, we
74  * must first cast ``dev`` to ``void *`` so we don't get warned when ``dev`` is
75  * a &struct device. Even though the latter branch is not taken, it will still
76  * get compiled and type-checked.
77  *
78  * The format strings in case of a ``NULL`` ``dev`` MUST be kept the same.
79  * Otherwise, @fmt will be duplicated in the data section (with slightly
80  * different prefixes). This is why ``(NULL udevice *)`` is printed as two
81  * string arguments, and not by string pasting.
82  */
83 #define __dev_printk(level, dev, fmt, ...) \
84 ({ \
85 	if (__same_type(dev, struct device  *)) { \
86 		dev_printk_emit(LOG_CATEGORY, level, fmt, ##__VA_ARGS__); \
87 	} else { \
88 		BUILD_BUG_ON(!__same_type(dev, struct udevice *)); \
89 		struct udevice *__dev = (void *)dev; \
90 		if (__dev) \
91 			dev_printk_emit(__dev->driver->id, level, \
92 					"%s %s: " fmt, \
93 					__dev->driver->name, __dev->name, \
94 					##__VA_ARGS__); \
95 		else \
96 			dev_printk_emit(LOG_CATEGORY, level, \
97 					"%s %s: " fmt, \
98 					"(NULL", "udevice *)", \
99 					##__VA_ARGS__); \
100 	} \
101 })
102 
103 #define dev_emerg(dev, fmt, ...) \
104 	__dev_printk(LOGL_EMERG, dev, fmt, ##__VA_ARGS__)
105 #define dev_alert(dev, fmt, ...) \
106 	__dev_printk(LOGL_ALERT, dev, fmt, ##__VA_ARGS__)
107 #define dev_crit(dev, fmt, ...) \
108 	__dev_printk(LOGL_CRIT, dev, fmt, ##__VA_ARGS__)
109 #define dev_err(dev, fmt, ...) \
110 	__dev_printk(LOGL_ERR, dev, fmt, ##__VA_ARGS__)
111 #define dev_warn(dev, fmt, ...) \
112 	__dev_printk(LOGL_WARNING, dev, fmt, ##__VA_ARGS__)
113 #define dev_notice(dev, fmt, ...) \
114 	__dev_printk(LOGL_NOTICE, dev, fmt, ##__VA_ARGS__)
115 #define dev_info(dev, fmt, ...) \
116 	__dev_printk(LOGL_INFO, dev, fmt, ##__VA_ARGS__)
117 #define dev_dbg(dev, fmt, ...) \
118 	__dev_printk(LOGL_DEBUG, dev, fmt, ##__VA_ARGS__)
119 #define dev_vdbg(dev, fmt, ...) \
120 	__dev_printk(LOGL_DEBUG_CONTENT, dev, fmt, ##__VA_ARGS__)
121 
122 #endif
123