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