Skip to content

Platform Bus Internals

Overview

The Linux Platform Bus is the most commonly used bus type for SoC-integrated peripherals in Embedded Linux systems.

Examples:

  • GPIO Controller
  • UART Controller
  • SPI Controller
  • I2C Controller
  • Watchdog
  • RTC
  • PWM
  • DMA
  • PCIe Controller

The Platform Bus is built on top of the Linux Driver Model.


Relationship with Driver Core

The Platform Bus is not a separate driver framework.

It is a specialization of the Linux Driver Model.

Driver Core

bus_type
device
device_driver

Platform Bus extends these structures:

platform_bus_type
        ↓
bus_type

platform_device
        ↓
device

platform_driver
        ↓
device_driver

Platform Bus Architecture

Platform Bus

platform_device
        ↕
platform_match()
        ↕
platform_driver

The Platform Bus is responsible for matching devices and drivers.

A successful match triggers the driver's probe callback.


Device Creation

Platform devices can be created in multiple ways.


Device Tree

Most modern ARM systems use Device Tree.

Device Tree
    ↓
OF Subsystem
    ↓
of_platform_populate()
    ↓
platform_device

Example:

uart0 {
    compatible = "vendor,uart";
};

The kernel creates a corresponding platform device.


Manual Registration

A platform device may also be created manually.

platform_device_register_simple(
    "demo_platform",
    -1,
    NULL,
    0);

This is commonly used for:

  • Testing
  • Legacy code
  • Virtual devices

Driver Registration

Platform drivers are registered through:

platform_driver_register()

Internally:

platform_driver_register()
        ↓
driver_register()

The driver becomes part of the Platform Bus.


Matching Flow

The Platform Bus provides its own match callback:

platform_match()

Conceptually:

platform_device
        ↓
platform_match()
        ↓
platform_driver

A successful match allows probing to proceed.


Device Tree Matching

The most common matching method on ARM systems uses Device Tree.

Driver:

static const struct of_device_id demo_of_match[] = {
    { .compatible = "demo,platform-bus" },
    {}
};
.driver = {
    .of_match_table = demo_of_match,
}

Device Tree:

demo-platform {
    compatible = "demo,platform-bus";
};

Matching:

compatible
        ↓
of_match_table
        ↓
platform_match()

Name Matching

If Device Tree matching is unavailable, Platform Bus may fall back to name matching.

Device:

platform_device_register_simple(
    "demo_platform",
    ...
);

Driver:

.driver = {
    .name = "demo_platform",
}

Matching:

platform_device.name
        ↓
platform_driver.name

Probe Flow

The complete flow is:

platform_driver_register()
        ↓
driver_register()
        ↓
driver_attach()
        ↓
platform_match()
        ↓
really_probe()
        ↓
platform_probe()
        ↓
driver probe()

The driver's probe callback is not called directly by Device Tree.


Device Tree and Probe

A common misunderstanding is:

Device Tree
        ↓
probe()

This is incorrect.

Actual flow:

Device Tree
        ↓
platform_device
        ↓
platform_match()
        ↓
platform_driver
        ↓
probe()

Device Tree creates devices.

The Platform Bus performs matching.


MODULE_DEVICE_TABLE(of)

Example:

MODULE_DEVICE_TABLE(of, demo_of_match);

This macro generates OF module aliases.

Example:

alias: of:N*T*Cdemo,platform-busC*

Purpose:

Module auto-loading
Module alias generation

It is not responsible for runtime matching.

Runtime matching uses:

.of_match_table

Sysfs Representation

Platform Bus objects are visible through sysfs.

Bus:

/sys/bus/platform

Devices:

/sys/bus/platform/devices

Drivers:

/sys/bus/platform/drivers

Device Tree association:

device
    ↓
of_node
    ↓
Device Tree node

Driver association:

device
    ↓
driver
    ↓
platform_driver

Key Takeaways

Platform Bus is built on top of Driver Core.

Device Tree creates platform_device objects.

Platform Bus performs matching.

Successful matching triggers probe().

Device Tree does not call probe() directly.

Related Topics

  • Linux Driver Model Fundamentals
  • Device Tree Fundamentals
  • Platform Driver and Device Tree Binding
  • Driver Probe and Remove Lifecycle

Related APIs

  • platform_driver_register()
  • platform_driver_unregister()
  • platform_device_register_simple()
  • platform_device_unregister()
  • MODULE_DEVICE_TABLE()