U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Improve logging on missing uclass
@ 2026-08-24  8:44 Julien Stephan
  2026-08-24  8:44 ` [PATCH v2 1/3] dm: add dm_err() and a driver model log verbosity choice Julien Stephan
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Julien Stephan @ 2026-08-24  8:44 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, Tom Rini, Julien Stephan,
	Markus Schneider-Pargmann (TI), dlechner

While writing a MISC driver, I forgot to enable CONFIG_MISC. The only thing
I got at boot was the following obscure error, with no hint about the root
cause:

  initcall_run_r(): initcall initr_dm() failed
  ### ERROR ### Please RESET the board ###

Commit 3346c87625b8 ("dm: Improve handling of a missing uclass") already
tried to improve this case by returning a strange error code and adding a
debug message. But since neither the debug message nor the return code are
displayed by default, it was not very helpful in practice.

This series improves the situation in a few ways:
 - a new dm_err() helper logs driver model errors at ERROR level, and the
   boolean DM_WARN option becomes a per-stage log verbosity choice
   (DM_NONE / DM_ERR / DM_WARN) with errors emitted by default. Note that
   a disabled level is not removed entirely but degraded to DEBUG level,
   which is compiled out by default, so even DM_NONE can still emit these
   messages as debug output when debug logging is enabled;
 - the missing-uclass message now uses dm_err(), so it shows up by default,
   with a shorter string to limit the code-size overhead;
 - the initcall failure now prints the actual error code (and its string
   when ERRNO_STR is enabled), for both INITCALL() and INITCALL_EVT().

The existing DM_DEBUG option is left as-is for now: it works differently
(it adds -DDEBUG to drivers/core/ via the Makefile and is not phase-aware).
Unifying it into the new choice, along with converting the DM core debug()
statements to log() as suggested in the "To Do" section of
doc/develop/logging.rst, could be a follow-up series.

Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
Changes in v2:
- dm: replace the boolean DM_WARN option with a per-stage log verbosity
  choice (DM_NONE / DM_ERR / DM_WARN) and add a dm_err() helper, rather
  than logging the missing-uclass message with a hardcoded log() call
  (suggested by Simon)
- dm: de-duplicate the util.h helpers to only select the log level
  (suggested by Simon)
- dm: split the change into the generic mechanism and its user in uclass.c
- dm: shorten the missing-uclass message to limit the SPL/TPL size overhead
- initcall: use the %dE format so no dangling ": " is printed when
  ERRNO_STR is disabled, and give INITCALL_EVT() the same treatment
- Link to v1: https://patch.msgid.link/20260806-improve-logging-on-missing-uclass-v1-0-d477f0054f48@baylibre.com

To: u-boot@lists.u-boot-project.org
Cc: GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>
Cc: "Markus Schneider-Pargmann (TI)" <msp@baylibre.com>
Cc: Julien Stephan <jstephan@baylibre.com>

---
Julien Stephan (3):
      dm: add dm_err() and a driver model log verbosity choice
      dm: uclass: use dm_err() for a missing uclass
      initcall: initcall_evt: display error code on error

 drivers/core/Kconfig  | 75 ++++++++++++++++++++++++++++++++++++++++++---------
 drivers/core/uclass.c |  3 +--
 include/dm/util.h     | 19 +++++++++++--
 include/initcall.h    | 14 +++++-----
 4 files changed, 88 insertions(+), 23 deletions(-)
---
base-commit: f562ed02aa7ae4dc2775d90d2e6c40bab82e2715
change-id: 20260806-improve-logging-on-missing-uclass-a76c46acfa13

Best regards,
--  
Julien Stephan <jstephan@baylibre.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/3] dm: add dm_err() and a driver model log verbosity choice
  2026-08-24  8:44 [PATCH v2 0/3] Improve logging on missing uclass Julien Stephan
@ 2026-08-24  8:44 ` Julien Stephan
  2026-08-24  8:44 ` [PATCH v2 2/3] dm: uclass: use dm_err() for a missing uclass Julien Stephan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Julien Stephan @ 2026-08-24  8:44 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, Tom Rini, Julien Stephan,
	Markus Schneider-Pargmann (TI), dlechner

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 <jstephan@baylibre.com>
---
 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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/3] dm: uclass: use dm_err() for a missing uclass
  2026-08-24  8:44 [PATCH v2 0/3] Improve logging on missing uclass Julien Stephan
  2026-08-24  8:44 ` [PATCH v2 1/3] dm: add dm_err() and a driver model log verbosity choice Julien Stephan
