diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-12-22 15:02:22 -0800 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-22 16:17:00 -0800 |
commit | 5eeec0ec931a01e85b3701ce121b7d8a1800ec60 (patch) | |
tree | 2efe474832b68a97c0460fc7f5e58a488f977dbb | |
parent | 7cc5997d1dada3bdeed95a59c2f4f6c66cbb0767 (diff) | |
download | linux-5eeec0ec931a01e85b3701ce121b7d8a1800ec60.tar.bz2 |
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.h | 1 | ||||
-rw-r--r-- | kernel/resource.c | 30 |
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 |