diff options
Diffstat (limited to 'drivers/base/core.c')
| -rw-r--r-- | drivers/base/core.c | 38 | 
1 files changed, 24 insertions, 14 deletions
| diff --git a/drivers/base/core.c b/drivers/base/core.c index fd034d742447..7bb957b11861 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -485,8 +485,7 @@ static void device_link_release_fn(struct work_struct *work)  	/* Ensure that all references to the link object have been dropped. */  	device_link_synchronize_removal(); -	while (refcount_dec_not_one(&link->rpm_active)) -		pm_runtime_put(link->supplier); +	pm_runtime_release_supplier(link, true);  	put_device(link->consumer);  	put_device(link->supplier); @@ -2261,9 +2260,9 @@ static struct kobj_type device_ktype = {  }; -static int dev_uevent_filter(struct kset *kset, struct kobject *kobj) +static int dev_uevent_filter(struct kobject *kobj)  { -	struct kobj_type *ktype = get_ktype(kobj); +	const struct kobj_type *ktype = get_ktype(kobj);  	if (ktype == &device_ktype) {  		struct device *dev = kobj_to_dev(kobj); @@ -2275,7 +2274,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)  	return 0;  } -static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj) +static const char *dev_uevent_name(struct kobject *kobj)  {  	struct device *dev = kobj_to_dev(kobj); @@ -2286,8 +2285,7 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)  	return NULL;  } -static int dev_uevent(struct kset *kset, struct kobject *kobj, -		      struct kobj_uevent_env *env) +static int dev_uevent(struct kobject *kobj, struct kobj_uevent_env *env)  {  	struct device *dev = kobj_to_dev(kobj);  	int retval = 0; @@ -2382,7 +2380,7 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,  	/* respect filter */  	if (kset->uevent_ops && kset->uevent_ops->filter) -		if (!kset->uevent_ops->filter(kset, &dev->kobj)) +		if (!kset->uevent_ops->filter(&dev->kobj))  			goto out;  	env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); @@ -2390,7 +2388,7 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,  		return -ENOMEM;  	/* let the kset specific function add its keys */ -	retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); +	retval = kset->uevent_ops->uevent(&dev->kobj, env);  	if (retval)  		goto out; @@ -2874,10 +2872,6 @@ void device_initialize(struct device *dev)  	INIT_LIST_HEAD(&dev->devres_head);  	device_pm_init(dev);  	set_dev_node(dev, NUMA_NO_NODE); -#ifdef CONFIG_GENERIC_MSI_IRQ -	raw_spin_lock_init(&dev->msi_lock); -	INIT_LIST_HEAD(&dev->msi_list); -#endif  	INIT_LIST_HEAD(&dev->links.consumers);  	INIT_LIST_HEAD(&dev->links.suppliers);  	INIT_LIST_HEAD(&dev->links.defer_sync); @@ -3029,6 +3023,23 @@ static inline struct kobject *get_glue_dir(struct device *dev)  	return dev->kobj.parent;  } +/** + * kobject_has_children - Returns whether a kobject has children. + * @kobj: the object to test + * + * This will return whether a kobject has other kobjects as children. + * + * It does NOT account for the presence of attribute files, only sub + * directories. It also assumes there is no concurrent addition or + * removal of such children, and thus relies on external locking. + */ +static inline bool kobject_has_children(struct kobject *kobj) +{ +	WARN_ON_ONCE(kref_read(&kobj->kref) == 0); + +	return kobj->sd && kobj->sd->dir.subdirs; +} +  /*   * make sure cleaning up dir as the last step, we need to make   * sure .release handler of kobject is run with holding the @@ -3582,7 +3593,6 @@ void device_del(struct device *dev)  	device_pm_remove(dev);  	driver_deferred_probe_del(dev);  	device_platform_notify_remove(dev); -	device_remove_properties(dev);  	device_links_purge(dev);  	if (dev->bus) |