platform驱动的probe过程

这篇博客详细解析了Linux平台驱动模型中probe函数的调用过程,从总线注册、设备添加到驱动注册的步骤。在设备驱动绑定过程中,通过driver_match_device和driver_probe_device函数实现驱动与设备的匹配和调用驱动的probe函数,确保设备正确工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

probe()函数是什么时候被调用,设备和驱动是怎么联系起来的??

1 总线注册阶段:

内核启动初始化时,main.c文件中platform平台初始化的路径:

                kernel_init()

                   -->do_basic_setup()

                        -->driver_init()

                              -->platform_bus_init()

                                   -->bus_register(&platform_bus_type),注册了一条platform总线(虚拟总线)。

2 添加设备时:

设备注册的时候(对于展讯8830 设备的在kernel/arch/arm/mach-sc/Board_sp8830ec.c中的sc8830_init_machine()中有platform_add_devices(devices,ARRAY_SIZE(devices)))注册的。
其中devices是platform_device类型的数组。

platform_add_devices(devices,ARRAY_SIZE(devices))//这是bsp中添加所有的设备

                   --》 platform_device_register(devs[i]);//注册平台设备

                    ---》platform_device_add(pdev);将平台设备加入到platform_bus中

                         ---》device_add(&pdev->dev);,就这样把设备给挂到虚拟的总线上。
                      


                
3 驱动注册时:

               Platform_driver_register()//注册平台驱动

                   -->driver_register()

                         -->bus_add_driver()//添加驱动到总线

                               -->driver_attach()//为驱动寻找相应的设备

                                      -->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);//遍历设备总线寻找驱动                            

                                                                                            -----》__driver_attach()//通过match判断驱动和设备是否匹配,这里通过比较dev和drv中的设备名来判断,所以设备名需要唯一
                                                                                            
                                                                                                        -->driver_probe_device(drv, dev);  //   驱动和设备绑定
                                                                                                        
                                                                                                        
从上面可以看出,platform机制最后还是调用了bus_register(), device_add() ,driver_register()这三个关键的函数。    
                                                                                    

static int __driver_attach(struct device *dev, void *data)
{
 struct device_driver *drv = data;

 /*
  * Lock device and try to bind to it. We drop the error
  * here and always return 0, because we need to keep trying
  * to bind to devices and some drivers will return an error
  * simply if it didn't support the device.
  *
  * driver_probe_device() will spit a warning if there
  * is an error.
  */

 if (drv->bus->match && !drv->bus->match(dev, drv))   //通过match判断驱动和设备是否匹配,这里通过比较dev和drv中的设备名来判断,所以设备名需要唯一
  return 0;

 if (dev->parent) /* Needed for USB */
  down(&dev->parent->sem);
 down(&dev->sem);
 if (!dev->driver)
  driver_probe_device(drv, dev);  //   驱动和设备绑定
 up(&dev->sem);
 if (dev->parent)
  up(&dev->parent->sem);

 return 0;
}

driver_probe_device(drv, dev);  ---》really_probe(dev, drv);

static int really_probe(struct device *dev, struct device_driver *drv)
{
 int ret = 0;

 atomic_inc(&probe_count);
 pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
   drv->bus->name, __func__, drv->name, dev->bus_id);
 WARN_ON(!list_empty(&dev->devres_head));

 dev->driver = drv;
 if (driver_sysfs_add(dev)) {
  printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
   __func__, dev->bus_id);
  goto probe_failed;
 }

 if (dev->bus->probe) {   
  ret = dev->bus->probe(dev);
  if (ret)
   goto probe_failed;
 } else if (drv->probe) {
  ret = drv->probe(dev);  //这里才真正调用了驱动的probe
  if (ret)
   goto probe_failed;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值