void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr) { if (get_driver(drv)) { sysfs_remove_file(&drv->kobj, &attr->attr); put_driver(drv); } }
/** * driver_register - register driver with bus * @drv: driver to register * * We pass off most of the work to the bus_add_driver() call, * since most of the things we have to do deal with the bus * structures. */ int driver_register(struct device_driver *drv) { int ret; struct device_driver *other; if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) printk(KERN_WARNING "Driver '%s' needs updating - please use " "bus_type methods\n", drv->name); other = driver_find(drv->name, drv->bus); if (other) { put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); return -EEXIST; } ret = bus_add_driver(drv); if (ret) return ret; ret = driver_add_groups(drv, drv->groups); if (ret) bus_remove_driver(drv); return ret; }
/** * driver_register - register driver with bus * @drv: driver to register * * We pass off most of the work to the bus_add_driver() call, * since most of the things we have to do deal with the bus * structures. */ int driver_register(struct device_driver *drv) { int ret; struct device_driver *other; /* 在注册驱动前,必须为驱动指定了总线类型,并且该总线类型已经注册到Linux驱动模型 */ BUG_ON(!drv->bus->p); /* 如果总线类型和驱动都定义了相同名字的函数,将给出一条警告消息 */ if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) printk(KERN_WARNING "Driver '%s' needs updating - please use " "bus_type methods\n", drv->name); /* 在总线类型的驱动链表中查找该驱动名,如果找到,表明该驱动名已经在使用中,返回错误 */ other = driver_find(drv->name, drv->bus); if (other) { put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); return -EBUSY; } ret = bus_add_driver(drv); /* Add a driver to the bus. */ if (ret) return ret; ret = driver_add_groups(drv, drv->groups); if (ret) bus_remove_driver(drv); return ret; }
static void klist_drivers_put(struct klist_node *n) { struct device_driver *drv = container_of(n, struct device_driver, knode_bus); put_driver(drv); }
/*函数用来向系统注册一个驱动*/ int driver_register(struct device_driver *drv) { int ret; struct device_driver *other; BUG_ON(!drv->bus->p); if ((drv->bus->probe && drv->probe) || (drv->bus->remove && drv->remove) || (drv->bus->shutdown && drv->shutdown)) printk(KERN_WARNING "Driver '%s' needs updating - please use " "bus_type methods\n", drv->name); /*在drv->bus上查找当前要注册的drv,这主要是防止向系统重复注册同一个驱动*/ other = driver_find(drv->name, drv->bus); if (other) { put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); return -EBUSY; } /*进行实际的注册*/ ret = bus_add_driver(drv); if (ret) return ret; ret = driver_add_groups(drv, drv->groups); if (ret) bus_remove_driver(drv); return ret; }
int driver_create_file(struct device_driver * drv, struct driver_attribute * attr) { int error; if (get_driver(drv)) { error = sysfs_create_file(&drv->kobj, &attr->attr); put_driver(drv); } else error = -EINVAL; return error; }
/** * fimc_md_register_platform_entities - register FIMC and CSIS media entities */ static int fimc_md_register_platform_entities(struct fimc_md *fmd) { struct device_driver *driver; int ret; driver = driver_find(FIMC_MODULE_NAME, &platform_bus_type); if (!driver) return -ENODEV; ret = driver_for_each_device(driver, NULL, fmd, fimc_register_callback); put_driver(driver); if (ret) return ret; driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type); if (driver) { ret = driver_for_each_device(driver, NULL, fmd, csis_register_callback); put_driver(driver); } return ret; }
static void __exit cx18_alsa_exit(void) { struct device_driver *drv; int ret; printk(KERN_INFO "cx18-alsa: module unloading...\n"); drv = driver_find("cx18", &pci_bus_type); ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); put_driver(drv); cx18_ext_init = NULL; printk(KERN_INFO "cx18-alsa: module unload complete\n"); }
void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) { struct device *dev; /* We don't want ccwgroup devices to live longer than their driver. */ get_driver(&cdriver->driver); while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, __ccwgroup_match_all))) { __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); device_unregister(dev); put_device(dev); } put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); }
static struct exynos_md *flite_get_capture_md(enum mdev_node node) { struct device_driver *drv; struct exynos_md *md[MDEV_MAX_NUM] = {NULL,}; int ret; drv = driver_find(MDEV_MODULE_NAME, &platform_bus_type); if (!drv) return ERR_PTR(-ENODEV); ret = driver_for_each_device(drv, NULL, &md[0], flite_get_md_callback); put_driver(drv); return ret ? NULL : md[node]; }
static int phy_remove(struct device *dev) { struct phy_device *phydev; phydev = to_phy_device(dev); mutex_lock(&phydev->lock); phydev->state = PHY_DOWN; mutex_unlock(&phydev->lock); if (phydev->drv->remove) phydev->drv->remove(phydev); put_driver(dev->driver); phydev->drv = NULL; return 0; }
/** * ccwgroup_driver_unregister() - deregister a ccw group driver * @cdriver: driver to be deregistered * * This function is mainly a wrapper around driver_unregister(). */ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) { struct device *dev; /* We don't want ccwgroup devices to live longer than their driver. */ get_driver(&cdriver->driver); while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, __ccwgroup_match_all))) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); mutex_lock(&gdev->reg_mutex); __ccwgroup_remove_symlinks(gdev); device_unregister(dev); __ccwgroup_remove_cdev_refs(gdev); mutex_unlock(&gdev->reg_mutex); put_device(dev); } put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); }
/* * test_put_drv * make test call to put_driver which should * decrease the reference count to the kobject * pointer in the driver structure */ static int test_put_drv() { int a, rc; struct device_driver *drv = &test_driver; /* get reference count before test call */ a = atomic_read(&drv->kobj.refcount); /* make test call */ put_driver(drv); /* check reference count */ if ((a == (atomic_read(&drv->kobj.refcount) + 1) )) { rc = 0; printk("tbase: correctly set ref count put driver\n"); } else { rc = 1; printk("tbase: incorrect ref count put driver\n"); } return rc; }
/* * __device_release_driver() must be called with @dev->sem held. * When called for a USB interface, @dev->parent->sem must be held as well. */ static void __device_release_driver(struct device * dev) { struct device_driver * drv; drv = get_driver(dev->driver); if (drv) { driver_sysfs_remove(dev); sysfs_remove_link(&dev->kobj, "driver"); klist_remove(&dev->knode_driver); if (dev->bus) blocking_notifier_call_chain(&dev->bus->bus_notifier, BUS_NOTIFY_UNBIND_DRIVER, dev); if (dev->bus && dev->bus->remove) dev->bus->remove(dev); else if (drv->remove) drv->remove(dev); devres_release_all(dev); dev->driver = NULL; put_driver(drv); } }
static int msm_mctl_register_subdevs(struct msm_cam_media_controller *p_mctl, int core_index) { struct device_driver *driver; struct device *dev; int rc = -ENODEV; /* register csiphy subdev */ driver = driver_find(MSM_CSIPHY_DRV_NAME, &platform_bus_type); if (!driver) goto out; dev = driver_find_device(driver, NULL, (void *)core_index, msm_mctl_subdev_match_core); if (!dev) goto out_put_driver; p_mctl->csiphy_sdev = dev_get_drvdata(dev); put_driver(driver); /* register csid subdev */ driver = driver_find(MSM_CSID_DRV_NAME, &platform_bus_type); if (!driver) goto out; dev = driver_find_device(driver, NULL, (void *)core_index, msm_mctl_subdev_match_core); if (!dev) goto out_put_driver; p_mctl->csid_sdev = dev_get_drvdata(dev); put_driver(driver); /* register ispif subdev */ driver = driver_find(MSM_ISPIF_DRV_NAME, &platform_bus_type); if (!driver) goto out; dev = driver_find_device(driver, NULL, 0, msm_mctl_subdev_match_core); if (!dev) goto out_put_driver; p_mctl->ispif_sdev = dev_get_drvdata(dev); put_driver(driver); /* register vfe subdev */ driver = driver_find(MSM_VFE_DRV_NAME, &platform_bus_type); if (!driver) goto out; dev = driver_find_device(driver, NULL, 0, msm_mctl_subdev_match_core); if (!dev) goto out_put_driver; p_mctl->isp_sdev->sd = dev_get_drvdata(dev); put_driver(driver); /* register vfe subdev */ driver = driver_find(MSM_VPE_DRV_NAME, &platform_bus_type); if (!driver) goto out; dev = driver_find_device(driver, NULL, 0, msm_mctl_subdev_match_core); if (!dev) goto out_put_driver; p_mctl->isp_sdev->sd_vpe = dev_get_drvdata(dev); put_driver(driver); rc = 0; return rc; out_put_driver: put_driver(driver); out: return rc; }