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