summaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/apm.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-06-16 23:00:36 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-06-16 23:00:36 +0000
commit14dd2ec093cfabda3ae7efeeaf0e23c66ebaccc0 (patch)
tree9a9ce5cff6ef92faa6e07a82785b9a6d6838f7e4 /arch/i386/kernel/apm.c
parent847290510f811c572cc2aa80c1f02a04721410b1 (diff)
Merge with 2.4.0-test1.
Diffstat (limited to 'arch/i386/kernel/apm.c')
-rw-r--r--arch/i386/kernel/apm.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index b1e0e8b7c..0b4517137 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -922,6 +922,10 @@ static int send_event(apm_event_t event, struct apm_user *sender)
case APM_USER_SUSPEND:
/* map all suspends to ACPI D3 */
if (pm_send_all(PM_SUSPEND, (void *)3)) {
+ if (event == APM_CRITICAL_SUSPEND) {
+ printk(KERN_CRIT "apm: Critical suspend was vetoed, expect armagedon\n" );
+ return 0;
+ }
if (apm_bios_info.version > 0x100)
apm_set_power_state(APM_STATE_REJECT);
return 0;
@@ -934,7 +938,6 @@ static int send_event(apm_event_t event, struct apm_user *sender)
break;
}
- queue_event(event, sender);
return 1;
}
@@ -964,6 +967,7 @@ static void check_events(void)
case APM_SYS_STANDBY:
case APM_USER_STANDBY:
if (send_event(event, NULL)) {
+ queue_event(event, NULL);
if (standbys_pending <= 0)
standby();
}
@@ -980,17 +984,18 @@ static void check_events(void)
if (ignore_bounce)
break;
#endif
- /*
- * If we are already processing a SUSPEND,
- * then further SUSPEND events from the BIOS
- * will be ignored. We also return here to
- * cope with the fact that the Thinkpads keep
- * sending a SUSPEND event until something else
- * happens!
- */
+ /*
+ * If we are already processing a SUSPEND,
+ * then further SUSPEND events from the BIOS
+ * will be ignored. We also return here to
+ * cope with the fact that the Thinkpads keep
+ * sending a SUSPEND event until something else
+ * happens!
+ */
if (waiting_for_resume)
- return;
+ return;
if (send_event(event, NULL)) {
+ queue_event(event, NULL);
waiting_for_resume = 1;
if (suspends_pending <= 0)
(void) suspend();
@@ -1007,6 +1012,7 @@ static void check_events(void)
#endif
set_time();
send_event(event, NULL);
+ queue_event(event, NULL);
break;
case APM_CAPABILITY_CHANGE:
@@ -1020,6 +1026,7 @@ static void check_events(void)
break;
case APM_CRITICAL_SUSPEND:
+ send_event(event, NULL); /* We can only hope it worked; critical suspend may not fail */
(void) suspend();
break;
}
@@ -1056,6 +1063,7 @@ static void apm_event_handler(void)
static void apm_mainloop(void)
{
+ int timeout = HZ;
DECLARE_WAITQUEUE(wait, current);
if (smp_num_cpus > 1)
@@ -1065,7 +1073,10 @@ static void apm_mainloop(void)
current->state = TASK_INTERRUPTIBLE;
for (;;) {
/* Nothing to do, just sleep for the timeout */
- schedule_timeout(APM_CHECK_TIMEOUT);
+ timeout = 2*timeout;
+ if (timeout > APM_CHECK_TIMEOUT)
+ timeout = APM_CHECK_TIMEOUT;
+ schedule_timeout(timeout);
if (exit_kapmd)
break;
@@ -1080,13 +1091,16 @@ static void apm_mainloop(void)
continue;
if (apm_do_idle()) {
unsigned long start = jiffies;
- while (system_idle()) {
+ while ((!exit_kapmd) && system_idle()) {
apm_do_idle();
- if (jiffies - start > APM_CHECK_TIMEOUT)
- break;
+ if (jiffies - start > (5*APM_CHECK_TIMEOUT)) {
+ apm_event_handler();
+ start = jiffies;
+ }
}
apm_do_busy();
apm_event_handler();
+ timeout = 1;
}
#endif
}