1. Platform Bus Position in the Kernel
1. Linux Driver Model Hierarchy
Platform bus is at the core position of the driver model, connecting:
- Upper character device framework (cdev)
- Lower hardware resources (registers, interrupts, etc.)
2. Platform Bus Kernel Implementation Location
Core code related to Platform bus in kernel source:
bash
TaishanPi-3-Linux/kernel-6.1/drivers/base/
├── platform.c # Platform bus core implementation
├── dd.c # Device-driver matching core logic
└── core.c # Device model core code
TaishanPi-3-Linux/kernel-6.1/include/linux/platform_device.h/
├── platform_device.h # platform_device structure definition
└── of_platform.h # Device tree related Platform interfaces1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
The kernel automatically registers Platform bus on startup: struct bus_type platform_bus_type and platform_bus_init()
2. Platform Bus Core Data Structures
1. Three Core Structures
2. Device Structure
struct platform_device is used to describe the hardware resources of a Platform device:
c
struct platform_device {
const char *name;
int id;
bool id_auto;
struct device dev;
u64 platform_dma_mask;
struct device_dma_parameters dma_parms;
u32 num_resources;
struct resource *resource;
const struct platform_device_id *id_entry;
/*
* Driver name to force a match. Do not set directly, because core
* frees it. Use driver_set_override() to set or clear it.
*/
const char *driver_override;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const char *name: String identifier for the device, usually matches thenameof the correspondingplatform_driver, e.g., "serial", "i2c-controller", etc.int id: Used to distinguish different instances when multiple devices of the same type exist in the system.bool id_auto: System automatically assigns a unique ID to the device.struct device dev: Base structure for all devices, containing core information of the device model.u64 platform_dma_mask: Indicates the physical address range the device can access.struct device_dma_parameters dma_parms: Contains specific parameters for device DMA transfers, such as maximum segment size, alignment requirements, etc.u32 num_resources: Total number of resources (memory, interrupts, IO ports, etc.) owned by the device.struct resource *resource: Pointer to an array of struct resource, describing hardware resources used by the device.const struct platform_device_id *id_entry: Pointer to a matching platform_device_id entry.const char *driver_override: Used to bypass normal device-driver matching mechanism, forcing binding to a specified driver.struct mfd_cell *mfd_cell: Used when the device is an MFD sub-device, pointing to the mfd_cell structure describing the sub-function.struct pdev_archdata archdata: Stores private data required for specific CPU architecture.
Resource Types (struct resource):
c
/*
* Resources are tree-like, allowing
* nesting etc..
*
* Resource structure - describes hardware resources (memory, IO, IRQ, etc.)
* Uses tree structure, supports nesting and hierarchical management
*/
struct resource {
resource_size_t start; /* Resource start address/number */
resource_size_t end; /* Resource end address/number (inclusive) */
const char *name; /* Resource name */
unsigned long flags; /* Resource type and flags (IORESOURCE_MEM/IRQ/IO/DMA, etc.) */
unsigned long desc; /* Resource descriptor (e.g., E820 memory type) */
struct resource *parent; /* Parent resource (larger range this resource belongs to) */
struct resource *sibling; /* Sibling resource (next resource at same level) */
struct resource *child; /* Child resource (nested subrange within this resource) */
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
How Device Tree converts to platform_device:
3. Driver Structure
c
struct platform_driver {
int (*probe)(struct platform_device *); // Device probe function, called when device and driver match successfully
int (*remove)(struct platform_device *); // Device remove function (old version)
void (*remove_new)(struct platform_device *); // Device remove function (new version)
void (*shutdown)(struct platform_device *); // Called when system shuts down/restarts
int (*suspend)(struct platform_device *, pm_message_t state); // Called when system suspends (hibernates)
int (*resume)(struct platform_device *); // Called when system resumes (wakes up)
struct device_driver driver; // Generic device driver structure, contains driver name, matching table, etc.
const struct platform_device_id *id_table; // Device ID matching table (for non-device tree matching)
bool prevent_deferred_probe; // Prevent deferred probing
bool driver_managed_dma; // Driver manages DMA itself
};1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Device Tree Matching Table (of_device_id):
c
struct of_device_id {
char name[32]; /* Device node name */
char type[32]; /* Device type */
char compatible[128]; /* Device compatibility string */
const void *data; /* Driver private data pointer */
};1
2
3
4
5
6
2
3
4
5
6
How driver code defines the matching table:
c
// Define matching table in driver code
static const struct of_device_id my_of_match[] = {
{ .compatible = "lckfb,mychardev" }, // Inform bus to match this compatible
{ /* Terminator */ }
};
static struct platform_driver my_driver = {
.probe = my_probe,
.remove = my_remove,
.driver = {
.name = "mychardev",
.of_match_table = my_of_match, // Specify matching table
},
};1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
3. Platform Bus Workflow in Detail
1. Sequence Diagram
2. Device Registration Flow
3. Driver Registration Flow
4. Device and Driver Matching Flow
Matching Priority:
| Priority | Matching Method | Match Field | Application Scenario |
|---|---|---|---|
| 1 | Device Tree Matching | compatible | ARM/ARM64 platforms |
| 2 | ACPI Matching | ACPI ID | x86 platforms |
| 3 | ID Table Matching | id_table.name | Legacy code compatibility |
| 4 | Name Matching | device.name == driver.name | Manually registered devices |
5. probe Function Call Flow
4. Device and Driver Linked Lists on the Bus
1. Linked List Structure Diagram
2. View Devices and Drivers in the System
View all registered Platform devices and drivers in the system through sysfs:
bash
# View all Platform devices
ls /sys/bus/platform/devices/
# View all Platform drivers
ls /sys/bus/platform/drivers/
# View detailed information for a specific device
cat /sys/bus/platform/devices/mychardev.0/uevent
# View devices bound to a specific driver
ls /sys/bus/platform/drivers/mychardev/1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
5. Platform Bus Architecture Summary
1. Core Component Relationship Diagram
| Concept | Description |
|---|---|
| platform_bus_type | Core structure of Platform bus, registered at kernel startup |
| platform_device | Describes hardware resources, automatically created from device tree |
| platform_driver | Describes driver capabilities, written and registered by us |
| of_match_table | Device tree matching table, contains compatible strings |
| platform_match() | Bus matching function, with 4 matching methods |
| probe() | Automatically called after successful matching, used to initialize device |
| resource | Hardware resources (register addresses, interrupt numbers, etc.) |
| Device Linked List | bus->devices, stores all registered devices |
| Driver Linked List | bus->drivers, stores all registered drivers |