linux driver probe 调用时机

1、DTS树解析,创建platform 设备,调用platform_device_register ,驱动加载后会调用platform_driver_register,最终都会调用device_register,driver_register。

2、通过device_register,driver_register等关联起来。

(1)device_register

      device_register->bus_probe_devce->device_attach->_device_attach->driver_probe_device->really_probe->  bus_probe或者driver_probe

针对设备去关联遍历每个驱动。

int device_attach(struct device *dev)
413 { 
414     int ret = 0;
415 
416     device_lock(dev);
417     if (dev->driver) {
418         if (klist_node_attached(&dev->p->knode_driver)) {
419             ret = 1;
420             goto out_unlock;
421         }
422         ret = device_bind_driver(dev);
423         if (ret == 0)
424             ret = 1;
425         else {
426             dev->driver = NULL;
427             ret = 0;
428         }
429     } else {
430         ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
431         pm_request_idle(dev);
432     }
433 out_unlock:
434     device_unlock(dev);
435     return ret;
436 }

1 int driver_probe_device(struct device_driver *drv, struct device *dev)
372 {
373     int ret = 0;
374 
375     if (!device_is_registered(dev))
376         return -ENODEV;
377 
378     pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
379          drv->bus->name, __func__, dev_name(dev), drv->name);
380 
381     pm_runtime_barrier(dev);
382     ret = really_probe(dev, drv);
383     pm_request_idle(dev);
384 
385     return ret;
386 }

265 static int really_probe(struct device *dev, struct device_driver *drv)
266 {
267     int ret = 0;
268 
269     atomic_inc(&probe_count);
270     pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
271          drv->bus->name, __func__, drv->name, dev_name(dev));
272     WARN_ON(!list_empty(&dev->devres_head));
273 
274     dev->driver = drv;
275 
276     /* If using pinctrl, bind pins now before probing */
277     ret = pinctrl_bind_pins(dev);
278     if (ret)
279         goto probe_failed;
280 
281     if (driver_sysfs_add(dev)) {
282         printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
283             __func__, dev_name(dev));
284         goto probe_failed;
285     }
286 
287     if (dev->bus->probe) {
288         ret = dev->bus->probe(dev);
289         if (ret)
290             goto probe_failed;
291     } else if (drv->probe) {
292         ret = drv->probe(dev);
293         if (ret)
294             goto probe_failed;
295     }
296 
297     driver_bound(dev);


(2)driver_register 

      driver_register ->bus_add_driver->driver_attach->__driver_attach->driver_probe_device->really_probe  ->bus_probe或者driver_probe

如果要使用driver_poble, device_driver的probe需要提前被设置好。

如果要使用bus_probe,需要封装好并调用具体设备驱动的probe.

                                                                                                                                                                                          

9 static int __driver_attach(struct device *dev, void *data)
440 {
441     struct device_driver *drv = data;
442 
443     /*
444      * Lock device and try to bind to it. We drop the error
445      * here and always return 0, because we need to keep trying
446      * to bind to devices and some drivers will return an error
447      * simply if it didn't support the device.
448      *
449      * driver_probe_device() will spit a warning if there
450      * is an error.
451      */
452 
453     if (!driver_match_device(drv, dev))
454         return 0;
455 
456     if (dev->parent)    /* Needed for USB */
457         device_lock(dev->parent);
458     device_lock(dev);
459     if (!dev->driver)
460         driver_probe_device(drv, dev);
461     device_unlock(dev);
462     if (dev->parent)
463         device_unlock(dev->parent);
464 
465     return 0;
466 }

265 static int really_probe(struct device *dev, struct device_driver *drv)
266 {
267     int ret = 0;
268 
269     atomic_inc(&probe_count);
270     pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
271          drv->bus->name, __func__, drv->name, dev_name(dev));
272     WARN_ON(!list_empty(&dev->devres_head));
273 
274     dev->driver = drv;
275 
276     /* If using pinctrl, bind pins now before probing */
277     ret = pinctrl_bind_pins(dev);
278     if (ret)
279         goto probe_failed;
280 
281     if (driver_sysfs_add(dev)) {
282         printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
283             __func__, dev_name(dev));
284         goto probe_failed;
285     }
286 
287     if (dev->bus->probe) {
288         ret = dev->bus->probe(dev);
289         if (ret)
290             goto probe_failed;
291     } else if (drv->probe) {
292         ret = drv->probe(dev);
293         if (ret)
294             goto probe_failed;
295     }
296 
297     driver_bound(dev);

3、platform,amba 设备等等通过对也会设置driver参数,最终回调到具体设备的probe。

      bus probe 也会设置driver参数,最终回调到具体设备的probe。


总结,因此可分为

直接调用通过设置driver->probe 参数为具体设备驱动probe,从而可以调用到具体设备驱动的probe.

间接调用通过设置driver->probe参数为latform_probe或者amba_probe等等,,最终也回调到具体设备的probe.

通过bus->probe 调用具体设备的probe,如i2c设备驱动的probe,调用方法设置如下

9 struct bus_type i2c_bus_type = {
 470     .name       = "i2c",
 471     .match      = i2c_device_match,
 472     .probe      = i2c_device_probe,
 473     .remove     = i2c_device_remove,
 474     .shutdown   = i2c_device_shutdown,
 475     .pm     = &i2c_device_pm_ops,
 476 };

 static int i2c_device_probe(struct device *dev)
 260 {
 261     struct i2c_client   *client = i2c_verify_client(dev);
 262     struct i2c_driver   *driver;
 263     int status;
 264 
 265     if (!client)
 266         return 0;
 267 
 268     driver = to_i2c_driver(dev->driver);
 269     if (!driver->probe || !driver->id_table)
 270         return -ENODEV;
 271 
 272     if (!device_can_wakeup(&client->dev))
 273         device_init_wakeup(&client->dev,
 274                     client->flags & I2C_CLIENT_WAKE);
 275     dev_dbg(dev, "probe\n");
 276 
 277     acpi_dev_pm_attach(&client->dev, true);
 278     status <span style="color:#FF0000;">=driver->probe(client, i2c_match_id(driver->id_table, client));</span>
 279     if (status)





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值