ACPI vs. APM power-off: proposed patch to linux-2.3.31/drivers/misc/acpi.c

Adam J. Richter (adam@yggdrasil.com)
Sun, 12 Dec 1999 09:49:58 -0800


On every computer on which I have tried the last few linux-2.3.x
releases, the hardware power off did not work. This is because if the
kernel is built with both CONFIG_ACPI and CONFIG_APM, the acpi routine
is the one that is set to be the power off handler, because it is
initialized later and overwrites the variable. I guess the machines
experiencing the problem support APM power down but not ACPI power down.

The following patch fixes the problem by having the ACPI
power off handler call the previous value of acpi_power_off (usually
apm_power_off). This implementation does not add any direct references
to the apm code, so it does not introduce any new usage of autoconfig.h.
It also does not impede the unloading of acpi, so it should not impede
any effort to modularize the acpi support. So, I think this is the
right approach for supporting software power down functinality on
the widest variety of hardware platforms.

Anyhow, this patch works for me.

Adam J. Richter __ ______________ 4880 Stevens Creek Blvd, Suite 104
adam@yggdrasil.com \ / San Jose, California 95129-1034
+1 408 261-6630 | g g d r a s i l United States of America
fax +1 408 261-6631 "Free Software For The Rest Of Us."
-------------------------------CUT HERE-----------------------------------

Index: linux/drivers/misc/acpi.c
===================================================================
RCS file: /usr/src.repository/repository/linux-2.3/drivers/misc/acpi.c,v
retrieving revision 1.1.1.11
diff -u -r1.1.1.11 acpi.c
--- acpi.c 1999/12/07 00:24:48 1.1.1.11
+++ acpi.c 1999/12/12 16:32:35
@@ -55,6 +55,8 @@
#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL
#endif

+static void (*old_acpi_power_off)(void) = NULL;
+
/*
* Yes, it's unfortunate that we are relying on get_cmos_time
* because it is slow (> 1 sec.) and i386 only. It might be better
@@ -826,6 +828,8 @@
static void acpi_power_off_handler(void)
{
acpi_enter_sx(ACPI_S5);
+ if (old_acpi_power_off != NULL)
+ (*old_acpi_power_off)();
}

/*
@@ -1140,6 +1144,7 @@
NULL,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND);

+ old_acpi_power_off = acpi_power_off;
acpi_power_off = acpi_power_off_handler;

/*
@@ -1163,7 +1168,7 @@
static void __exit acpi_exit(void)
{
acpi_idle = NULL;
- acpi_power_off = NULL;
+ acpi_power_off = old_acpi_power_off;

unregister_sysctl_table(acpi_sysctl);
acpi_disable(acpi_facp);

-
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/