summaryrefslogtreecommitdiffstats
path: root/include/linux/device.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/device.h')
-rw-r--r--include/linux/device.h50
1 files changed, 49 insertions, 1 deletions
diff --git a/include/linux/device.h b/include/linux/device.h
index f44247fe813..26e4692f2d1 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -126,6 +126,7 @@ struct device_driver {
struct klist_node knode_bus;
struct module * owner;
+ const char * mod_name; /* used for built-in modules */
int (*probe) (struct device * dev);
int (*remove) (struct device * dev);
@@ -327,6 +328,13 @@ extern struct class_device *class_device_create(struct class *cls,
__attribute__((format(printf,5,6)));
extern void class_device_destroy(struct class *cls, dev_t devt);
+struct device_type {
+ struct device_attribute *attrs;
+ int (*uevent)(struct device *dev, char **envp, int num_envp,
+ char *buffer, int buffer_size);
+ void (*release)(struct device *dev);
+};
+
/* interface for exporting device attributes */
struct device_attribute {
struct attribute attr;
@@ -346,6 +354,41 @@ extern int __must_check device_create_bin_file(struct device *dev,
struct bin_attribute *attr);
extern void device_remove_bin_file(struct device *dev,
struct bin_attribute *attr);
+
+/* device resource management */
+typedef void (*dr_release_t)(struct device *dev, void *res);
+typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
+
+#ifdef CONFIG_DEBUG_DEVRES
+extern void * __devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
+ const char *name);
+#define devres_alloc(release, size, gfp) \
+ __devres_alloc(release, size, gfp, #release)
+#else
+extern void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp);
+#endif
+extern void devres_free(void *res);
+extern void devres_add(struct device *dev, void *res);
+extern void * devres_find(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data);
+extern void * devres_get(struct device *dev, void *new_res,
+ dr_match_t match, void *match_data);
+extern void * devres_remove(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data);
+extern int devres_destroy(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data);
+
+/* devres group */
+extern void * __must_check devres_open_group(struct device *dev, void *id,
+ gfp_t gfp);
+extern void devres_close_group(struct device *dev, void *id);
+extern void devres_remove_group(struct device *dev, void *id);
+extern int devres_release_group(struct device *dev, void *id);
+
+/* managed kzalloc/kfree for device drivers, no kmalloc, always use kzalloc */
+extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
+extern void devm_kfree(struct device *dev, void *p);
+
struct device {
struct klist klist_children;
struct klist_node knode_parent; /* node in sibling list */
@@ -355,6 +398,7 @@ struct device {
struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
+ struct device_type *type;
unsigned is_registered:1;
struct device_attribute uevent_attr;
struct device_attribute *devt_attr;
@@ -388,11 +432,15 @@ struct device {
/* arch specific additions */
struct dev_archdata archdata;
+ spinlock_t devres_lock;
+ struct list_head devres_head;
+
/* class_device migration path */
struct list_head node;
- struct class *class; /* optional*/
+ struct class *class;
dev_t devt; /* dev_t, creates the sysfs "dev" */
struct attribute_group **groups; /* optional groups */
+ int uevent_suppress;
void (*release)(struct device * dev);
};