summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2009-12-23 02:02:22 +0300
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-02-23 03:17:00 +0300
commit5eeec0ec931a01e85b3701ce121b7d8a1800ec60 (patch)
tree2efe474832b68a97c0460fc7f5e58a488f977dbb
parent7cc5997d1dada3bdeed95a59c2f4f6c66cbb0767 (diff)
downloadlinux-5eeec0ec931a01e85b3701ce121b7d8a1800ec60.tar.xz
resource: add release_child_resources
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>
-rw-r--r--include/linux/ioport.h1
-rw-r--r--kernel/resource.c30
2 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 4a811891dbe3..dda98410d588 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -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);
diff --git a/kernel/resource.c b/kernel/resource.c
index 7fd123ad00aa..24e9e60c1459 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -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