platform_driver is common in embedded Linux. SoC internal peripherals such as UART, I2C controllers, SPI controllers, PWM, watchdogs, GPIO controllers, clock controllers, and interrupt controllers often use platform drivers.
When debugging this kind of driver, the most common problem is not a wrong register write. It is that probe never happens.
The Device Tree node exists, and the driver is built in, but why does probe not run?
The compatible string looks right, but why does it not match?
probe runs, but why are resources missing?
What does EPROBE_DEFER in the log mean?
The safest first model is this: platform driver probe happens after a platform device is created and the platform bus finds a matching driver. Device Tree describes the hardware instance, the platform bus matches it, and probe takes ownership of that instance.
DTS node
-> kernel parses Device Tree
-> platform device is created
-> platform driver is registered
-> platform bus match
-> probe is called
-> driver gets resources and initializes hardware
So when probe does not run, first check whether device creation and bus matching actually happened.
Where platform device Comes From
A platform device represents a device instance attached to the platform bus.
In embedded Linux, its most common source is Device Tree.
Example:
uart0: serial@10000000 {
compatible = "vendor,soc-uart";
reg = <0x10000000 0x1000>;
interrupts = <5>;
clocks = <&clk 3>;
status = "okay";
};
This node is not driver code. It tells the kernel that this board has a UART peripheral, where its registers are, how its interrupt is wired, which clock it uses, and whether it is enabled.
During boot, the kernel parses Device Tree. For suitable nodes, it creates platform devices. The device stores information such as the node pointer, resources, name, and parent-child relationship.
If the node does not appear in the runtime Device Tree, or status = "disabled", or the parent bus is not enabled, the corresponding platform device may never be created.
Without a platform device, there is no platform driver probe.
What platform driver Registers
A platform driver registers a set of capabilities with the platform bus.
A typical structure looks like this:
static const struct of_device_id uart_of_match[] = {
{ .compatible = "vendor,soc-uart" },
{ }
};
static struct platform_driver uart_driver = {
.probe = uart_probe,
.remove = uart_remove,
.driver = {
.name = "soc-uart",
.of_match_table = uart_of_match,
},
};
The important parts are not only the probe function:
- this driver is registered on the platform bus
- it has an
of_match_table uart_probeis called after a successful matchdriver.namemay also participate in some matching paths
Successful driver registration only means the kernel knows that a driver exists for some class of platform devices. It does not guarantee that probe runs immediately.
probe runs only when an existing device matches this driver, or a newly created device later matches it.
How compatible Triggers Matching
In Device Tree systems, the most common platform-driver matching mechanism is compatible.
Device Tree says:
compatible = "vendor,soc-uart";
The driver match table says:
{ .compatible = "vendor,soc-uart" }
The platform bus compares the compatible strings. If they match, this device can be handed to this driver.
Several details are easy to miss.
First, the strings must really match. One extra character, a different vendor prefix, or a case difference can prevent matching.
Second, Device Tree can list multiple compatible strings, usually from more specific to more generic:
compatible = "vendor,soc-uart-v2", "vendor,soc-uart";
If the driver supports only the generic item, it can still match "vendor,soc-uart".
Third, check the Device Tree the running kernel actually received, not only the .dts source. The bootloader may select a different dtb or apply overlays.
Fourth, a compatible match does not mean resources are correct. It only decides whether this driver owns this device. reg, interrupts, clocks, and other resources can still be wrong.
status and Parent Nodes Can Block Device Creation
Many “probe did not run” problems are not compatible problems. The device was never created.
Device Tree nodes often contain:
status = "okay";
If they contain:
status = "disabled";
the kernel usually does not create an enabled device for them.
Parent nodes matter too. If an I2C controller node is disabled, its sensor child nodes will not work as expected even if they are written correctly. Platform devices are similar: if parent buses, address domains, interrupt controllers, or clock providers are wrong, child devices may not be created or initialized correctly.
Debug the whole path:
SoC dtsi default node
-> board dts overrides status
-> bootloader selects dtb / overlay
-> runtime /proc/device-tree
-> kernel creates platform device
Looking only at one source DTS node is often not enough.
Resources in probe Come From device
The probe argument is usually a struct platform_device *pdev.
The driver obtains resources from pdev:
platform_get_resource()gets MMIO register resourcesdevm_platform_ioremap_resource()maps registersplatform_get_irq()gets interrupt numbersdevm_clk_get()gets clocksdevm_gpiod_get()gets GPIOsdevm_regulator_get()gets suppliesdevm_reset_control_get()gets reset controls
These resources do not appear from nowhere. Most come from the Device Tree node or kernel objects connected to it.
So if probe runs but resource acquisition fails, go back to Device Tree and providers:
- does
regmatch the parent’s#address-cellsand#size-cells - are
interruptsandinterrupt-parentcorrect - has the clock provider registered
- does the regulator name match the
xxx-supplyproperty - are GPIO property names, polarity, and pinctrl correct
- does the reset controller exist
probe is where the driver takes ownership of the device, but resource availability depends on device description and provider readiness.
EPROBE_DEFER Is Not an Ordinary Failure
While obtaining resources in probe, a driver may see -EPROBE_DEFER.
This usually does not mean the device failed forever. It means “a dependency is not ready yet; try again later.”
Common cases include:
- clock provider has not probed yet
- regulator provider is not ready
- GPIO controller is not registered
- pinctrl or reset controller is not available
- dependent MFD child devices are not created yet
This is common in embedded Linux because devices depend on each other. A driver may probe early, but the provider it needs has not finished initialization, so it returns -EPROBE_DEFER.
The kernel retries later.
So when you see deferred probe, do not immediately treat it as a driver bug. Find which resource it is waiting for, and why that provider is not ready.
devm Manages Lifetime, Not Ordering
Platform drivers often use devm_ APIs.
Example:
base = devm_platform_ioremap_resource(pdev, 0);
irq = platform_get_irq(pdev, 0);
clk = devm_clk_get(dev, NULL);
The value of devm_ is that resource lifetime is tied to the device. If probe succeeds and later remove runs, or if probe fails halfway, the kernel can automatically release managed resources.
This reduces leaks and error-path cleanup code.
But devm_ does not change matching logic, and it does not create missing resources. If compatible is wrong, the device will not match. If the clock provider is not ready, probe may still defer. If Device Tree resources are wrong, acquisition still fails.
devm_ is a resource-management tool, not a universal fix for probe problems.
Successful probe Still Needs an Upper Interface
After a platform driver initializes hardware, it usually has to register the device with an upper kernel subsystem.
For example:
- UART controller registers with the tty/serial subsystem
- network device registers as a netdev
- buttons register with the input subsystem
- sensors register with the IIO subsystem
- simple private devices register as misc or char devices
User-space artifacts such as /dev/xxx, /sys/class/..., network interface names, and input event nodes usually come from these subsystem registrations, not automatically from the platform bus.
So if probe succeeds but user space has no entry, continue checking:
- did the driver register the subsystem object
- did subsystem registration succeed
- did devtmpfs/udev create the node
- are permissions and rules correct
- was the device runtime-suspended or partially initialized after an error
Platform probe only takes ownership of a hardware instance. It does not automatically mean the user-space interface is complete.
What to Check First for platform probe
When platform driver probe does not run or fails, split the chain:
First, check whether the runtime Device Tree contains the node. Do not rely only on DTS source; inspect what the kernel actually sees.
Second, check whether the node and its parents are enabled. Look at status, parent bus, address domain, interrupt controller, and clock provider.
Third, check whether the platform device was created. Startup logs and /sys/bus/platform/devices/ are useful places to look.
Fourth, check whether the platform driver was registered. Is it built in? Is the module loaded? Is of_match_table correct?
Fifth, check whether compatible matches. Compare the runtime compatible strings with the driver’s match table.
Sixth, check whether probe was deferred. Find which provider it is waiting for.
Seventh, check which resource failed in probe. Separate reg, irq, clock, GPIO, regulator, reset, and pinctrl.
Eighth, check whether an upper interface was registered after successful probe. Missing /dev nodes are not always platform matching problems.
This order turns “probe did not run” into device creation, driver registration, bus matching, resource readiness, and user-space interface stages.
What to Remember in Practice
platform driver probe does not run just because the driver wants it to.
Device Tree or board description first tells the kernel that a hardware instance exists. The kernel creates a platform device. After a platform driver registers, the platform bus matches by compatible or name. Only after that does the kernel call probe.
Resources in probe come from the device, and device resources come from Device Tree and related providers. After probe succeeds, user-space interfaces still depend on tty, netdev, input, IIO, misc, char, or other subsystem registration.
Splitting this chain prevents every platform-driver problem from becoming the same vague sentence: “the driver did not come up.”