Bus Matching In Device Drivers
Free Linux Device Drivers Course — Free Linux Kernel Development Course — Free Embedded Systems Course
Bus matching is the process the Linux kernel runs every time a device or a driver is registered, to decide whether the two belong together. This free linux device drivers course lecture explains platform bus matching in the Linux kernel — the role of platform_match(), how it decides a match on kernel 6.x, and what happens the moment a match is found. We close with an original demo showing one driver matching only the device it is meant for, out of two candidates.
What You Will Learn
- Why the bus, not the device or the driver, owns the matching decision
- What
platform_match()actually checks on a modern kernel - Where device tree compatible strings fit into bus matching
- What happens after a match: udev/mdev, module autoloading, and probe()
- A working demo: two devices, one driver, only one match
Prerequisites
- Our platform bus concept lecture (probe/remove, platform_driver)
- Our platform data lecture (platform_device_register_data(), dev_get_platdata())
Why The Bus Decides, Not You
In the Linux device model, every bus type — platform, I2C, USB, PCI, SPI — keeps its own list of registered devices and its own list of registered drivers. Whenever a new device or a new driver is added to a bus, that bus runs a matching loop over its lists. This is deliberate: the bus is the one place that knows about every device and every driver on it at once, so it is the natural place to own the pairing decision. Neither the device code nor the driver code decides the pairing directly.
ep-led-demo
ep-sensor-demo
runs for every pair
ep-led-demo driver
ep-sensor-demo driver
probe() runs
device waits, unbound
What platform_match() Actually Checks
The old approach — matching purely on a name string — still exists, but it is only one of several checks the platform bus performs today, and it is checked last. On kernel 6.x, platform_match() tries, in order:
- Device tree compatible match — if the device came from device tree, the driver’s
of_match_tableis checked against the device’scompatibleproperty - ACPI match — if the device came from ACPI firmware, the driver’s
acpi_match_tableis checked - id_table match — if the driver provides a
platform_device_idtable, the device name is looked up in that table - Plain name-string match — the fallback: the device’s name is compared directly against the driver’s
driver.name
This ordering matters conceptually: on a real, modern board booting from device tree, matching almost always happens at step 1, through the compatible string — not through a plain name comparison. The name-string fallback is what our earlier ep_led_demo device relies on, because it was registered manually rather than described in device tree.
What Happens After A Match
A match by itself does not run any driver code — it only tells the kernel that this device and this driver belong together. If the driver’s module is not loaded yet, the kernel notifies the user-space device manager (udev or mdev) over a netlink socket, which loads the module. Once the driver is present and bound, its probe() function runs immediately. This is why, in our earlier demo, loading the driver module first and the board module second produced a clean probe() log line — the match had already been made and was simply waiting for the device to appear.
Original Demo: One Driver, Two Devices, One Match
To make matching concrete, we register two platform devices with different names and one driver that only names one of them.
ep_match_board.c — registers two devices
#include <linux/module.h>
#include <linux/platform_device.h>
static struct platform_device *ep_dev_a;
static struct platform_device *ep_dev_b;
static int __init ep_match_board_init(void)
{
ep_dev_a = platform_device_register_simple("ep-match-demo", -1, NULL, 0);
if (IS_ERR(ep_dev_a))
return PTR_ERR(ep_dev_a);
ep_dev_b = platform_device_register_simple("ep-other-demo", -1, NULL, 0);
if (IS_ERR(ep_dev_b)) {
platform_device_unregister(ep_dev_a);
return PTR_ERR(ep_dev_b);
}
return 0;
}
static void __exit ep_match_board_exit(void)
{
platform_device_unregister(ep_dev_b);
platform_device_unregister(ep_dev_a);
}
module_init(ep_match_board_init);
module_exit(ep_match_board_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EmbeddedPathashala bus matching demo - two devices");
ep_match_driver.c — matches only one of them
#include <linux/module.h>
#include <linux/platform_device.h>
static int ep_match_probe(struct platform_device *pdev)
{
dev_info(&pdev->dev, "matched and probed: %s\n", pdev->name);
return 0;
}
static void ep_match_remove(struct platform_device *pdev)
{
dev_info(&pdev->dev, "removed: %s\n", pdev->name);
}
static struct platform_driver ep_match_driver = {
.driver = {
.name = "ep-match-demo",
},
.probe = ep_match_probe,
.remove = ep_match_remove,
};
module_platform_driver(ep_match_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("EmbeddedPathashala bus matching demo - single driver");
Building And Running The Demo
$ make
$ sudo insmod ep_match_driver.ko
$ sudo insmod ep_match_board.ko
$ dmesg | tail -5
Expected output
ep-match-demo ep-match-demo.-1: matched and probed: ep-match-demo
Notice there is no probe log line for ep-other-demo at all. The device was registered successfully and sits on the platform bus, but since no loaded driver’s name (or id_table, or of_match_table) matches it, probe() never runs for it. You can confirm it exists but is unbound by checking sysfs:
$ ls /sys/bus/platform/devices/ | grep ep-
ep-match-demo.-1
ep-other-demo.-1
$ ls /sys/bus/platform/drivers/ep-match-demo/
ep-match-demo.-1
ep-other-demo appears under devices but never appears bound under any driver directory — direct, visible proof of what a “no match” outcome looks like on a running kernel.
Legacy Board Files vs Device Tree
Historically, platform devices for a given board were declared in that board’s init file under the architecture tree, and every change meant rebuilding the kernel image. This became unmanageable as the number of supported boards grew, since board-specific code that nobody could test on real hardware kept accumulating inside the kernel source itself. Device tree solved this by moving hardware description out of kernel source entirely, into a separate, recompilable data file matched against drivers through of_match_table and compatible strings — the first matching path platform_match() checks today. We cover writing and binding a device tree node to a driver in the next lecture.
Comparison: Matching Paths
| Match Type | Driver Field | Typical Use Today |
|---|---|---|
| Device tree compatible | of_match_table |
Standard on ARM/embedded boards |
| ACPI | acpi_match_table |
x86 and ACPI-based platforms |
| id_table | id_table |
Multiple related device names sharing one driver |
| Plain name string | driver.name |
Manually registered devices, in-kernel test drivers |
Common Mistakes
- Assuming a device that registered successfully will automatically get probed — registration and matching are separate steps
- Using the same driver name string for two functionally different drivers, causing an unintended match
- Forgetting to check sysfs when a probe() mysteriously never fires — it is the fastest way to see whether a match happened at all
Best Practices
- On real hardware, match through device tree (
of_match_table) rather than name strings - Keep driver names unique and descriptive across your own modules
- Use sysfs (
/sys/bus/platform/devicesand/sys/bus/platform/drivers) as your first debugging step for “why isn’t probe() running”
Summary
Bus matching is owned by the bus, not the device or the driver. On kernel 6.x, platform_match() checks device tree compatibility, ACPI, an id_table, and finally a plain name string, in that order. A successful match triggers module autoload through udev/mdev and then probe(); an unsuccessful match leaves the device registered but unbound, which our two-device demo showed directly through both dmesg and sysfs.
FAQ
Does registering a platform device guarantee probe() will run?
No. Registration only makes the device visible to the bus. probe() only runs after platform_match() finds a driver that matches it.
What is checked first: device tree or the name string?
Device tree compatible matching is checked first on kernel 6.x, followed by ACPI, then id_table, with the plain name string as the last fallback.
How can I tell if a device failed to match any driver?
Check /sys/bus/platform/devices/ for the device and /sys/bus/platform/drivers/<name>/ for whether it appears bound under any driver.
Can two different drivers match the same device name?
No, only one driver can bind to a given device at a time; if both are loaded, the first successful match wins.
Why does module autoloading involve udev or mdev?
When the kernel finds a match but the driver’s module isn’t loaded, it notifies the user-space device manager over netlink, which is responsible for actually loading the module.
Is name-string matching still relevant on kernel 6.x?
Yes, it’s still the fallback used by manually registered platform devices, such as the demos in this course, even though device tree matching is primary on real hardware.
free linux device drivers course
free linux kernel development course
free embedded systems course
free embedded linux course
Continue The Free Linux Device Drivers Course
Next: writing your first device tree node and binding it to a driver.
