1、Linux驱动中的platform总线
在设备驱动程序中经常会见到和platform相关的字段,分布在驱动程序的多个角落,这也是2.6内核中比较重要的一种机制,把它的原理弄懂了,对以后分析驱动程序很有帮助,下面简单介绍一下:
struct platform_device { const char *name; //设备名 u32 id; struct device dev; u32 num_resources; //设备所使用的各类资源数量 struct resource *resource; //使用的资源 }
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 pm_ext_ops *pm; struct device_driver driver; };
struct platform_device s3c_device_lcd = { .name = "s3c2410-lcd", .id = -1, .num_resources = ARRAY_SIZE(s3c_lcd_resource), .resource = s3c_lcd_resource, .dev = { .dma_mask = &s3c_device_lcd_dmamask, .coherent_dma_mask = 0xffffffffUL } };
为了完成LCD设备的注册,将其放进/arch/arm/mach-s3c2440/mach-smdk2440.c中定义的smdk2440_devices数组中:
static struct platform_device *smdk2440_devices[] __initdata = { ........ ........ &s3c_device_lcd, };
static struct platform_driver s3c2410fb_driver = { .probe = s3c2410fb_probe, //驱动探测 .remove = __devexit_p(s3c2410fb_remove), //驱动移除 .suspend = s3c2410fb_suspend, .resume = s3c2410fb_resume, .driver = { .name = "s3c2410-lcd", //和platform_device中的name相同 .owner = THIS_MODULE, }, }; static int __devinit s3c2410_fb_init(void) { return platform_driver_register(&s3c2410fb_driver); } static void __exit s3c2410fb_cleanup(void) { platform_driver_unregister(&s3c2410fb_driver); }
struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; struct resource *parent, *sibling, *child; };
static struct resource s3c_lcd_resource[] = { [0] = { .start = S3C24XX_PA_LCD, //LCD的IO资源起始地始(LCD控制器寄存器地址) .end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1, //结束地址 .flags = IORESOURCE_MEM, }, [1] = { .start = IRQ_LCD, //LCD中断号 .end = IRQ_LCD, .flags = IORESOURCE_IRQ, } };
在driver中用platform_get_resource()或platform_get_irq()等函数获取设备资源
struct resource *platform_get_resource(struct platform_device *, unsigned int, unsigned int); int platform_get_irq(struct platform_device *dev, unsigned int num);
获取到的内存或IO资源,需要ioremap后才能使用 获取到的IRQ资源,需要request_irq
static struct dm9000_plat_data s3c_dm9000_platdata = { .flags = DM9000_PLATF_16BITONLY, }; static struct platform_device s3c_device_dm9000 = { .name = "dm9000", .id = 0, .num_resources = ARRAY_SIZE(s3c_dm9000_resource), .resource = s3c_dm9000_resource, .dev = { .platform_data = &s3c_dm9000_platdata, } };
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。