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