天天看点

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

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

   platform_add_devices(ldd6410_devices, ARRAY_SIZE(ldd6410_devices));  //这是bsp中添加所有的设备--》 platform_device_register(devs[i]);//注册平台设备---》platform_device_add(pdev);将平台设备加入到platform_bus中---》device_add(&pdev->dev);

下面是驱动

static int __init gpio_led_init(void)

{

 return platform_driver_register(&gpio_led_driver);   //注册平台驱动

}

platform_driver_register(&gpio_led_driver) ----》driver_register(&drv->driver);----》bus_add_driver(drv); //添加驱动到总线 ---》driver_attach(drv);//为驱动寻找相应的设备----》

int driver_attach(struct device_driver *drv)

{

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

}

-----》__driver_attach()

static int __driver_attach(struct device *dev, void *data)

{

 struct device_driver *drv = data;

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

  return 0;

 if (dev->parent) 

  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;

 }

 driver_bound(dev);

 ret = 1;

 pr_debug("bus: '%s': %s: bound device %s to driver %s\n",

   drv->bus->name, __func__, dev->bus_id, drv->name);

 goto done;

probe_failed:

 devres_release_all(dev);

 driver_sysfs_remove(dev);

 dev->driver = NULL;

 if (ret != -ENODEV && ret != -ENXIO) {

  printk(KERN_WARNING

         "%s: probe of %s failed with error %d\n",

         drv->name, dev->bus_id, ret);

 }

 ret = 0;

done:

 atomic_dec(&probe_count);

 wake_up(&probe_waitqueue);

 return ret;

}

继续阅读