183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
20e98b0a6SSimon Glass /*
30e98b0a6SSimon Glass * Logging support
40e98b0a6SSimon Glass *
50e98b0a6SSimon Glass * Copyright (c) 2017 Google, Inc
60e98b0a6SSimon Glass * Written by Simon Glass <sjg@chromium.org>
70e98b0a6SSimon Glass */
80e98b0a6SSimon Glass
90e98b0a6SSimon Glass #ifndef __LOG_H
100e98b0a6SSimon Glass #define __LOG_H
110e98b0a6SSimon Glass
12e9c8d49dSSimon Glass #include <dm/uclass-id.h>
13e9c8d49dSSimon Glass #include <linux/list.h>
14e9c8d49dSSimon Glass
15e9c8d49dSSimon Glass /** Log levels supported, ranging from most to least important */
16e9c8d49dSSimon Glass enum log_level_t {
17e9c8d49dSSimon Glass LOGL_EMERG = 0, /* U-Boot is unstable */
18e9c8d49dSSimon Glass LOGL_ALERT, /* Action must be taken immediately */
19e9c8d49dSSimon Glass LOGL_CRIT, /* Critical conditions */
20e9c8d49dSSimon Glass LOGL_ERR, /* Error that prevents something from working */
21e9c8d49dSSimon Glass LOGL_WARNING, /* Warning may prevent optimial operation */
22e9c8d49dSSimon Glass LOGL_NOTICE, /* Normal but significant condition, printf() */
23e9c8d49dSSimon Glass LOGL_INFO, /* General information message */
24e9c8d49dSSimon Glass LOGL_DEBUG, /* Basic debug-level message */
25e9c8d49dSSimon Glass LOGL_DEBUG_CONTENT, /* Debug message showing full message content */
26e9c8d49dSSimon Glass LOGL_DEBUG_IO, /* Debug message showing hardware I/O access */
27e9c8d49dSSimon Glass
28e9c8d49dSSimon Glass LOGL_COUNT,
29f941c8d7SSimon Glass LOGL_NONE,
30f941c8d7SSimon Glass
31e9c8d49dSSimon Glass LOGL_FIRST = LOGL_EMERG,
32f941c8d7SSimon Glass LOGL_MAX = LOGL_DEBUG_IO,
33e9c8d49dSSimon Glass };
34e9c8d49dSSimon Glass
35e9c8d49dSSimon Glass /**
36e9c8d49dSSimon Glass * Log categories supported. Most of these correspond to uclasses (i.e.
37e9c8d49dSSimon Glass * enum uclass_id) but there are also some more generic categories
38e9c8d49dSSimon Glass */
39e9c8d49dSSimon Glass enum log_category_t {
40e9c8d49dSSimon Glass LOGC_FIRST = 0, /* First part mirrors UCLASS_... */
41e9c8d49dSSimon Glass
420bf96459SSimon Glass LOGC_NONE = UCLASS_COUNT, /* First number is after all uclasses */
430bf96459SSimon Glass LOGC_ARCH, /* Related to arch-specific code */
440bf96459SSimon Glass LOGC_BOARD, /* Related to board-specific code */
450bf96459SSimon Glass LOGC_CORE, /* Related to core features (non-driver-model) */
46f941c8d7SSimon Glass LOGC_DM, /* Core driver-model */
47f941c8d7SSimon Glass LOGC_DT, /* Device-tree */
48d8d8997bSHeinrich Schuchardt LOGC_EFI, /* EFI implementation */
49c3aed5dbSSimon Glass LOGC_ALLOC, /* Memory allocation */
50a5c13b68SSimon Glass LOGC_SANDBOX, /* Related to the sandbox board */
519f407d4eSSimon Glass LOGC_BLOBLIST, /* Bloblist */
52e9c8d49dSSimon Glass
530bf96459SSimon Glass LOGC_COUNT, /* Number of log categories */
540bf96459SSimon Glass LOGC_END, /* Sentinel value for a list of log categories */
55e9c8d49dSSimon Glass };
56e9c8d49dSSimon Glass
57e9c8d49dSSimon Glass /* Helper to cast a uclass ID to a log category */
log_uc_cat(enum uclass_id id)58e9c8d49dSSimon Glass static inline int log_uc_cat(enum uclass_id id)
59e9c8d49dSSimon Glass {
60e9c8d49dSSimon Glass return (enum log_category_t)id;
61e9c8d49dSSimon Glass }
62e9c8d49dSSimon Glass
63e9c8d49dSSimon Glass /**
64e9c8d49dSSimon Glass * _log() - Internal function to emit a new log record
65e9c8d49dSSimon Glass *
66e9c8d49dSSimon Glass * @cat: Category of log record (indicating which subsystem generated it)
67e9c8d49dSSimon Glass * @level: Level of log record (indicating its severity)
68e9c8d49dSSimon Glass * @file: File name of file where log record was generated
69e9c8d49dSSimon Glass * @line: Line number in file where log record was generated
70e9c8d49dSSimon Glass * @func: Function where log record was generated
71e9c8d49dSSimon Glass * @fmt: printf() format string for log record
72e9c8d49dSSimon Glass * @...: Optional parameters, according to the format string @fmt
73e9c8d49dSSimon Glass * @return 0 if log record was emitted, -ve on error
74e9c8d49dSSimon Glass */
75e9c8d49dSSimon Glass int _log(enum log_category_t cat, enum log_level_t level, const char *file,
76ed4e933dSSimon Glass int line, const char *func, const char *fmt, ...)
77ed4e933dSSimon Glass __attribute__ ((format (__printf__, 6, 7)));
78e9c8d49dSSimon Glass
79e9c8d49dSSimon Glass /* Define this at the top of a file to add a prefix to debug messages */
80e9c8d49dSSimon Glass #ifndef pr_fmt
81e9c8d49dSSimon Glass #define pr_fmt(fmt) fmt
82e9c8d49dSSimon Glass #endif
83e9c8d49dSSimon Glass
84e9c8d49dSSimon Glass /* Use a default category if this file does not supply one */
85e9c8d49dSSimon Glass #ifndef LOG_CATEGORY
86e9c8d49dSSimon Glass #define LOG_CATEGORY LOGC_NONE
87e9c8d49dSSimon Glass #endif
88e9c8d49dSSimon Glass
89e9c8d49dSSimon Glass /*
90e9c8d49dSSimon Glass * This header may be including when CONFIG_LOG is disabled, in which case
91e9c8d49dSSimon Glass * CONFIG_LOG_MAX_LEVEL is not defined. Add a check for this.
92e9c8d49dSSimon Glass */
93e9c8d49dSSimon Glass #if CONFIG_IS_ENABLED(LOG)
94e9c8d49dSSimon Glass #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
95cdd140afSSimon Glass #define log_err(_fmt...) log(LOG_CATEGORY, LOGL_ERR, ##_fmt)
96cdd140afSSimon Glass #define log_warning(_fmt...) log(LOG_CATEGORY, LOGL_WARNING, ##_fmt)
97cdd140afSSimon Glass #define log_notice(_fmt...) log(LOG_CATEGORY, LOGL_NOTICE, ##_fmt)
98cdd140afSSimon Glass #define log_info(_fmt...) log(LOG_CATEGORY, LOGL_INFO, ##_fmt)
99cdd140afSSimon Glass #define log_debug(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG, ##_fmt)
100cdd140afSSimon Glass #define log_content(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_CONTENT, ##_fmt)
101cdd140afSSimon Glass #define log_io(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt)
102e9c8d49dSSimon Glass #else
103e9c8d49dSSimon Glass #define _LOG_MAX_LEVEL LOGL_INFO
104cdd140afSSimon Glass #define log_err(_fmt...)
105cdd140afSSimon Glass #define log_warning(_fmt...)
106cdd140afSSimon Glass #define log_notice(_fmt...)
107cdd140afSSimon Glass #define log_info(_fmt...)
108cdd140afSSimon Glass #define log_debug(_fmt...)
109cdd140afSSimon Glass #define log_content(_fmt...)
110cdd140afSSimon Glass #define log_io(_fmt...)
111e9c8d49dSSimon Glass #endif
112e9c8d49dSSimon Glass
1134d8d3056SSimon Glass #if CONFIG_IS_ENABLED(LOG)
114*f9811e85SSimon Glass #ifdef LOG_DEBUG
115*f9811e85SSimon Glass #define _LOG_DEBUG 1
116*f9811e85SSimon Glass #else
117*f9811e85SSimon Glass #define _LOG_DEBUG 0
118*f9811e85SSimon Glass #endif
1194d8d3056SSimon Glass
120e9c8d49dSSimon Glass /* Emit a log record if the level is less that the maximum */
121e9c8d49dSSimon Glass #define log(_cat, _level, _fmt, _args...) ({ \
122e9c8d49dSSimon Glass int _l = _level; \
123*f9811e85SSimon Glass if (CONFIG_IS_ENABLED(LOG) && (_l <= _LOG_MAX_LEVEL || _LOG_DEBUG)) \
124e9c8d49dSSimon Glass _log((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \
125e9c8d49dSSimon Glass __func__, \
126e9c8d49dSSimon Glass pr_fmt(_fmt), ##_args); \
127e9c8d49dSSimon Glass })
1284d8d3056SSimon Glass #else
1294d8d3056SSimon Glass #define log(_cat, _level, _fmt, _args...)
1304d8d3056SSimon Glass #endif
131e9c8d49dSSimon Glass
1320e98b0a6SSimon Glass #ifdef DEBUG
1330e98b0a6SSimon Glass #define _DEBUG 1
1340e98b0a6SSimon Glass #else
1350e98b0a6SSimon Glass #define _DEBUG 0
1360e98b0a6SSimon Glass #endif
1370e98b0a6SSimon Glass
1380e98b0a6SSimon Glass #ifdef CONFIG_SPL_BUILD
1390e98b0a6SSimon Glass #define _SPL_BUILD 1
1400e98b0a6SSimon Glass #else
1410e98b0a6SSimon Glass #define _SPL_BUILD 0
1420e98b0a6SSimon Glass #endif
1430e98b0a6SSimon Glass
144e9c8d49dSSimon Glass #if !_DEBUG && CONFIG_IS_ENABLED(LOG)
145e9c8d49dSSimon Glass
146e9c8d49dSSimon Glass #define debug_cond(cond, fmt, args...) \
147e9c8d49dSSimon Glass do { \
148e9c8d49dSSimon Glass if (1) \
149e9c8d49dSSimon Glass log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
150e9c8d49dSSimon Glass } while (0)
151e9c8d49dSSimon Glass
152e9c8d49dSSimon Glass #else /* _DEBUG */
153e9c8d49dSSimon Glass
1540e98b0a6SSimon Glass /*
1550e98b0a6SSimon Glass * Output a debug text when condition "cond" is met. The "cond" should be
1560e98b0a6SSimon Glass * computed by a preprocessor in the best case, allowing for the best
1570e98b0a6SSimon Glass * optimization.
1580e98b0a6SSimon Glass */
1590e98b0a6SSimon Glass #define debug_cond(cond, fmt, args...) \
1600e98b0a6SSimon Glass do { \
1610e98b0a6SSimon Glass if (cond) \
1620e98b0a6SSimon Glass printf(pr_fmt(fmt), ##args); \
1630e98b0a6SSimon Glass } while (0)
1640e98b0a6SSimon Glass
165e9c8d49dSSimon Glass #endif /* _DEBUG */
166e9c8d49dSSimon Glass
1670e98b0a6SSimon Glass /* Show a message if DEBUG is defined in a file */
1680e98b0a6SSimon Glass #define debug(fmt, args...) \
1690e98b0a6SSimon Glass debug_cond(_DEBUG, fmt, ##args)
1700e98b0a6SSimon Glass
1710e98b0a6SSimon Glass /* Show a message if not in SPL */
1720e98b0a6SSimon Glass #define warn_non_spl(fmt, args...) \
1730e98b0a6SSimon Glass debug_cond(!_SPL_BUILD, fmt, ##args)
1740e98b0a6SSimon Glass
1750e98b0a6SSimon Glass /*
1760e98b0a6SSimon Glass * An assertion is run-time check done in debug mode only. If DEBUG is not
1770e98b0a6SSimon Glass * defined then it is skipped. If DEBUG is defined and the assertion fails,
1780e98b0a6SSimon Glass * then it calls panic*( which may or may not reset/halt U-Boot (see
1790e98b0a6SSimon Glass * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
1800e98b0a6SSimon Glass * before release, and after release it is hoped that they don't matter. But
1810e98b0a6SSimon Glass * in any case these failing assertions cannot be fixed with a reset (which
1820e98b0a6SSimon Glass * may just do the same assertion again).
1830e98b0a6SSimon Glass */
1840e98b0a6SSimon Glass void __assert_fail(const char *assertion, const char *file, unsigned int line,
1850e98b0a6SSimon Glass const char *function);
1860e98b0a6SSimon Glass #define assert(x) \
1870e98b0a6SSimon Glass ({ if (!(x) && _DEBUG) \
1880e98b0a6SSimon Glass __assert_fail(#x, __FILE__, __LINE__, __func__); })
1890e98b0a6SSimon Glass
1904d8d3056SSimon Glass #if CONFIG_IS_ENABLED(LOG) && defined(CONFIG_LOG_ERROR_RETURN)
1914d8d3056SSimon Glass /*
1924d8d3056SSimon Glass * Log an error return value, possibly with a message. Usage:
1934d8d3056SSimon Glass *
1944d8d3056SSimon Glass * return log_ret(fred_call());
1954d8d3056SSimon Glass *
1964d8d3056SSimon Glass * or:
1974d8d3056SSimon Glass *
1984d8d3056SSimon Glass * return log_msg_ret("fred failed", fred_call());
1994d8d3056SSimon Glass */
2003707c6eeSSimon Glass #define log_ret(_ret) ({ \
2013707c6eeSSimon Glass int __ret = (_ret); \
2023707c6eeSSimon Glass if (__ret < 0) \
2033707c6eeSSimon Glass log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \
2043707c6eeSSimon Glass __ret; \
2053707c6eeSSimon Glass })
206b616cef9SSimon Glass #define log_msg_ret(_msg, _ret) ({ \
207b616cef9SSimon Glass int __ret = (_ret); \
208b616cef9SSimon Glass if (__ret < 0) \
209b616cef9SSimon Glass log(LOG_CATEGORY, LOGL_ERR, "%s: returning err=%d\n", _msg, \
210b616cef9SSimon Glass __ret); \
211b616cef9SSimon Glass __ret; \
212b616cef9SSimon Glass })
2133707c6eeSSimon Glass #else
2144d8d3056SSimon Glass /* Non-logging versions of the above which just return the error code */
2153707c6eeSSimon Glass #define log_ret(_ret) (_ret)
2164d8d3056SSimon Glass #define log_msg_ret(_msg, _ret) ((void)(_msg), _ret)
2173707c6eeSSimon Glass #endif
2183707c6eeSSimon Glass
219e9c8d49dSSimon Glass /**
220e9c8d49dSSimon Glass * struct log_rec - a single log record
221e9c8d49dSSimon Glass *
222e9c8d49dSSimon Glass * Holds information about a single record in the log
223e9c8d49dSSimon Glass *
224e9c8d49dSSimon Glass * Members marked as 'not allocated' are stored as pointers and the caller is
225e9c8d49dSSimon Glass * responsible for making sure that the data pointed to is not overwritten.
226e9c8d49dSSimon Glass * Memebers marked as 'allocated' are allocated (e.g. via strdup()) by the log
227e9c8d49dSSimon Glass * system.
228e9c8d49dSSimon Glass *
229e9c8d49dSSimon Glass * @cat: Category, representing a uclass or part of U-Boot
230e9c8d49dSSimon Glass * @level: Severity level, less severe is higher
231e9c8d49dSSimon Glass * @file: Name of file where the log record was generated (not allocated)
232e9c8d49dSSimon Glass * @line: Line number where the log record was generated
233e9c8d49dSSimon Glass * @func: Function where the log record was generated (not allocated)
234e9c8d49dSSimon Glass * @msg: Log message (allocated)
235e9c8d49dSSimon Glass */
236e9c8d49dSSimon Glass struct log_rec {
237e9c8d49dSSimon Glass enum log_category_t cat;
238e9c8d49dSSimon Glass enum log_level_t level;
239e9c8d49dSSimon Glass const char *file;
240e9c8d49dSSimon Glass int line;
241e9c8d49dSSimon Glass const char *func;
242e9c8d49dSSimon Glass const char *msg;
243e9c8d49dSSimon Glass };
244e9c8d49dSSimon Glass
245e9c8d49dSSimon Glass struct log_device;
246e9c8d49dSSimon Glass
247e9c8d49dSSimon Glass /**
248e9c8d49dSSimon Glass * struct log_driver - a driver which accepts and processes log records
249e9c8d49dSSimon Glass *
250e9c8d49dSSimon Glass * @name: Name of driver
251e9c8d49dSSimon Glass */
252e9c8d49dSSimon Glass struct log_driver {
253e9c8d49dSSimon Glass const char *name;
254e9c8d49dSSimon Glass /**
255e9c8d49dSSimon Glass * emit() - emit a log record
256e9c8d49dSSimon Glass *
257e9c8d49dSSimon Glass * Called by the log system to pass a log record to a particular driver
258e9c8d49dSSimon Glass * for processing. The filter is checked before calling this function.
259e9c8d49dSSimon Glass */
260e9c8d49dSSimon Glass int (*emit)(struct log_device *ldev, struct log_rec *rec);
261e9c8d49dSSimon Glass };
262e9c8d49dSSimon Glass
263e9c8d49dSSimon Glass /**
264e9c8d49dSSimon Glass * struct log_device - an instance of a log driver
265e9c8d49dSSimon Glass *
266e9c8d49dSSimon Glass * Since drivers are set up at build-time we need to have a separate device for
267e9c8d49dSSimon Glass * the run-time aspects of drivers (currently just a list of filters to apply
268e9c8d49dSSimon Glass * to records send to this device).
269e9c8d49dSSimon Glass *
270e9c8d49dSSimon Glass * @next_filter_num: Seqence number of next filter filter added (0=no filters
271e9c8d49dSSimon Glass * yet). This increments with each new filter on the device, but never
272e9c8d49dSSimon Glass * decrements
273e9c8d49dSSimon Glass * @drv: Pointer to driver for this device
274e9c8d49dSSimon Glass * @filter_head: List of filters for this device
275e9c8d49dSSimon Glass * @sibling_node: Next device in the list of all devices
276e9c8d49dSSimon Glass */
277e9c8d49dSSimon Glass struct log_device {
278e9c8d49dSSimon Glass int next_filter_num;
279e9c8d49dSSimon Glass struct log_driver *drv;
280e9c8d49dSSimon Glass struct list_head filter_head;
281e9c8d49dSSimon Glass struct list_head sibling_node;
282e9c8d49dSSimon Glass };
283e9c8d49dSSimon Glass
284e9c8d49dSSimon Glass enum {
285e9c8d49dSSimon Glass LOGF_MAX_CATEGORIES = 5, /* maximum categories per filter */
286e9c8d49dSSimon Glass };
287e9c8d49dSSimon Glass
288e9c8d49dSSimon Glass enum log_filter_flags {
289e9c8d49dSSimon Glass LOGFF_HAS_CAT = 1 << 0, /* Filter has a category list */
290e9c8d49dSSimon Glass };
291e9c8d49dSSimon Glass
292e9c8d49dSSimon Glass /**
293e9c8d49dSSimon Glass * struct log_filter - criterial to filter out log messages
294e9c8d49dSSimon Glass *
295e9c8d49dSSimon Glass * @filter_num: Sequence number of this filter. This is returned when adding a
296e9c8d49dSSimon Glass * new filter, and must be provided when removing a previously added
297e9c8d49dSSimon Glass * filter.
298e9c8d49dSSimon Glass * @flags: Flags for this filter (LOGFF_...)
299e9c8d49dSSimon Glass * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
300e9c8d49dSSimon Glass * then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
301e9c8d49dSSimon Glass * can be provided
302e9c8d49dSSimon Glass * @max_level: Maximum log level to allow
303e9c8d49dSSimon Glass * @file_list: List of files to allow, separated by comma. If NULL then all
304e9c8d49dSSimon Glass * files are permitted
305e9c8d49dSSimon Glass * @sibling_node: Next filter in the list of filters for this log device
306e9c8d49dSSimon Glass */
307e9c8d49dSSimon Glass struct log_filter {
308e9c8d49dSSimon Glass int filter_num;
309e9c8d49dSSimon Glass int flags;
310e9c8d49dSSimon Glass enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
311e9c8d49dSSimon Glass enum log_level_t max_level;
312e9c8d49dSSimon Glass const char *file_list;
313e9c8d49dSSimon Glass struct list_head sibling_node;
314e9c8d49dSSimon Glass };
315e9c8d49dSSimon Glass
316e9c8d49dSSimon Glass #define LOG_DRIVER(_name) \
317e9c8d49dSSimon Glass ll_entry_declare(struct log_driver, _name, log_driver)
318e9c8d49dSSimon Glass
319f941c8d7SSimon Glass /**
320f941c8d7SSimon Glass * log_get_cat_name() - Get the name of a category
321f941c8d7SSimon Glass *
322f941c8d7SSimon Glass * @cat: Category to look up
323c2e4e7e6SSimon Glass * @return category name (which may be a uclass driver name) if found, or
324c2e4e7e6SSimon Glass * "<invalid>" if invalid, or "<missing>" if not found
325f941c8d7SSimon Glass */
326f941c8d7SSimon Glass const char *log_get_cat_name(enum log_category_t cat);
327f941c8d7SSimon Glass
328f941c8d7SSimon Glass /**
329f941c8d7SSimon Glass * log_get_cat_by_name() - Look up a category by name
330f941c8d7SSimon Glass *
331f941c8d7SSimon Glass * @name: Name to look up
332f941c8d7SSimon Glass * @return category ID, or LOGC_NONE if not found
333f941c8d7SSimon Glass */
334f941c8d7SSimon Glass enum log_category_t log_get_cat_by_name(const char *name);
335f941c8d7SSimon Glass
336f941c8d7SSimon Glass /**
337f941c8d7SSimon Glass * log_get_level_name() - Get the name of a log level
338f941c8d7SSimon Glass *
339f941c8d7SSimon Glass * @level: Log level to look up
340f941c8d7SSimon Glass * @return log level name (in ALL CAPS)
341f941c8d7SSimon Glass */
342f941c8d7SSimon Glass const char *log_get_level_name(enum log_level_t level);
343f941c8d7SSimon Glass
344f941c8d7SSimon Glass /**
345f941c8d7SSimon Glass * log_get_level_by_name() - Look up a log level by name
346f941c8d7SSimon Glass *
347f941c8d7SSimon Glass * @name: Name to look up
348f941c8d7SSimon Glass * @return log level ID, or LOGL_NONE if not found
349f941c8d7SSimon Glass */
350f941c8d7SSimon Glass enum log_level_t log_get_level_by_name(const char *name);
351f941c8d7SSimon Glass
3523b73e8d0SSimon Glass /* Log format flags (bit numbers) for gd->log_fmt. See log_fmt_chars */
3533b73e8d0SSimon Glass enum log_fmt {
3543b73e8d0SSimon Glass LOGF_CAT = 0,
3553b73e8d0SSimon Glass LOGF_LEVEL,
3563b73e8d0SSimon Glass LOGF_FILE,
3573b73e8d0SSimon Glass LOGF_LINE,
3583b73e8d0SSimon Glass LOGF_FUNC,
3593b73e8d0SSimon Glass LOGF_MSG,
3603b73e8d0SSimon Glass
3613b73e8d0SSimon Glass LOGF_COUNT,
3623b73e8d0SSimon Glass LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
3633b73e8d0SSimon Glass LOGF_ALL = 0x3f,
3643b73e8d0SSimon Glass };
3653b73e8d0SSimon Glass
366ef11ed82SSimon Glass /* Handle the 'log test' command */
367ef11ed82SSimon Glass int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
368ef11ed82SSimon Glass
369e9c8d49dSSimon Glass /**
370e9c8d49dSSimon Glass * log_add_filter() - Add a new filter to a log device
371e9c8d49dSSimon Glass *
372e9c8d49dSSimon Glass * @drv_name: Driver name to add the filter to (since each driver only has a
373e9c8d49dSSimon Glass * single device)
374e9c8d49dSSimon Glass * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
375e9c8d49dSSimon Glass * then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
376e9c8d49dSSimon Glass * can be provided
377e9c8d49dSSimon Glass * @max_level: Maximum log level to allow
378e9c8d49dSSimon Glass * @file_list: List of files to allow, separated by comma. If NULL then all
379e9c8d49dSSimon Glass * files are permitted
380e9c8d49dSSimon Glass * @return the sequence number of the new filter (>=0) if the filter was added,
381e9c8d49dSSimon Glass * or a -ve value on error
382e9c8d49dSSimon Glass */
383e9c8d49dSSimon Glass int log_add_filter(const char *drv_name, enum log_category_t cat_list[],
384e9c8d49dSSimon Glass enum log_level_t max_level, const char *file_list);
385e9c8d49dSSimon Glass
386e9c8d49dSSimon Glass /**
387e9c8d49dSSimon Glass * log_remove_filter() - Remove a filter from a log device
388e9c8d49dSSimon Glass *
389e9c8d49dSSimon Glass * @drv_name: Driver name to remove the filter from (since each driver only has
390e9c8d49dSSimon Glass * a single device)
391e9c8d49dSSimon Glass * @filter_num: Filter number to remove (as returned by log_add_filter())
392e9c8d49dSSimon Glass * @return 0 if the filter was removed, -ENOENT if either the driver or the
393e9c8d49dSSimon Glass * filter number was not found
394e9c8d49dSSimon Glass */
395e9c8d49dSSimon Glass int log_remove_filter(const char *drv_name, int filter_num);
396e9c8d49dSSimon Glass
397e9c8d49dSSimon Glass #if CONFIG_IS_ENABLED(LOG)
398e9c8d49dSSimon Glass /**
399e9c8d49dSSimon Glass * log_init() - Set up the log system ready for use
400e9c8d49dSSimon Glass *
401e9c8d49dSSimon Glass * @return 0 if OK, -ENOMEM if out of memory
402e9c8d49dSSimon Glass */
403e9c8d49dSSimon Glass int log_init(void);
404e9c8d49dSSimon Glass #else
log_init(void)405e9c8d49dSSimon Glass static inline int log_init(void)
406e9c8d49dSSimon Glass {
407e9c8d49dSSimon Glass return 0;
408e9c8d49dSSimon Glass }
409e9c8d49dSSimon Glass #endif
410e9c8d49dSSimon Glass
4110e98b0a6SSimon Glass #endif
412