resource: add release_child_resources
authorYinghai Lu <yinghai@kernel.org>
Tue, 22 Dec 2009 23:02:22 +0000 (15:02 -0800)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Tue, 23 Feb 2010 00:17:00 +0000 (16:17 -0800)
Useful for freeing a portion of the resource tree, e.g. when trying to
reallocate resources more efficiently.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
include/linux/ioport.h
kernel/resource.c

index 4a81189..dda9841 100644 (file)
@@ -112,6 +112,7 @@ extern struct resource iomem_resource;
 
 extern int request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
+void release_child_resources(struct resource *new);
 extern void reserve_region_with_split(struct resource *root,
                             resource_size_t start, resource_size_t end,
                             const char *name);
index 7fd123a..24e9e60 100644 (file)
@@ -188,6 +188,36 @@ static int __release_resource(struct resource *old)
        return -EINVAL;
 }
 
+static void __release_child_resources(struct resource *r)
+{
+       struct resource *tmp, *p;
+       resource_size_t size;
+
+       p = r->child;
+       r->child = NULL;
+       while (p) {
+               tmp = p;
+               p = p->sibling;
+
+               tmp->parent = NULL;
+               tmp->sibling = NULL;
+               __release_child_resources(tmp);
+
+               printk(KERN_DEBUG "release child resource %pR\n", tmp);
+               /* need to restore size, and keep flags */
+               size = resource_size(tmp);
+               tmp->start = 0;
+               tmp->end = size - 1;
+       }
+}
+
+void release_child_resources(struct resource *r)
+{
+       write_lock(&resource_lock);
+       __release_child_resources(r);
+       write_unlock(&resource_lock);
+}
+
 /**
  * request_resource - request and reserve an I/O or memory resource
  * @root: root resource descriptor