U-Boot Driver Model Probing: Separate a Bound Device from a Completed Probe

A peripheral appears in U-Boot’s device tree, yet the first command
that uses it fails. That observation can look contradictory if device
discovery is treated as hardware initialization. Driver model
intentionally separates those steps. A device can be known to the model
before the hardware and its dependencies are ready for an operation.

The discussion follows upstream U-Boot v2025.01. A Buildroot-based
product must check the selected bootloader configuration and downstream
drivers against that version. No peripheral was probed for this article;
the workflow is a source-derived diagnostic plan.

Ask which lifecycle
boundary was reached

The driver-model
design documentation
distinguishes binding, platform-data conversion
and probing. Binding associates a device with a driver. Platform-data
conversion interprets configuration. Probing prepares the device for
use, and U-Boot performs that work lazily because many devices will
never be needed during a boot.

A useful failure report therefore records more than a node name.
Include the devicetree path, driver and uclass, whether the relevant
lookup merely found a device, and whether the operation requested
activation. Record the return value at the boundary where activation was
attempted. Otherwise, two reports can describe the same node while
referring to different lifecycle states.

Do not assume every lookup API has the same activation behavior.
Follow the actual caller in the deployed source. A diagnostic that only
enumerates known objects may leave the failure untouched until a later
command requests real work. Conversely, a diagnostic that activates
devices can change the state it is trying to inspect.

Conceptual lifecycle diagram distinguishing binding, configuration conversion, completed probing and an actual peripheral operation.

Inspect
parent activation before blaming the child

The tagged
device_probe implementation
converts platform data and ensures the
parent is probed before proceeding through the child’s activation work.
A parent error can therefore stop progress before the child’s driver
probe callback runs. The returned error needs to be traced to its origin
rather than attributed automatically to the final requested device.

Build a dependency sketch for the failing operation. At minimum,
identify the device’s parent chain and any explicitly referenced support
devices used by its driver. Label the sketch with observed return values
when those become available. A child request that stops at a bus
initialization failure should lead to a different investigation than a
child whose own hardware transaction times out.

Keep this sketch specific to the driver. Clocks, resets, regulators
and pin control are common dependencies, but not every peripheral uses
them in the same way. Treat an absent property as a hypothesis to check
against its binding and code, not a universal explanation for all probe
failures.

Avoid
treating an internal flag as a success certificate

There is a subtle ordering detail in this version’s implementation.
device_probe sets DM_FLAG_ACTIVATED before several later steps,
including the driver’s probe callback. The source explains a re-entrant
parent/child case where this early flag is needed. Failure paths clear
the flag again.

As a result, an in-function snapshot of the flag is not equivalent to
observing a successfully completed probe call. Log the entry and return
of the relevant operation, together with the error path, instead of
adding a one-time flag print and declaring the peripheral healthy. The
lifecycle model remains useful, but the implementation’s intermediate
state matters when instrumenting it.

Successful probing is also narrower than successful service. It
prepares the device; the first read, transfer or controller operation
can still fail. Preserve that next return value separately. Combining
probe and operation into a single “device failed” status loses the
boundary that tells the next engineer where to look.

Instrument the smallest
useful path

Start with the command or caller that first needs the device. Follow
its lookup or activation API, then the parent, uclass hooks and driver
callback relevant to the failure. Collect enough evidence to identify
the first error without enabling unrelated peripheral probing across the
board.

The design documentation describes using return-code logging for
tracing failures. The exact diagnostic configuration should be chosen
for the product build and available console. Preserve the original code
and configuration alongside the instrumented build so that a later
reviewer can identify what changed.

Instrumentation can alter timing and memory consumption, especially
early in boot. If the failure disappears under logging, that is useful
information but not proof that the hardware issue is fixed. Record the
difference and reduce instrumentation carefully rather than accepting a
diagnostic build as equivalent to the release image.

Qualify distinct failure
classes

A proposed test matrix should include a device that binds but fails
platform-data interpretation, a parent that cannot activate, a driver
probe that returns an error and an operation that fails after a
successful probe. Suitable fixtures depend on the board and may be
easier to construct in sandbox or driver tests than on production
hardware.

For each fixture, state the expected stopping boundary before running
it. Record whether the child callback was entered, the return value
propagated to the caller and whether a later attempt starts from the
intended state. Do not assume all drivers undo every hardware side
effect when probing fails; inspect the driver’s cleanup behavior before
relying on retries.

The final acceptance criterion is a chain of evidence: the intended
device was bound, its configuration was interpreted, the required
activation path completed, and the requested operation succeeded. A tree
listing contributes to the first assertion. It cannot substitute for the
remaining ones. That distinction makes a first-use failure easier to
isolate without turning every discovery command into an uncontrolled
initialization experiment.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *