Commit bfeb7256 authored by Russell King's avatar Russell King

[ARM] Keep APM threads frozen

Ensure threads waiting for suspend to occur in apm_ioctl are
not woken by the pm_suspend thread freezing - they're already
frozen.
parent 975ec51b
...@@ -176,7 +176,7 @@ static void queue_event(apm_event_t event, struct apm_user *sender) ...@@ -176,7 +176,7 @@ static void queue_event(apm_event_t event, struct apm_user *sender)
wake_up_interruptible(&apm_waitqueue); wake_up_interruptible(&apm_waitqueue);
} }
static int apm_suspend(void) static void apm_suspend(void)
{ {
struct apm_user *as; struct apm_user *as;
int err = pm_suspend(PM_SUSPEND_MEM); int err = pm_suspend(PM_SUSPEND_MEM);
...@@ -198,7 +198,6 @@ static int apm_suspend(void) ...@@ -198,7 +198,6 @@ static int apm_suspend(void)
up_read(&user_list_lock); up_read(&user_list_lock);
wake_up_interruptible(&apm_suspend_waitqueue); wake_up_interruptible(&apm_suspend_waitqueue);
return err;
} }
static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
...@@ -257,6 +256,7 @@ static int ...@@ -257,6 +256,7 @@ static int
apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
{ {
struct apm_user *as = filp->private_data; struct apm_user *as = filp->private_data;
unsigned long flags;
int err = -EINVAL; int err = -EINVAL;
if (!as->suser || !as->writer) if (!as->suser || !as->writer)
...@@ -285,18 +285,27 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) ...@@ -285,18 +285,27 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
} }
/* /*
* If there are outstanding suspend requests for other * If there are no further acknowledges required, suspend
* people on /dev/apm_bios, we must sleep for them. * the system.
* Last one to bed turns the lights out.
*/ */
if (suspends_pending > 0) { if (suspends_pending == 0)
err = wait_event_interruptible(apm_suspend_waitqueue, apm_suspend();
/*
* Wait for the suspend/resume to complete. If there are
* pending acknowledges, we wait here for them.
*
* Note that we need to ensure that the PM subsystem does
* not kick us out of the wait when it suspends the threads.
*/
flags = current->flags;
current->flags |= PF_NOFREEZE;
wait_event_interruptible(apm_suspend_waitqueue,
as->suspend_state == SUSPEND_DONE); as->suspend_state == SUSPEND_DONE);
if (err == 0)
current->flags = flags;
err = as->suspend_result; err = as->suspend_result;
} else {
err = apm_suspend();
}
as->suspend_state = SUSPEND_NONE; as->suspend_state = SUSPEND_NONE;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment