diff options
Diffstat (limited to 'drivers/base/attribute_container.c')
| -rw-r--r-- | drivers/base/attribute_container.c | 38 | 
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index ec615d854be..62c093db11e 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -58,6 +58,7 @@ attribute_container_register(struct attribute_container *cont)  {  	INIT_LIST_HEAD(&cont->node);  	INIT_LIST_HEAD(&cont->containers); +	spin_lock_init(&cont->containers_lock);  	down(&attribute_container_mutex);  	list_add_tail(&cont->node, &attribute_container_list); @@ -77,11 +78,13 @@ attribute_container_unregister(struct attribute_container *cont)  {  	int retval = -EBUSY;  	down(&attribute_container_mutex); +	spin_lock(&cont->containers_lock);  	if (!list_empty(&cont->containers))  		goto out;  	retval = 0;  	list_del(&cont->node);   out: +	spin_unlock(&cont->containers_lock);  	up(&attribute_container_mutex);  	return retval; @@ -151,7 +154,9 @@ attribute_container_add_device(struct device *dev,  			fn(cont, dev, &ic->classdev);  		else  			attribute_container_add_class_device(&ic->classdev); +		spin_lock(&cont->containers_lock);  		list_add_tail(&ic->node, &cont->containers); +		spin_unlock(&cont->containers_lock);  	}  	up(&attribute_container_mutex);  } @@ -189,6 +194,7 @@ attribute_container_remove_device(struct device *dev,  		if (!cont->match(cont, dev))  			continue; +		spin_lock(&cont->containers_lock);  		list_for_each_entry_safe(ic, tmp, &cont->containers, node) {  			if (dev != ic->classdev.dev)  				continue; @@ -200,6 +206,7 @@ attribute_container_remove_device(struct device *dev,  				class_device_unregister(&ic->classdev);  			}  		} +		spin_unlock(&cont->containers_lock);  	}  	up(&attribute_container_mutex);  } @@ -230,10 +237,12 @@ attribute_container_device_trigger(struct device *dev,  		if (!cont->match(cont, dev))  			continue; +		spin_lock(&cont->containers_lock);  		list_for_each_entry_safe(ic, tmp, &cont->containers, node) {  			if (dev == ic->classdev.dev)  				fn(cont, dev, &ic->classdev);  		} +		spin_unlock(&cont->containers_lock);  	}  	up(&attribute_container_mutex);  } @@ -368,6 +377,35 @@ attribute_container_class_device_del(struct class_device *classdev)  }  EXPORT_SYMBOL_GPL(attribute_container_class_device_del); +/** + * attribute_container_find_class_device - find the corresponding class_device + * + * @cont:	the container + * @dev:	the generic device + * + * Looks up the device in the container's list of class devices and returns + * the corresponding class_device. + */ +struct class_device * +attribute_container_find_class_device(struct attribute_container *cont, +				      struct device *dev) +{ +	struct class_device *cdev = NULL; +	struct internal_container *ic; + +	spin_lock(&cont->containers_lock); +	list_for_each_entry(ic, &cont->containers, node) { +		if (ic->classdev.dev == dev) { +			cdev = &ic->classdev; +			break; +		} +	} +	spin_unlock(&cont->containers_lock); + +	return cdev; +} +EXPORT_SYMBOL_GPL(attribute_container_find_class_device); +  int __init  attribute_container_init(void)  {  |