platform-driver
Driver裡面先定義出platform-driver的名稱
這個名稱是s3c2410-ohci
static struct platform_driver ohci_hcd_s3c2410_driver = {
.probe = ohci_hcd_s3c2410_drv_probe,
.remove = ohci_hcd_s3c2410_drv_remove,
.shutdown = usb_hcd_platform_shutdown,
/*.suspend = ohci_hcd_s3c2410_drv_suspend, */
/*.resume = ohci_hcd_s3c2410_drv_resume, */
.driver = {
.owner = THIS_MODULE,
.name = "s3c2410-ohci",
},
};
----
platform_driver的資料結構:
[include/linux/platform_device.h]
struct platform_driver {
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;
};
resource
[arch/arm/plat-s3c24xx/devs.c"]
/* USB Host Controller */
static struct resource s3c_usb_resource[] = {
[0] = {
.start = S3C24XX_PA_USBHOST,
.end = S3C24XX_PA_USBHOST + S3C24XX_SZ_USBHOST - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_USBH,
.end = IRQ_USBH,
.flags = IORESOURCE_IRQ,
}
};
platform-device (單一)
platporm裡要註冊device
使用的name對應到欲使用的driver
還有resource則是對應到上面
[arch/arm/plat-s3c24xx/devs.c"]
struct platform_device s3c_device_usb = {
.name = "s3c2410-ohci",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_usb_resource),
.resource = s3c_usb_resource,
.dev = {
.dma_mask = &s3c_device_usb_dmamask,
.coherent_dma_mask = 0xffffffffUL
}
};
EXPORT_SYMBOL(s3c_device_usb)
----
platform_device的資料結構:
[include/linux/platform_device.h]
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
----
device的資料結構:
[include/linux/device.h]
struct device {
struct klist klist_children;
struct klist_node knode_parent; /* node in sibling list */
struct klist_node knode_driver;
struct klist_node knode_bus;
struct device *parent;
struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
struct device_type *type;
unsigned is_registered:1;
unsigned uevent_suppress:1;
struct semaphore sem; /* semaphore to synchronize calls to
* its driver.
*/
struct bus_type * bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power;
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
struct list_head dma_pools; /* dma pools (if dma'ble) */
struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
/* arch specific additions */
struct dev_archdata archdata;
spinlock_t devres_lock;
struct list_head devres_head;
/* class_device migration path */
struct list_head node;
struct class *class;
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct attribute_group **groups; /* optional groups */
void (*release)(struct device * dev);
};
platform-device (全部)
最後把整個platform特有的device放在devices[]裡面
[arch/arm/mach-s3c2440/mach-smdk2440.c]
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
};
machine init
在machine init的時候,把devices加進platform
[arch/arm/mach-s3c2440/mach-smdk2440.c]
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
printk("smdk2440 machine init\n");
smdk_machine_init();
}
參考資料
帥哥安的 linux kernel 2.6.24.3 platform device driver
2.6.24 Kernel Document :
driver-model/Platform.txt
driver-model/Driver.txt
0 comments:
Post a Comment