@ 2026-08-24  8:44 ` Julien Stephan
  2026-08-24  8:44 ` [PATCH v2 3/3] initcall: initcall_evt: display error code on error Julien Stephan
  2026-09-03 22:56 ` [PATCH v2 0/3] Improve logging on missing uclass Tom Rini
  3 siblings, 0 replies; 5+ messages in thread
From: Julien Stephan @ 2026-08-24  8:44 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, Tom Rini, Julien Stephan,
	Markus Schneider-Pargmann (TI), dlechner

When a uclass definition is missing for an enabled driver, the board
cannot boot, and without any extra debug option enabled the only output
is an obscure message with no hint about the root cause:

  initcall_run_r(): initcall initr_dm() failed
  ### ERROR ### Please RESET the board ###

The existing message used dm_warn(), which is not shown by default. Since
this is a fatal error preventing the board from booting, use the new
dm_err() helper so it is emitted at ERROR level and visible by default.
Shorten the message as well to limit the code size overhead.

Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
 drivers/core/uclass.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 5365ac68f9e..83a67dfb4de 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -60,8 +60,7 @@ static int uclass_add(enum uclass_id id, struct uclass **ucp)
 	*ucp = NULL;
 	uc_drv = lists_uclass_lookup(id);
 	if (!uc_drv) {
-		dm_warn("Cannot find uclass for id %d: please add the UCLASS_DRIVER() declaration for this UCLASS_... id\n",
-			id);
+		dm_err("uclass %d: no UCLASS_DRIVER()\n", id);
 		/*
 		 * Use a strange error to make this case easier to find. When
 		 * a uclass is not available it can prevent driver model from

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 3/3] initcall: initcall_evt: display error code on error
  2026-08-24  8:44 [PATCH v2 0/3] Improve logging on missing uclass Julien Stephan
  2026-08-24  8:44 ` [PATCH v2 1/3] dm: add dm_err() and a driver model log verbosity choice Julien Stephan
  2026-08-24  8:44 ` [PATCH v2 2/3] dm: uclass: use dm_err() for a missing uclass Julien Stephan
@ 2026-08-24  8:44 ` Julien Stephan
  2026-09-03 22:56 ` [PATCH v2 0/3] Improve logging on missing uclass Tom Rini
  3 siblings, 0 replies; 5+ messages in thread
From: Julien Stephan @ 2026-08-24  8:44 UTC (permalink / raw)
  To: u-boot
  Cc: GSS_MTK_Uboot_upstream, Simon Glass, Tom Rini, Julien Stephan,
	Markus Schneider-Pargmann (TI), dlechner

Currently when an initcall/initcall_evt fails the error code is not
displayed. Display it, along with the corresponding error string if
ERRNO_STR is enabled.

Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
 include/initcall.h | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/initcall.h b/include/initcall.h
index 220a55ad84d..12e5235f506 100644
--- a/include/initcall.h
+++ b/include/initcall.h
@@ -14,18 +14,20 @@ _Static_assert(EVT_COUNT < 256, "Can only support 256 event types with 8 bits");
 
 #define INITCALL(_call) \
 	do { \
-		if (_call()) { \
-			printf("%s(): initcall %s() failed\n", __func__, \
-			       #_call); \
+		int _ret = _call(); \
+		if (_ret) { \
+			printf("%s(): initcall %s() failed (err=%dE)\n", \
+			       __func__, #_call, _ret); \
 			hang(); \
 		} \
 	} while (0)
 
 #define INITCALL_EVT(_evt) \
 	do { \
-		if (event_notify_null(_evt)) { \
-			printf("%s(): event %d/%s failed\n", __func__, _evt, \
-			       event_type_name(_evt)) ; \
+		int _ret = event_notify_null(_evt); \
+		if (_ret) { \
+			printf("%s(): event %d/%s failed (err=%dE)\n", \
+			       __func__, _evt, event_type_name(_evt), _ret); \
 			hang(); \
 		} \
 	} while (0)

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 0/3] Improve logging on missing uclass
  2026-08-24  8:44 [PATCH v2 0/3] Improve logging on missing uclass Julien Stephan
                   ` (2 preceding siblings ...)
  2026-08-24  8:44 ` [PATCH v2 3/3] initcall: initcall_evt: display error code on error Julien Stephan
@ 2026-09-03 22:56 ` Tom Rini
  3 siblings, 0 replies; 5+ messages in thread
