In the device-driven model of the kernel, the three entities are concerned with the bus, device, and drive.
When the system registers a device, the bus looks for the matching driver, and the bus will look for the matching device when the system is registered with each driver.
A realistic Linux device and driver usually need to be mounted on a bus, which is not a problem for devices that are attached to PCI,USB,I2C,SPI and so on.
But in the embedded system, the SOC system integrates the independent peripheral controller, and the peripherals integrated in the SOC are not dependent on this kind of bus. Based on this background, Linux
Invented a virtual bus, called the platform bus, the resources described by platform have one thing in common: the direct access on the CPU bus. corresponding to the
The device is called Platform_device, and the drive is called Platform_driver.
The order in which they work is
- First define Platform_device---Registration Platform_device
- Re-define Platform_driver-I registration Platform_driver
Note: The so-called platform_device is not a parallel concept with character devices, block devices, network devices, but an additional means provided by the Linux system.
The definition of the Platform_device struct (include/linux/platform_device.h), as follows:
structPlatform_device {Const Char* NAME;//device names are used to bind to and drive intId//Device ID structdevice Dev; U32 num_resources; //number of resources used by the device structResource * resource;//Resources Const structPLATFORM_DEVICE_ID *Id_entry; /*MFD Cell Pointer*/ structMfd_cell *Mfd_cell; /*Arch Specific Additions*/ structpdev_archdata Archdata;};
The definition of the platform_driver struct (include/linux/platform_device.h), as follows:
structPlatform_driver {int(*probe) (structPlatform_device *); int(*remove) (structPlatform_device *); void(*shutdown) (structPlatform_device *); int(*suspend) (structPlatform_device *, pm_message_t State); int(*resume) (structPlatform_device *); structDevice_driver driver; Const structPLATFORM_DEVICE_ID *id_table;};
The structure contains probe (), remove (), shutdown, suspend (), and resume functions, which are usually also implemented by the driver.
A Bus_type instance Platform_bus_type (DRIVERS/BASE/PLATFORM.C) is defined for the platform bus in the system, which is defined as follows:
struct bus_type platform_bus_type = { . Name "platform", . Dev_attrs = Platform_dev_attrs, . Match = platform_match, . uevent = platform_ Uevent, . PM = &Platform_dev_pm_ops,}; EXPORT_SYMBOL_GPL (platform_bus_type);
This is where you focus on the match () member function, which determines how Platform_device and Platform_driver are configured.
The Platform_match definition (DRIVERS/BASE/PLATFORM.C) is as follows:
/** * Platform_match-bind platform device to platform driver. * @dev: Device. * @drv: Driver. * * Platform Device IDs was assumed to being encoded like this: * "<name><instance>", where <name> was a short description of the Ty PE of * device, like "PCI" or "floppy", and <instance> are the enumerated * instance of the device, like ' 0 ' or ' 42 '. Driver IDs is simply * "<name>". So, extract the <name> from the platform_device structure, * and compare it against the name of the driver. Return whether they match * or not. */Static intPlatform_match (structDevice *dev,structDevice_driver *DRV) { structPlatform_device *pdev =To_platform_device (Dev); structPlatform_driver *pdrv =To_platform_driver (DRV); /*attempt an of style match first*/ if(Of_driver_match_device (Dev, DRV))return 1; /*Then try to match against the ID table*/ if(pdrv->id_table)returnPLATFORM_MATCH_ID (pdrv->id_table, pdev)! =NULL; /*Fall-back to driver name match*/ return(strcmp (pdev->name, drv->name) = =0);}
As we can see, 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 BSP Board file, in the board file, the Platform_device is summed up as an array, which is finally passed
The Platform_add_devices () function is registered uniformly. The definition (DRIVERS/BASE/PLATFORM.C) is as follows:
/** * Platform_add_devices-add a numbers of platform devices * @devs: Array of platform devices to add * @num: Number of platform devices in array*/intPlatform_add_devices (structPlatform_device **devs,intnum) { intI, ret =0; for(i =0; i < num; i++) {ret=Platform_device_register (Devs[i]); if(ret) { while(-I. >=0) Platform_device_unregister (Devs[i]); Break; } } returnret;} EXPORT_SYMBOL_GPL (platform_add_devices);
The Platform_add_devices () function can add a platform device to the system, the first parameter of the function is a pointer to the platform device array, and the second parameter is the platform device
, it internally invokes the Platform_device_register () function, which is used to register a single platform device.
3.0.35 platform bus, device and driver