1. Overview
2. system initialization platform device
3. The driver uses platform device
1. Overview
The Linux-2.6.11 introduces the concept of a device model that mounts most device drivers to a virtual bus.
Its purpose is:
1) provides friendly user interfaces. You can find the corresponding drivers and devices under sys/bus/platform.
2) more conducive to power management.
2. system initialization platform device
In the initialization function xxx_probe (struct platform_device * pdev) of the driver, the structure parameter platform_device is the precondition that the device exists during system initialization, register through platform_device_register (Dev), and the schema variable of struct platform_device is assigned a value.
Take xscal as an example to initialize the SD card controller,
/* Linux/ARCH/ARM/Mach-PXA/starwood_p1.c */
Machine_start (Saar, "pxa935 handheld platform (Starwood P1 )")
......
. Init_machine = saar_init,
Machine_end
Static void _ init saar_init (void)
{
......
Saar_init_mmc ();
......
}
Static void _ init saar_init_mmc (void)
{
......
Pxa_set_mci_info (& saar_mci_platform_data); // saar_mci_platform_data assigns a value to the unique data of the device.
......
}
Static struct pxamci_platform_data saar_mci_platform_data = {
. Detect_delay = 50,
. Ocr_mask = mmc_vdd_32_33 | mmc_vdd_33_34,
. Init = saar_mci_init, // callback function, set the SD card controller's probe interrupt pin gpio_cd
. Exit = saar_mci_exit,
};
Void _ init pxa_set_mci_info (struct pxamci_platform_data * info)
{
Pxa_register_device (& pxa_device_mci, Info );
}
StructPlatform_devicePxa_device_mci = {// complete the assignment of the structure platform_device
. Name = "pxa2xx-mci", // The device name of the chip, the driver finds the device by matching the name
. ID = 0,
. Dev = {
. Dma_mask = & pxamci_dmamask,
. Coherent_dma_mask = 0 xffffffff,
},
. Num_resources = array_size (pxamci_resources ),
. Resource = pxamci_resources, // set the physical address of the chip
};
Void _ init pxa_register_device (struct platform_device * Dev, void * Data)
{
......
Dev-> Dev. platform_data = data; // mount the unique data of the device to Dev-> Dev. platform_data
Platform_device_register (Dev );
......
}
3. The driver uses platform device
The driver finds the device corresponding to the driver through platform_driver_register (), binds the driver to the device, and mounts it to the virtual bus.
The specific process is as follows,
Platform_driver_register (struct platform_driver * DRV );
|
Driver_register (& DRV-> driver );
|
Bus_add_driver (DRV );
|
Driver_attach (DRV );
Int driver_attach (struct device_driver * DRV)
{
Return bus_for_each_dev (DRV-> bus, null, DRV, _ driver_attach); // _ driver_attach finally calls driver_bound (Dev );
}
Int bus_for_each_dev (struct bus_type * bus, struct device * start,
Void * data, INT (* fN) (struct device *, void *))
{
......
While (Dev = next_device (& I ))&&! Error)
FN (Dev, data); // FN is _ driver_attach to bind the device to the driver.
......
}
Static void driver_bound (struct device * Dev)
{
......
Klist_add_tail (& Dev-> knode_driver, & Dev-> driver-> P-> klist_devices );
}
After the driver finds the corresponding device, it can initialize the device, that is, the probe () operation, in probe, you can use the data in the platform_device struct.
Take the SD card controller as an example,
/* Linux/Drivers/MMC/host/pxamci. C */
Static int _ init pxamci_init (void)
{
......
Return platform_driver_register (& pxamci_driver );
}
Static struct platform_driver pxamci_driver = {
. Probe = pxamci_probe,
......
};
Static int pxamci_probe (struct platform_device * pdev)
{
Struct resource * R;
/*
* Obtain the physical address of the SD card controller chip.
*/
R = platform_get_resource (pdev, ioresource_mem, 0 );
R = request_mem_region (R-> Start, sz_4k, driver_name );
Host-> res = R;
/*
* Obtain the internal interrupt source of the SD card controller chip and apply for an interrupt
*/
IRQ = platform_get_irq (pdev, 0 );
Host-> IRQ = IRQ;
Request_irq (host-> IRQ, pxamci_irq, 0, driver_name, host );
......
}