Cleaning up the Nulls: Introducing ofnode Stubs for Non-DT Builds

In the world of U-Boot, the Device Model (DM) and Device Tree (DT) are the standard for hardware description. However, U-Boot runs on a massive variety of hardware, including constrained systems where full Device Tree support (OF_REAL) might be disabled.

A recent patch cleans up how the core handles these “no-Device-Tree” scenarios, ensuring that code remains clean, compilable, and safe even when the DT is missing.

The Problem: When the Tree Falls

When OF_REAL is disabled, there is logically no point in trying to find nodes, read properties, or traverse a tree—everything is effectively null.

Previously, handling this required scattering #ifdef guards throughout driver code or dealing with linking errors if a driver attempted to call an ofnode function that wasn’t compiled in. This made the codebase harder to read and harder to maintain.

The Solution: Static Inline Stubs

The patch, dm: core: Create ofnode stubs when OF_REAL is disabled introduces a comprehensive set of static inline “stub” functions in include/dm/ofnode.h.

Here is the logic:

  1. Check Configuration: The header now checks #if CONFIG_IS_ENABLED(OF_REAL).
  2. Provide Stubs: If OF_REAL is off, it defines dummy versions of functions like ofnode_read_u32 or ofnode_next_subnode.
  3. Safe Returns: These stubs return safe default values—typically NULL, false, -ENOSYS, or -EINVAL—allowing the compiler to optimise the code paths without breaking the build.

This allows drivers to call ofnode functions blindly. If the DT is missing, the function simply returns an error code, and the driver handles it gracefully rather than the build failing.

The Cost: Pushing the Limits

While this approach significantly cleans up driver code, it comes with a trade-off. include/dm/ofnode.h has grown significantly with this patch.

As noted in the commit, the file is becoming “a little convoluted” due to the sheer volume of inline implementations and dual definitions. We are likely reaching the limit of how many static inlines can reasonably live in this single header! While this solution is better than the alternative (broken builds or messy #ifdefs in drivers), future work may require splitting the header file to keep the core API definitions digestible and organised.

Key Refinements

The patch also includes some “plumbing” adjustments:

  • Macro Relocation: Iterator macros like ofnode_for_each_compatible_node() were moved outside the OF_REAL condition. Since they rely on the newly created stubs, these loops will now simply do nothing on a non-DT system, rather than causing compiler errors.
  • Edge-Case Support: A specific adjustment in drivers/Makefile ensures ofnode.o is compiled when OF_REAL is enabled but the full DM is not, preserving necessary support for boards like the kontron-sl-mx6ul.