When a fatal driver model error occurs the board often cannot boot, yet
without any extra debug option enabled such errors are not shown: driver
model only had dm_warn(), emitted at WARNING level (or DEBUG when DM_WARN
was disabled). A fatal error deserves a message that is visible out of
the box.

Add a dm_err() helper, logging at ERROR level, and replace the DM_WARN /
SPL_DM_WARN boolean options with a per-stage verbosity choice:

  - DM_NONE: degrade all messages to DEBUG level (smallest size);
  - DM_ERR:  emit dm_err() at ERROR level only (default);
  - DM_WARN: emit both dm_warn() and dm_err().

Each level includes the ones below it, so selecting warnings never
silences errors. A disabled level is not removed entirely: it degrades to
DEBUG level, which is compiled out by default but can still be displayed
when debug logging is enabled (e.g. DEBUG defined or a high enough log
level). So even DM_NONE can still show these messages as debug output.
Production builds can drop the strings by selecting a lower level, while a
fatal error is shown by default during development, including in SPL/TPL.

Note this changes the default behaviour: driver model errors are now
emitted by default (previously nothing was shown unless DM_WARN was
enabled).

The existing DM_DEBUG option is deliberately left untouched here. It works
differently: it adds -DDEBUG to drivers/core/ via the Makefile rather than
selecting a log level, and it is not phase-aware. Unifying it into this
choice, along with converting the DM core debug() statements to
log()/dm_dbg() (as recommended in the "To Do" section of
doc/develop/logging.rst), could be done as a follow-up series.

Signed-off-by: Julien Stephan <[email protected]>
---
 drivers/core/Kconfig | 75 +++++++++++++++++++++++++++++++++++++++++++---------
 include/dm/util.h    | 19 +++++++++++--
 2 files changed, 79 insertions(+), 15 deletions(-)

diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index ae0c3466772..5e276474b4b 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -45,28 +45,77 @@ config VPL_DM
          full malloc() enabled by CFG_TPL_SYS_MALLOC_START,
          consider using CONFIG_TPL_SYS_MALLOC_SIMPLE.
 
-config DM_WARN
-       bool "Enable warnings in driver model"
+choice
+       prompt "Driver model log verbosity"
        depends on DM
+       default DM_ERR
+       help
+         Select which driver model messages are compiled into the binary.
+         Each level includes the levels below it. Lower verbosity saves code
+         size by compiling the message strings out (useful for production
+         builds), while higher verbosity helps with debugging.
+
+config DM_NONE
+       bool "No messages"
        help
-         Enable this to see warnings related to driver model.
+         Compile out all driver model messages. This gives the smallest code
+         size, but a fatal condition gives no hint about its root cause.
+
+config DM_ERR
+       bool "Errors"
+       help
+         Emit driver model error messages via dm_err(), at ERROR level.
+         These report fatal conditions that typically prevent the board from
+         booting. Warnings are compiled out.
+
+config DM_WARN
+       bool "Warnings and errors"
+       help
+         Emit driver model warnings via dm_warn() (WARNING level) in addition
+         to errors. This is the most verbose and uses the most code space.
 
          Warnings may help with debugging, such as when expected devices do
-         not bind correctly. If the option is disabled, dm_warn() is compiled
-         out - it will do nothing when called.
+         not bind correctly.
 
-config SPL_DM_WARN
-       bool "Enable warnings in driver model in SPL"
+endchoice
+
+choice
+       prompt "Driver model log verbosity in SPL"
        depends on SPL_DM
+       default SPL_DM_ERR
        help
-         Enable this to see warnings related to driver model in SPL
+         Select which driver model messages are compiled into the SPL binary.
+         See the "Driver model log verbosity" choice for details.
 
-         The dm_warn() function can use up quite a bit of space for its
-         strings. By default this is disabled for SPL builds to save space.
+config SPL_DM_NONE
+       bool "No messages"
 
-         Warnings may help with debugging, such as when expected devices do
-         not bind correctly. If the option is disabled, dm_warn() is compiled
-         out - it will do nothing when called.
+config SPL_DM_ERR
+       bool "Errors"
+
+config SPL_DM_WARN
+       bool "Warnings and errors"
+
+endchoice
+
+choice
+       prompt "Driver model log verbosity in TPL"
+       depends on TPL_DM
+       default TPL_DM_ERR
+       help
+         Select which driver model messages are compiled into the TPL binary.
+         See the "Driver model log verbosity" choice for details.
+
+config TPL_DM_NONE
+       bool "No messages"
+
+config TPL_DM_ERR
+       bool "Errors"
+
+config TPL_DM_WARN
+       bool "Warnings and errors"
+
+endchoice
 
 config DM_DEBUG
        bool "Enable debug messages in driver model core"
diff --git a/include/dm/util.h b/include/dm/util.h
index ec518c51d93..89ffaa467aa 100644
--- a/include/dm/util.h
+++ b/include/dm/util.h
@@ -8,12 +8,27 @@
 
 struct dm_stats;
 
+/*
+ * Pick the log level for each helper based on the DM log verbosity choice.
+ * A disabled level falls back to LOGL_DEBUG, which is compiled out by
+ * default. Each level includes the ones below it, so DM_WARN also enables
+ * errors.
+ */
 #if CONFIG_IS_ENABLED(DM_WARN)
-#define dm_warn(fmt...) log(LOGC_DM, LOGL_WARNING, ##fmt)
+#define _DM_WARN_LEVEL LOGL_WARNING
+#else
+#define _DM_WARN_LEVEL LOGL_DEBUG
+#endif
+
+#if CONFIG_IS_ENABLED(DM_WARN) || CONFIG_IS_ENABLED(DM_ERR)
+#define _DM_ERR_LEVEL  LOGL_ERR
 #else
-#define dm_warn(fmt...) log(LOGC_DM, LOGL_DEBUG, ##fmt)
+#define _DM_ERR_LEVEL  LOGL_DEBUG
 #endif
 
+#define dm_warn(fmt...) log(LOGC_DM, _DM_WARN_LEVEL, ##fmt)
+#define dm_err(fmt...) log(LOGC_DM, _DM_ERR_LEVEL, ##fmt)
+
 struct list_head;
 
 /**

-- 
2.54.0

Reply via email to