Linux内核-平台设备-platform
发布时间:2020-12-14 01:46:53 所属栏目:Linux 来源:网络整理
导读:一、注册一个平台设备 方法1:platform_device_register 核心数据结构: 1 struct platform_device { 2 const char * name; 3 int id; 4 bool id_auto; 5 struct device dev; 6 u32 num_resources; 7 struct resource * resource; 8 9 const struct platform
一、注册一个平台设备 方法1:platform_device_register 核心数据结构: 1 struct platform_device { 2 const char *name; 3 int id; 4 bool id_auto; 5 struct device dev; 6 u32 num_resources; 7 struct resource *resource; 8 9 const struct platform_device_id *id_entry; 10 char *driver_override; /* Driver name to force a match */ 11 12 /* MFD cell pointer */ 13 struct mfd_cell *mfd_cell; 14 15 /* arch specific additions */ 16 struct pdev_archdata archdata; 17 }; 核心接口 1 extern int platform_device_register(struct platform_device *); 代码示例 static struct resource my_resoure1[]={ { .start = 0x00,.end = 0x10,.name = "resource1 MEM",.flags = IORESOURCE_MEM,},{ .start = 0x11,.end = 0x20,.name = "resource2 MEM",{ .start = 5,.end = 9,.name = "resource3 IRQ",.flags = IORESOURCE_IRQ,{ .start = 10,.end = 15,.name = "resource4 IRQ",}; static struct platform_device my_device1 = { .name = "xym-test-platform-device-1",.id = -1,.num_resources = ARRAY_SIZE(my_resoure1),.resource = my_resoure1,.dev = { .release = my_platform_device_release,//不注册此接口,卸载驱动时会报警告 .platform_data = &platform_data_1,}; struct platform_device * p_device_1 = &my_device1; //device 1 ret = platform_device_register(&my_device1); if (ret) { printk(KERN_INFO"Unable to device 1 register(%d)n",ret); return ret; } 方法2:platform_device_register_full 核心数据结构 1 struct platform_device_info { 2 struct device *parent; 3 struct fwnode_handle *fwnode; 4 5 const char *name; 6 int id; 7 8 const struct resource *res; 9 unsigned int num_res; 10 11 const void *data; 12 size_t size_data; 13 u64 dma_mask; 14 }; 核心接口 1 extern struct platform_device *platform_device_register_full(const struct platform_device_info *pdevinfo); 2 3 static inline struct platform_device *platform_device_register_simple( 4 const char *name,int id, 5 const struct resource *res,unsigned int num) 6 7 static inline struct platform_device *platform_device_register_resndata( 8 struct device *parent,const char *name, 9 const struct resource *res,unsigned int num,10 const void *data,size_t size) 代码示例 static struct resource my_resoure2[]={ { .start = 0x21,.end = 0x30,{ .start = 0x31,.end = 0x40,{ .start = 20,.end = 30,{ .start = 40,.end = 50,}; static struct platform_device_info my_device_2 = { .name = "xym-test-platform-device-2",.num_res = ARRAY_SIZE(my_resoure2),.res = my_resoure2,.data = &platform_data_2,.size_data = sizeof(platform_data_2),}; struct platform_device * p_device_2; //device 2 p_device_2 = platform_device_register_full(&my_device_2); if (!p_device_2) { printk(KERN_INFO"Unable to device 2 registern"); return ret; } static struct resource my_resoure3[]={ { .start = 0x41,.end = 0x50,{ .start = 0x51,.end = 0x60,{ .start = 60,.end = 70,{ .start = 80,.end = 90,}; struct platform_device * p_device_3; p_device_3 = platform_device_register_resndata(NULL,"xym-test-platform-device-3",-1,my_resoure3,ARRAY_SIZE(my_resoure3),&platform_data_3,sizeof(platform_data_3)); if (!p_device_3) { printk(KERN_INFO"Unable to device 3 registern"); return ret; } static struct resource my_resoure4[]={ { .start = 0x61,.end = 0x70,{ .start = 0x71,.end = 0x80,{ .start = 100,.end = 110,{ .start = 120,.end = 130,}; struct platform_device * p_device_4; //device 4 p_device_4 = platform_device_register_simple("xym-test-platform-device-4",-1,my_resoure4,ARRAY_SIZE(my_resoure4)); if (!p_device_4) { printk(KERN_INFO"Unable to device 4 registern"); return ret; } 方法3、DTS注册 / { platform_device_test,test{ compatible = "dts_test"; #address-cells = <1>; #size-cells = <1>; reg = <0x500 0x32>,<0x200 0x32>; reg-names = "test mem1","resource2 MEM"; interrupt-parent = <&vic0>; interrupts = <IRQ_TIMER0>,<IRQ_TIMER1>; interrupt-names = "test irq1","resource4 IRQ"; }; }; 二、获取平台设备资源 核心接口 1 extern struct resource *platform_get_resource(struct platform_device *unsigned int,unsigned int); 2 extern int platform_get_irq(struct platform_device *,unsigned int); 3 extern struct resource *platform_get_resource_byname(struct platform_device *,unsigned int,const char *); 4 extern int platform_get_irq_byname(struct platform_device *,const char *); 代码示例 struct resource *presource; int irq = 0; printk(KERN_INFO"---------------------------n"); printk(KERN_INFO"%sn",__func__); printk(KERN_INFO"%sn",pdev->name); if(pdev->dev.platform_data) { printk(KERN_INFO"platform_data is %dn",*((int*)pdev->dev.platform_data)); } presource = platform_get_resource(pdev,IORESOURCE_MEM,0); if(!presource) { printk(KERN_INFO"get mem1 resource failedn"); return -1; } printk(KERN_INFO"resoure1 name %sn",presource->name); printk(KERN_INFO"resoure1 start 0x%08Xn",presource->start); printk(KERN_INFO"resoure1 end 0x%08Xn",presource->end); presource = NULL; presource = platform_get_resource_byname(pdev,"resource2 MEM"); if(!presource) { printk(KERN_INFO"get mem2 resource failedn"); return -1; } printk(KERN_INFO"resoure1 name %sn",presource->end); irq = platform_get_irq(pdev,0); if(irq < 0) { printk(KERN_INFO"get irq1 resource failedn"); return -1; } printk(KERN_INFO"irq1 value is %dn",irq); irq = 0; irq = platform_get_irq_byname(pdev,"resource4 IRQ"); if(irq < 0) { printk(KERN_INFO"get irq2 resource failedn"); return -1; } printk(KERN_INFO"irq2 value is %dn",irq); printk(KERN_INFO"---------------------------nnn"); 三、销毁设备 1 platform_device_unregister(&my_device); 2 platform_device_unregister(p_device_2); ?四、注册平台设备驱动 核心数据结构 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 (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; bool prevent_deferred_probe; }; 核心接口 platform_driver_register 代码示例 static struct platform_driver my_driver1 = { .driver = { .name = "xym-test-platform-device-1",.probe = my_platform_probe,.remove = my_platform_remove,.shutdown = my_platform_shutdown,.suspend = my_platform_suspend,.resume = my_platform_resume,}; ret = platform_driver_register(&my_driver1); if (ret) { printk(KERN_INFO"Unable to driver 1 register(%d)n",ret); return ret; } 其中,driver中的 ”.name“ 字段和device中的?”.name“ 相同,即可完成驱动和设备的匹配,即进入probe阶段。 结果输出 完整代码如下: #include <linux/init.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/ioport.h> static struct resource my_resoure1[]={ { .start = 0x00,}; static struct resource my_resoure2[]={ { .start = 0x21,}; static struct resource my_resoure3[]={ { .start = 0x41,}; static struct resource my_resoure4[]={ { .start = 0x61,}; static int platform_data_1 = 1; static int platform_data_2 = 2; static int platform_data_3 = 3; static int platform_data_4 = 4; static int my_platform_probe(struct platform_device * pdev) { struct resource *presource; int irq = 0; printk(KERN_INFO"---------------------------n"); printk(KERN_INFO"%sn",irq); printk(KERN_INFO"---------------------------nnn"); return 0; } static int my_platform_remove(struct platform_device * pdev) { printk(KERN_INFO"%sn",__func__); return 0; } static void my_platform_shutdown(struct platform_device *pdev) { printk(KERN_INFO"%sn",__func__); } static int my_platform_suspend(struct platform_device * pdev,pm_message_t state) { printk(KERN_INFO"%sn",__func__); return 0; } static int my_platform_resume(struct platform_device * pdev) { printk(KERN_INFO"%sn",__func__); return 0; } static void my_platform_device_release(struct device *dev) { printk(KERN_INFO"%sn",__func__); } static struct platform_device my_device1 = { .name = "xym-test-platform-device-1",}; struct platform_device * p_device_1 = &my_device1; static struct platform_driver my_driver1 = { .driver = { .name = "xym-test-platform-device-1",}; static struct platform_device_info my_device_2 = { .name = "xym-test-platform-device-2",}; struct platform_device * p_device_2; static struct platform_driver my_driver2 = { .driver = { .name = "xym-test-platform-device-2",.remove = my_platform_remove,.resume = my_platform_resume,}; struct platform_device * p_device_3; static struct platform_driver my_driver3 = { .driver = { .name = "xym-test-platform-device-3",}; struct platform_device * p_device_4; static struct platform_driver my_driver4 = { .driver = { .name = "xym-test-platform-device-4",}; static struct of_device_id oz1c007_match_table[] = { { .compatible = "dts_test"},}; static struct platform_driver my_driver5 = { .driver = { .name = "xym-test-platform-device-5",.of_match_table = oz1c007_match_table,.owner = THIS_MODULE,}; static int platform_device_init(void) { int ret = 0; printk(KERN_INFO"%sn",__func__); //device 1 ret = platform_device_register(&my_device1); if (ret) { printk(KERN_INFO"Unable to device 1 register(%d)n",ret); return ret; } ret = platform_driver_register(&my_driver1); if (ret) { printk(KERN_INFO"Unable to driver 1 register(%d)n",ret); return ret; } //device 2 p_device_2 = platform_device_register_full(&my_device_2); if (!p_device_2) { printk(KERN_INFO"Unable to device 2 registern"); return ret; } ret = platform_driver_register(&my_driver2); if (ret) { printk(KERN_INFO"Unable to driver 2 register(%d)n",ret); return ret; } //device 3 p_device_3 = platform_device_register_resndata(NULL,sizeof(platform_data_3)); if (!p_device_3) { printk(KERN_INFO"Unable to device 3 registern"); return ret; } ret = platform_driver_register(&my_driver3); if (ret) { printk(KERN_INFO"Unable to driver 4 register(%d)n",ret); return ret; } //device 4 p_device_4 = platform_device_register_simple("xym-test-platform-device-4",ARRAY_SIZE(my_resoure4)); if (!p_device_4) { printk(KERN_INFO"Unable to device 4 registern"); return ret; } platform_device_add_data(p_device_4,&platform_data_4,sizeof(platform_data_4)); ret = platform_driver_register(&my_driver4); if (ret) { printk(KERN_INFO"Unable to driver 4 register(%d)n",ret); return ret; } //device 5 dts ret = platform_driver_register(&my_driver5); if (ret) { printk(KERN_INFO"Unable to driver 5 register(%d)n",ret); return ret; } printk(KERN_INFO"---------------------------nnn"); return ret; } static void platform_device_destory(void) { printk(KERN_INFO"%sn",__func__); platform_device_unregister(p_device_1); platform_device_unregister(p_device_2); platform_device_unregister(p_device_3); platform_device_unregister(p_device_4); platform_driver_unregister(&my_driver1); platform_driver_unregister(&my_driver2); platform_driver_unregister(&my_driver3); platform_driver_unregister(&my_driver4); platform_driver_unregister(&my_driver5); } static int __init platform_test_init(void) { printk(KERN_INFO"Enter platform testnn"); platform_device_init(); return 0; } static void __exit platform_test_exit(void) { printk(KERN_INFO"Exit platform testn"); platform_device_destory(); } module_init(platform_test_init); module_exit(platform_test_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marvin.xin"); MODULE_DESCRIPTION("A Test Module for Platform driver"); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
热点阅读