Main reference: http://blog.chinaunix.net/uid-26285146-id-3307147.htmlhttp://blog.chinaunix.net/uid-26285146-id-3307147.html
Important struct
<1> struct device <Linux/device. h> // describe the hierarchical relationship between devices related to devices and the relationship between devices and bus and drivers. * platform_data;/* platform specific data, device core doesn' t touch it */struct device_driver * driver; // point to the device driver allocated to the device. // In really_probe (struct device * Dev, struct device_driver * DRV) in the function, Dev-> driver = DRV; bind the device to the drive with Char bus_id [bus_id_size];/* position on parent bus */struct bus_type * bus; // In platform_device_add () pdev-> Dev. bus = & platform_bus_type; struct device * parent; // point to its parent device which is assigned as & platform_bus; void (* release) (struct device * Dev) in platform_device_add ); // call back the device descriptor
<2> struct resource <Linux/ioport. h>
// This structure indicates the resources owned by the device, such as the I/O port, I/O ing memory, interrupt, and DMA. The address here refers to the physical address.
Member:
Resource_size_t start; // defines the starting address of the resource.
Resource_size_t end; // defines the end address of the resource.
Const char * Name; // define the Resource Name
Unsigned long flags; // defines the resource type, such as MEM, Io, IRQ, and DMA.
Struct resource * parent, * sibling, * child;
<3> struct device_driver <Linux/device. h>
Const char * Name;
Struct bus_type * bus;
Struct module * owner;
Const char * mod_name;/* used for built-in modules */
INT (* probe) (struct device * Dev );
INT (* remove) (struct device * Dev );
Void (* shutdown) (struct device * Dev );
INT (* suspend) (struct device * Dev, pm_message_t State );
INT (* resume) (struct device * Dev );
Struct attribute_group ** groups;
Struct driver_private * P;
Device_driver provides some operation interfaces, but it is not implemented. It is equivalent to some virtual functions and is overloaded by the platform_driver derived from the device_driver class, the specific operations are based on the unified basic class interface, thus implementing the object-oriented design.
In the device_driver structure, the name variable is consistent with the name variable in platform_device. The kernel uses this consistency to find resources for the driver, that is, resources in platform_device.
<4> struct platform_device <Linux/platform_device.h> member:
Const char * Name; // define the name of the platform device. The name of the device must be the same as that of the driver.
Int ID;
Struct device dev; // describes the device status,Platform_device is derived from device and is a special device.
U32 num_resources;
Struct resource * resource; // defines the resources of the platform device.
<4> struct platform_driver <Linux/platform_device.h> // implement the shutdown, suspend, and resume functions in this structure. If not, set them to null. Member: int (* probe) (struct platform_device *);
INT (* remove) (struct platform_device *);
Void (* shutdown) (struct platform_device *);
INT (* suspend) (struct platform_device *, pm_message_t State );
INT (* suspend_late) (struct platform_device *, pm_message_t State );
INT (* resume_early) (struct platform_device *);
INT (* resume) (struct platform_device *);
Struct device_driver driver;
Important Functions<1> platform_device_register (srtuct platform_device * pdev) // Drivers/base/platform. C // call platform_device_add (pdev) to register on the platform bus // platform_device_add call device_add () platform_device_unregister () device_register (struct device * Dev) // Linux/Drivers/base/core. C // call device_add (Dev) // Insert the device object Dev into the device model. The device_unregister () device_register () and platform_device_register () initialize the device first. The difference lies in step 2: in fact, platform_device _ Add () includes device_add (), but you must register resources first and then mount the device to a specific platform bus. <2> platform_driver_register (struct platform_driver * DRV) // Drivers/base/platform. C // call driver_register (& DRV-> driver) Register () platform_device_alloc () // dynamically apply for a platform_device device and add related resources and attributes through platform_device_add_resources and platform_device_add_data. // Register to the platform bus through platform_device_add
<3> platform_add_devices ()The device resources in the system can be listed in a pointer array.
Static struct platform_device * smdk6410_devices [] _ initdata = {
......
& Amp; cloud_device_usbgadget,
& Initi_device_usb, // Jeff add.
......
}
Then execute
Platform_add_devices (smdk6410_devices, array_size (smdk6410_devices); add all devices to the system. The benefit of platform_add_devices is that it executes multiple platform_device_register at a time.
Implementation of device and driver binding<1> virtual bus "Platform" attributes and operation definitions: // Drivers/base/platform. cstruct bus_type platform_bus_type = {. name = "Platform ",. dev_attrs = platform_dev_attrs ,. match = platform_match ,. uevent = platform_uevent ,. PM = & platform_dev_pm_ops,}; // The bus is an intermediate hub connecting driver and device. The device finds the driver through the bus to which it belongs, and matches the driver by the match operation method. Static int platform_match (struct device * Dev, struct device_driver * DRV) {struct platform_device * pdev = to_platform_device (Dev); struct platform_driver * pdrv = to_platform_driver (DRV );... return (strcmp (pdev-> name, DRV-> name) = 0);} <2> Register a device with platform_device_register ()-> platform_device_add () -> (pdev-> Dev. bus = & platform_bus_type) to mount the device under the virtual platform bus; <3> driver registration platform_driver_register (struct platform _ Driver * DRV)-> driver_register (struct device_driver * DRV)-> bus_add_driver (struct device_driver * DRV)-> driver_attach (struct device_driver * DRV) // return bus_for_each_dev (DRV-> bus, null, DRV, _ driver_attach);-> bus_for_each_dev (), perform _ driver_attach (struct device * Dev, void * Data)-> driver_probe_device (struct device_driver * DRV, struct device * Dev) on each device mounted to the virtual platform bus ), determine whether DRV-> bus-> match () exists and whether execution is successful. Execute platform_match through the pointer to compare strncmp (pdev-> name, DRV-> name, bus_id_size). If yes, call really_probe (struct device * Dev, struct device_driver * DRV) // driver_sysfs_add () in this function, there is DRV-> probe (Dev): Call the probe (Dev) of device_driver, which is actually the platform_driver-> probe (platform_device) of the corresponding device) the probe function generally enables hardware devices, obtains struct resources, dynamically maps virtual addresses, and registers devices of specific types (because platform devices are just virtual devices ); the remove function disables hardware devices, releases dynamic struing between struct resources and virtual addresses, and cancels devices of specific types. Note: platfor M_drv_probe's _ Dev parameter is obtained by the next_device of bus_for_each_dev). If probe is successful, the device is bound to the driver. Int bus_for_each_dev (struct bus_type * bus, struct device * Start, void * data, INT (* fN) (struct device *, void *) {struct klist_iter I; struct device * dev; int error = 0; If (! Bus) Return-einval; klist_iter_init_node (& bus-> klist_devices, & I, (start? & START-> knode_bus: NULL); While (Dev = next_device (& I ))&&! Error) error = FN (Dev, data); klist_iter_exit (& I); Return Error ;}< 4> init/main. in C: start_kernel rest_init kernel_init do_basic_setup driver_init platform_bus_init initialize platform_bus (Virtual Bus); (first) start_kernel rest_init kernel_init do_basic_setup do_initcils platform driver and platform device initialize (later) to create a platform_bus device, which will be used as a parent for later platform devices. In sysfs, all platform devices are added to the directory represented by platform_bus, that is, under/sys/devices/platform.
Platform Driver Model 1