From bfd011cf798da190c7d9747bbe125c348ae19724 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 29 Mar 2010 19:38:00 +0200 Subject: [PATCH] --- yaml --- r: 197898 b: refs/heads/master c: 8b6d043b7ee2d1b819dc833d677ea2aead71a0c0 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/ioport.h | 4 +++- trunk/kernel/resource.c | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index a9a2252a827d..19e348571de1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d19f61f098ae9315b76a97962007f687683916d4 +refs/heads/master: 8b6d043b7ee2d1b819dc833d677ea2aead71a0c0 diff --git a/trunk/include/linux/ioport.h b/trunk/include/linux/ioport.h index 26fad187d661..b22790268b64 100644 --- a/trunk/include/linux/ioport.h +++ b/trunk/include/linux/ioport.h @@ -52,6 +52,7 @@ struct resource_list { #define IORESOURCE_MEM_64 0x00100000 #define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */ +#define IORESOURCE_MUXED 0x00400000 /* Resource is software muxed */ #define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ #define IORESOURCE_DISABLED 0x10000000 @@ -143,7 +144,8 @@ static inline unsigned long resource_type(const struct resource *res) } /* Convenience shorthand with allocation */ -#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) +#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) +#define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED) #define __request_mem_region(start,n,name, excl) __request_region(&iomem_resource, (start), (n), (name), excl) #define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name), 0) #define request_mem_region_exclusive(start,n,name) \ diff --git a/trunk/kernel/resource.c b/trunk/kernel/resource.c index 9c358e263534..7b36976e5dea 100644 --- a/trunk/kernel/resource.c +++ b/trunk/kernel/resource.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -681,6 +682,8 @@ resource_size_t resource_alignment(struct resource *res) * release_region releases a matching busy region. */ +static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait); + /** * __request_region - create a new busy resource region * @parent: parent resource descriptor @@ -693,6 +696,7 @@ struct resource * __request_region(struct resource *parent, resource_size_t start, resource_size_t n, const char *name, int flags) { + DECLARE_WAITQUEUE(wait, current); struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); if (!res) @@ -717,7 +721,15 @@ struct resource * __request_region(struct resource *parent, if (!(conflict->flags & IORESOURCE_BUSY)) continue; } - + if (conflict->flags & flags & IORESOURCE_MUXED) { + add_wait_queue(&muxed_resource_wait, &wait); + write_unlock(&resource_lock); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule(); + remove_wait_queue(&muxed_resource_wait, &wait); + write_lock(&resource_lock); + continue; + } /* Uhhuh, that didn't work out.. */ kfree(res); res = NULL; @@ -791,6 +803,8 @@ void __release_region(struct resource *parent, resource_size_t start, break; *p = res->sibling; write_unlock(&resource_lock); + if (res->flags & IORESOURCE_MUXED) + wake_up(&muxed_resource_wait); kfree(res); return; }