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);
	}
}
示例#2
0
/**
 * 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;
}
示例#3
0
/**
 * 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;
}
示例#4
0
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;
}
示例#7
0
/**
 * 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;
}
示例#8
0
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");
}
示例#9
0
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);
}
示例#10
0
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];

}
示例#11
0
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;
}
示例#12
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);
}
示例#13
0
/*
 * 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;
}
示例#14
0
文件: dd.c 项目: PennPanda/linux-repo
/*
 *	__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);
	}
}
示例#15
0
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;
}