Patchwork [-v12,03/15] resources: Replace registered resource in tree.

login
register
mail settings
Submitter Yinghai Lu
Date June 26, 2012, 6:53 p.m.
Message ID <1340736849-14875-4-git-send-email-yinghai@kernel.org>
Download mbox | patch
Permalink /patch/167451/
State Rejected
Headers show

Comments

Yinghai Lu - June 26, 2012, 6:53 p.m.
We could have one resource inserted in tree at first during probing.

Later we need to put real resource into the tree.

So try to hold the lock to swap them.

-v2: make it more generic to handle old one with children or no parent.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
---
 include/linux/ioport.h |    1 +
 kernel/resource.c      |   25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

Patch

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 8292e8b..cbf3480 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -163,6 +163,7 @@  int probe_resource(struct resource *b_res,
 			struct resource *busn_res,
 			resource_size_t needed_size, struct resource **p,
 			int skip_nr, int limit, int flags);
+void replace_resource(struct resource *old_res, struct resource *new_res);
 struct resource *lookup_resource(struct resource *root, resource_size_t start);
 int adjust_resource(struct resource *res, resource_size_t start,
 		    resource_size_t size);
diff --git a/kernel/resource.c b/kernel/resource.c
index d5d9aef..8da0e76 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1129,6 +1129,31 @@  reduce_needed_size:
 	return ret;
 }
 
+/* replace old with new in the resource tree */
+void replace_resource(struct resource *old, struct resource *new)
+{
+	struct resource *parent, *tmp, *p;
+
+	write_lock(&resource_lock);
+	new->start = old->start;
+	new->end = old->end;
+	new->flags = old->flags;
+
+	p = old->child;
+	while (p) {
+		tmp = p;
+		p = p->sibling;
+		__release_resource(tmp);
+		__request_resource(new, tmp);
+	}
+	parent = old->parent;
+	if (parent) {
+		__release_resource(old);
+		__request_resource(parent, new);
+	}
+	write_unlock(&resource_lock);
+}
+
 /*
  * Managed region resource
  */