|
@@ -15,6 +15,7 @@
|
|
#include <linux/spinlock.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/proc_fs.h>
|
|
|
|
+#include <linux/sched.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/device.h>
|
|
#include <linux/device.h>
|
|
#include <linux/pfn.h>
|
|
#include <linux/pfn.h>
|
|
@@ -681,6 +682,8 @@ resource_size_t resource_alignment(struct resource *res)
|
|
* release_region releases a matching busy region.
|
|
* release_region releases a matching busy region.
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+static DECLARE_WAIT_QUEUE_HEAD(muxed_resource_wait);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* __request_region - create a new busy resource region
|
|
* __request_region - create a new busy resource region
|
|
* @parent: parent resource descriptor
|
|
* @parent: parent resource descriptor
|
|
@@ -693,6 +696,7 @@ struct resource * __request_region(struct resource *parent,
|
|
resource_size_t start, resource_size_t n,
|
|
resource_size_t start, resource_size_t n,
|
|
const char *name, int flags)
|
|
const char *name, int flags)
|
|
{
|
|
{
|
|
|
|
+ DECLARE_WAITQUEUE(wait, current);
|
|
struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
|
|
struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
|
|
|
|
|
|
if (!res)
|
|
if (!res)
|
|
@@ -717,7 +721,15 @@ struct resource * __request_region(struct resource *parent,
|
|
if (!(conflict->flags & IORESOURCE_BUSY))
|
|
if (!(conflict->flags & IORESOURCE_BUSY))
|
|
continue;
|
|
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.. */
|
|
/* Uhhuh, that didn't work out.. */
|
|
kfree(res);
|
|
kfree(res);
|
|
res = NULL;
|
|
res = NULL;
|
|
@@ -791,6 +803,8 @@ void __release_region(struct resource *parent, resource_size_t start,
|
|
break;
|
|
break;
|
|
*p = res->sibling;
|
|
*p = res->sibling;
|
|
write_unlock(&resource_lock);
|
|
write_unlock(&resource_lock);
|
|
|
|
+ if (res->flags & IORESOURCE_MUXED)
|
|
|
|
+ wake_up(&muxed_resource_wait);
|
|
kfree(res);
|
|
kfree(res);
|
|
return;
|
|
return;
|
|
}
|
|
}
|