bus_add_driver

 

int bus_add_driver(struct device_driver *drv)
{
 struct bus_type *bus;
 struct driver_private *priv;
 int error = 0;

//  获取 i2c 总线

 bus = bus_get(drv->bus);
 if (!bus)
  return -EINVAL;

 pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);

 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 if (!priv) {
  error = -ENOMEM;
  goto out_put_bus;
 }
 klist_init(&priv->klist_devices, NULL, NULL);

// 互指
 priv->driver = drv;
 drv->p = priv;

//设置此i2c 的kset
 priv->kobj.kset = bus->p->drivers_kset;

//设置 i2c 中kobj->name 为drv->name
 error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
         "%s", drv->name);
 if (error)
  goto out_unregister;

//' 用name 匹配设备,然后调用probe

 if (drv->bus->p->drivers_autoprobe) {
  error = driver_attach(drv);
  if (error)
   goto out_unregister;
 }
 klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
 module_add_driver(drv->owner, drv);

 error = driver_create_file(drv, &driver_attr_uevent);
 if (error) {
  printk(KERN_ERR "%s: uevent attr (%s) failed\n",
   __func__, drv->name);
 }
 error = driver_add_attrs(bus, drv);
 if (error) {
  /* How the hell do we get out of this pickle? Give up */
  printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
   __func__, drv->name);
 }

 if (!drv->suppress_bind_attrs) {
  error = add_bind_files(drv);
  if (error) {
   /* Ditto */
   printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
    __func__, drv->name);
  }
 }

 kobject_uevent(&priv->kobj, KOBJ_ADD);
 return 0;

out_unregister:
 kobject_put(&priv->kobj);
 kfree(drv->p);
 drv->p = NULL;
out_put_bus:
 bus_put(bus);
 return error;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值