基于Linux 3.10.49内核的gpio步骤分析
发布时间:2021-12-07 16:07:30 所属栏目:教程 来源:互联网
导读:Linux kernel 3.10.49+ 在这里, 我们说说linux 是怎么通过platform_driver驱动代码匹配到platform_device的. static const struct of_device_id ***_gpio_of_match[] = { { .compatible = ******,***-gpio, }, // 这个字符串就是dts里的compatible字符串 {}
Linux kernel 3.10.49+ 在这里, 我们说说linux 是怎么通过platform_driver驱动代码匹配到platform_device的. static const struct of_device_id ***_gpio_of_match[] = { { .compatible = "******,***-gpio", }, // 这个字符串就是dts里的compatible字符串 {} }; MODULE_DEVICE_TABLE(of, ***_gpio_of_match); static struct platform_driver ***_gpio_driver = { .probe = ***_gpio_probe, // 匹配完成后, 运行的probe函数, 可以做一些初始化. .driver = { .name = "***_gpio", .owner = THIS_MODULE, .of_match_table = ***_gpio_of_match, }, }; module_platform_driver(***_gpio_driver); 1. drivers/gpio/gpio-***.c : module_platform_driver(***_gpio_driver); // gpio驱动入口 2. include/linux/platform_device.h 宏 : module_platform_driver #define module_platform_driver(__platform_driver) module_driver(__platform_driver, platform_driver_register, platform_driver_unregister) 3. drivers/base/platform.c : platform_driver_register(...) drv->driver.bus = &platform_bus_type; drv->driver.bus = &platform_bus_type; if (drv->probe) drv->driver.probe = platform_drv_probe; // 后面会使用. if (drv->remove) drv->driver.remove = platform_drv_remove; if (drv->shutdown) drv->driver.shutdown = platform_drv_shutdown; return driver_register(&drv->driver); 4. drivers/base/driver.c : driver_register(...) ... ret = bus_add_driver(drv); ... 5. drivers/base/bus.c : bus_add_driver(...) ... error = driver_attach(drv); ... 6. drivers/base/bus.c : driver_attach(...) int driver_attach(struct device_driver *drv) { return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); } 7. drivers/base/dd.c : bus_for_each_dev(...) ... klist_iter_init_node(&bus->p->klist_devices, &i, (start ? &start->p->knode_bus : NULL)); while ((dev = next_device(&i)) && !error) // 这个就是全局变量中, 所有已经进行过注册的device. // 在上一篇 基于Linux 3.10.49内核 从dts文件里注册platform_device流程分析 已介绍过 http://www.linuxidc.com/Linux/2017-10/147522.htm error = fn(dev, data); // fn 就是 __driver_attach 函数指针. 轮询device进行匹配. klist_iter_exit(&i); ... 8. drivers/base/dd.c : __driver_attach(...) ... if (!driver_match_device(drv, dev)) // 匹配成功, 返加非0, 否则返回0. // 跳到第8-1-1步 return 0; if (dev->parent) /* Needed for USB */ // 有父设备, 父设备也就加锁 device_lock(dev->parent); device_lock(dev); // 设备加锁 if (!dev->driver) // 如果device没有驱动程序, 就driver_probe_device driver_probe_device(drv, dev); // 跳到第8-2-1步 device_unlock(dev); // 设备释放锁 if (dev->parent) // 有父设备, 父设备也就释放锁 device_unlock(dev->parent); return 0 8-1-1. drivers/base/base.h : driver_match_device(...) static inline int driver_match_device(struct device_driver *drv, struct device *dev) { return drv->bus->match ? drv->bus->match(dev, drv) : 1; } // drv->bus 就是 第三步的 drv->driver.bus = &platform_bus_type; // 也就是相当于platform_bus_type->match(dev, drv); // struct bus_type platform_bus_type = { // drivers/base/platform.c // .name = "platform", // .dev_attrs = platform_dev_attrs, // .match = platform_match, // .uevent = platform_uevent, // .pm = &platform_dev_pm_ops, // }; // EXPORT_SYMBOL_GPL(platform_bus_type); // 也就是platform_match(dev, drv); 8-1-2. drivers/base/platform.c : platform_match(...) static int platform_match(struct device *dev, struct device_driver *drv) { ... if (of_driver_match_device(dev, drv)) return 1; ... } 8-1-3. include/linux/of_device.h : of_driver_match_device(...) static inline int of_driver_match_device(struct device *dev, const struct device_driver *drv) (编辑:宿州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