#include <linux/slab.h>
#include <linux/list.h>
#include <linux/module.h>
+#include <linux/mutex.h>
+
+#include "base.h"
/* This is a private structure used to tie the classdev and the
* container .. it should never be visible outside this file */
struct class_device classdev;
};
+static void internal_container_klist_get(struct klist_node *n)
+{
+ struct internal_container *ic =
+ container_of(n, struct internal_container, node);
+ class_device_get(&ic->classdev);
+}
+
+static void internal_container_klist_put(struct klist_node *n)
+{
+ struct internal_container *ic =
+ container_of(n, struct internal_container, node);
+ class_device_put(&ic->classdev);
+}
+
+
/**
* attribute_container_classdev_to_container - given a classdev, return the container
*
static struct list_head attribute_container_list;
-static DECLARE_MUTEX(attribute_container_mutex);
+static DEFINE_MUTEX(attribute_container_mutex);
/**
* attribute_container_register - register an attribute container
attribute_container_register(struct attribute_container *cont)
{
INIT_LIST_HEAD(&cont->node);
- klist_init(&cont->containers);
+ klist_init(&cont->containers,internal_container_klist_get,
+ internal_container_klist_put);
- down(&attribute_container_mutex);
+ mutex_lock(&attribute_container_mutex);
list_add_tail(&cont->node, &attribute_container_list);
- up(&attribute_container_mutex);
+ mutex_unlock(&attribute_container_mutex);
return 0;
}
attribute_container_unregister(struct attribute_container *cont)
{
int retval = -EBUSY;
- down(&attribute_container_mutex);
+ mutex_lock(&attribute_container_mutex);
spin_lock(&cont->containers.k_lock);
if (!list_empty(&cont->containers.k_list))
goto out;
list_del(&cont->node);
out:
spin_unlock(&cont->containers.k_lock);
- up(&attribute_container_mutex);
+ mutex_unlock(&attribute_container_mutex);
return retval;
}
{
struct attribute_container *cont;
- down(&attribute_container_mutex);
+ mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
if (!cont->match(cont, dev))
continue;
- ic = kmalloc(sizeof(struct internal_container), GFP_KERNEL);
+
+ ic = kzalloc(sizeof(*ic), GFP_KERNEL);
if (!ic) {
dev_printk(KERN_ERR, dev, "failed to allocate class container\n");
continue;
}
- memset(ic, 0, sizeof(struct internal_container));
+
ic->cont = cont;
class_device_initialize(&ic->classdev);
ic->classdev.dev = get_device(dev);
attribute_container_add_class_device(&ic->classdev);
klist_add_tail(&ic->node, &cont->containers);
}
- up(&attribute_container_mutex);
+ mutex_unlock(&attribute_container_mutex);
}
/* FIXME: can't break out of this unless klist_iter_exit is also
#define klist_for_each_entry(pos, head, member, iter) \
for (klist_iter_init(head, iter); (pos = ({ \
struct klist_node *n = klist_next(iter); \
- n ? ({ klist_iter_exit(iter) ; NULL; }) : \
- container_of(n, typeof(*pos), member);\
+ n ? container_of(n, typeof(*pos), member) : \
+ ({ klist_iter_exit(iter) ; NULL; }); \
}) ) != NULL; )
{
struct attribute_container *cont;
- down(&attribute_container_mutex);
+ mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
struct klist_iter iter;
klist_for_each_entry(ic, &cont->containers, node, &iter) {
if (dev != ic->classdev.dev)
continue;
- klist_remove(&ic->node);
+ klist_del(&ic->node);
if (fn)
fn(cont, dev, &ic->classdev);
else {
}
}
}
- up(&attribute_container_mutex);
+ mutex_unlock(&attribute_container_mutex);
}
-EXPORT_SYMBOL_GPL(attribute_container_remove_device);
/**
* attribute_container_device_trigger - execute a trigger for each matching classdev
{
struct attribute_container *cont;
- down(&attribute_container_mutex);
+ mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
struct klist_iter iter;
fn(cont, dev, &ic->classdev);
}
}
- up(&attribute_container_mutex);
+ mutex_unlock(&attribute_container_mutex);
}
-EXPORT_SYMBOL_GPL(attribute_container_device_trigger);
/**
* attribute_container_trigger - trigger a function for each matching container
{
struct attribute_container *cont;
- down(&attribute_container_mutex);
+ mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
if (cont->match(cont, dev))
fn(cont, dev);
}
- up(&attribute_container_mutex);
+ mutex_unlock(&attribute_container_mutex);
}
-EXPORT_SYMBOL_GPL(attribute_container_trigger);
/**
* attribute_container_add_attrs - add attributes
return 0;
}
-EXPORT_SYMBOL_GPL(attribute_container_add_attrs);
/**
* attribute_container_add_class_device - same function as class_device_add
return error;
return attribute_container_add_attrs(classdev);
}
-EXPORT_SYMBOL_GPL(attribute_container_add_class_device);
/**
* attribute_container_add_class_device_adapter - simple adapter for triggers
{
return attribute_container_add_class_device(classdev);
}
-EXPORT_SYMBOL_GPL(attribute_container_add_class_device_adapter);
/**
* attribute_container_remove_attrs - remove any attribute files
for (i = 0; attrs[i]; i++)
class_device_remove_file(classdev, attrs[i]);
}
-EXPORT_SYMBOL_GPL(attribute_container_remove_attrs);
/**
* attribute_container_class_device_del - equivalent of class_device_del
attribute_container_remove_attrs(classdev);
class_device_del(classdev);
}
-EXPORT_SYMBOL_GPL(attribute_container_class_device_del);
/**
* attribute_container_find_class_device - find the corresponding class_device