platform match 和probe

int platform_driver_register(struct platform_driver *drv)
{
     drv->driver.bus = &platform_bus_type;
     if (drv->probe)
     drv->driver.probe = platform_drv_probe;
     if (drv->remove)
     drv->driver.remove = platform_drv_remove;
     if (drv->shutdown)
     drv->driver.shutdown = platform_drv_shutdown;

     return driver_register(&drv->driver);
}

 

int driver_register(struct device_driver *drv)
{

     ......

     other = driver_find(drv->name, drv->bus);//查找驱动是否注册
     .........

       ret = bus_add_driver(drv);//添加驱动

    ..........
}

 

int bus_add_driver(struct device_driver *drv)
{

          ................

         if (drv->bus->p->drivers_autoprobe) {
              error = driver_attach(drv);
              if (error)
              goto out_unregister;
        }

        ............

}

int driver_attach(struct device_driver *drv)
{
           return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

 

int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device *, void *))
{
     error = fn(dev, data);
}

 

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

      if (!driver_match_device(drv, dev))
           return 0;

      if (dev->parent) /* Needed for USB */
      device_lock(dev->parent);
      device_lock(dev);
      if (!dev->driver)
      driver_probe_device(drv, dev);
      device_unlock(dev);
      if (dev->parent)
      device_unlock(dev->parent);

     return 0;
}

 

static inline int driver_match_device(struct device_driver *drv,struct device *dev)
{
       return drv->bus->match ? drv->bus->match(dev, drv) : 1;//这里调用的正是platform总线实现的match函数
}

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

     if (!device_is_registered(dev))
         return -ENODEV;

     pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
    drv->bus->name, __func__, dev_name(dev), drv->name);

     pm_runtime_get_noresume(dev);
     pm_runtime_barrier(dev);
     ret = really_probe(dev, drv);
     pm_runtime_put_sync(dev);

    return ret;
}


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_name(dev));
    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_name(dev));
    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);
        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_name(dev), 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_name(dev), ret);
    }
    ret = 0;
  done:
     atomic_dec(&probe_count);
    wake_up(&probe_waitqueue);
    return ret;
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值