summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2004-09-20 20:22:26 +0100
committerRussell King <rmk@flint.arm.linux.org.uk>2004-09-20 20:22:26 +0100
commitefb4cd1196d066f8c345f1935c53246db7641c8a (patch)
treeb7d0438b9ccf9f4e129e5ee70dd1a831564b6cd5
parente7f10a52f7682ddf818bd793b56a587aae1bc160 (diff)
[ARM] Prevent state machine leakage in ARM APM emulation.
Don't allow threads which are acking a suspend request to leave the APM ioctl call. This prevents the state machine breaking.
-rw-r--r--arch/arm/kernel/apm.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
index 267f6971082e..70aade05b50d 100644
--- a/arch/arm/kernel/apm.c
+++ b/arch/arm/kernel/apm.c
@@ -202,7 +202,7 @@ static void apm_suspend(void)
}
up_read(&user_list_lock);
- wake_up_interruptible(&apm_suspend_waitqueue);
+ wake_up(&apm_suspend_waitqueue);
}
static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
@@ -306,7 +306,15 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
flags = current->flags;
current->flags |= PF_NOFREEZE;
- wait_event_interruptible(apm_suspend_waitqueue,
+ /*
+ * Note: do not allow a thread which is acking the suspend
+ * to escape until the resume is complete.
+ */
+ if (as->suspend_state == SUSPEND_ACKED)
+ wait_event(apm_suspend_waitqueue,
+ as->suspend_state == SUSPEND_DONE);
+ else
+ wait_event_interruptible(apm_suspend_waitqueue,
as->suspend_state == SUSPEND_DONE);
current->flags = flags;