From: Tom Rini @ 2026-09-03 22:56 UTC (permalink / raw)
  To: Julien Stephan
  Cc: u-boot, GSS_MTK_Uboot_upstream, Simon Glass,
	Markus Schneider-Pargmann (TI), dlechner

[-- Attachment #1: Type: text/plain, Size: 2365 bytes --]

On Mon, Aug 24, 2026 at 10:44:15AM +0200, Julien Stephan wrote:

> While writing a MISC driver, I forgot to enable CONFIG_MISC. The only thing
> I got at boot was the following obscure error, with no hint about the root
> cause:
> 
>   initcall_run_r(): initcall initr_dm() failed
>   ### ERROR ### Please RESET the board ###
> 
> Commit 3346c87625b8 ("dm: Improve handling of a missing uclass") already
> tried to improve this case by returning a strange error code and adding a
> debug message. But since neither the debug message nor the return code are
> displayed by default, it was not very helpful in practice.
> 
> This series improves the situation in a few ways:
>  - a new dm_err() helper logs driver model errors at ERROR level, and the
>    boolean DM_WARN option becomes a per-stage log verbosity choice
>    (DM_NONE / DM_ERR / DM_WARN) with errors emitted by default. Note that
>    a disabled level is not removed entirely but degraded to DEBUG level,
>    which is compiled out by default, so even DM_NONE can still emit these
>    messages as debug output when debug logging is enabled;
>  - the missing-uclass message now uses dm_err(), so it shows up by default,
>    with a shorter string to limit the code-size overhead;
>  - the initcall failure now prints the actual error code (and its string
>    when ERRNO_STR is enabled), for both INITCALL() and INITCALL_EVT().
> 
> The existing DM_DEBUG option is left as-is for now: it works differently
> (it adds -DDEBUG to drivers/core/ via the Makefile and is not phase-aware).
> Unifying it into the new choice, along with converting the DM core debug()
> statements to log() as suggested in the "To Do" section of
> doc/develop/logging.rst, could be a follow-up series.

There are two issues here. One issue is that tests need to be adjusted,
as CI fails:
https://git.u-boot-project.org/u-boot/u-boot/-/jobs/83678
for example.
The second issue is that am335x_evm overflows in SPL due to size growth.
I am currently seeing if we can enable LTO on that family now, or if it
still has a run time problem. If the latter, then defaulting to
SPL_DM_ERR_NONE might be how that has to be handled.

For re-testing this in CI, please feel free to use a WIP branch or
something in the mediatek tree, or just a tree under your own username.
Thanks.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-09-03 22:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-24  8:44 [PATCH v2 0/3] Improve logging on missing uclass Julien Stephan
2026-08-24  8:44 ` [PATCH v2 1/3] dm: add dm_err() and a driver model log verbosity choice Julien Stephan
2026-08-24  8:44 ` [PATCH v2 2/3] dm: uclass: use dm_err() for a missing uclass Julien Stephan
2026-08-24  8:44 ` [PATCH v2 3/3] initcall: initcall_evt: display error code on error Julien Stephan
2026-09-03 22:56 ` [PATCH v2 0/3] Improve logging on missing uclass Tom Rini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox