]>
Commit | Line | Data |
---|---|---|
336d4615 SG |
1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* | |
ceb70bb8 | 3 | * Copyright (C) 2020 Sean Anderson <[email protected]> |
336d4615 SG |
4 | * Copyright (c) 2013 Google, Inc |
5 | * | |
6 | * (C) Copyright 2012 | |
7 | * Pavel Herrmann <[email protected]> | |
8 | * Marek Vasut <[email protected]> | |
9 | */ | |
10 | ||
11 | #ifndef _DM_DEVICE_COMPAT_H | |
12 | #define _DM_DEVICE_COMPAT_H | |
13 | ||
4d14600b | 14 | #include <log.h> |
ceb70bb8 | 15 | #include <linux/build_bug.h> |
336d4615 | 16 | #include <linux/compat.h> |
1e94b46f | 17 | #include <linux/printk.h> |
336d4615 | 18 | |
336d4615 | 19 | /* |
ceb70bb8 SA |
20 | * Define a new identifier which can be tested on by C code. A similar |
21 | * definition is made for DEBUG in <log.h>. | |
336d4615 | 22 | */ |
ceb70bb8 SA |
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__); \ | |
336d4615 SG |
56 | }) |
57 | ||
ceb70bb8 SA |
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 | } \ | |
336d4615 SG |
101 | }) |
102 | ||
103 | #define dev_emerg(dev, fmt, ...) \ | |
4d14600b | 104 | __dev_printk(LOGL_EMERG, dev, fmt, ##__VA_ARGS__) |
336d4615 | 105 | #define dev_alert(dev, fmt, ...) \ |
4d14600b | 106 | __dev_printk(LOGL_ALERT, dev, fmt, ##__VA_ARGS__) |
336d4615 | 107 | #define dev_crit(dev, fmt, ...) \ |
4d14600b | 108 | __dev_printk(LOGL_CRIT, dev, fmt, ##__VA_ARGS__) |
336d4615 | 109 | #define dev_err(dev, fmt, ...) \ |
4d14600b | 110 | __dev_printk(LOGL_ERR, dev, fmt, ##__VA_ARGS__) |
336d4615 | 111 | #define dev_warn(dev, fmt, ...) \ |
4d14600b | 112 | __dev_printk(LOGL_WARNING, dev, fmt, ##__VA_ARGS__) |
336d4615 | 113 | #define dev_notice(dev, fmt, ...) \ |
4d14600b | 114 | __dev_printk(LOGL_NOTICE, dev, fmt, ##__VA_ARGS__) |
336d4615 | 115 | #define dev_info(dev, fmt, ...) \ |
4d14600b | 116 | __dev_printk(LOGL_INFO, dev, fmt, ##__VA_ARGS__) |
336d4615 | 117 | #define dev_dbg(dev, fmt, ...) \ |
4d14600b | 118 | __dev_printk(LOGL_DEBUG, dev, fmt, ##__VA_ARGS__) |
ceb70bb8 SA |
119 | #define dev_vdbg(dev, fmt, ...) \ |
120 | __dev_printk(LOGL_DEBUG_CONTENT, dev, fmt, ##__VA_ARGS__) | |
336d4615 SG |
121 | |
122 | #endif |