Use this file to discover all available pages before exploring further.
Linux organizes hardware into bus subsystems, each with its own discovery mechanism, device identity format, and driver registration API. Choosing the correct bus type is the first decision you make when writing a new driver, because it determines how the kernel finds your hardware, what data structures you work with, and how your driver fits into the power management and hotplug infrastructure. This page covers the five most common bus types and the Device Tree binding layer used on ARM and embedded platforms.
The platform bus is a pseudo-bus for SoC-integrated peripherals and legacy PC-style hardware that is directly addressable by the CPU but has no dynamic discovery protocol. Devices are described statically—either in board setup code or, on modern systems, in Device Tree or ACPI tables.
#include <linux/platform_device.h>#include <linux/mod_devicetable.h>/* Device ID table for non-DT matching */static const struct platform_device_id mydrv_id_table[] = { { "my-device-v1", 0 }, { "my-device-v2", 1 }, { /* sentinel */ }};MODULE_DEVICE_TABLE(platform, mydrv_id_table);static int mydrv_probe(struct platform_device *pdev){ struct resource *res; void __iomem *base; /* Get the first memory resource from DT/board file */ base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); dev_info(&pdev->dev, "probed successfully\n"); return 0;}static void mydrv_remove(struct platform_device *pdev){ /* devm resources released automatically */}static struct platform_driver mydrv_driver = { .probe = mydrv_probe, .remove = mydrv_remove, .driver = { .name = "my-device", .of_match_table = mydrv_of_match, /* see Device Tree section */ }, .id_table = mydrv_id_table,};module_platform_driver(mydrv_driver);MODULE_LICENSE("GPL");
module_platform_driver() expands to module_init() and module_exit() wrappers that call platform_driver_register() and platform_driver_unregister().To register a platform device from board code (not Device Tree):
PCI and PCIe devices are discovered automatically at boot by the PCI subsystem. Each device advertises its vendor ID, device ID, class code, and subsystem IDs. Drivers declare an id_table listing the combinations they support.
Prefer pcim_enable_device() over pci_enable_device(). The pcim_* family is managed (analogous to devm_*) and automatically disables and releases resources when the driver unbinds.
USB devices are discovered and enumerated by the USB host controller driver. Each device and each interface within a device has a class, subclass, protocol, vendor, and product ID. USB drivers typically bind to interfaces, not to whole devices.
I2C is a two-wire serial bus widely used for sensors, EEPROMs, and power management ICs. Devices are not discoverable by the bus itself; they must be described in Device Tree or board code.
SPI is a four-wire synchronous serial bus for high-speed peripherals like flash memory, displays, and ADCs. Like I2C, SPI devices must be described in Device Tree.
On ARM and RISC-V systems, hardware is described in Device Tree source (.dts) files. Drivers match against DT nodes using a compatible string. Each driver declares the set of compatible strings it supports in an of_match_table:
The of_match_table is placed in the driver’s driver.of_match_table field (for platform, I2C, SPI) or the equivalent for other buses. The kernel calls of_match_device() during probe to find the matching entry, which your driver can read to discover hardware revision data:
static int mydrv_probe(struct platform_device *pdev){ const struct of_device_id *match; unsigned long variant; match = of_match_device(mydrv_of_match, &pdev->dev); if (match) variant = (unsigned long)match->data; /* ... */ return 0;}
A minimal Device Tree node for the platform example above:
SoC-integrated peripherals, legacy ports, memory-mapped hardware without a discovery protocol. Use when hardware is described in Device Tree or ACPI.
PCI / PCIe
Expansion cards, NVMe storage, Ethernet controllers, GPUs. Use when the hardware plugs into a PCI slot or is wired as a PCIe endpoint.
USB
Externally attached peripherals: storage, HID, audio, cameras. Use when the hardware connects via USB and has a USB vendor/product ID.
I2C / SPI
Sensors, power management ICs, displays, flash. I2C for low-speed (400 kHz–1 MHz); SPI for higher throughput. Both require Device Tree descriptions.
If your device appears in Device Tree with a compatible string and is memory-mapped, it is almost certainly a platform device. Start with platform_driver and module_platform_driver().