In the definition of structural body platform_device (include/linux/platform_device.h):
structPlatform_device {Const Char*name; intID; structdevice Dev; U32 num_resources; structResource *resource; Const structPLATFORM_DEVICE_ID *Id_entry; /*MFD Cell Pointer*/ structMfd_cell *Mfd_cell; /*Arch Specific Additions*/ structpdev_archdata Archdata;};
Describes the resources of Platform_device, which are described by the struct resource itself, and its definition (include/linux/ioport.h) is as follows:
/**struct resource { resource_size_t start; resource_size_t end; Const Char *name; Long flags; struct resource *parent, *sibling, * child;};
We usually care about the three fields of start, end, and flags, which represent the start value, end value, and type of the resource, respectively.
Type fields are also defined in ioport.h, supporting Ioresource_io, Ioresource_mem, IORESOURCE_IRQ, IORESOURCE_DMA, and so on.
Start, the meaning of end is changed with the flags, such as when flags is Ioresource_mem, start, and end indicate the memory occupied by the Platform_device, respectively.
Start and end addresses; When flags is IORESOURCE_IRQ, start, end represents the start and end values of the interrupt number used by the Platform_device.
The definition of resource is usually done in the BSP board file, and the resource file is registered to the device via Platform_device_add_resources (), while the specific
Platform_get_resource (), which is defined (DRIVERS/BASE/PLATFORM.C), as follows:
/** * Platform_get_resource-get A resource for a device * @dev: Platform device * @type: Resource type * @num: RESOURC E index*/structResource *platform_get_resource (structPlatform_device *Dev, unsignedintType, unsignedintnum) { inti; for(i =0; I < dev->num_resources; i++) { structResource *r = &dev->Resource[i]; if(Type = = Resource_type (r) && num--= =0) returnR; } returnNULL;} EXPORT_SYMBOL_GPL (Platform_get_resource);
For example, in MY. The following resource are defined for ECSPI (ARCH/ARM/PLAT-MXC/DEVICES/PLATFORM-SPI_IMX.C) in the board file of the IMx6 Development Board:
structPlatform_device *__init Imx_add_spi_imx (Const structImx_spi_imx_data *data,Const structSpi_imx_master *pdata) { structResource res[] ={. Start= data->iobase,. End= Data->iobase + Data->iosize-1,. Flags=Ioresource_mem,}, {. Start= data->IRQ,. End= data->IRQ,. Flags=Ioresource_irq,},}; returnImx_add_platform_device (Data->devid, data->ID, res, array_size (res), pdata,sizeof(*pdata));}
Add the resource file by Imx_add_platform_device (), whose definition (Arch/arm/plat-mxc/include/mach/devices-common.h) is as follows:
static inline struct platform_ Device *imx_add_platform_device ( const char *name, int ID, const struct resource *res, unsigned int Num_resources, const void *
data, size_t size_data) {
return
Imx_add _platform_device_dmamask (name, ID, res, num_resources, data, Size_data,
0
Imx_add_platform_device_dmamask (), whose definition (ARCH/ARM/PLAT-MXC/DEVICES.C) is as follows:
structPlatform_device *__init Imx_add_platform_device_dmamask (Const Char*name,intID,Const structResource *res, unsignedintNum_resources,Const void*data, size_t size_data, U64 dmamask) { intRET =-Enomem; structPlatform_device *Pdev; Pdev=Platform_device_alloc (name, id); if(!Pdev)Gotoerr; if(dmamask) {/** This memory isn't freed when the device is put, * I don ' t has a nice idea for that though. Conceptually * dma_mask in struct device should is not a pointer. * Seehttp://thread.gmane.org/gmane.linux.kernel.pci/9081 */Pdev->dev.dma_mask =Kmalloc (sizeof(*pdev->dev.dma_mask), Gfp_kernel); if(!pdev->dev.dma_mask)/*ret is still-enomem;*/ Gotoerr; *pdev->dev.dma_mask =Dmamask; Pdev->dev.coherent_dma_mask =Dmamask; } if(res) {ret=platform_device_add_resources (Pdev, res, num_resources); if(ret)Gotoerr; } if(data) {RET=Platform_device_add_data (Pdev, data, size_data); if(ret)Gotoerr; } ret=Platform_device_add (Pdev); if(ret) {err:if(Dmamask) kfree (Pdev-dev.dma_mask); Platform_device_put (Pdev); returnerr_ptr (ret); } returnPdev;}
And finally called Platform_device_add_resources () whose definition (DRIVERS/BASE/PLATFORM.C) is as follows:
/** * Platform_device_add_resources-add resources to a platform device * @pdev: Platform device allocated by PLATFORM_ Device_alloc to add resources to * @res: Set of resources, needs to being allocated for the device * @num: Number of Reso Urces * * Add a copy of the resources to the platform device. The memory * associated with the resources would be freed if the platform device is * released. */intPlatform_device_add_resources (structPlatform_device *Pdev,Const structResource *res, unsignedintnum) { structResource *r =NULL; if(res) {R= Kmemdup (res,sizeof(structResource) *num, Gfp_kernel); if(!R)return-Enomem; } kfree (Pdev-Resource); Pdev->resource =R; Pdev->num_resources =num; return 0;} EXPORT_SYMBOL_GPL (platform_device_add_resources);
In the SPI driver of IMx6, these 2 resources are obtained by the following methods:
Specifically in the Spi_imx_probe () method of the DRIVERS/SPI/SPI_IMX.C
0 ); Spi_imx0);
The definition of PLATFORM_GET_IRQ is as follows:
/**/int platform_get_irq (structint num ) { struct Resource *r = platform_get_resource (dev, Ioresource_irq, num); return R? R->start:-Enxio;} EXPORT_SYMBOL_GPL (PLATFORM_GET_IRQ);
In addition to defining the resource files in the BSP, the device can also attach some data information, because the hardware description of the device in addition to interrupts, memory, DMA, there may be
Some configuration information, which is also dependent on the board, is not suitable to be placed directly on the drive itself, so platform also provides support for Platform_data.
The concept of introducing platform in device drivers has at least the following two benefits:
1) allows the device to be attached to a bus, the text will be managed
2) The BSP and driver are isolated. In BSP, the specific information about the resources and devices used by platform devices and devices is defined, and in the drive, only the generic API is needed to obtain
Resources and data to achieve the separation of board-related code and drive code, the drive has better scalability and cross-platform.
3.0.35 platform device Resources and data