platform driver and device学习笔记
2014-03-06 23:30
375 查看
-v0.1 2014.3.4 *** 以gpio驱动为中心,整理设备模型和设备树, 只是整理了gpio
驱动的注册过程, gpio的驱动见driver/gpio/gpio-mxc.c
1. 顺序整理device建立,driver和device结合的过程
设备要先写在device tree中,kernel在启动阶段先解析dtb中的信息(dtb由dts编译得来),
解析得到的信息先以device_node组成的结构保存,在启动的do_initcall()函数中再使用该
信息向系统中注册设备,随后驱动程序和设备联系在一起,整个过程完成
从dtb中解析信息:unflatten_device_tree()
向系统中注册设备:
v2m.c中的v2m_dt_init()函数
向系统注册, 可见device_driver中已经有了bus的信息,在driver_register中就可以把
本driver向它对应的bus注册,在driver向bus注册的时候会和device做匹配
同样的道理,也可以在注册设备的时候实现设备和驱动的绑定:
驱动的注册过程, gpio的驱动见driver/gpio/gpio-mxc.c
1. 顺序整理device建立,driver和device结合的过程
设备要先写在device tree中,kernel在启动阶段先解析dtb中的信息(dtb由dts编译得来),解析得到的信息先以device_node组成的结构保存,在启动的do_initcall()函数中再使用该
信息向系统中注册设备,随后驱动程序和设备联系在一起,整个过程完成
从dtb中解析信息:unflatten_device_tree()
向系统中注册设备:
start_kernel() -->rest_init(); kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); -->kernel_init(); // 在1号线程中执行的函数 -->kernel_init_freeable(); -->do_basic_setup(); -->driver_init(); //初始化sys文件系统的顶层文件 do_initcalls(); -->do_initcall_level(level);do_initcall_level(level)会调用各级的初始化函数,其中就会调用到:
v2m.c中的v2m_dt_init()函数
DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") .dt_compat = v2m_dt_match, .smp = smp_ops(***_smp_ops), .smp_init = smp_init_ops(***_smp_init_ops), .map_io = v2m_dt_map_io, .init_early = v2m_dt_init_early, .init_time = v2m_dt_timer_init, .init_machine = v2m_dt_init, MACHINE_END调用v2m_dt_init()函数其实是因为调用了.init_machine
static void __init v2m_dt_init(void) { l2x0_of_init(0x00400000, 0xfe0fffff); #ifndef CONFIG_ARCH_*** of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL); #else of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); #endif }接着往下走
of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL); -->of_platform_bus_create(child, matches, lookup, parent, true); -->of_platform_device_create_pdata(bus, bus_id, platform_data, parent); //上面创建struct platform_device -->of_device_alloc(np, bus_id, parent); -->platform_device_alloc("", -1); -->device_initialize(&pa->pdev.dev); //初始化设备 pa->pdev.dev.release = platform_device_release; arch_setup_pdev_archdata(&pa->pdev); ... -->of_device_alloc() end! of_device_add(dev); -->device_add(&ofdev->dev); 接第3部分的device_add()之后的内容
2. 从gpio的驱动入手
可以分析下kernel中drivers/gpio/gpio-mxc.c的代码,其中的核心数据结构是platform_driverstruct 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;-->|-->*name, *bus.. |-->callbacks: *probe,*remove,*shutdown | *sudpend,*resume |-->struct attribute_group **groups |-->struct driver_private *p |-->struct of_device_if *of_match_table |... | |-->const struct platform_device_id *id_table;
platform_driver_register(&***_gpio_driver); -->__platform_driver_register(drv, THIS_MODULE) //宏 drv->driver.owner = owner; drv->driver.bus = &platform_bus_type; drv->driver.probe = platform_drv_probe; drv->driver.remove = platform_drv_remove; drv->driver.shutdown = platform_drv_shutdown; driver_register(&drv->driver);以上的代码填充了platform_driver中的device_driver中的回调函数,并把device_driver
向系统注册, 可见device_driver中已经有了bus的信息,在driver_register中就可以把
本driver向它对应的bus注册,在driver向bus注册的时候会和device做匹配
3. 怎么调用到probe函数,实现device和driver的绑定
上面gpio-mxc.c代码中的核心是mxc_gpio_probe函数driver_register() -->bus_add_driver(drv); -->driver_attach(drv);
__driver_attach(struct device *dev, void *data) //上个函数中的回调函数 -->driver_probe_device(drv, dev); -->really_probe(dev, drv); // struct device_driver *drv -->drv->probe(dev); // platform_drv_probe
platform_drv_probe(_dev); // struct device *_dev -->drv->probe(dev);// struct platform_device *dev
由此可见整个probe的目的就是把platform_device *dev找见传给probe函数,这样可以把驱动和设备绑定
同样的道理,也可以在注册设备的时候实现设备和驱动的绑定:
platform_device_register(struct platform_device *pdev) -->platform_device_add(pdev); -->device_add(&pdev->dev); -->bus_probe_device(dev); -->device_attach(dev); -->bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
__device_attach() -->driver_probe_device(drv, dev); ... 余下和上面相同
相关文章推荐
- MSDN Kernel-Mode Driver Architecture学习笔记(3)——Device Objects and Device Stacks (4)
- smmu学习笔记之device的platform_data和driver_data
- MSDN Kernel-Mode Driver Architecture学习笔记(3)——Device Objects and Device Stacks (3)
- MSDN Kernel-Mode Driver Architecture学习笔记(3)——Device Objects and Device Stacks (2)
- MSDN Kernel-Mode Driver Architecture学习笔记(3)——Device Objects and Device Stacks (1)
- Samsung_tiny4412(驱动笔记10)----mdev,bus,device,driver,platform
- Linux Platform Device and Driver,platform_add_devices()->platform_driver_register()
- Linux Platform Device and Driver
- Linux Platform Device and Driver
- linux平台设备驱动架构详解 Linux Platform Device and Driver
- Linux Platform Device and Driver,platform_add_devices()->platform_driver_register()
- 【驱动学习】Essential Linux Device Driver学习笔记(一)
- Linux Platform Device and Driver的注册过程解析
- Linux Platform Device and Driver
- Linux Platform Device and Driver
- Linux Platform Device and Driver
- Linux Platform Device and Driver
- 操作系统_再识(Linux Platform Device and Driver)
- Linux Platform Device and Driver
- Linux Platform Device and Driver,platform_add_devices()->platform_driver_register()