Re: [PATCH] APM fixes, workarounds and tidying

Richard Gooch (rgooch@atnf.csiro.au)
Sun, 29 Nov 1998 20:56:08 +1100


Stephen Rothwell writes:
> Hi Linus,
>
> Could you apply this patch to 2.1.130, please. It is an aggregation
> of patches from various people to fix or work around various
> problems they are having.
>
> Summary:
> keep /proc/apm consistant
> Reset interrupt 0 timer to 100Hz after suspend
> Add CONFIG_APM_IGNORE_SUSPEND_BOUNCE
> Allow boot time disabling of APM
> Make boot messages far less verbose by default
> Make asm safer

This is great to see. I've written a patch against 2.1.130 which
incorporates my CONFIG_APM_IGNORE_SUSPEND_BOUNCE patch and also a
CONFIG_APM_RTC_IS_GMT option. I've appended my combined patch below.

Could you please extract the CONFIG_APM_RTC_IS_GMT component and
include it in a new patch for Linus? If necessary, I'll rework the
patch against your patch. Just let me know.

Regards,

Richard....

diff -urN linux-2.1.130/Documentation/Configure.help linux/Documentation/Configure.help
--- linux-2.1.130/Documentation/Configure.help Thu Nov 26 12:25:16 1998
+++ linux/Documentation/Configure.help Sat Nov 28 11:56:50 1998
@@ -8328,6 +8328,35 @@
ignored. Without this the Thinkpad 560 has troubles with the user
level daemon apmd, and with the PCMCIA package pcmcia-cs.

+Ignore multiple suspend/resume cycles
+CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ This option is necessary on the Dell Inspiron 3200, but should be
+ safe for all other laptops. When enabled, a system suspend event
+ that occurs within one second of a resume is ignored. Without this
+ the Inspiron will shut itself off a few seconds after you open the
+ lid, requiring you to press the power button to resume it a second
+ time.
+ Say Y.
+
+RTC stores time in GMT
+CONFIG_APM_RTC_IS_GMT
+ This option can be used when your RTC (Real Time Clock aka. Hardware
+ Clock) stores the time in GMT (Greenwich Mean Time) rather than
+ localtime. When suspending/resuming, the kernel needs to know what
+ is stored in the RTC so it can update the system clock (which is
+ always GMT). Without this option the kernel attempts to measure the
+ offset between the RTC and the system clock. This means you can
+ loose one second on each suspend/resume cycle.
+ Also, on the Dell Inspiron 3200, the hardware slows down the system
+ even before the kernel can measure the RTC/system clock offset. It
+ can then take 15 seconds to do this measurement and it can be
+ incorrect by several seconds.
+ Say Y if GMT is stored in your RTC.
+ GMT is usually the best anyway, because you don't have to
+ worry about daylight savings time changes. The only reason to not
+ use GMT in your RTC is if you also run a broken OS that doesn't
+ understand GMT.
+
Watchdog Timer Support
CONFIG_WATCHDOG
If you say Y here (and to one of the following options) and create a
diff -urN linux-2.1.130/arch/i386/config.in linux/arch/i386/config.in
--- linux-2.1.130/arch/i386/config.in Thu Nov 26 12:25:16 1998
+++ linux/arch/i386/config.in Sat Nov 28 11:57:02 1998
@@ -72,6 +72,8 @@
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
bool ' Power off on shutdown' CONFIG_APM_POWER_OFF
bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
+ bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
fi

endmenu
diff -urN linux-2.1.130/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- linux-2.1.130/arch/i386/kernel/apm.c Thu Nov 26 12:25:16 1998
+++ linux/arch/i386/kernel/apm.c Sat Nov 28 13:09:12 1998
@@ -265,8 +265,13 @@
static int waiting_for_resume = 0;
#endif

+#ifdef CONFIG_APM_RTC_IS_GMT
+# define clock_cmos_diff 0
+# define got_clock_diff 1
+#else
static long clock_cmos_diff;
static int got_clock_diff = 0;
+#endif

static struct wait_queue * process_list = NULL;
static struct apm_bios_struct * user_list = NULL;
@@ -707,6 +712,7 @@
unsigned long flags;
int err;

+#ifndef CONFIG_APM_RTC_IS_GMT
/* Estimate time zone so that set_time can
update the clock */
save_flags(flags);
@@ -715,6 +721,7 @@
clock_cmos_diff += CURRENT_TIME;
got_clock_diff = 1;
restore_flags(flags);
+#endif

err = apm_set_power_state(APM_STATE_SUSPEND);
if (err)
@@ -772,6 +779,9 @@
static void check_events(void)
{
apm_event_t event;
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ long last_resume = 0;
+#endif

while ((event = get_event()) != 0) {
#ifdef APM_DEBUG
@@ -803,6 +813,10 @@
break;
#endif
case APM_SYS_SUSPEND:
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ if (last_resume + HZ > jiffies)
+ break;
+#endif
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
if (waiting_for_resume) {
return;
@@ -819,6 +833,9 @@
case APM_STANDBY_RESUME:
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
waiting_for_resume = 0;
+#endif
+#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
+ last_resume = jiffies;
#endif
set_time();
send_event(event, 0, NULL);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/