天天看點

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;

}

繼續閱讀