1.1 Platform bus, equipment and drive
In the Linux 2.6 device-driven model, care is being put on the bus, device, and drive of these 3 entities, and the bus binds the device and the driver. When the system registers a device, it looks for a matching driver; instead, when the system registers a drive, it looks for a matching device, and the match is done by the bus.
A realistic Linux device and driver usually need to be hooked up on a bus, which is naturally not a problem for devices that are attached to PCI, USB, I2C, SPI, and so on, but in embedded systems, an integrated independent peripheral controller in the SOC system, Peripherals attached to the SOC memory space are not attached to such a bus. Based on this background, Linux invented a virtual bus, called the platform Bus, the corresponding device called Platform_device, and drive to become platform_driver.
Note that the so-called platform_device is not a juxtaposition of character devices, block devices, and network devices, but an add-on provided by Linux systems, for example, in the S3C6410 processor, internally integrated I2C, RTC, SPI, LCD, Controllers such as watchdog are summed up as Platform_device, and they are character devices themselves. The definition of the PLATFORM_DEVICE structure is shown in code Listing 1.
Code Listing 1 Platform_device structural body
1 struct Platform_device {
2 const char * name;/* Device Name * *
3 u32 ID;
4 struct device dev;
5 u32 num_resources;/* Equipment to use the number of resources
6 struct Resource * resource;/* Resources * *
7};
Platform_driver This structure contains probe (), remove (), shutdown (), suspend (), resume () functions, and is usually required by the driver, as shown in Listing 2.
Code Listing 2 Platform_driver structural body
1 struct Platform_driver {
2 int (*probe) (struct platform_device *);
3 int (*remove) (struct platform_device *);
4 void (*shutdown) (struct platform_device *);
5 int (*suspend) (struct Platform_device *, pm_message_t State);
6 int (*suspend_late) (struct Platform_device *, pm_message_t State);
7 int (*resume_early) (struct platform_device *);
8 int (*resume) (struct platform_device *);
9 struct Pm_ext_ops *pm;
Ten struct device_driver driver;
11};
A Bus_type instance platform_bus_type is defined for the platform bus in the system, which is defined as code listing 15.3.
Code Listing 15.3 Platform Bus Bus_type instance Platform_bus_type
1 struct Bus_type Platform_bus_type = {
2. Name = "Platform",
3. Dev_attrs = Platform_dev_attrs,
4. Match = Platform_match,
5. uevent = Platform_uevent,
6. PM = platform_pm_ops_ptr,
7};
8 EXPORT_SYMBOL_GPL (Platform_bus_type);
The focus here is on the match () member function, which shows how Platform_device and Platform_driver match, as shown in Listing 4.
The match () member function in code Listing 4 Platform_bus_type
1 static int platform_match (struct device *dev, struct device_driver)
2 {
3 struct Platform_device *pdev;
4
5 Pdev = container_of (dev, struct platform_device, dev);
6 return (strncmp (Pdev->name, drv->name, bus_id_size) = = 0);
7}
As you can see from line 6th of code Listing 4, matching platform_device and platform_driver mainly depends on whether the name field is the same.
The definition of Platform_device is usually implemented in the board file of the BSP, in the board file, the Platform_device is summed up as an array, and eventually the Platform_add_devices () function is registered uniformly. The Platform_add_devices () function can add a platform device to the system, and the prototype of this function is:
int platform_add_devices (struct platform_device **devs, int num);
The first parameter of the function is a pointer to a platform device array, the second parameter is the number of platform devices, and the Platform_device_register () function is called internally to register a single platform device.