summaryrefslogtreecommitdiff
path: root/include/linux/device.h
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-01-20 10:00:26 +0300
committerJeff Garzik <jeff@garzik.org>2007-02-10 01:39:36 +0300
commit9ac7849e35f705830f7b016ff272b0ff1f7ff759 (patch)
tree7f17cdff87e154937a15cc2ec8da9b4e6018ce8e /include/linux/device.h
parent77a527eadb425b60db3f5f0aae6a4c51c38e35e5 (diff)
downloadlinux-9ac7849e35f705830f7b016ff272b0ff1f7ff759.tar.xz
devres: device resource management
Implement device resource management, in short, devres. A device driver can allocate arbirary size of devres data which is associated with a release function. On driver detach, release function is invoked on the devres data, then, devres data is freed. devreses are typed by associated release functions. Some devreses are better represented by single instance of the type while others need multiple instances sharing the same release function. Both usages are supported. devreses can be grouped using devres group such that a device driver can easily release acquired resources halfway through initialization or selectively release resources (e.g. resources for port 1 out of 4 ports). This patch adds devres core including documentation and the following managed interfaces. * alloc/free : devm_kzalloc(), devm_kzfree() * IO region : devm_request_region(), devm_release_region() * IRQ : devm_request_irq(), devm_free_irq() * DMA : dmam_alloc_coherent(), dmam_free_coherent(), dmam_declare_coherent_memory(), dmam_pool_create(), dmam_pool_destroy() * PCI : pcim_enable_device(), pcim_pin_device(), pci_is_managed() * iomap : devm_ioport_map(), devm_ioport_unmap(), devm_ioremap(), devm_ioremap_nocache(), devm_iounmap(), pcim_iomap_table(), pcim_iomap(), pcim_iounmap() Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'include/linux/device.h')
-rw-r--r--include/linux/device.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/include/linux/device.h b/include/linux/device.h
index 5ca1cdba563a..26e4692f2d1a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -354,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 */
@@ -397,6 +432,9 @@ 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;