[ltp] Problem with Acpi

Peter Frühberger linux-thinkpad@linux-thinkpad.org
Wed, 06 Oct 2004 13:14:16 +0200


This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enigDDF9DA33E392CCF1F0890705
Content-Type: multipart/mixed;
 boundary="------------040003000608000701070207"

This is a multi-part message in MIME format.
--------------040003000608000701070207
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Martin Hauser wrote:
> Hello there,
> 
> i've been having a slight problem with my acpi on a IBM THinkpad R40 running
> a Gentoo Linux 2004.1 with a 2.6.7 kernel.org kernel and acpi enabled. 
> (had this on debian too, think it's rather distribution indipendand) If i 
> send the system to suspend to ram, there is no key to wake it up again, 
> anyone got an Idea how to tell the kernel which key to use for wakeup?
> 
> Thanks In Advance
> 
> Martin Hauser

If you use a 2.6.7 kernel, you need at least acpi-20040715-2.6.7
to let it work reliable.
This version adds a special wakeup device to the /proc interface.

compile uhci_hcd, ehci_hcd as modules and unload them before suspend to ram.
Be warned suspend to Ram still consumes to much power.

I attached you my acpi script for sus to ram and the acpi diff, I think
its not anymore on the acpi.sf.net page.


sers
Peter
-- 
		    Key-ID:     0x1A995A9B
		    keyserver: pgp.mit.edu
==============================================================
Fingerprint: 4606 DA19 EC2E 9A0B 0157  C81B DA07 CF63 1A99 5A9B

--------------040003000608000701070207
Content-Type: text/x-patch;
 name="acpi-20040715-2.6.7.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="acpi-20040715-2.6.7.diff"

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/07/17 01:37:59-04:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040715 from Bob Moore
#   
#   Restructured the internal HW GPE interfaces to pass/track
#   the current state of interrupts (enabled/disabled) in
#   order to avoid possible deadlock and increase flexibility
#   of the interfaces.
#   
#   Implemented a "lexicographical compare" for String and
#   Buffer objects within the logical operators -- LGreater,
#   LLess, LGreaterEqual, and LLessEqual -- as per further
#   clarification to the ACPI specification.  Behavior is
#   similar to C library "strcmp".
#   
#   Completed a major reduction in CPU stack use for the
#   acpi_get_firmware_table external function.  In the 32-bit
#   non-debug case, the stack use has been reduced from 168
#   bytes to 32 bytes.
#   
#   Deployed a new run-time configuration flag,
#   acpi_gbl_enable_interpeter_slack, whose purpose is to allow
#   the AML interpreter to forgive certain bad AML constructs.
#   Default setting is FALSE.
#   
#   Implemented the first use of acpi_gbl_enable_interpeter_slack
#   in the Field IO support code.  If enabled, it allows field
#   access to go beyond the end of a region definition if the
#   field is within the region length rounded up to the next
#   access width boundary (a common coding error.)
#   
#   Renamed OSD_HANDLER to acpi_osd_handler, and
#   OSD_EXECUTION_CALLBACK to acpi_osd_exec_callback for
#   consistency with other ACPI symbols.  Also, these symbols
#   are lowercased by the latest version of the acpisrc tool.
#   
#   The prototypes for the PCI interfaces in acpiosxf.h
#   have been updated to rename "register" to simply "reg"
#   to prevent certain compilers from complaining.
# 
# include/acpi/actypes.h
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040715
# 
# include/acpi/acpiosxf.h
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +9 -6
#   ACPICA 20040715
# 
# include/acpi/achware.h
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +3 -3
#   ACPICA 20040715
# 
# include/acpi/acglobal.h
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +11 -4
#   ACPICA 20040715
# 
# include/acpi/acevents.h
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -1
#   ACPICA 20040715
# 
# include/acpi/acconfig.h
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040715
# 
# drivers/acpi/tables/tbxfroot.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +63 -43
#   ACPICA 20040715
# 
# drivers/acpi/osl.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +5 -5
#   ACPICA 20040715
# 
# drivers/acpi/hardware/hwsleep.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +7 -6
#   ACPICA 20040715
# 
# drivers/acpi/hardware/hwregs.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -1
#   ACPICA 20040715
# 
# drivers/acpi/hardware/hwgpe.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +10 -10
#   ACPICA 20040715
# 
# drivers/acpi/executer/exmisc.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +20 -20
#   ACPICA 20040715
# 
# drivers/acpi/executer/exfldio.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +15 -0
#   ACPICA 20040715
# 
# drivers/acpi/events/evmisc.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040715
# 
# drivers/acpi/events/evgpeblk.c
#   2004/07/17 01:37:53-04:00 len.brown@intel.com +5 -4
#   ACPICA 20040715
# 
# ChangeSet
#   2004/07/15 15:17:42-04:00 len.brown@intel.com 
#   [ACPI] Enable run-time CM button/LID events (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=1415
# 
# drivers/acpi/sleep/wakeup.c
#   2004/07/15 05:05:42-04:00 len.brown@intel.com +41 -9
#   Enable run-time CM button/LID events
# 
# drivers/acpi/button.c
#   2004/07/15 04:09:03-04:00 len.brown@intel.com +9 -0
#   Enable run-time CM button/LID events
# 
# drivers/acpi/acpi_ksyms.c
#   2004/07/15 04:05:19-04:00 len.brown@intel.com +2 -0
#   Enable run-time CM button/LID events
# 
# ChangeSet
#   2004/07/15 00:39:15-04:00 len.brown@intel.com 
#   [ACPI] Create /proc/acpi/wakeup to allow enabling
#   the optional wakeup event sources. (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=1415
# 
# drivers/acpi/sleep/wakeup.c
#   2004/07/14 02:35:15-04:00 len.brown@intel.com +147 -0
#   /proc/acpi/wakeup
# 
# drivers/acpi/sleep/sleep.h
#   2004/07/14 01:29:14-04:00 len.brown@intel.com +3 -0
#   /proc/acpi/wakeup
# 
# drivers/acpi/sleep/proc.c
#   2004/07/14 02:14:03-04:00 len.brown@intel.com +86 -0
#   /proc/acpi/wakeup
# 
# drivers/acpi/sleep/main.c
#   2004/07/14 01:29:13-04:00 len.brown@intel.com +3 -0
#   /proc/acpi/wakeup
# 
# drivers/acpi/sleep/Makefile
#   2004/07/14 01:29:07-04:00 len.brown@intel.com +1 -1
#   /proc/acpi/wakeup
# 
# drivers/acpi/sleep/wakeup.c
#   2004/07/14 02:35:15-04:00 len.brown@intel.com +0 -0
#   BitKeeper file /home/lenb/src/linux-acpi-test-2.6.7/drivers/acpi/sleep/wakeup.c
# 
# ChangeSet
#   2004/07/15 00:37:33-04:00 len.brown@intel.com 
#   [ACPI] ACPI bus support for wakeup GPE (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=1415
# 
# include/acpi/acpi_drivers.h
#   2004/07/14 01:22:19-04:00 len.brown@intel.com +2 -1
#   ACPI bus support for wakeup GPE
# 
# include/acpi/acpi_bus.h
#   2004/07/14 01:22:19-04:00 len.brown@intel.com +24 -4
#   ACPI bus support for wakeup GPE
# 
# drivers/acpi/scan.c
#   2004/07/14 01:24:56-04:00 len.brown@intel.com +137 -28
#   ACPI bus support for wakeup GPE
# 
# drivers/acpi/power.c
#   2004/07/14 01:22:19-04:00 len.brown@intel.com +80 -0
#   ACPI bus support for wakeup GPE
# 
# ChangeSet
#   2004/07/15 00:27:33-04:00 len.brown@intel.com 
#   [ACPI] IOAPIC suspend/resume (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=3037
# 
# arch/i386/kernel/io_apic.c
#   2004/07/07 23:28:17-04:00 len.brown@intel.com +93 -0
#   IOAPIC suspend/resume
# 
# ChangeSet
#   2004/07/14 15:47:04-04:00 len.brown@intel.com 
#   [ACPI] Tell the BIOS Linux can handle
#   Enhanced Speed Step (EST). (Venkatesh Pallipadi)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2712
# 
# include/asm-i386/acpi.h
#   2004/05/18 18:45:51-04:00 len.brown@intel.com +6 -0
#   use _PDC to enable Enhanced Speed Step (EST)
# 
# drivers/acpi/processor.c
#   2004/05/19 20:04:43-04:00 len.brown@intel.com +2 -2
#   use _PDC to enable Enhanced Speed Step (EST)
# 
# arch/i386/kernel/cpu/cpufreq/acpi.c
#   2004/05/19 14:55:14-04:00 len.brown@intel.com +73 -0
#   use _PDC to enable Enhanced Speed Step (EST)
# 
# ChangeSet
#   2004/07/14 15:39:55-04:00 len.brown@intel.com 
#   [ACPI] add SMP suport to processor driver (Venkatesh Pallipadi)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2615
# 
# include/asm-x86_64/acpi.h
#   2004/06/25 01:40:47-04:00 len.brown@intel.com +2 -0
#   add SMP support to processor driver
# 
# include/asm-ia64/acpi.h
#   2004/06/25 01:40:46-04:00 len.brown@intel.com +2 -0
#   add SMP support to processor driver
# 
# include/asm-i386/smp.h
#   2004/06/25 01:40:47-04:00 len.brown@intel.com +1 -0
#   add SMP support to processor driver
# 
# include/asm-i386/acpi.h
#   2004/06/25 01:40:47-04:00 len.brown@intel.com +2 -0
#   add SMP support to processor driver
# 
# drivers/acpi/processor.c
#   2004/06/25 03:53:02-04:00 len.brown@intel.com +55 -10
#   add SMP support to processor driver
# 
# arch/x86_64/kernel/smpboot.c
#   2004/06/25 01:40:50-04:00 len.brown@intel.com +1 -0
#   add SMP support to processor driver
# 
# arch/ia64/kernel/acpi.c
#   2004/06/25 01:40:49-04:00 len.brown@intel.com +6 -0
#   add SMP support to processor driver
# 
# arch/i386/kernel/smpboot.c
#   2004/06/25 01:40:49-04:00 len.brown@intel.com +6 -0
#   add SMP support to processor driver
# 
# arch/i386/kernel/cpu/cpufreq/acpi.c
#   2004/06/25 01:40:43-04:00 len.brown@intel.com +25 -5
#   add SMP support to processor driver
# 
# arch/i386/kernel/acpi/boot.c
#   2004/06/25 01:40:49-04:00 len.brown@intel.com +7 -0
#   add SMP support to processor driver
# 
# ChangeSet
#   2004/07/14 15:35:54-04:00 len.brown@intel.com 
#   [ACPI] save/restore ELCR on suspend/resume (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2643
# 
# arch/x86_64/kernel/i8259.c
#   2004/07/14 15:35:49-04:00 len.brown@intel.com +52 -1
#   save/restore ELCR on suspend/resume
# 
# arch/i386/kernel/i8259.c
#   2004/07/14 15:35:49-04:00 len.brown@intel.com +25 -0
#   save/restore ELCR on suspend/resume
# 
# ChangeSet
#   2004/07/14 14:47:30-04:00 len.brown@intel.com 
#   [ACPI] /proc/acpi/thermal_zone/THRM/cooling_mode
#   Add concept of (mandatory) "critical", when (optional)
#   "passive" and "active" are not present.  (Zhenyu Z Wang)
#   http://bugzilla.kernel.org/show_bug.cgi?id=1770
# 
# drivers/acpi/thermal.c
#   2004/07/08 01:56:01-04:00 len.brown@intel.com +32 -16
#   create cooling_mode "critical"
# 
# ChangeSet
#   2004/07/14 00:34:54-04:00 len.brown@intel.com 
#   [ACPI] fix ability to set thermal trip points (Hugo Haas, Stefan Seyfried)
#   eg. # echo -n "100:90:80:70:60:50" > /proc/acpi/thermal_zone/THRM/trip_points
#   http://bugzilla.kernel.org/show_bug.cgi?id=2588
# 
# drivers/acpi/thermal.c
#   2004/06/29 17:43:00-04:00 len.brown@intel.com +14 -5
#   fix ability to set thermal trip points
# 
# ChangeSet
#   2004/07/07 13:53:29-04:00 len.brown@intel.com 
#   [ACPI] reserve EBDA for Dell BIOS that neglects to. (David Shaohua Li)
#   http://bugme.osdl.org/show_bug.cgi?id=2990
# 
# arch/x86_64/kernel/setup.c
#   2004/06/30 23:30:27-04:00 len.brown@intel.com +17 -0
#   reserve EBDA for Dell BIOS that neglects to.
# 
# arch/i386/mm/discontig.c
#   2004/06/30 22:51:37-04:00 len.brown@intel.com +15 -0
#   reserve EBDA for Dell BIOS that neglects to.
# 
# arch/i386/kernel/setup.c
#   2004/06/30 22:51:37-04:00 len.brown@intel.com +15 -0
#   reserve EBDA for Dell BIOS that neglects to.
# 
# drivers/acpi/ec.c
#   2004/06/24 06:39:53-04:00 len.brown@intel.com +2 -0
#   enable GPE for ECDT
# 
# ChangeSet
#   2004/06/24 01:43:06-04:00 len.brown@intel.com 
#   [ACPI] reserve IOPORTS for ACPI (David Shaohua Li)
#   http://bugzilla.kernel.org/show_bug.cgi?id=2641
# 
# drivers/acpi/processor.c
#   2004/05/20 02:36:01-04:00 len.brown@intel.com +0 -1
#   reserve IOPORTS for ACPI
# 
# drivers/acpi/motherboard.c
#   2004/05/20 05:01:24-04:00 len.brown@intel.com +161 -0
#   reserve IOPORTS for ACPI
# 
# drivers/acpi/Makefile
#   2004/05/20 02:36:01-04:00 len.brown@intel.com +1 -1
#   reserve IOPORTS for ACPI
# 
# drivers/acpi/motherboard.c
#   2004/05/20 05:01:24-04:00 len.brown@intel.com +0 -0
#   BitKeeper file /home/lenb/bk/linux-acpi-test-2.6.7/drivers/acpi/motherboard.c
# 
# ChangeSet
#   2004/06/24 00:53:45-04:00 len.brown@intel.com 
#   [ACPI] enable GPE for ECDT (David Shaohua Li)
# 
# ChangeSet
#   2004/06/23 17:01:29-04:00 len.brown@intel.com 
#   [ACPI] enable Embedded Controller (EC)'s
#   General Purpose Event (GPE) from David Shaohua Li
# 
# drivers/acpi/ec.c
#   2004/06/07 13:35:25-04:00 len.brown@intel.com +2 -0
#   enable EC GPE
# 
# ChangeSet
#   2004/06/23 01:22:23-04:00 len.brown@intel.com 
#   [ACPI] fix return-from-sleep PM/ACPI state conversion bug (David Shaohua Li)
# 
# drivers/acpi/sleep/main.c
#   2004/06/23 01:22:17-04:00 len.brown@intel.com +16 -14
#   fix conversion between pm_state and acpi_state on return from sleep
# 
# ChangeSet
#   2004/06/22 16:27:51-04:00 len.brown@intel.com 
#   merge ACPICA
# 
# drivers/acpi/events/evxface.c
#   2004/06/22 16:27:46-04:00 len.brown@intel.com +22 -17
#   merge
# 
# drivers/acpi/events/evmisc.c
#   2004/06/22 16:27:46-04:00 len.brown@intel.com +0 -2
#   merge
# 
# drivers/acpi/osl.c
#   2004/06/22 16:05:25-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/acpi/ec.c
#   2004/06/22 16:05:25-04:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/06/22 15:56:16-04:00 len.brown@intel.com 
#   [ACPI] update EC GPE handler to new ACPICA handler type
# 
# drivers/acpi/ec.c
#   2004/06/22 15:13:22-04:00 len.brown@intel.com +7 -2
#   An acpi_gpe_handler is an acpi_event_handler
#   as of ACPICA 20040427, and needs a return value.
# 
# ChangeSet
#   2004/06/22 13:48:26-04:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040615 from Bob Moore
#   
#   Implemented support for Buffer and String objects (as
#   per ACPI 2.0) for the following ASL operators: LEqual,
#   LGreater, LLess, LGreaterEqual, and LLessEqual.
# 
# include/acpi/acinterp.h
#   2004/06/21 20:35:19-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040615
# 
# include/acpi/acdebug.h
#   2004/06/21 20:35:19-04:00 len.brown@intel.com +4 -0
#   ACPICA 20040615
# 
# include/acpi/acconfig.h
#   2004/06/21 20:35:20-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040615
# 
# drivers/acpi/utilities/utalloc.c
#   2004/06/21 20:35:22-04:00 len.brown@intel.com +8 -5
#   ACPICA 20040615
# 
# drivers/acpi/parser/psopcode.c
#   2004/06/21 20:35:22-04:00 len.brown@intel.com +4 -4
#   ACPICA 20040615
# 
# drivers/acpi/executer/exoparg2.c
#   2004/06/21 20:35:22-04:00 len.brown@intel.com +10 -2
#   ACPICA 20040615
# 
# drivers/acpi/executer/exmisc.c
#   2004/06/21 20:35:22-04:00 len.brown@intel.com +119 -32
#   ACPICA 20040615
# 
# drivers/acpi/events/evgpeblk.c
#   2004/06/21 20:35:22-04:00 len.brown@intel.com +2 -1
#   ACPICA 20040615
# 
# ChangeSet
#   2004/06/22 13:42:17-04:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040527 from Bob Moore
#   
#   Completed a new design and implementation for EBDA
#   (Extended BIOS Data Area) support in the RSDP scan code.
#   The original code improperly scanned for the EBDA by simply
#   scanning from memory location 0 to 0x400.  The correct
#   method is to first obtain the EBDA pointer from within
#   the BIOS data area, then scan 1K of memory starting at the
#   EBDA pointer.  There appear to be few if any machines that
#   place the RSDP in the EBDA, however.
#   http://bugme.osdl.org/show_bug.cgi?id=2415
#   
#   Integrated a fix for a possible fault during evaluation
#   of BufferField arguments.  Obsolete code that was causing
#   the problem was removed. (Asus laptop boot crash)
#   https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=121760
#   
#   Found and fixed a problem in the Field Support Code
#   where data could be corrupted on a bit field read that
#   starts on an aligned boundary but does not end on an
#   aligned boundary.  Merged the read/write "datum length"
#   calculation code into a common procedure.
# 
# include/acpi/acmacros.h
#   2004/06/01 21:39:18-04:00 len.brown@intel.com +3 -0
#   ACPICA 20040527
# 
# include/acpi/acinterp.h
#   2004/06/01 21:39:18-04:00 len.brown@intel.com +6 -0
#   ACPICA 20040527
# 
# include/acpi/acconfig.h
#   2004/06/01 21:39:18-04:00 len.brown@intel.com +7 -6
#   ACPICA 20040527
# 
# drivers/acpi/tables/tbxfroot.c
#   2004/06/01 21:39:21-04:00 len.brown@intel.com +68 -35
#   ACPICA 20040527
# 
# drivers/acpi/executer/exfldio.c
#   2004/06/01 21:39:21-04:00 len.brown@intel.com +84 -64
#   ACPICA 20040527
# 
# drivers/acpi/executer/exconfig.c
#   2004/06/01 21:39:21-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040527
# 
# drivers/acpi/events/evgpeblk.c
#   2004/06/01 21:39:21-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040527
# 
# drivers/acpi/events/evgpe.c
#   2004/06/01 21:39:21-04:00 len.brown@intel.com +24 -20
#   ACPICA 20040527
# 
# drivers/acpi/dispatcher/dsopcode.c
#   2004/06/01 21:39:21-04:00 len.brown@intel.com +0 -3
#   ACPICA 20040527
# 
# ChangeSet
#   2004/06/22 13:15:18-04:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040514 from Bob Moore
#   
#   Fixed a problem where hardware GPE enable bits sometimes
#   not set properly during and after GPE method execution.
#   Result of ACPICA 20040427 changes.
#   
#   Removed extra "clear all GPEs" when sleeping/waking.
#   
#   Removed acpi_ht_enable_gpe and acpi_hw_disable_gpe, replaced
#   by the single acpi_hw_write_gpe_enable_reg. Changed a couple
#   of calls to the functions above to the new acpi_ev* calls
#   as appropriate.
#   
#   ACPI_OS_NAME was removed from the OS-specific headers.
#   The default name is now "Microsoft Windows NT" for maximum
#   compatibility. However this can be changed by modifying
#   the acconfig.h file.  Fixes EHCI probe issue:
#   http://bugme.osdl.org/show_bug.cgi?id=1762
#   
#   Allow a single invocation of acpi_install_notify_handler
#   for a handler that traps both types of notifies (System,
#   Device). Use ACPI_ALL_NOTIFY flag.
#   
#   Run _INI methods on ThermalZone objects. This is against
#   the ACPI specification, but there is apparently ASL code
#   in the field that has these _INI methods, and apparently
#   "other" AML interpreters execute them.
#   
#   Performed a full 16/32/64 bit lint that resulted in some
#   small changes.
# 
# include/acpi/platform/aclinux.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +0 -2
#   ACPICA 20040514
# 
# include/acpi/platform/acenv.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +2 -6
#   ACPICA 20040514
# 
# include/acpi/actypes.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +4 -3
#   ACPICA 20040514
# 
# include/acpi/acmacros.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040514
# 
# include/acpi/achware.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +6 -5
#   ACPICA 20040514
# 
# include/acpi/acdebug.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +4 -0
#   ACPICA 20040514
# 
# include/acpi/acconfig.h
#   2004/06/01 21:37:50-04:00 len.brown@intel.com +11 -1
#   ACPICA 20040514
# 
# drivers/acpi/utilities/utglobal.c
#   2004/06/01 21:37:53-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040514
# 
# drivers/acpi/resources/rsxface.c
#   2004/06/01 21:37:53-04:00 len.brown@intel.com +2 -1
#   ACPICA 20040514
# 
# drivers/acpi/parser/psxface.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +2 -3
#   ACPICA 20040514
# 
# drivers/acpi/namespace/nsinit.c
#   2004/06/01 21:37:53-04:00 len.brown@intel.com +8 -7
#   ACPICA 20040514
# 
# drivers/acpi/namespace/nseval.c
#   2004/06/01 21:37:53-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040514
# 
# drivers/acpi/namespace/nsalloc.c
#   2004/06/01 21:37:53-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040514
# 
# drivers/acpi/hardware/hwsleep.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040514
# 
# drivers/acpi/hardware/hwgpe.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +16 -51
#   ACPICA 20040514
# 
# drivers/acpi/executer/exresolv.c
#   2004/06/01 21:37:53-04:00 len.brown@intel.com +4 -4
#   ACPICA 20040514
# 
# drivers/acpi/events/evxfregn.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +0 -1
#   ACPICA 20040514
# 
# drivers/acpi/events/evxfevnt.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +1 -8
#   ACPICA 20040514
# 
# drivers/acpi/events/evxface.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +45 -31
#   ACPICA 20040514
# 
# drivers/acpi/events/evmisc.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040514
# 
# drivers/acpi/events/evgpeblk.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +14 -7
#   ACPICA 20040514
# 
# drivers/acpi/events/evgpe.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +21 -14
#   ACPICA 20040514
# 
# drivers/acpi/dispatcher/dsmethod.c
#   2004/06/01 21:37:52-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040514
# 
# ChangeSet
#   2004/05/07 17:24:44-04:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040427 from Bob Moore
#   
#   Completed a major overhaul of the GPE handling within ACPI CA.
#   There are now three types of GPEs:
#   wake-only; runtime-only; combination wake/run.
#   
#   The only GPEs allowed to be combination wake/run are for
#   button-style devices such as a control-method power button,
#   control-method sleep button, or a notebook lid switch.
#   GPEs that have an _Lxx or _Exx method and are not referenced
#   by any _PRW methods are marked for "runtime" and hardware enabled.
#   
#   Any GPE that is referenced by a _PRW method is marked for "wake"
#   (and disabled at runtime).  However, at sleep time, only those
#   GPEs that have been specifically enabled for wake via the
#   acpi_enable_gpe() interface will actually be hardware enabled.
#   
#   A new external interface has been added, acpi_set_gpe_type()
#   that is meant to be used by device drivers to force a GPE
#   to a particular type.  It will be especially useful for the
#   drivers for the button devices mentioned above.
#   
#   Completed restructuring of the ACPI CA initialization sequence
#   so that default operation region handlers are installed
#   before GPEs are initialized and the _PRW methods are executed.
#   This will prevent errors when the _PRW methods attempt to
#   access system memory or I/O space.
#   
#   GPE enable/disable no longer reads the GPE enable register.
#   We now keep the enable info for runtime and wake separate
#   and in the GPE_EVENT_INFO.  We thus no longer depend on
#   the hardware to maintain these bits.
#   
#   Always clear the wake status and fixed/GPE status bits
#   before sleep, even for state S5.
#   
#   Improved the AML debugger output for displaying the
#   GPE blocks and their current status.
#   
#   Added new strings for the _OSI method, of the form
#   "Windows 2001 SPx" where x = 0,1,2,3,4.
#   
#   Fixed a problem where the physical address was incorrectly
#   calculated when the Load() operator was used to directly
#   load from an Operation Region (vs. loading from a Field object.)
#   Also added check for minimum table length for this case.
#   
#   Fix for multiple mutex acquisition.  Restore original thread
#   SyncLevel on mutex release.
#   
#   Added ACPI_VALID_SXDS flag to the acpi_get_object_info interface
#   for consistency with the other fields returned.
#   
#   Shrunk the ACPI_GPE_EVENT_INFO structure by 40%.
#   There is one such structure for each GPE in the system,
#   so the size of this structure is important.
#   
#   CPU stack requirement reduction:
#   Cleaned up the method execution and object evaluation paths
#   so that now a parameter structure is passed, instead of copying
#   the various method parameters over and over again.
#   
#   In evregion.c:
#   Correctly exit and reenter the interpreter region if and only
#   if dispatching an operation region request to a user-installed
#   handler. Do not exit/reenter when dispatching to a default
#   handler (e.g., default system memory or I/O handlers)
# 
# include/acpi/actypes.h
#   2004/05/07 13:10:42-04:00 len.brown@intel.com +46 -27
#   ACPICA 20040427
# 
# include/acpi/actbl.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +16 -13
#   ACPICA 20040427
# 
# include/acpi/acstruct.h
#   2004/05/07 13:10:42-04:00 len.brown@intel.com +21 -2
#   ACPICA 20040427
# 
# include/acpi/acpixf.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +8 -2
#   ACPICA 20040427
# 
# include/acpi/acparser.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +1 -3
#   ACPICA 20040427
# 
# include/acpi/acobject.h
#   2004/05/07 13:10:42-04:00 len.brown@intel.com +7 -6
#   ACPICA 20040427
# 
# include/acpi/acnamesp.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +5 -13
#   ACPICA 20040427
# 
# include/acpi/aclocal.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +25 -14
#   ACPICA 20040427
# 
# include/acpi/achware.h
#   2004/05/07 13:10:42-04:00 len.brown@intel.com +11 -10
#   ACPICA 20040427
# 
# include/acpi/acglobal.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +1 -0
#   ACPICA 20040427
# 
# include/acpi/acexcep.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +4 -2
#   ACPICA 20040427
# 
# include/acpi/acevents.h
#   2004/05/07 13:10:42-04:00 len.brown@intel.com +48 -3
#   ACPICA 20040427
# 
# include/acpi/acdispat.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +1 -2
#   ACPICA 20040427
# 
# include/acpi/acconfig.h
#   2004/05/07 13:10:43-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040427
# 
# drivers/acpi/utilities/utxface.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +26 -15
#   ACPICA 20040427
# 
# drivers/acpi/utilities/utglobal.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +35 -21
#   ACPICA 20040427
# 
# drivers/acpi/utilities/uteval.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +11 -7
#   ACPICA 20040427
# 
# drivers/acpi/resources/rsutils.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +6 -1
#   ACPICA 20040427
# 
# drivers/acpi/parser/psxface.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +27 -25
#   ACPICA 20040427
# 
# drivers/acpi/namespace/nsxfname.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040427
# 
# drivers/acpi/namespace/nsxfeval.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +28 -24
#   ACPICA 20040427
# 
# drivers/acpi/namespace/nsparse.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +3 -2
#   ACPICA 20040427
# 
# drivers/acpi/namespace/nsinit.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +17 -14
#   ACPICA 20040427
# 
# drivers/acpi/namespace/nseval.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +32 -58
#   ACPICA 20040427
# 
# drivers/acpi/namespace/nsaccess.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040427
# 
# drivers/acpi/hardware/hwsleep.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +36 -16
#   ACPICA 20040427
# 
# drivers/acpi/hardware/hwregs.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +17 -14
#   ACPICA 20040427
# 
# drivers/acpi/hardware/hwgpe.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +92 -212
#   ACPICA 20040427
# 
# drivers/acpi/executer/exoparg2.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +33 -3
#   ACPICA 20040427
# 
# drivers/acpi/executer/exmutex.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +25 -21
#   ACPICA 20040427
# 
# drivers/acpi/executer/exconfig.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +35 -12
#   ACPICA 20040427
# 
# drivers/acpi/events/evxfregn.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +5 -195
#   ACPICA 20040427
# 
# drivers/acpi/events/evxfevnt.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +101 -75
#   ACPICA 20040427
# 
# drivers/acpi/events/evxface.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +58 -25
#   ACPICA 20040427
# 
# drivers/acpi/events/evregion.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +346 -27
#   ACPICA 20040427
# 
# drivers/acpi/events/evmisc.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +4 -0
#   ACPICA 20040427
# 
# drivers/acpi/events/evgpeblk.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +104 -46
#   ACPICA 20040427
# 
# drivers/acpi/events/evgpe.c
#   2004/05/07 13:10:45-04:00 len.brown@intel.com +343 -25
#   ACPICA 20040427
# 
# drivers/acpi/events/evevent.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +6 -6
#   ACPICA 20040427
# 
# drivers/acpi/dispatcher/dswstate.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +13 -5
#   ACPICA 20040427
# 
# drivers/acpi/dispatcher/dsopcode.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +2 -2
#   ACPICA 20040427
# 
# drivers/acpi/dispatcher/dsmethod.c
#   2004/05/07 13:10:46-04:00 len.brown@intel.com +10 -6
#   ACPICA 20040427
# 
# ChangeSet
#   2004/05/07 17:21:19-04:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040402 from Bob Moore
#   
#   Fixed an interpreter problem where an indirect store through an
#   ArgX parameter was incorrectly applying the "implicit conversion
#   rules" during the store.  From the ACPI specification: "If the
#   target is a method local or argument (LocalX or ArgX), no
#   conversion is performed and the result is stored directly to the
#   target".  The new behavior is to disable implicit conversion
#   during ALL stores to an ArgX.
#   
#   Changed the behavior of the _PRW method scan to ignore any and
#   all errors returned by a given _PRW.  This prevents the scan from
#   aborting from the failure of any single _PRW.
#   
#   Moved the runtime configuration parameters from the global init
#   procedure to static variables in acglobal.h.  This will allow the
#   host to override the default values easily.
# 
# include/acpi/acinterp.h
#   2004/05/07 13:11:48-04:00 len.brown@intel.com +4 -1
#   ACPICA 20040402
# 
# include/acpi/acglobal.h
#   2004/05/07 13:11:49-04:00 len.brown@intel.com +29 -7
#   ACPICA 20040402
# 
# include/acpi/acdisasm.h
#   2004/05/07 13:11:49-04:00 len.brown@intel.com +15 -0
#   ACPICA 20040402
# 
# include/acpi/acconfig.h
#   2004/05/07 13:11:49-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040402
# 
# drivers/acpi/utilities/utglobal.c
#   2004/05/07 13:11:52-04:00 len.brown@intel.com +16 -10
#   ACPICA 20040402
# 
# drivers/acpi/executer/exstore.c
#   2004/05/07 13:11:52-04:00 len.brown@intel.com +14 -3
#   ACPICA 20040402
# 
# drivers/acpi/executer/exfldio.c
#   2004/05/07 13:11:52-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040402
# 
# drivers/acpi/events/evmisc.c
#   2004/05/07 13:11:51-04:00 len.brown@intel.com +1 -1
#   ACPICA 20040402
# 
# drivers/acpi/events/evgpeblk.c
#   2004/05/07 13:11:51-04:00 len.brown@intel.com +4 -6
#   ACPICA 20040402
# 
# drivers/acpi/dispatcher/dswload.c
#   2004/05/07 13:11:51-04:00 len.brown@intel.com +22 -0
#   ACPICA 20040402
# 
# drivers/acpi/dispatcher/dsmthdat.c
#   2004/05/07 13:11:51-04:00 len.brown@intel.com +5 -3
#   ACPICA 20040402
# 
# ChangeSet
#   2004/05/03 12:31:49-04:00 len.brown@intel.com 
#   Cset exclude: torvalds@evo.osdl.org|ChangeSet|20040401021818|60003
# 
# drivers/acpi/utilities/utglobal.c
#   2004/05/03 12:31:41-04:00 len.brown@intel.com +0 -0
#   Exclude
# 
# drivers/acpi/osl.c
#   2004/05/03 12:31:41-04:00 len.brown@intel.com +0 -0
#   Exclude
# 
diff -Nru a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c	Sat Jul 17 03:30:00 2004
+++ b/arch/i386/kernel/acpi/boot.c	Sat Jul 17 03:30:00 2004
@@ -83,6 +83,11 @@
 #warning ACPI uses CMPXCHG, i486 and later hardware
 #endif
 
+#define MAX_MADT_ENTRIES	256
+u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
+			{ [0 ... MAX_MADT_ENTRIES-1] = 0xff };
+EXPORT_SYMBOL(x86_acpiid_to_apicid);
+
 /* --------------------------------------------------------------------------
                               Boot-time Configuration
    -------------------------------------------------------------------------- */
@@ -223,6 +228,8 @@
 	/* no utility in registering a disabled processor */
 	if (processor->flags.enabled == 0)
 		return 0;
+
+	x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
 
 	mp_register_lapic (
 		processor->id,					   /* APIC ID */
diff -Nru a/arch/i386/kernel/cpu/cpufreq/acpi.c b/arch/i386/kernel/cpu/cpufreq/acpi.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi.c	Sat Jul 17 03:29:59 2004
+++ b/arch/i386/kernel/cpu/cpufreq/acpi.c	Sat Jul 17 03:29:59 2004
@@ -108,13 +108,27 @@
 	u32			value = 0;
 	int			i = 0;
 	struct cpufreq_freqs    cpufreq_freqs;
+	cpumask_t		saved_mask;
+	int			retval;
 
 	ACPI_FUNCTION_TRACE("acpi_processor_set_performance");
 
+	/*
+	 * TBD: Use something other than set_cpus_allowed.
+	 * As set_cpus_allowed is a bit racy, 
+	 * with any other set_cpus_allowed for this process.
+	 */
+	saved_mask = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(cpu));
+	if (smp_processor_id() != cpu) {
+		return_VALUE(-EAGAIN);
+	}
+	
 	if (state == data->acpi_data.state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
 			"Already at target state (P%d)\n", state));
-		return_VALUE(0);
+		retval = 0;
+		goto migrate_end;
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Transitioning from P%d to P%d\n",
@@ -144,7 +158,8 @@
 	if (ret) {
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
 			"Invalid port width 0x%04x\n", bit_width));
-		return_VALUE(ret);
+		retval = ret;
+		goto migrate_end;
 	}
 
 	/*
@@ -166,7 +181,8 @@
 		if (ret) {	
 			ACPI_DEBUG_PRINT((ACPI_DB_WARN,
 				"Invalid port width 0x%04x\n", bit_width));
-			return_VALUE(ret);
+			retval = ret;
+			goto migrate_end;
 		}
 		if (value == (u32) data->acpi_data.states[state].status)
 			break;
@@ -183,7 +199,8 @@
 		cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_PRECHANGE);
 		cpufreq_notify_transition(&cpufreq_freqs, CPUFREQ_POSTCHANGE);
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Transition failed\n"));
-		return_VALUE(-ENODEV);
+		retval = -ENODEV;
+		goto migrate_end;
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
@@ -192,7 +209,10 @@
 
 	data->acpi_data.state = state;
 
-	return_VALUE(0);
+	retval = 0;
+migrate_end:
+	set_cpus_allowed(current, saved_mask);
+	return_VALUE(retval);
 }
 
 
@@ -266,6 +286,69 @@
 	
 }
 
+
+/* 
+ * acpi_processor_cpu_init_pdc_est - let BIOS know about the SMP capabilities
+ * of this driver
+ * @perf: processor-specific acpi_io_data struct
+ * @cpu: CPU being initialized
+ *
+ * To avoid issues with legacy OSes, some BIOSes require to be informed of
+ * the SMP capabilities of OS P-state driver. Here we set the bits in _PDC 
+ * accordingly, for Enhanced Speedstep. Actual call to _PDC is done in
+ * driver/acpi/processor.c
+ */
+static void 
+acpi_processor_cpu_init_pdc_est(
+		struct acpi_processor_performance *perf, 
+		unsigned int cpu,
+		struct acpi_object_list *obj_list
+		)
+{
+	union acpi_object *obj;
+	u32 *buf;
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+	ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc_est");
+
+	if (!cpu_has(c, X86_FEATURE_EST))
+		return_VOID;
+
+	/* Initialize pdc. It will be used later. */
+	if (!obj_list)
+		return_VOID;
+		
+	if (!(obj_list->count && obj_list->pointer))
+		return_VOID;
+
+	obj = obj_list->pointer;
+	if ((obj->buffer.length == 12) && obj->buffer.pointer) {
+		buf = (u32 *)obj->buffer.pointer;
+       		buf[0] = ACPI_PDC_REVISION_ID;
+       		buf[1] = 1;
+       		buf[2] = ACPI_PDC_EST_CAPABILITY_SMP;
+		perf->pdc = obj_list;
+	}
+	return_VOID;
+}
+ 
+
+/* CPU specific PDC initialization */
+static void 
+acpi_processor_cpu_init_pdc(
+		struct acpi_processor_performance *perf, 
+		unsigned int cpu,
+		struct acpi_object_list *obj_list
+		)
+{
+	struct cpuinfo_x86 *c = cpu_data + cpu;
+	ACPI_FUNCTION_TRACE("acpi_processor_cpu_init_pdc");
+	perf->pdc = NULL;
+	if (cpu_has(c, X86_FEATURE_EST))
+		acpi_processor_cpu_init_pdc_est(perf, cpu, obj_list);
+	return_VOID;
+}
+
+
 static int
 acpi_cpufreq_cpu_init (
 	struct cpufreq_policy   *policy)
@@ -275,7 +358,14 @@
 	struct cpufreq_acpi_io	*data;
 	unsigned int		result = 0;
 
+	union acpi_object		arg0 = {ACPI_TYPE_BUFFER};
+	u32				arg0_buf[3];
+	struct acpi_object_list 	arg_list = {1, &arg0};
+
 	ACPI_FUNCTION_TRACE("acpi_cpufreq_cpu_init");
+	/* setup arg_list for _PDC settings */
+        arg0.buffer.length = 12;
+        arg0.buffer.pointer = (u8 *) arg0_buf;
 
 	data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
 	if (!data)
@@ -284,7 +374,10 @@
 
 	acpi_io_data[cpu] = data;
 
+	acpi_processor_cpu_init_pdc(&data->acpi_data, cpu, &arg_list);
 	result = acpi_processor_register_performance(&data->acpi_data, cpu);
+	data->acpi_data.pdc = NULL;
+
 	if (result)
 		goto err_free;
 
diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c	Sat Jul 17 03:30:00 2004
+++ b/arch/i386/kernel/i8259.c	Sat Jul 17 03:30:00 2004
@@ -238,14 +238,39 @@
 	}
 }
 
+static char irq_trigger[2];
+/**
+ * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
+ */
+static void restore_ELCR(char *trigger)
+{
+	outb(trigger[0], 0x4d0);
+	outb(trigger[1], 0x4d1);
+}
+
+static void save_ELCR(char *trigger)
+{
+	/* IRQ 0,1,2,8,13 are marked as reserved */
+	trigger[0] = inb(0x4d0) & 0xF8;
+	trigger[1] = inb(0x4d1) & 0xDE;
+}
+
 static int i8259A_resume(struct sys_device *dev)
 {
 	init_8259A(0);
+	restore_ELCR(irq_trigger);
+	return 0;
+}
+
+static int i8259A_suspend(struct sys_device *dev, u32 state)
+{
+	save_ELCR(irq_trigger);
 	return 0;
 }
 
 static struct sysdev_class i8259_sysdev_class = {
 	set_kset_name("i8259"),
+	.suspend = i8259A_suspend,
 	.resume = i8259A_resume,
 };
 
diff -Nru a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
--- a/arch/i386/kernel/io_apic.c	Sat Jul 17 03:29:59 2004
+++ b/arch/i386/kernel/io_apic.c	Sat Jul 17 03:29:59 2004
@@ -32,6 +32,7 @@
 #include <linux/compiler.h>
 #include <linux/acpi.h>
 
+#include <linux/sysdev.h>
 #include <asm/io.h>
 #include <asm/smp.h>
 #include <asm/desc.h>
@@ -2315,6 +2316,98 @@
 }
 
 late_initcall(io_apic_bug_finalize);
+
+struct sysfs_ioapic_data {
+	struct sys_device dev;
+	struct IO_APIC_route_entry entry[0];
+};
+static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
+
+static int ioapic_suspend(struct sys_device *dev, u32 state)
+{
+	struct IO_APIC_route_entry *entry;
+	struct sysfs_ioapic_data *data;
+	unsigned long flags;
+	int i;
+	
+	data = container_of(dev, struct sysfs_ioapic_data, dev);
+	entry = data->entry;
+	spin_lock_irqsave(&ioapic_lock, flags);
+	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
+		*(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
+		*(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
+	}
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return 0;
+}
+
+static int ioapic_resume(struct sys_device *dev)
+{
+	struct IO_APIC_route_entry *entry;
+	struct sysfs_ioapic_data *data;
+	unsigned long flags;
+	union IO_APIC_reg_00 reg_00;
+	int i;
+	
+	data = container_of(dev, struct sysfs_ioapic_data, dev);
+	entry = data->entry;
+
+	spin_lock_irqsave(&ioapic_lock, flags);
+	reg_00.raw = io_apic_read(dev->id, 0);
+	if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
+		reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
+		io_apic_write(dev->id, 0, reg_00.raw);
+	}
+	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
+		io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
+		io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
+	}
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+
+	return 0;
+}
+
+static struct sysdev_class ioapic_sysdev_class = {
+	set_kset_name("ioapic"),
+	.suspend = ioapic_suspend,
+	.resume = ioapic_resume,
+};
+
+static int __init ioapic_init_sysfs(void)
+{
+	struct sys_device * dev;
+	int i, size, error = 0;
+
+	error = sysdev_class_register(&ioapic_sysdev_class);
+	if (error)
+		return error;
+
+	for (i = 0; i < nr_ioapics; i++ ) {
+		size = sizeof(struct sys_device) + nr_ioapic_registers[i] 
+			* sizeof(struct IO_APIC_route_entry);
+		mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL);
+		if (!mp_ioapic_data[i]) {
+			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
+			continue;
+		}
+		memset(mp_ioapic_data[i], 0, size);
+		dev = &mp_ioapic_data[i]->dev;
+		dev->id = i; 
+		dev->cls = &ioapic_sysdev_class;
+		error = sysdev_register(dev);
+		if (error) {
+			kfree(mp_ioapic_data[i]);
+			mp_ioapic_data[i] = NULL;
+			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+device_initcall(ioapic_init_sysfs);
 
 /* --------------------------------------------------------------------------
                           ACPI-based IOAPIC Configuration
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Sat Jul 17 03:29:59 2004
+++ b/arch/i386/kernel/setup.c	Sat Jul 17 03:29:59 2004
@@ -49,6 +49,7 @@
 #include <asm/ist.h>
 #include <asm/std_resources.h>
 #include "setup_arch_pre.h"
+#include <bios_ebda.h>
 
 /* This value is set up by the early boot code to point to the value
    immediately after the boot time page tables.  It contains a *physical*
@@ -808,6 +809,17 @@
 	}
 }
 
+/*
+ * workaround for Dell systems that neglect to reserve EBDA
+ */
+static void __init reserve_ebda_region(void)
+{
+	unsigned int addr;
+	addr = get_bios_ebda();
+	if (addr)
+		reserve_bootmem(addr, PAGE_SIZE);	
+}
+
 static unsigned long __init setup_memory(void)
 {
 	unsigned long bootmap_size, start_pfn, max_low_pfn;
@@ -853,6 +865,9 @@
 	 * enabling clean reboots, SMP operation, laptop functions.
 	 */
 	reserve_bootmem(0, PAGE_SIZE);
+
+	/* reserve EBDA region, it's a 4K region */
+	reserve_ebda_region();
 
     /* could be an AMD 768MPX chipset. Reserve a page  before VGA to prevent
        PCI prefetch into it (errata #56). Usually the page is reserved anyways,
diff -Nru a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c	Sat Jul 17 03:29:59 2004
+++ b/arch/i386/kernel/smpboot.c	Sat Jul 17 03:29:59 2004
@@ -73,6 +73,10 @@
 /* Per CPU bogomips and other parameters */
 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
 
+u8 x86_cpu_to_apicid[NR_CPUS] =
+			{ [0 ... NR_CPUS-1] = 0xff };
+EXPORT_SYMBOL(x86_cpu_to_apicid);
+
 /* Set when the idlers are all forked */
 int smp_threads_ready;
 
@@ -871,6 +875,7 @@
 			inquire_remote_apic(apicid);
 		}
 	}
+	x86_cpu_to_apicid[cpu] = apicid;
 	if (boot_error) {
 		/* Try to put things back the way they were before ... */
 		unmap_cpu_to_logical_apicid(cpu);
@@ -953,6 +958,7 @@
 
 	boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
 	boot_cpu_logical_apicid = logical_smp_processor_id();
+	x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
 
 	current_thread_info()->cpu = 0;
 	smp_tune_scheduling();
diff -Nru a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
--- a/arch/i386/mm/discontig.c	Sat Jul 17 03:29:59 2004
+++ b/arch/i386/mm/discontig.c	Sat Jul 17 03:29:59 2004
@@ -31,6 +31,7 @@
 #include <asm/e820.h>
 #include <asm/setup.h>
 #include <asm/mmzone.h>
+#include <bios_ebda.h>
 
 struct pglist_data *node_data[MAX_NUMNODES];
 bootmem_data_t node0_bdata;
@@ -227,6 +228,17 @@
 	return reserve_pages;
 }
 
+/*
+ * workaround for Dell systems that neglect to reserve EBDA
+ */
+static void __init reserve_ebda_region_node(void)
+{
+	unsigned int addr;
+	addr = get_bios_ebda();
+	if (addr)
+		reserve_bootmem_node(NODE_DATA(0), addr, PAGE_SIZE);
+}
+
 unsigned long __init setup_memory(void)
 {
 	int nid;
@@ -300,6 +312,9 @@
 	 * trampoline before removing it. (see the GDT stuff)
 	 */
 	reserve_bootmem_node(NODE_DATA(0), PAGE_SIZE, PAGE_SIZE);
+
+	/* reserve EBDA region, it's a 4K region */
+	reserve_ebda_region_node();
 
 #ifdef CONFIG_ACPI_SLEEP
 	/*
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	Sat Jul 17 03:29:59 2004
+++ b/arch/ia64/kernel/acpi.c	Sat Jul 17 03:29:59 2004
@@ -65,6 +65,11 @@
 unsigned char acpi_kbd_controller_present = 1;
 unsigned char acpi_legacy_devices;
 
+#define MAX_SAPICS 256
+u16 ia64_acpiid_to_sapicid[MAX_SAPICS] =
+	{ [0 ... MAX_SAPICS - 1] = -1 };
+EXPORT_SYMBOL(ia64_acpiid_to_sapicid);
+
 const char *
 acpi_get_sysname (void)
 {
@@ -205,6 +210,7 @@
 		    == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
 			printk(" (BSP)");
 #endif
+		ia64_acpiid_to_sapicid[lsapic->acpi_id] = (lsapic->id << 8) | lsapic->eid;
 		++available_cpus;
 	}
 
diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
--- a/arch/x86_64/kernel/i8259.c	Sat Jul 17 03:29:59 2004
+++ b/arch/x86_64/kernel/i8259.c	Sat Jul 17 03:29:59 2004
@@ -318,7 +318,7 @@
 	}
 }
 
-void __init init_8259A(int auto_eoi)
+void init_8259A(int auto_eoi)
 {
 	unsigned long flags;
 
@@ -360,6 +360,57 @@
 
 	spin_unlock_irqrestore(&i8259A_lock, flags);
 }
+
+static char irq_trigger[2];
+/**
+ * ELCR registers (0x4d0, 0x4d1) control edge/level of IRQ
+ */
+static void restore_ELCR(char *trigger)
+{
+	outb(trigger[0], 0x4d0);
+	outb(trigger[1], 0x4d1);
+}
+
+static void save_ELCR(char *trigger)
+{
+	/* IRQ 0,1,2,8,13 are marked as reserved */
+	trigger[0] = inb(0x4d0) & 0xF8;
+	trigger[1] = inb(0x4d1) & 0xDE;
+}
+
+static int i8259A_resume(struct sys_device *dev)
+{
+	init_8259A(0);
+	restore_ELCR(irq_trigger);
+	return 0;
+}
+
+static int i8259A_suspend(struct sys_device *dev, u32 state)
+{
+	save_ELCR(irq_trigger);
+	return 0;
+}
+
+static struct sysdev_class i8259_sysdev_class = {
+	set_kset_name("i8259"),
+	.suspend = i8259A_suspend,
+	.resume = i8259A_resume,
+};
+
+static struct sys_device device_i8259A = {
+	.id	= 0,
+	.cls	= &i8259_sysdev_class,
+};
+
+static int __init i8259A_init_sysfs(void)
+{
+	int error = sysdev_class_register(&i8259_sysdev_class);
+	if (!error)
+		error = sysdev_register(&device_i8259A);
+	return error;
+}
+
+device_initcall(i8259A_init_sysfs);
 
 /*
  * IRQ2 is cascade interrupt to second interrupt controller
diff -Nru a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c	Sat Jul 17 03:29:59 2004
+++ b/arch/x86_64/kernel/setup.c	Sat Jul 17 03:29:59 2004
@@ -422,6 +422,20 @@
 #define copy_edd() do {} while (0)
 #endif
 
+#define EBDA_ADDR_POINTER 0x40E
+static void __init reserve_ebda_region(void)
+{
+	unsigned int addr;
+	/** 
+	 * there is a real-mode segmented pointer pointing to the 
+	 * 4K EBDA area at 0x40E
+	 */
+	addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER);
+	addr <<= 4;
+	if (addr)
+		reserve_bootmem_generic(addr, PAGE_SIZE);
+}
+
 void __init setup_arch(char **cmdline_p)
 {
 	unsigned long low_mem_size;
@@ -485,6 +499,9 @@
 	 * enabling clean reboots, SMP operation, laptop functions.
 	 */
 	reserve_bootmem_generic(0, PAGE_SIZE);
+
+	/* reserve ebda region */
+	reserve_ebda_region();
 
 #ifdef CONFIG_SMP
 	/*
diff -Nru a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
--- a/arch/x86_64/kernel/smpboot.c	Sat Jul 17 03:30:00 2004
+++ b/arch/x86_64/kernel/smpboot.c	Sat Jul 17 03:30:00 2004
@@ -62,6 +62,7 @@
 
 /* which logical CPU number maps to which CPU (physical APIC ID) */
 volatile char x86_cpu_to_apicid[NR_CPUS];
+EXPORT_SYMBOL(x86_cpu_to_apicid);
 
 static cpumask_t cpu_callin_map;
 cpumask_t cpu_callout_map;
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/Makefile	Sat Jul 17 03:30:00 2004
@@ -47,4 +47,4 @@
 obj-$(CONFIG_ACPI_NUMA)		+= numa.o
 obj-$(CONFIG_ACPI_ASUS)		+= asus_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
-obj-$(CONFIG_ACPI_BUS)		+= scan.o 
+obj-$(CONFIG_ACPI_BUS)		+= scan.o motherboard.o
diff -Nru a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c
--- a/drivers/acpi/acpi_ksyms.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/acpi_ksyms.c	Sat Jul 17 03:29:59 2004
@@ -84,6 +84,8 @@
 EXPORT_SYMBOL(acpi_enable_event);
 EXPORT_SYMBOL(acpi_disable_event);
 EXPORT_SYMBOL(acpi_clear_event);
+EXPORT_SYMBOL(acpi_set_gpe_type);
+EXPORT_SYMBOL(acpi_enable_gpe);
 EXPORT_SYMBOL(acpi_get_timer_duration);
 EXPORT_SYMBOL(acpi_get_timer);
 EXPORT_SYMBOL(acpi_get_sleep_type_data);
diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c
--- a/drivers/acpi/button.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/button.c	Sat Jul 17 03:29:59 2004
@@ -456,6 +456,15 @@
 		goto end;
 	}
 
+	if (device->wakeup.flags.valid) {
+		/* Button's GPE is run-wake GPE */
+		acpi_set_gpe_type(device->wakeup.gpe_device, 
+			device->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+		acpi_enable_gpe(device->wakeup.gpe_device, 
+			device->wakeup.gpe_number, ACPI_NOT_ISR);
+		device->wakeup.state.enabled = 1;
+	}
+
 	printk(KERN_INFO PREFIX "%s [%s]\n", 
 		acpi_device_name(device), acpi_device_bid(device));
 
diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
--- a/drivers/acpi/dispatcher/dsmethod.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/dispatcher/dsmethod.c	Sat Jul 17 03:29:59 2004
@@ -145,8 +145,9 @@
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	status = acpi_ds_init_aml_walk (walk_state, op, node, obj_desc->method.aml_start,
-			  obj_desc->method.aml_length, NULL, NULL, 1);
+	status = acpi_ds_init_aml_walk (walk_state, op, node,
+			  obj_desc->method.aml_start,
+			  obj_desc->method.aml_length, NULL, 1);
 	if (ACPI_FAILURE (status)) {
 		acpi_ds_delete_walk_state (walk_state);
 		return_ACPI_STATUS (status);
@@ -267,8 +268,9 @@
 {
 	acpi_status                     status;
 	struct acpi_namespace_node      *method_node;
-	union acpi_operand_object       *obj_desc;
 	struct acpi_walk_state          *next_walk_state;
+	union acpi_operand_object       *obj_desc;
+	struct acpi_parameter_info      info;
 	u32                             i;
 
 
@@ -309,7 +311,6 @@
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
 
-
 		/* Create and init a Root Node */
 
 		op = acpi_ps_create_scope_op ();
@@ -320,7 +321,7 @@
 
 		status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
 				  obj_desc->method.aml_start, obj_desc->method.aml_length,
-				  NULL, NULL, 1);
+				  NULL, 1);
 		if (ACPI_FAILURE (status)) {
 			acpi_ds_delete_walk_state (next_walk_state);
 			goto cleanup;
@@ -348,9 +349,12 @@
 	 */
 	this_walk_state->operands [this_walk_state->num_operands] = NULL;
 
+	info.parameters = &this_walk_state->operands[0];
+	info.parameter_type = ACPI_PARAM_ARGS;
+
 	status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node,
 			  obj_desc->method.aml_start, obj_desc->method.aml_length,
-			  &this_walk_state->operands[0], NULL, 3);
+			  &info, 3);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
@@ -382,7 +386,7 @@
 	/* On error, we must delete the new walk state */
 
 cleanup:
-	if (next_walk_state->method_desc) {
+	if (next_walk_state && (next_walk_state->method_desc)) {
 		/* Decrement the thread count on the method parse tree */
 
 	   next_walk_state->method_desc->method.thread_count--;
diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
--- a/drivers/acpi/dispatcher/dsmthdat.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/dispatcher/dsmthdat.c	Sat Jul 17 03:29:59 2004
@@ -656,11 +656,13 @@
 						new_obj_desc, current_obj_desc));
 
 				/*
-				 * Store this object to the Node
-				 * (perform the indirect store)
+				 * Store this object to the Node (perform the indirect store)
+				 * NOTE: No implicit conversion is performed, as per the ACPI
+				 * specification rules on storing to Locals/Args.
 				 */
 				status = acpi_ex_store_object_to_node (new_obj_desc,
-						 current_obj_desc->reference.object, walk_state);
+						 current_obj_desc->reference.object, walk_state,
+						 ACPI_NO_IMPLICIT_CONVERSION);
 
 				/* Remove local reference if we copied the object above */
 
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/dispatcher/dsopcode.c	Sat Jul 17 03:30:00 2004
@@ -79,7 +79,6 @@
 	acpi_status                     status;
 	union acpi_parse_object         *op;
 	struct acpi_walk_state          *walk_state;
-	union acpi_parse_object         *arg;
 
 
 	ACPI_FUNCTION_TRACE ("ds_execute_arguments");
@@ -105,7 +104,7 @@
 	}
 
 	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
-			  aml_length, NULL, NULL, 1);
+			  aml_length, NULL, 1);
 	if (ACPI_FAILURE (status)) {
 		acpi_ds_delete_walk_state (walk_state);
 		return_ACPI_STATUS (status);
@@ -126,9 +125,7 @@
 
 	/* Get and init the Op created above */
 
-	arg = op->common.value.arg;
 	op->common.node = node;
-	arg->common.node = node;
 	acpi_ps_delete_parse_tree (op);
 
 	/* Evaluate the deferred arguments */
@@ -150,7 +147,7 @@
 	/* Execute the opcode and arguments */
 
 	status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
-			  aml_length, NULL, NULL, 3);
+			  aml_length, NULL, 3);
 	if (ACPI_FAILURE (status)) {
 		acpi_ds_delete_walk_state (walk_state);
 		return_ACPI_STATUS (status);
diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
--- a/drivers/acpi/dispatcher/dswload.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/dispatcher/dswload.c	Sat Jul 17 03:29:59 2004
@@ -50,6 +50,9 @@
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
 
+#ifdef _ACPI_ASL_COMPILER
+#include <acpi/acdisasm.h>
+#endif
 
 #define _COMPONENT          ACPI_DISPATCHER
 	 ACPI_MODULE_NAME    ("dswload")
@@ -180,7 +183,17 @@
 		status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
 				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
 		if (ACPI_FAILURE (status)) {
+#ifdef _ACPI_ASL_COMPILER
+			if (status == AE_NOT_FOUND) {
+				acpi_dm_add_to_external_list (path);
+				status = AE_OK;
+			}
+			else {
+				ACPI_REPORT_NSERROR (path, status);
+			}
+#else
 			ACPI_REPORT_NSERROR (path, status);
+#endif
 			return (status);
 		}
 
@@ -529,7 +542,16 @@
 		status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
 				  ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
 		if (ACPI_FAILURE (status)) {
+#ifdef _ACPI_ASL_COMPILER
+			if (status == AE_NOT_FOUND) {
+				status = AE_OK;
+			}
+			else {
+				ACPI_REPORT_NSERROR (buffer_ptr, status);
+			}
+#else
 			ACPI_REPORT_NSERROR (buffer_ptr, status);
+#endif
 			return_ACPI_STATUS (status);
 		}
 		/*
diff -Nru a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
--- a/drivers/acpi/dispatcher/dswstate.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/dispatcher/dswstate.c	Sat Jul 17 03:30:00 2004
@@ -906,8 +906,7 @@
 	struct acpi_namespace_node      *method_node,
 	u8                              *aml_start,
 	u32                             aml_length,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc,
+	struct acpi_parameter_info      *info,
 	u32                             pass_number)
 {
 	acpi_status                     status;
@@ -926,8 +925,17 @@
 	/* The next_op of the next_walk will be the beginning of the method */
 
 	walk_state->next_op             = NULL;
-	walk_state->params              = params;
-	walk_state->caller_return_desc  = return_obj_desc;
+
+	if (info) {
+		if (info->parameter_type == ACPI_PARAM_GPE) {
+			walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
+					   info->parameters);
+		}
+		else {
+			walk_state->params              = info->parameters;
+			walk_state->caller_return_desc  = &info->return_object;
+		}
+	}
 
 	status = acpi_ps_init_scope (&walk_state->parser_state, op);
 	if (ACPI_FAILURE (status)) {
@@ -949,7 +957,7 @@
 
 		/* Init the method arguments */
 
-		status = acpi_ds_method_data_init_args (params, ACPI_METHOD_NUM_ARGS, walk_state);
+		status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/ec.c	Sat Jul 17 03:29:59 2004
@@ -381,7 +381,7 @@
 	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 }
 
-static void
+static u32
 acpi_ec_gpe_handler (
 	void			*data)
 {
@@ -389,12 +389,17 @@
 	struct acpi_ec		*ec = (struct acpi_ec *) data;
 
 	if (!ec)
-		return;
+		return ACPI_INTERRUPT_NOT_HANDLED;
 
 	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
 
 	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
 		acpi_ec_gpe_query, ec);
+
+	if (status == AE_OK)
+		return ACPI_INTERRUPT_HANDLED;
+	else
+		return ACPI_INTERRUPT_NOT_HANDLED;
 }
 
 /* --------------------------------------------------------------------------
@@ -729,6 +734,8 @@
 	if (ACPI_FAILURE(status)) {
 		return_VALUE(-ENODEV);
 	}
+	acpi_set_gpe_type (NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe (NULL, ec->gpe_bit, ACPI_NOT_ISR);
 
 	status = acpi_install_address_space_handler (ec->handle,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
@@ -814,6 +821,8 @@
 	if (ACPI_FAILURE(status)) {
 		goto error;
 	}
+	acpi_set_gpe_type (NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
+	acpi_enable_gpe (NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
 
 	status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler,
diff -Nru a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
--- a/drivers/acpi/events/evevent.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/events/evevent.c	Sat Jul 17 03:30:00 2004
@@ -50,7 +50,7 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_initialize
+ * FUNCTION:    acpi_ev_initialize_events
  *
  * PARAMETERS:  None
  *
@@ -61,13 +61,13 @@
  ******************************************************************************/
 
 acpi_status
-acpi_ev_initialize (
+acpi_ev_initialize_events (
 	void)
 {
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_TRACE ("ev_initialize");
+	ACPI_FUNCTION_TRACE ("ev_initialize_events");
 
 
 	/* Make sure we have ACPI tables */
@@ -104,7 +104,7 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_handler_initialize
+ * FUNCTION:    acpi_ev_install_xrupt_handlers
  *
  * PARAMETERS:  None
  *
@@ -115,13 +115,13 @@
  ******************************************************************************/
 
 acpi_status
-acpi_ev_handler_initialize (
+acpi_ev_install_xrupt_handlers (
 	void)
 {
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_TRACE ("ev_handler_initialize");
+	ACPI_FUNCTION_TRACE ("ev_install_xrupt_handlers");
 
 
 	/* Install the SCI handler */
diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- a/drivers/acpi/events/evgpe.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evgpe.c	Sat Jul 17 03:29:59 2004
@@ -51,6 +51,249 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ev_set_gpe_type
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to set
+ *              Type                    - New type
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_set_gpe_type (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              type)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_set_gpe_type");
+
+
+	/* Validate type and update register enable masks */
+
+	switch (type) {
+	case ACPI_GPE_TYPE_WAKE:
+	case ACPI_GPE_TYPE_RUNTIME:
+	case ACPI_GPE_TYPE_WAKE_RUN:
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	/* Disable the GPE if currently enabled */
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
+
+	/* Type was validated above */
+
+	gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
+	gpe_event_info->flags |= type;              /* Insert type */
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_update_gpe_enable_masks
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to update
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Updates GPE register enable masks based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_update_gpe_enable_masks (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              type)
+{
+	struct acpi_gpe_register_info   *gpe_register_info;
+	u8                              register_bit;
+
+
+	ACPI_FUNCTION_TRACE ("ev_update_gpe_enable_masks");
+
+
+	gpe_register_info = gpe_event_info->register_info;
+	if (!gpe_register_info) {
+		return_ACPI_STATUS (AE_NOT_EXIST);
+	}
+	register_bit = gpe_event_info->register_bit;
+
+	/* 1) Disable case.  Simply clear all enable bits */
+
+	if (type == ACPI_GPE_DISABLE) {
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* 2) Enable case.  Set/Clear the appropriate enable bits */
+
+	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+	case ACPI_GPE_TYPE_WAKE:
+		ACPI_SET_BIT   (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
+		break;
+
+	case ACPI_GPE_TYPE_RUNTIME:
+		ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_SET_BIT   (gpe_register_info->enable_for_run, register_bit);
+		break;
+
+	case ACPI_GPE_TYPE_WAKE_RUN:
+		ACPI_SET_BIT   (gpe_register_info->enable_for_wake, register_bit);
+		ACPI_SET_BIT   (gpe_register_info->enable_for_run, register_bit);
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_enable_gpe
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to enable
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable a GPE based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_enable_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              write_to_hardware)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_enable_gpe");
+
+
+	/* Make sure HW enable masks are updated */
+
+	status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_ENABLE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Mark wake-enabled or HW enable, or both */
+
+	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+	case ACPI_GPE_TYPE_WAKE:
+
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+		break;
+
+	case ACPI_GPE_TYPE_WAKE_RUN:
+
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+
+		/*lint -fallthrough */
+
+	case ACPI_GPE_TYPE_RUNTIME:
+
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
+
+		if (write_to_hardware) {
+			/* Clear the GPE (of stale events), then enable it */
+
+			status = acpi_hw_clear_gpe (gpe_event_info);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+
+			/* Enable the requested runtime GPE */
+
+			status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
+		}
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_disable_gpe
+ *
+ * PARAMETERS:  gpe_event_info          - GPE to disable
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable a GPE based on the GPE type
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_disable_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_disable_gpe");
+
+
+	if (!(gpe_event_info->flags & ACPI_GPE_ENABLE_MASK)) {
+		return_ACPI_STATUS (AE_OK);
+	}
+
+	/* Make sure HW enable masks are updated */
+
+	status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/* Mark wake-disabled or HW disable, or both */
+
+	switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
+	case ACPI_GPE_TYPE_WAKE:
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+		break;
+
+	case ACPI_GPE_TYPE_WAKE_RUN:
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
+
+		/*lint -fallthrough */
+
+	case ACPI_GPE_TYPE_RUNTIME:
+
+		/* Disable the requested runtime GPE */
+
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
+		status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
+		break;
+
+	default:
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ev_get_gpe_event_info
  *
  * PARAMETERS:  gpe_device          - Device node.  NULL for GPE0/GPE1
@@ -139,11 +382,12 @@
 	u32                             int_status = ACPI_INTERRUPT_NOT_HANDLED;
 	u8                              enabled_status_byte;
 	struct acpi_gpe_register_info   *gpe_register_info;
-	u32                             in_value;
+	u32                             status_reg;
+	u32                             enable_reg;
 	acpi_status                     status;
 	struct acpi_gpe_block_info      *gpe_block;
-	u32                             i;
-	u32                             j;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
 
 
 	ACPI_FUNCTION_NAME ("ev_gpe_detect");
@@ -171,33 +415,32 @@
 
 			/* Read the Status Register */
 
-			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
+			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &status_reg,
 					 &gpe_register_info->status_address);
-			gpe_register_info->status = (u8) in_value;
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
 
 			/* Read the Enable Register */
 
-			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value,
+			status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &enable_reg,
 					 &gpe_register_info->enable_address);
-			gpe_register_info->enable = (u8) in_value;
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
 				"GPE pair: Status %8.8X%8.8X = %02X, Enable %8.8X%8.8X = %02X\n",
-				ACPI_FORMAT_UINT64 (gpe_register_info->status_address.address),
-				gpe_register_info->status,
-				ACPI_FORMAT_UINT64 (gpe_register_info->enable_address.address),
-				gpe_register_info->enable));
+				ACPI_FORMAT_UINT64 (
+					gpe_register_info->status_address.address),
+					status_reg,
+				ACPI_FORMAT_UINT64 (
+					gpe_register_info->enable_address.address),
+					enable_reg));
 
 			/* First check if there is anything active at all in this register */
 
-			enabled_status_byte = (u8) (gpe_register_info->status &
-					   gpe_register_info->enable);
+			enabled_status_byte = (u8) (status_reg & enable_reg);
 			if (!enabled_status_byte) {
 				/* No active GPEs in this register, move on */
 
@@ -216,7 +459,7 @@
 					 */
 					int_status |= acpi_ev_gpe_dispatch (
 							  &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j],
-							  j + gpe_register_info->base_gpe_number);
+							  (u32) j + gpe_register_info->base_gpe_number);
 				}
 			}
 		}
@@ -255,6 +498,7 @@
 	u32                             gpe_number = 0;
 	acpi_status                     status;
 	struct acpi_gpe_event_info      local_gpe_event_info;
+	struct acpi_parameter_info      info;
 
 
 	ACPI_FUNCTION_TRACE ("ev_asynch_execute_gpe_method");
@@ -272,6 +516,10 @@
 		return_VOID;
 	}
 
+	/* Set the GPE flags for return to enabled state */
+
+	(void) acpi_ev_enable_gpe (gpe_event_info, FALSE);
+
 	/*
 	 * Take a snapshot of the GPE info for this level - we copy the
 	 * info to prevent a race condition with remove_handler/remove_block.
@@ -283,23 +531,33 @@
 		return_VOID;
 	}
 
-	if (local_gpe_event_info.method_node) {
+	/*
+	 * Must check for control method type dispatch one more
+	 * time to avoid race with ev_gpe_install_handler
+	 */
+	if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) {
 		/*
-		 * Invoke the GPE Method (_Lxx, _Exx):
-		 * (Evaluate the _Lxx/_Exx control method that corresponds to this GPE.)
+		 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
+		 * control method that corresponds to this GPE
 		 */
-		status = acpi_ns_evaluate_by_handle (local_gpe_event_info.method_node, NULL, NULL);
+		info.node = local_gpe_event_info.dispatch.method_node;
+		info.parameters = ACPI_CAST_PTR (union acpi_operand_object *, gpe_event_info);
+		info.parameter_type = ACPI_PARAM_GPE;
+
+		status = acpi_ns_evaluate_by_handle (&info);
 		if (ACPI_FAILURE (status)) {
-			ACPI_REPORT_ERROR (("%s while evaluating method [%4.4s] for GPE[%2X]\n",
+			ACPI_REPORT_ERROR ((
+				"%s while evaluating method [%4.4s] for GPE[%2X]\n",
 				acpi_format_exception (status),
-				acpi_ut_get_node_name (local_gpe_event_info.method_node), gpe_number));
+				acpi_ut_get_node_name (local_gpe_event_info.dispatch.method_node),
+				gpe_number));
 		}
 	}
 
 	if ((local_gpe_event_info.flags & ACPI_GPE_XRUPT_TYPE_MASK) == ACPI_GPE_LEVEL_TRIGGERED) {
 		/*
-		 * GPE is level-triggered, we clear the GPE status bit after handling
-		 * the event.
+		 * GPE is level-triggered, we clear the GPE status bit after
+		 * handling the event.
 		 */
 		status = acpi_hw_clear_gpe (&local_gpe_event_info);
 		if (ACPI_FAILURE (status)) {
@@ -309,7 +567,7 @@
 
 	/* Enable this GPE */
 
-	(void) acpi_hw_enable_gpe (&local_gpe_event_info);
+	(void) acpi_hw_write_gpe_enable_reg (&local_gpe_event_info);
 	return_VOID;
 }
 
@@ -354,6 +612,15 @@
 		}
 	}
 
+	/* Save current system state */
+
+	if (acpi_gbl_system_awake_and_running) {
+		ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
+	}
+	else {
+		ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
+	}
+
 	/*
 	 * Dispatch the GPE to either an installed handler, or the control
 	 * method associated with this GPE (_Lxx or _Exx).
@@ -361,10 +628,15 @@
 	 * If there is neither a handler nor a method, we disable the level to
 	 * prevent further events from coming in here.
 	 */
-	if (gpe_event_info->handler) {
-		/* Invoke the installed handler (at interrupt level) */
+	switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
+	case ACPI_GPE_DISPATCH_HANDLER:
 
-		gpe_event_info->handler (gpe_event_info->context);
+		/*
+		 * Invoke the installed handler (at interrupt level)
+		 * Ignore return status for now.  TBD: leave GPE disabled on error?
+		 */
+		(void) gpe_event_info->dispatch.handler->address (
+				  gpe_event_info->dispatch.handler->context);
 
 		/* It is now safe to clear level-triggered events. */
 
@@ -377,13 +649,15 @@
 				return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 			}
 		}
-	}
-	else if (gpe_event_info->method_node) {
+		break;
+
+	case ACPI_GPE_DISPATCH_METHOD:
+
 		/*
 		 * Disable GPE, so it doesn't keep firing before the method has a
 		 * chance to run.
 		 */
-		status = acpi_hw_disable_gpe (gpe_event_info);
+		status = acpi_ev_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR ((
 				"acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
@@ -402,8 +676,10 @@
 				"acpi_ev_gpe_dispatch: Unable to queue handler for GPE[%2X], event is disabled\n",
 				gpe_number));
 		}
-	}
-	else {
+		break;
+
+	default:
+
 		/* No handler or method to run! */
 
 		ACPI_REPORT_ERROR ((
@@ -414,15 +690,68 @@
 		 * Disable the GPE.  The GPE will remain disabled until the ACPI
 		 * Core Subsystem is restarted, or a handler is installed.
 		 */
-		status = acpi_hw_disable_gpe (gpe_event_info);
+		status = acpi_ev_disable_gpe (gpe_event_info);
 		if (ACPI_FAILURE (status)) {
 			ACPI_REPORT_ERROR ((
 				"acpi_ev_gpe_dispatch: Unable to disable GPE[%2X]\n",
 				gpe_number));
 			return_VALUE (ACPI_INTERRUPT_NOT_HANDLED);
 		}
+		break;
 	}
 
 	return_VALUE (ACPI_INTERRUPT_HANDLED);
 }
+
+
+#ifdef ACPI_GPE_NOTIFY_CHECK
+
+/*******************************************************************************
+ * NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
+ *
+ * FUNCTION:    acpi_ev_check_for_wake_only_gpe
+ *
+ * PARAMETERS:  gpe_event_info  - info for this GPE
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Determine if a a GPE is "wake-only".
+ *
+ *              Called from Notify() code in interpreter when a "device_wake"
+ *              Notify comes in.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_check_for_wake_only_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_check_for_wake_only_gpe");
+
+
+	if ((gpe_event_info) &&  /* Only >0 for _Lxx/_Exx */
+	   ((gpe_event_info->flags & ACPI_GPE_SYSTEM_MASK) == ACPI_GPE_SYSTEM_RUNNING)) /* System state at GPE time */ {
+		/* This must be a wake-only GPE, disable it */
+
+		status = acpi_ev_disable_gpe (gpe_event_info);
+
+		/* Set GPE to wake-only.  Do not change wake disabled/enabled status */
+
+		acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+
+		ACPI_REPORT_INFO (("GPE %p was updated from wake/run to wake-only\n",
+				gpe_event_info));
+
+		/* This was a wake-only GPE */
+
+		return_ACPI_STATUS (AE_WAKE_ONLY_GPE);
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+#endif
+
 
diff -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
--- a/drivers/acpi/events/evgpeblk.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evgpeblk.c	Sat Jul 17 03:29:59 2004
@@ -53,7 +53,7 @@
  *
  * FUNCTION:    acpi_ev_valid_gpe_event
  *
- * PARAMETERS:  gpe_event_info - Info for this GPE
+ * PARAMETERS:  gpe_event_info              - Info for this GPE
  *
  * RETURN:      TRUE if the gpe_event is valid
  *
@@ -105,17 +105,18 @@
  * FUNCTION:    acpi_ev_walk_gpe_list
  *
  * PARAMETERS:  gpe_walk_callback   - Routine called for each GPE block
+ *              Flags               - ACPI_NOT_ISR or ACPI_ISR
  *
  * RETURN:      Status
  *
  * DESCRIPTION: Walk the GPE lists.
- *              FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
 
 acpi_status
 acpi_ev_walk_gpe_list (
-	ACPI_GPE_CALLBACK       gpe_walk_callback)
+	ACPI_GPE_CALLBACK       gpe_walk_callback,
+	u32                             flags)
 {
 	struct acpi_gpe_block_info      *gpe_block;
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_info;
@@ -125,7 +126,7 @@
 	ACPI_FUNCTION_TRACE ("ev_walk_gpe_list");
 
 
-	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_ISR);
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, flags);
 
 	/* Walk the interrupt level descriptor list */
 
@@ -149,11 +150,58 @@
 	}
 
 unlock_and_exit:
-	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_ISR);
+	acpi_os_release_lock (acpi_gbl_gpe_lock, flags);
 	return_ACPI_STATUS (status);
 }
 
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_delete_gpe_handlers
+ *
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
+ *              Used only prior to termination.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_delete_gpe_handlers (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
+{
+	struct acpi_gpe_event_info      *gpe_event_info;
+	acpi_native_uint                i;
+	acpi_native_uint                j;
+
+
+	ACPI_FUNCTION_TRACE ("ev_delete_gpe_handlers");
+
+
+	/* Examine each GPE Register within the block */
+
+	for (i = 0; i < gpe_block->register_count; i++) {
+		/* Now look at the individual GPEs in this byte register */
+
+		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
+			gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
+
+			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
+				ACPI_MEM_FREE (gpe_event_info->dispatch.handler);
+				gpe_event_info->dispatch.handler = NULL;
+				gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
+			}
+		}
+	}
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_save_method_info
@@ -188,6 +236,7 @@
 	u32                             gpe_number;
 	char                            name[ACPI_NAME_SIZE + 1];
 	u8                              type;
+	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE ("ev_save_method_info");
@@ -206,16 +255,16 @@
 	 * 2) Edge/Level determination is based on the 2nd character
 	 *    of the method name
 	 *
-	 * NOTE: Default GPE type is RUNTIME.  May be changed later to WAKE if a
-	 * _PRW object is found that points to this GPE.
+	 * NOTE: Default GPE type is RUNTIME.  May be changed later to WAKE
+	 * if a _PRW object is found that points to this GPE.
 	 */
 	switch (name[1]) {
 	case 'L':
-		type = ACPI_GPE_LEVEL_TRIGGERED | ACPI_GPE_TYPE_RUNTIME;
+		type = ACPI_GPE_LEVEL_TRIGGERED;
 		break;
 
 	case 'E':
-		type = ACPI_GPE_EDGE_TRIGGERED | ACPI_GPE_TYPE_RUNTIME;
+		type = ACPI_GPE_EDGE_TRIGGERED;
 		break;
 
 	default:
@@ -253,27 +302,35 @@
 
 	/*
 	 * Now we can add this information to the gpe_event_info block
-	 * for use during dispatch of this GPE.
+	 * for use during dispatch of this GPE.  Default type is RUNTIME, although
+	 * this may change when the _PRW methods are executed later.
 	 */
 	gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
 
-	gpe_event_info->flags    = type;
-	gpe_event_info->method_node = (struct acpi_namespace_node *) obj_handle;
+	gpe_event_info->flags = (u8) (type | ACPI_GPE_DISPATCH_METHOD |
+			   ACPI_GPE_TYPE_RUNTIME);
+
+	gpe_event_info->dispatch.method_node = (struct acpi_namespace_node *) obj_handle;
+
+	/* Update enable mask, but don't enable the HW GPE as of yet */
+
+	status = acpi_ev_enable_gpe (gpe_event_info, FALSE);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
 		"Registered GPE method %s as GPE number 0x%.2X\n",
 		name, gpe_number));
-	return_ACPI_STATUS (AE_OK);
+	return_ACPI_STATUS (status);
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_get_gpe_type
+ * FUNCTION:    acpi_ev_match_prw_and_gpe
  *
  * PARAMETERS:  Callback from walk_namespace
  *
- * RETURN:      Status
+ * RETURN:      Status.  NOTE: We ignore errors so that the _PRW walk is
+ *              not aborted on a single _PRW failure.
  *
  * DESCRIPTION: Called from acpi_walk_namespace. Expects each object to be a
  *              Device.  Run the _PRW method.  If present, extract the GPE
@@ -282,7 +339,7 @@
  ******************************************************************************/
 
 static acpi_status
-acpi_ev_get_gpe_type (
+acpi_ev_match_prw_and_gpe (
 	acpi_handle                     obj_handle,
 	u32                             level,
 	void                            *info,
@@ -299,19 +356,18 @@
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_TRACE ("ev_get_gpe_type");
+	ACPI_FUNCTION_TRACE ("ev_match_prw_and_gpe");
 
 
 	/* Check for a _PRW method under this device */
 
 	status = acpi_ut_evaluate_object (obj_handle, METHOD_NAME__PRW,
 			 ACPI_BTYPE_PACKAGE, &pkg_desc);
-	if (status == AE_NOT_FOUND) {
+	if (ACPI_FAILURE (status)) {
+		/* Ignore all errors from _PRW, we don't want to abort the subsystem */
+
 		return_ACPI_STATUS (AE_OK);
 	}
-	else if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
 
 	/* The returned _PRW package must have at least two elements */
 
@@ -370,16 +426,21 @@
 	if ((gpe_device == target_gpe_device) &&
 		(gpe_number >= gpe_block->block_base_number) &&
 		(gpe_number < gpe_block->block_base_number + (gpe_block->register_count * 8))) {
-		/* Mark GPE for WAKE but DISABLED (even for wake) */
-
 		gpe_event_info = &gpe_block->event_info[gpe_number - gpe_block->block_base_number];
-		gpe_event_info->flags |= ACPI_GPE_TYPE_WAKE;
+
+		/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
+
+		gpe_event_info->flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
+		status = acpi_ev_set_gpe_type (gpe_event_info, ACPI_GPE_TYPE_WAKE);
+		if (ACPI_FAILURE (status)) {
+			goto cleanup;
+		}
+		status = acpi_ev_update_gpe_enable_masks (gpe_event_info, ACPI_GPE_DISABLE);
 	}
 
 cleanup:
 	acpi_ut_remove_reference (pkg_desc);
-
-	return_ACPI_STATUS (status);
+	return_ACPI_STATUS (AE_OK);
 }
 
 
@@ -742,7 +803,7 @@
 		/* Init the event_info for each GPE within this register */
 
 		for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
-			this_event->bit_mask = acpi_gbl_decode_to8bit[j];
+			this_event->register_bit = acpi_gbl_decode_to8bit[j];
 			this_event->register_info = this_register;
 			this_event++;
 		}
@@ -817,6 +878,7 @@
 	acpi_status                     status;
 	struct acpi_gpe_walk_info       gpe_info;
 
+
 	ACPI_FUNCTION_TRACE ("ev_create_gpe_block");
 
 
@@ -835,6 +897,7 @@
 
 	gpe_block->register_count = register_count;
 	gpe_block->block_base_number = gpe_block_base_number;
+	gpe_block->node           = gpe_device;
 
 	ACPI_MEMCPY (&gpe_block->block_address, gpe_block_address, sizeof (struct acpi_generic_address));
 
@@ -854,18 +917,6 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* Dump info about this GPE block */
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
-		"GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
-		gpe_block->block_base_number,
-		(u32) (gpe_block->block_base_number +
-				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
-		gpe_device->name.ascii,
-		gpe_block->register_count,
-		ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
-		interrupt_level));
-
 	/* Find all GPE methods (_Lxx, _Exx) for this block */
 
 	status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device,
@@ -873,27 +924,28 @@
 			  gpe_block, NULL);
 
 	/*
-	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default is
-	 * No,they should only be enabled just as the machine goes to sleep.
+	 * Runtime option: Should Wake GPEs be enabled at runtime?  The default
+	 * is No,they should only be enabled just as the machine goes to sleep.
 	 */
 	if (acpi_gbl_leave_wake_gpes_disabled) {
 		/*
-		 * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods. (Each
-		 * GPE that has one or more _PRWs that reference it is by definition a
-		 * WAKE GPE and will not be enabled while the machine is running.)
+		 * Differentiate RUNTIME vs WAKE GPEs, via the _PRW control methods.
+		 * (Each GPE that has one or more _PRWs that reference it is by
+		 * definition a WAKE GPE and will not be enabled while the machine
+		 * is running.)
 		 */
 		gpe_info.gpe_block = gpe_block;
 		gpe_info.gpe_device = gpe_device;
 
 		status = acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
-				  ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_get_gpe_type,
+				  ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, acpi_ev_match_prw_and_gpe,
 				  &gpe_info, NULL);
 	}
 
 	/*
-	 * Enable all GPEs in this block that are 1) "runtime" GPEs, and 2) have
-	 * a corresponding _Lxx or _Exx method.  All other GPEs must be enabled via
-	 * the acpi_enable_gpe() external interface.
+	 * Enable all GPEs in this block that are 1) "runtime" or "run/wake" GPEs,
+	 * and 2) have a corresponding _Lxx or _Exx method.  All other GPEs must
+	 * be enabled via the acpi_enable_gpe() external interface.
 	 */
 	wake_gpe_count = 0;
 	gpe_enabled_count = 0;
@@ -903,23 +955,35 @@
 			/* Get the info block for this particular GPE */
 
 			gpe_event_info = &gpe_block->event_info[(i * ACPI_GPE_REGISTER_WIDTH) + j];
-			if ((gpe_event_info->method_node) &&
-			   ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == ACPI_GPE_TYPE_RUNTIME)) {
-				/* Enable this GPE, it is 1) RUNTIME and 2) has an _Lxx or _Exx method */
-
-				status = acpi_hw_enable_gpe (gpe_event_info);
-				if (ACPI_FAILURE (status)) {
-					return_ACPI_STATUS (status);
-				}
+
+			if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_METHOD) &&
+				 (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
 				gpe_enabled_count++;
 			}
 
-			if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == ACPI_GPE_TYPE_WAKE) {
+			if (gpe_event_info->flags & ACPI_GPE_TYPE_WAKE) {
 				wake_gpe_count++;
 			}
 		}
 	}
 
+	/* Dump info about this GPE block */
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+		"GPE %02X to %02X [%4.4s] %u regs at %8.8X%8.8X on int 0x%X\n",
+		(u32) gpe_block->block_base_number,
+		(u32) (gpe_block->block_base_number +
+				((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
+		gpe_device->name.ascii,
+		gpe_block->register_count,
+		ACPI_FORMAT_UINT64 (gpe_block->block_address.address),
+		interrupt_level));
+
+
+	/* Enable all valid GPEs found above */
+
+	status = acpi_hw_enable_runtime_gpe_block (NULL, gpe_block);
+
 	ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
 			"Found %u Wake, Enabled %u Runtime GPEs in this block\n",
 			wake_gpe_count, gpe_enabled_count));
@@ -1056,7 +1120,8 @@
 	if ((register_count0 + register_count1) == 0) {
 		/* GPEs are not required by ACPI, this is OK */
 
-		ACPI_REPORT_INFO (("There are no GPE blocks defined in the FADT\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
+				"There are no GPE blocks defined in the FADT\n"));
 		status = AE_OK;
 		goto cleanup;
 	}
diff -Nru a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
--- a/drivers/acpi/events/evmisc.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evmisc.c	Sat Jul 17 03:29:59 2004
@@ -139,8 +139,7 @@
 				acpi_notify_value_names[notify_value]));
 	}
 	else {
-		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-				"notify value: 0x%2.2x **Device Specific**\n",
+		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Notify value: 0x%2.2X **Device Specific**\n",
 				notify_value));
 	}
 
@@ -197,8 +196,8 @@
 		/* There is no per-device notify handler for this device */
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
-			"No notify handler for [%4.4s] node %p\n",
-			acpi_ut_get_node_name (node), node));
+			"No notify handler for Notify(%4.4s, %X) node %p\n",
+			acpi_ut_get_node_name (node), notify_value, node));
 	}
 
 	return (status);
@@ -548,7 +547,7 @@
 
 		/* Disable all GPEs in all GPE blocks */
 
-		status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block);
+		status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, ACPI_NOT_ISR);
 
 		/* Remove SCI handler */
 
@@ -557,6 +556,10 @@
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not remove SCI handler\n"));
 		}
 	}
+
+	/* Deallocate all handler objects installed within GPE info structs */
+
+	status = acpi_ev_walk_gpe_list (acpi_ev_delete_gpe_handlers, ACPI_NOT_ISR);
 
 	/* Return to original mode if necessary */
 
diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
--- a/drivers/acpi/events/evregion.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evregion.c	Sat Jul 17 03:29:59 2004
@@ -61,7 +61,7 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ev_init_address_spaces
+ * FUNCTION:    acpi_ev_install_region_handlers
  *
  * PARAMETERS:  None
  *
@@ -72,15 +72,20 @@
  ******************************************************************************/
 
 acpi_status
-acpi_ev_init_address_spaces (
+acpi_ev_install_region_handlers (
 	void) {
 	acpi_status                     status;
 	acpi_native_uint                i;
 
 
-	ACPI_FUNCTION_TRACE ("ev_init_address_spaces");
+	ACPI_FUNCTION_TRACE ("ev_install_region_handlers");
 
 
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
 	/*
 	 * All address spaces (PCI Config, EC, SMBus) are scope dependent
 	 * and registration must occur for a specific device.
@@ -99,9 +104,8 @@
 	 * has already been installed (via acpi_install_address_space_handler).
 	 * Similar for AE_SAME_HANDLER.
 	 */
-
 	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
-		status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node,
+		status = acpi_ev_install_space_handler (acpi_gbl_root_node,
 				  acpi_gbl_default_address_spaces[i],
 				  ACPI_DEFAULT_HANDLER, NULL, NULL);
 		switch (status) {
@@ -111,15 +115,63 @@
 
 			/* These exceptions are all OK */
 
+			status = AE_OK;
 			break;
 
 		default:
 
-			return_ACPI_STATUS (status);
+			goto unlock_and_exit;
 		}
 	}
 
-	return_ACPI_STATUS (AE_OK);
+unlock_and_exit:
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_initialize_op_regions
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Execute _REG methods for all Operation Regions that have
+ *              an installed default region handler.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_initialize_op_regions (
+	void)
+{
+	acpi_status                     status;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ev_initialize_op_regions");
+
+
+	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	/*
+	 * Run the _REG methods for op_regions in each default address space
+	 */
+	for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
+		/* TBD: Make sure handler is the DEFAULT handler, otherwise
+		 * _REG will have already been run.
+		 */
+		status = acpi_ev_execute_reg_methods (acpi_gbl_root_node,
+				  acpi_gbl_default_address_spaces[i]);
+	}
+
+	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+	return_ACPI_STATUS (status);
 }
 
 
@@ -138,11 +190,12 @@
 
 acpi_status
 acpi_ev_execute_reg_method (
-	union acpi_operand_object      *region_obj,
+	union acpi_operand_object       *region_obj,
 	u32                             function)
 {
-	union acpi_operand_object      *params[3];
-	union acpi_operand_object      *region_obj2;
+	struct acpi_parameter_info      info;
+	union acpi_operand_object       *params[3];
+	union acpi_operand_object       *region_obj2;
 	acpi_status                     status;
 
 
@@ -159,10 +212,11 @@
 	}
 
 	/*
-	 * _REG method has two arguments
-	 * Arg0:   Integer: Operation region space ID
+	 * The _REG method has two arguments:
+	 *
+	 * Arg0, Integer: Operation region space ID
 	 *          Same value as region_obj->Region.space_id
-	 * Arg1:   Integer: connection status
+	 * Arg1, Integer: connection status
 	 *          1 for connecting the handler,
 	 *          0 for disconnecting the handler
 	 *          Passed as a parameter
@@ -184,10 +238,15 @@
 	params[1]->integer.value = function;
 	params[2] = NULL;
 
+	info.node = region_obj2->extra.method_REG;
+	info.parameters = params;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
 	/* Execute the method, no return value */
 
-	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
-	status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (
+			   ACPI_TYPE_METHOD, info.node, NULL));
+	status = acpi_ns_evaluate_by_handle (&info);
 
 	acpi_ut_remove_reference (params[1]);
 
@@ -326,7 +385,7 @@
 		ACPI_FORMAT_UINT64 (address),
 		acpi_ut_get_region_name (region_obj->region.space_id)));
 
-	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+	if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 		/*
 		 * For handlers other than the default (supplied) handlers, we must
 		 * exit the interpreter because the handler *might* block -- we don't
@@ -347,7 +406,7 @@
 			acpi_format_exception (status)));
 	}
 
-	if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+	if (!(handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
 		/*
 		 * We just returned from a non-default handler, we must re-enter the
 		 * interpreter
@@ -676,6 +735,273 @@
 	return (status);
 }
 
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_install_space_handler
+ *
+ * PARAMETERS:  Node            - Namespace node for the device
+ *              space_id        - The address space ID
+ *              Handler         - Address of the handler
+ *              Setup           - Address of the setup function
+ *              Context         - Value passed to the handler on each access
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for all op_regions of a given space_id.
+ *              Assumes namespace is locked
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_install_space_handler (
+	struct acpi_namespace_node      *node,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler,
+	acpi_adr_space_setup            setup,
+	void                            *context)
+{
+	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *handler_obj;
+	acpi_status                     status;
+	acpi_object_type                type;
+	u16                             flags = 0;
+
+
+	ACPI_FUNCTION_TRACE ("ev_install_space_handler");
+
+
+	/*
+	 * This registration is valid for only the types below
+	 * and the root.  This is where the default handlers
+	 * get placed.
+	 */
+	if ((node->type != ACPI_TYPE_DEVICE)     &&
+		(node->type != ACPI_TYPE_PROCESSOR)  &&
+		(node->type != ACPI_TYPE_THERMAL)    &&
+		(node != acpi_gbl_root_node)) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
+	}
+
+	if (handler == ACPI_DEFAULT_HANDLER) {
+		flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
+
+		switch (space_id) {
+		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+			handler = acpi_ex_system_memory_space_handler;
+			setup   = acpi_ev_system_memory_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_SYSTEM_IO:
+			handler = acpi_ex_system_io_space_handler;
+			setup   = acpi_ev_io_space_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_PCI_CONFIG:
+			handler = acpi_ex_pci_config_space_handler;
+			setup   = acpi_ev_pci_config_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_CMOS:
+			handler = acpi_ex_cmos_space_handler;
+			setup   = acpi_ev_cmos_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_PCI_BAR_TARGET:
+			handler = acpi_ex_pci_bar_space_handler;
+			setup   = acpi_ev_pci_bar_region_setup;
+			break;
+
+		case ACPI_ADR_SPACE_DATA_TABLE:
+			handler = acpi_ex_data_table_space_handler;
+			setup   = NULL;
+			break;
+
+		default:
+			status = AE_BAD_PARAMETER;
+			goto unlock_and_exit;
+		}
+	}
+
+	/* If the caller hasn't specified a setup routine, use the default */
+
+	if (!setup) {
+		setup = acpi_ev_default_region_setup;
+	}
+
+	/* Check for an existing internal object */
+
+	obj_desc = acpi_ns_get_attached_object (node);
+	if (obj_desc) {
+		/*
+		 * The attached device object already exists.
+		 * Make sure the handler is not already installed.
+		 */
+		handler_obj = obj_desc->device.handler;
+
+		/* Walk the handler list for this device */
+
+		while (handler_obj) {
+			/* Same space_id indicates a handler already installed */
+
+			if (handler_obj->address_space.space_id == space_id) {
+				if (handler_obj->address_space.handler == handler) {
+					/*
+					 * It is (relatively) OK to attempt to install the SAME
+					 * handler twice. This can easily happen with PCI_Config space.
+					 */
+					status = AE_SAME_HANDLER;
+					goto unlock_and_exit;
+				}
+				else {
+					/* A handler is already installed */
+
+					status = AE_ALREADY_EXISTS;
+				}
+				goto unlock_and_exit;
+			}
+
+			/* Walk the linked list of handlers */
+
+			handler_obj = handler_obj->address_space.next;
+		}
+	}
+	else {
+		ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+			"Creating object on Device %p while installing handler\n", node));
+
+		/* obj_desc does not exist, create one */
+
+		if (node->type == ACPI_TYPE_ANY) {
+			type = ACPI_TYPE_DEVICE;
+		}
+		else {
+			type = node->type;
+		}
+
+		obj_desc = acpi_ut_create_internal_object (type);
+		if (!obj_desc) {
+			status = AE_NO_MEMORY;
+			goto unlock_and_exit;
+		}
+
+		/* Init new descriptor */
+
+		obj_desc->common.type = (u8) type;
+
+		/* Attach the new object to the Node */
+
+		status = acpi_ns_attach_object (node, obj_desc, type);
+
+		/* Remove local reference to the object */
+
+		acpi_ut_remove_reference (obj_desc);
+
+		if (ACPI_FAILURE (status)) {
+			goto unlock_and_exit;
+		}
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+		"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
+		acpi_ut_get_region_name (space_id), space_id,
+		acpi_ut_get_node_name (node), node, obj_desc));
+
+	/*
+	 * Install the handler
+	 *
+	 * At this point there is no existing handler.
+	 * Just allocate the object for the handler and link it
+	 * into the list.
+	 */
+	handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
+	if (!handler_obj) {
+		status = AE_NO_MEMORY;
+		goto unlock_and_exit;
+	}
+
+	/* Init handler obj */
+
+	handler_obj->address_space.space_id  = (u8) space_id;
+	handler_obj->address_space.hflags    = flags;
+	handler_obj->address_space.region_list = NULL;
+	handler_obj->address_space.node      = node;
+	handler_obj->address_space.handler   = handler;
+	handler_obj->address_space.context   = context;
+	handler_obj->address_space.setup     = setup;
+
+	/* Install at head of Device.address_space list */
+
+	handler_obj->address_space.next      = obj_desc->device.handler;
+
+	/*
+	 * The Device object is the first reference on the handler_obj.
+	 * Each region that uses the handler adds a reference.
+	 */
+	obj_desc->device.handler = handler_obj;
+
+	/*
+	 * Walk the namespace finding all of the regions this
+	 * handler will manage.
+	 *
+	 * Start at the device and search the branch toward
+	 * the leaf nodes until either the leaf is encountered or
+	 * a device is detected that has an address handler of the
+	 * same type.
+	 *
+	 * In either case, back up and search down the remainder
+	 * of the branch
+	 */
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
+			  handler_obj, NULL);
+
+unlock_and_exit:
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_execute_reg_methods
+ *
+ * PARAMETERS:  Node            - Namespace node for the device
+ *              space_id        - The address space ID
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Run _REG methods for the Space ID;
+ *              Note: assumes namespace is locked, or system init time.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ev_execute_reg_methods (
+	struct acpi_namespace_node      *node,
+	acpi_adr_space_type             space_id)
+{
+	acpi_status                     status;
+
+
+	ACPI_FUNCTION_TRACE ("ev_execute_reg_methods");
+
+
+	/*
+	 * Run all _REG methods for all Operation Regions for this
+	 * space ID.  This is a separate walk in order to handle any
+	 * interdependencies between regions and _REG methods.  (i.e. handlers
+	 * must be installed for all regions of this Space ID before we
+	 * can run any _REG methods)
+	 */
+	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+			  ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
+			  &space_id, NULL);
+
+	return_ACPI_STATUS (status);
+}
+
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_reg_run
@@ -693,19 +1019,13 @@
 	void                            *context,
 	void                            **return_value)
 {
-	union acpi_operand_object       *handler_obj;
 	union acpi_operand_object       *obj_desc;
 	struct acpi_namespace_node      *node;
+	acpi_adr_space_type             space_id;
 	acpi_status                     status;
 
 
-	handler_obj = (union acpi_operand_object   *) context;
-
-	/* Parameter validation */
-
-	if (!handler_obj) {
-		return (AE_OK);
-	}
+	space_id = *ACPI_CAST_PTR (acpi_adr_space_type, context);
 
 	/* Convert and validate the device handle */
 
@@ -732,10 +1052,9 @@
 		return (AE_OK);
 	}
 
-
 	/* Object is a Region */
 
-	if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
+	if (obj_desc->region.space_id != space_id) {
 		/*
 		 * This region is for a different address space
 		 * -- just ignore it
diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evxface.c	Sat Jul 17 03:29:59 2004
@@ -188,6 +188,7 @@
  *              handler_type    - The type of handler:
  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
+ *                                  ACPI_ALL_NOTIFY:  both system and device
  *              Handler         - Address of the handler
  *              Context         - Value passed to the handler on each GPE
  *
@@ -243,20 +244,21 @@
 	if (device == ACPI_ROOT_OBJECT) {
 		/* Make sure the handler is not already installed */
 
-		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-				acpi_gbl_system_notify.handler)        ||
-			((handler_type == ACPI_DEVICE_NOTIFY) &&
+		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
+				acpi_gbl_system_notify.handler)     ||
+			((handler_type & ACPI_DEVICE_NOTIFY) &&
 				acpi_gbl_device_notify.handler)) {
 			status = AE_ALREADY_EXISTS;
 			goto unlock_and_exit;
 		}
 
-		if (handler_type == ACPI_SYSTEM_NOTIFY) {
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			acpi_gbl_system_notify.node  = node;
 			acpi_gbl_system_notify.handler = handler;
 			acpi_gbl_system_notify.context = context;
 		}
-		else /* ACPI_DEVICE_NOTIFY */ {
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
 			acpi_gbl_device_notify.node  = node;
 			acpi_gbl_device_notify.handler = handler;
 			acpi_gbl_device_notify.context = context;
@@ -284,9 +286,9 @@
 		if (obj_desc) {
 			/* Object exists - make sure there's no handler */
 
-			if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
+			if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
 					obj_desc->common_notify.system_notify) ||
-				((handler_type == ACPI_DEVICE_NOTIFY) &&
+				((handler_type & ACPI_DEVICE_NOTIFY) &&
 					obj_desc->common_notify.device_notify)) {
 				status = AE_ALREADY_EXISTS;
 				goto unlock_and_exit;
@@ -308,7 +310,6 @@
 			/* Remove local reference to the object */
 
 			acpi_ut_remove_reference (obj_desc);
-
 			if (ACPI_FAILURE (status)) {
 				goto unlock_and_exit;
 			}
@@ -326,12 +327,19 @@
 		notify_obj->notify.handler = handler;
 		notify_obj->notify.context = context;
 
-		if (handler_type == ACPI_SYSTEM_NOTIFY) {
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			obj_desc->common_notify.system_notify = notify_obj;
 		}
-		else /* ACPI_DEVICE_NOTIFY */ {
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
 			obj_desc->common_notify.device_notify = notify_obj;
 		}
+
+		if (handler_type == ACPI_ALL_NOTIFY) {
+			/* Extra ref if installed in both */
+
+			acpi_ut_add_reference (notify_obj);
+		}
 	}
 
 
@@ -349,6 +357,7 @@
  *              handler_type    - The type of handler:
  *                                  ACPI_SYSTEM_NOTIFY: system_handler (00-7f)
  *                                  ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
+ *                                  ACPI_ALL_NOTIFY:  both system and device
  *              Handler         - Address of the handler
  * RETURN:      Status
  *
@@ -398,9 +407,9 @@
 	if (device == ACPI_ROOT_OBJECT) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
 
-		if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
-			  !acpi_gbl_system_notify.handler) ||
-			((handler_type == ACPI_DEVICE_NOTIFY) &&
+		if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
+			  !acpi_gbl_system_notify.handler)      ||
+			((handler_type & ACPI_DEVICE_NOTIFY) &&
 			  !acpi_gbl_device_notify.handler)) {
 			status = AE_NOT_EXIST;
 			goto unlock_and_exit;
@@ -415,12 +424,13 @@
 			return_ACPI_STATUS (status);
  		}
 
-		if (handler_type == ACPI_SYSTEM_NOTIFY) {
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			acpi_gbl_system_notify.node  = NULL;
 			acpi_gbl_system_notify.handler = NULL;
 			acpi_gbl_system_notify.context = NULL;
 		}
-		else {
+
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
 			acpi_gbl_device_notify.node  = NULL;
 			acpi_gbl_device_notify.handler = NULL;
 			acpi_gbl_device_notify.context = NULL;
@@ -448,38 +458,47 @@
 
 		/* Object exists - make sure there's an existing handler */
 
-		if (handler_type == ACPI_SYSTEM_NOTIFY) {
+		if (handler_type & ACPI_SYSTEM_NOTIFY) {
 			notify_obj = obj_desc->common_notify.system_notify;
-		}
-		else {
-			notify_obj = obj_desc->common_notify.device_notify;
-		}
+			if ((!notify_obj) ||
+				 (notify_obj->notify.handler != handler)) {
+				status = AE_BAD_PARAMETER;
+				goto unlock_and_exit;
+			}
+			/* Make sure all deferred tasks are completed */
 
-		if ((!notify_obj) ||
-			(notify_obj->notify.handler != handler)) {
-			status = AE_BAD_PARAMETER;
-			goto unlock_and_exit;
-		}
+			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+			acpi_os_wait_events_complete(NULL);
+			status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+ 			}
 
-		/* Make sure all deferred tasks are completed */
+			/* Remove the handler */
+			obj_desc->common_notify.system_notify = NULL;
+			acpi_ut_remove_reference (notify_obj);
+		}
 
-		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
-		acpi_os_wait_events_complete(NULL);
-		status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
- 		}
+		if (handler_type & ACPI_DEVICE_NOTIFY) {
+			notify_obj = obj_desc->common_notify.device_notify;
+			if ((!notify_obj) ||
+				 (notify_obj->notify.handler != handler)) {
+				status = AE_BAD_PARAMETER;
+				goto unlock_and_exit;
+			}
+			/* Make sure all deferred tasks are completed */
 
-		/* Remove the handler */
+			(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+			acpi_os_wait_events_complete(NULL);
+			status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+ 			}
 
-		if (handler_type == ACPI_SYSTEM_NOTIFY) {
-			obj_desc->common_notify.system_notify = NULL;
-		}
-		else {
+			/* Remove the handler */
 			obj_desc->common_notify.device_notify = NULL;
+			acpi_ut_remove_reference (notify_obj);
 		}
-
-		acpi_ut_remove_reference (notify_obj);
 	}
 
 
@@ -497,7 +516,7 @@
  *              gpe_block       - GPE block (NULL == FADT GPEs)
  *              Type            - Whether this GPE should be treated as an
  *                                edge- or level-triggered interrupt.
- *              Handler         - Address of the handler
+ *              Address         - Address of the handler
  *              Context         - Value passed to the handler on each GPE
  *
  * RETURN:      Status
@@ -511,11 +530,12 @@
 	acpi_handle                     gpe_device,
 	u32                             gpe_number,
 	u32                             type,
-	acpi_gpe_handler                handler,
+	acpi_event_handler              address,
 	void                            *context)
 {
-	acpi_status                     status;
 	struct acpi_gpe_event_info      *gpe_event_info;
+	struct acpi_handler_info        *handler;
+	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
@@ -523,7 +543,7 @@
 
 	/* Parameter validation */
 
-	if (!handler) {
+	if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
@@ -542,27 +562,41 @@
 
 	/* Make sure that there isn't a handler there already */
 
-	if (gpe_event_info->handler) {
+	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
 		status = AE_ALREADY_EXISTS;
 		goto unlock_and_exit;
 	}
 
-	/* Install the handler */
+	/* Allocate and init handler object */
 
-	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
-	gpe_event_info->handler = handler;
-	gpe_event_info->context = context;
-	gpe_event_info->flags = (u8) type;
-	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info));
+	if (!handler) {
+		status = AE_NO_MEMORY;
+		goto unlock_and_exit;
+	}
 
-	/* Clear the GPE (of stale events), the enable it */
+	handler->address    = address;
+	handler->context    = context;
+	handler->method_node = gpe_event_info->dispatch.method_node;
 
-	status = acpi_hw_clear_gpe (gpe_event_info);
+	/* Disable the GPE before installing the handler */
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
 
-	status = acpi_hw_enable_gpe (gpe_event_info);
+	/* Install the handler */
+
+	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+	gpe_event_info->dispatch.handler = handler;
+
+	/* Setup up dispatch flags to indicate handler (vs. method) */
+
+	gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
+	gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
+
+	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
 
 
 unlock_and_exit:
@@ -577,7 +611,7 @@
  *
  * PARAMETERS:  gpe_number      - The event to remove a handler
  *              gpe_block       - GPE block (NULL == FADT GPEs)
- *              Handler         - Address of the handler
+ *              Address         - Address of the handler
  *
  * RETURN:      Status
  *
@@ -589,10 +623,11 @@
 acpi_remove_gpe_handler (
 	acpi_handle                     gpe_device,
 	u32                             gpe_number,
-	acpi_gpe_handler                handler)
+	acpi_event_handler              address)
 {
-	acpi_status                     status;
 	struct acpi_gpe_event_info      *gpe_event_info;
+	struct acpi_handler_info        *handler;
+	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
@@ -600,7 +635,7 @@
 
 	/* Parameter validation */
 
-	if (!handler) {
+	if (!address) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
@@ -617,21 +652,27 @@
 		goto unlock_and_exit;
 	}
 
-	/* Disable the GPE before removing the handler */
+	/* Make sure that a handler is indeed installed */
 
-	status = acpi_hw_disable_gpe (gpe_event_info);
-	if (ACPI_FAILURE (status)) {
+	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
+		status = AE_NOT_EXIST;
 		goto unlock_and_exit;
 	}
 
 	/* Make sure that the installed handler is the same */
 
-	if (gpe_event_info->handler != handler) {
-		(void) acpi_hw_enable_gpe (gpe_event_info);
+	if (gpe_event_info->dispatch.handler->address != address) {
 		status = AE_BAD_PARAMETER;
 		goto unlock_and_exit;
 	}
 
+	/* Disable the GPE before removing the handler */
+
+	status = acpi_ev_disable_gpe (gpe_event_info);
+	if (ACPI_FAILURE (status)) {
+		goto unlock_and_exit;
+	}
+
 	/* Make sure all deferred tasks are completed */
 
 	(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
@@ -644,9 +685,20 @@
 	/* Remove the handler */
 
 	acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
-	gpe_event_info->handler = NULL;
-	gpe_event_info->context = NULL;
+	handler = gpe_event_info->dispatch.handler;
+
+	/* Restore Method node (if any), set dispatch flags */
+
+	gpe_event_info->dispatch.method_node = handler->method_node;
+	gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; /* Clear bits */
+	if (handler->method_node) {
+		gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
+	}
 	acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
+
+	/* Now we can free the handler object */
+
+	ACPI_MEM_FREE (handler);
 
 
 unlock_and_exit:
diff -Nru a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
--- a/drivers/acpi/events/evxfevnt.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evxfevnt.c	Sat Jul 17 03:29:59 2004
@@ -204,12 +204,11 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_enable_gpe
+ * FUNCTION:    acpi_set_gpe_type
  *
  * PARAMETERS:  gpe_device      - Parent GPE Device
  *              gpe_number      - GPE level within the GPE block
- *              Flags           - Just enable, or also wake enable?
- *                                Called from ISR or not
+ *              Type            - New GPE type
  *
  * RETURN:      Status
  *
@@ -218,26 +217,17 @@
  ******************************************************************************/
 
 acpi_status
-acpi_enable_gpe (
+acpi_set_gpe_type (
 	acpi_handle                     gpe_device,
 	u32                             gpe_number,
-	u32                             flags)
+	u8                              type)
 {
 	acpi_status                     status = AE_OK;
 	struct acpi_gpe_event_info      *gpe_event_info;
 
 
-	ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
-
-
-	/* Use semaphore lock if not executing at interrupt level */
+	ACPI_FUNCTION_TRACE ("acpi_set_gpe_type");
 
-	if (flags & ACPI_NOT_ISR) {
-		status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
-	}
 
 	/* Ensure that we have a valid GPE number */
 
@@ -247,91 +237,72 @@
 		goto unlock_and_exit;
 	}
 
-	/* Check for Wake vs Runtime GPE */
-
-	if (flags & ACPI_EVENT_WAKE_ENABLE) {
-		/* Ensure the requested wake GPE is disabled */
-
-		status = acpi_hw_disable_gpe (gpe_event_info);
-		if (ACPI_FAILURE (status)) {
-			goto unlock_and_exit;
-		}
-
-		/* Defer Enable of Wake GPE until sleep time */
-
-		acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
+	if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
+		return_ACPI_STATUS (AE_OK);
 	}
-	else {
-		/* Enable the requested runtime GPE  */
 
-		status = acpi_hw_enable_gpe (gpe_event_info);
-		if (ACPI_FAILURE (status)) {
-			goto unlock_and_exit;
-		}
-	}
+	/* Set the new type (will disable GPE if currently enabled) */
 
+	status = acpi_ev_set_gpe_type (gpe_event_info, type);
 
 unlock_and_exit:
-	if (flags & ACPI_NOT_ISR) {
-		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
-	}
 	return_ACPI_STATUS (status);
 }
 
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_disable_event
+ * FUNCTION:    acpi_enable_gpe
  *
- * PARAMETERS:  Event           - The fixed eventto be enabled
- *              Flags           - Reserved
+ * PARAMETERS:  gpe_device      - Parent GPE Device
+ *              gpe_number      - GPE level within the GPE block
+ *              Flags           - Just enable, or also wake enable?
+ *                                Called from ISR or not
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable an ACPI event (fixed)
+ * DESCRIPTION: Enable an ACPI event (general purpose)
  *
  ******************************************************************************/
 
 acpi_status
-acpi_disable_event (
-	u32                             event,
+acpi_enable_gpe (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
 	u32                             flags)
 {
 	acpi_status                     status = AE_OK;
-	u32                             value;
+	struct acpi_gpe_event_info      *gpe_event_info;
 
 
-	ACPI_FUNCTION_TRACE ("acpi_disable_event");
+	ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
 
 
-	/* Decode the Fixed Event */
+	/* Use semaphore lock if not executing at interrupt level */
 
-	if (event > ACPI_EVENT_MAX) {
-		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	if (flags & ACPI_NOT_ISR) {
+		status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
 	}
 
-	/*
-	 * Disable the requested fixed event (by writing a zero to the
-	 * enable register bit)
-	 */
-	status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
-			 0, ACPI_MTX_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
-	}
+	/* Ensure that we have a valid GPE number */
 
-	status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
-			 &value, ACPI_MTX_LOCK);
-	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
+	gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+	if (!gpe_event_info) {
+		status = AE_BAD_PARAMETER;
+		goto unlock_and_exit;
 	}
 
-	if (value != 0) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Could not disable %s events\n", acpi_ut_get_event_name (event)));
-		return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
-	}
+	/* Perform the enable */
+
+	status = acpi_ev_enable_gpe (gpe_event_info, TRUE);
 
+unlock_and_exit:
+	if (flags & ACPI_NOT_ISR) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	}
 	return_ACPI_STATUS (status);
 }
 
@@ -342,7 +313,7 @@
  *
  * PARAMETERS:  gpe_device      - Parent GPE Device
  *              gpe_number      - GPE level within the GPE block
- *              Flags           - Just enable, or also wake enable?
+ *              Flags           - Just disable, or also wake disable?
  *                                Called from ISR or not
  *
  * RETURN:      Status
@@ -381,21 +352,69 @@
 		goto unlock_and_exit;
 	}
 
+	status = acpi_ev_disable_gpe (gpe_event_info);
+
+unlock_and_exit:
+	if (flags & ACPI_NOT_ISR) {
+		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	}
+	return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_disable_event
+ *
+ * PARAMETERS:  Event           - The fixed eventto be enabled
+ *              Flags           - Reserved
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Disable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_disable_event (
+	u32                             event,
+	u32                             flags)
+{
+	acpi_status                     status = AE_OK;
+	u32                             value;
+
+
+	ACPI_FUNCTION_TRACE ("acpi_disable_event");
+
+
+	/* Decode the Fixed Event */
+
+	if (event > ACPI_EVENT_MAX) {
+		return_ACPI_STATUS (AE_BAD_PARAMETER);
+	}
+
 	/*
-	 * Only disable the requested GPE number for wake if specified.
-	 * Otherwise, turn it totally off
+	 * Disable the requested fixed event (by writing a zero to the
+	 * enable register bit)
 	 */
-	if (flags & ACPI_EVENT_WAKE_DISABLE) {
-		acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
+	status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+			 0, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
 	}
-	else {
-		status = acpi_hw_disable_gpe (gpe_event_info);
+
+	status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+			 &value, ACPI_MTX_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
 	}
 
-unlock_and_exit:
-	if (flags & ACPI_NOT_ISR) {
-		(void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+	if (value != 0) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"Could not disable %s events\n", acpi_ut_get_event_name (event)));
+		return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
 	}
+
 	return_ACPI_STATUS (status);
 }
 
diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
--- a/drivers/acpi/events/evxfregn.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/events/evxfregn.c	Sat Jul 17 03:29:59 2004
@@ -46,7 +46,6 @@
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
-#include <acpi/acinterp.h>
 
 #define _COMPONENT          ACPI_EVENTS
 	 ACPI_MODULE_NAME    ("evxfregn")
@@ -76,12 +75,8 @@
 	acpi_adr_space_setup            setup,
 	void                            *context)
 {
-	union acpi_operand_object       *obj_desc;
-	union acpi_operand_object       *handler_obj;
 	struct acpi_namespace_node      *node;
 	acpi_status                     status;
-	acpi_object_type                type;
-	u16                             flags = 0;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_install_address_space_handler");
@@ -106,202 +101,16 @@
 		goto unlock_and_exit;
 	}
 
-	/*
-	 * This registration is valid for only the types below
-	 * and the root.  This is where the default handlers
-	 * get placed.
-	 */
-	if ((node->type != ACPI_TYPE_DEVICE)     &&
-		(node->type != ACPI_TYPE_PROCESSOR)  &&
-		(node->type != ACPI_TYPE_THERMAL)    &&
-		(node != acpi_gbl_root_node)) {
-		status = AE_BAD_PARAMETER;
-		goto unlock_and_exit;
-	}
-
-	if (handler == ACPI_DEFAULT_HANDLER) {
-		flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
-
-		switch (space_id) {
-		case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-			handler = acpi_ex_system_memory_space_handler;
-			setup   = acpi_ev_system_memory_region_setup;
-			break;
-
-		case ACPI_ADR_SPACE_SYSTEM_IO:
-			handler = acpi_ex_system_io_space_handler;
-			setup   = acpi_ev_io_space_region_setup;
-			break;
-
-		case ACPI_ADR_SPACE_PCI_CONFIG:
-			handler = acpi_ex_pci_config_space_handler;
-			setup   = acpi_ev_pci_config_region_setup;
-			break;
-
-		case ACPI_ADR_SPACE_CMOS:
-			handler = acpi_ex_cmos_space_handler;
-			setup   = acpi_ev_cmos_region_setup;
-			break;
-
-		case ACPI_ADR_SPACE_PCI_BAR_TARGET:
-			handler = acpi_ex_pci_bar_space_handler;
-			setup   = acpi_ev_pci_bar_region_setup;
-			break;
-
-		case ACPI_ADR_SPACE_DATA_TABLE:
-			handler = acpi_ex_data_table_space_handler;
-			setup   = NULL;
-			break;
-
-		default:
-			status = AE_BAD_PARAMETER;
-			goto unlock_and_exit;
-		}
-	}
-
-	/* If the caller hasn't specified a setup routine, use the default */
-
-	if (!setup) {
-		setup = acpi_ev_default_region_setup;
-	}
-
-	/* Check for an existing internal object */
-
-	obj_desc = acpi_ns_get_attached_object (node);
-	if (obj_desc) {
-		/*
-		 * The attached device object already exists.
-		 * Make sure the handler is not already installed.
-		 */
-		handler_obj = obj_desc->device.handler;
-
-		/* Walk the handler list for this device */
-
-		while (handler_obj) {
-			/* Same space_id indicates a handler already installed */
-
-			if(handler_obj->address_space.space_id == space_id) {
-				if (handler_obj->address_space.handler == handler) {
-					/*
-					 * It is (relatively) OK to attempt to install the SAME
-					 * handler twice. This can easily happen with PCI_Config space.
-					 */
-					status = AE_SAME_HANDLER;
-					goto unlock_and_exit;
-				}
-				else {
-					/* A handler is already installed */
-
-					status = AE_ALREADY_EXISTS;
-				}
-				goto unlock_and_exit;
-			}
-
-			/* Walk the linked list of handlers */
-
-			handler_obj = handler_obj->address_space.next;
-		}
-	}
-	else {
-		ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-			"Creating object on Device %p while installing handler\n", node));
-
-		/* obj_desc does not exist, create one */
-
-		if (node->type == ACPI_TYPE_ANY) {
-			type = ACPI_TYPE_DEVICE;
-		}
-		else {
-			type = node->type;
-		}
-
-		obj_desc = acpi_ut_create_internal_object (type);
-		if (!obj_desc) {
-			status = AE_NO_MEMORY;
-			goto unlock_and_exit;
-		}
-
-		/* Init new descriptor */
-
-		obj_desc->common.type = (u8) type;
-
-		/* Attach the new object to the Node */
+	/* Install the handler for all Regions for this Space ID */
 
-		status = acpi_ns_attach_object (node, obj_desc, type);
-
-		/* Remove local reference to the object */
-
-		acpi_ut_remove_reference (obj_desc);
-
-		if (ACPI_FAILURE (status)) {
-			goto unlock_and_exit;
-		}
-	}
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-		"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
-		acpi_ut_get_region_name (space_id), space_id,
-		acpi_ut_get_node_name (node), node, obj_desc));
-
-	/*
-	 * Install the handler
-	 *
-	 * At this point there is no existing handler.
-	 * Just allocate the object for the handler and link it
-	 * into the list.
-	 */
-	handler_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
-	if (!handler_obj) {
-		status = AE_NO_MEMORY;
+	status = acpi_ev_install_space_handler (node, space_id, handler, setup, context);
+	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
 
-	/* Init handler obj */
+	/* Run all _REG methods for this address space */
 
-	handler_obj->address_space.space_id  = (u8) space_id;
-	handler_obj->address_space.hflags    = flags;
-	handler_obj->address_space.region_list = NULL;
-	handler_obj->address_space.node      = node;
-	handler_obj->address_space.handler   = handler;
-	handler_obj->address_space.context   = context;
-	handler_obj->address_space.setup     = setup;
-
-	/* Install at head of Device.address_space list */
-
-	handler_obj->address_space.next      = obj_desc->device.handler;
-
-	/*
-	 * The Device object is the first reference on the handler_obj.
-	 * Each region that uses the handler adds a reference.
-	 */
-	obj_desc->device.handler = handler_obj;
-
-	/*
-	 * Walk the namespace finding all of the regions this
-	 * handler will manage.
-	 *
-	 * Start at the device and search the branch toward
-	 * the leaf nodes until either the leaf is encountered or
-	 * a device is detected that has an address handler of the
-	 * same type.
-	 *
-	 * In either case, back up and search down the remainder
-	 * of the branch
-	 */
-	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
-			  ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
-			  handler_obj, NULL);
-
-	/*
-	 * Now we can run the _REG methods for all Regions for this
-	 * space ID.  This is a separate walk in order to handle any
-	 * interdependencies between regions and _REG methods.  (i.e. handlers
-	 * must be installed for all regions of this Space ID before we
-	 * can run any _REG methods.
-	 */
-	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
-			  ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
-			  handler_obj, NULL);
+	status = acpi_ev_execute_reg_methods (node, space_id);
 
 unlock_and_exit:
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
diff -Nru a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
--- a/drivers/acpi/executer/exconfig.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/executer/exconfig.c	Sat Jul 17 03:29:59 2004
@@ -48,6 +48,7 @@
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
 #include <acpi/actables.h>
+#include <acpi/acdispat.h>
 
 
 #define _COMPONENT          ACPI_EXECUTER
@@ -285,7 +286,7 @@
 	union acpi_operand_object       *ddb_handle;
 	union acpi_operand_object       *buffer_desc = NULL;
 	struct acpi_table_header        *table_ptr = NULL;
-	u8                              *table_data_ptr;
+	acpi_physical_address           address;
 	struct acpi_table_header        table_header;
 	u32                             i;
 
@@ -300,18 +301,39 @@
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Load from Region %p %s\n",
 			obj_desc, acpi_ut_get_object_type_name (obj_desc)));
 
-		/* Get the table header */
+		/*
+		 * If the Region Address and Length have not been previously evaluated,
+		 * evaluate them now and save the results.
+		 */
+		if (!(obj_desc->common.flags & AOPOBJ_DATA_VALID)) {
+			status = acpi_ds_get_region_arguments (obj_desc);
+			if (ACPI_FAILURE (status)) {
+				return_ACPI_STATUS (status);
+			}
+		}
+
+		/* Get the base physical address of the region */
+
+		address = obj_desc->region.address;
+
+		/* Get the table length from the table header */
 
 		table_header.length = 0;
-		for (i = 0; i < sizeof (struct acpi_table_header); i++) {
+		for (i = 0; i < 8; i++) {
 			status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
-					   (acpi_physical_address) i, 8,
+					   (acpi_physical_address) (i + address), 8,
 					   ((u8 *) &table_header) + i);
 			if (ACPI_FAILURE (status)) {
 				return_ACPI_STATUS (status);
 			}
 		}
 
+		/* Sanity check the table length */
+
+		if (table_header.length < sizeof (struct acpi_table_header)) {
+			return_ACPI_STATUS (AE_BAD_HEADER);
+		}
+
 		/* Allocate a buffer for the entire table */
 
 		table_ptr = ACPI_MEM_ALLOCATE (table_header.length);
@@ -319,17 +341,12 @@
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
 
-		/* Copy the header to the buffer */
-
-		ACPI_MEMCPY (table_ptr, &table_header, sizeof (struct acpi_table_header));
-		table_data_ptr = ACPI_PTR_ADD (u8, table_ptr, sizeof (struct acpi_table_header));
-
-		/* Get the table from the op region */
+		/* Get the entire table from the op region */
 
 		for (i = 0; i < table_header.length; i++) {
 			status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
-					   (acpi_physical_address) i, 8,
-					   ((u8 *) table_data_ptr + i));
+					   (acpi_physical_address) (i + address), 8,
+					   ((u8 *) table_ptr + i));
 			if (ACPI_FAILURE (status)) {
 				goto cleanup;
 			}
@@ -355,6 +372,12 @@
 		}
 
 		table_ptr = ACPI_CAST_PTR (struct acpi_table_header, buffer_desc->buffer.pointer);
+
+		 /* Sanity check the table length */
+
+		if (table_ptr->length < sizeof (struct acpi_table_header)) {
+			return_ACPI_STATUS (AE_BAD_HEADER);
+		}
 		break;
 
 
diff -Nru a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
--- a/drivers/acpi/executer/exfldio.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/executer/exfldio.c	Sat Jul 17 03:29:59 2004
@@ -130,6 +130,21 @@
 	if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
 			   + field_datum_byte_offset
 			   + obj_desc->common_field.access_byte_width)) {
+		if (acpi_gbl_enable_interpeter_slack) {
+			/*
+			 * Slack mode only:  We will go ahead and allow access to this
+			 * field if it is within the region length rounded up to the next
+			 * access width boundary.
+			 */
+			if (ACPI_ROUND_UP (rgn_desc->region.length,
+					   obj_desc->common_field.access_byte_width) >=
+				(obj_desc->common_field.base_byte_offset +
+				 obj_desc->common_field.access_byte_width +
+				 field_datum_byte_offset)) {
+				return_ACPI_STATUS (AE_OK);
+			}
+		}
+
 		if (rgn_desc->region.length < obj_desc->common_field.access_byte_width) {
 			/*
 			 * This is the case where the access_type (acc_word, etc.) is wider
@@ -277,7 +292,7 @@
 				rgn_desc->region.space_id));
 		}
 		else if (status == AE_NOT_EXIST) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			ACPI_REPORT_ERROR ((
 				"Region %s(%X) has no handler\n",
 				acpi_ut_get_region_name (rgn_desc->region.space_id),
 				rgn_desc->region.space_id));
@@ -766,14 +781,83 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ex_common_buffer_setup
+ *
+ * PARAMETERS:  obj_desc            - Field object
+ *              buffer_length       - Length of caller's buffer
+ *              datum_count         - Where the datum_count is returned
+ *
+ * RETURN:      Status, datum_count
+ *
+ * DESCRIPTION: Common code to validate the incoming buffer size and compute
+ *              the number of field "datums" that must be read or written.
+ *              A "datum" is the smallest unit that can be read or written
+ *              to the field, it is either 1,2,4, or 8 bytes.
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_common_buffer_setup (
+	union acpi_operand_object       *obj_desc,
+	u32                             buffer_length,
+	u32                             *datum_count)
+{
+	u32                             byte_field_length;
+	u32                             actual_byte_field_length;
+
+
+	ACPI_FUNCTION_TRACE ("ex_common_buffer_setup");
+
+
+	/*
+	 * Incoming buffer must be at least as long as the field, we do not
+	 * allow "partial" field reads/writes.  We do not care if the buffer is
+	 * larger than the field, this typically happens when an integer is
+	 * read/written to a field that is actually smaller than an integer.
+	 */
+	byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
+			 obj_desc->common_field.bit_length);
+	if (byte_field_length > buffer_length) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+			"Field size %X (bytes) is too large for buffer (%X)\n",
+			byte_field_length, buffer_length));
+
+		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+	}
+
+	/*
+	 * Create "actual" field byte count (minimum number of bytes that
+	 * must be read), then convert to datum count (minimum number
+	 * of datum-sized units that must be read)
+	 */
+	actual_byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
+			  obj_desc->common_field.start_field_bit_offset +
+			  obj_desc->common_field.bit_length);
+
+
+	*datum_count = ACPI_ROUND_UP_TO (actual_byte_field_length,
+			   obj_desc->common_field.access_byte_width);
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
+		"buffer_bytes %X, actual_bytes %X, Datums %X, byte_gran %X\n",
+		byte_field_length, actual_byte_field_length,
+		*datum_count, obj_desc->common_field.access_byte_width));
+
+	return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ex_extract_from_field
  *
- * PARAMETERS:  *obj_desc           - Field to be read
- *              *Value              - Where to store value
+ * PARAMETERS:  obj_desc            - Field to be read
+ *              Buffer              - Where to store the field data
+ *              buffer_length       - Length of Buffer
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Retrieve the value of the given field
+ * DESCRIPTION: Retrieve the current value of the given field
  *
  ******************************************************************************/
 
@@ -789,7 +873,6 @@
 	acpi_integer                    previous_raw_datum = 0;
 	acpi_integer                    this_raw_datum = 0;
 	acpi_integer                    merged_datum = 0;
-	u32                             byte_field_length;
 	u32                             datum_count;
 	u32                             i;
 
@@ -797,39 +880,13 @@
 	ACPI_FUNCTION_TRACE ("ex_extract_from_field");
 
 
-	/*
-	 * The field must fit within the caller's buffer
-	 */
-	byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
-	if (byte_field_length > buffer_length) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-			"Field size %X (bytes) too large for buffer (%X)\n",
-			byte_field_length, buffer_length));
+	/* Validate buffer, compute number of datums */
 
-		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
-	}
-
-	/* Convert field byte count to datum count, round up if necessary */
-
-	datum_count = ACPI_ROUND_UP_TO (byte_field_length,
-			   obj_desc->common_field.access_byte_width);
-
-	/*
-	 * If the field is not aligned on a datum boundary and does not
-	 * fit within a single datum, we must read an extra datum.
-	 *
-	 * We could just split the aligned and non-aligned cases since the
-	 * aligned case is so very simple, but this would require more code.
-	 */
-	if ((obj_desc->common_field.end_field_valid_bits != 0)    &&
-		(!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) {
-		datum_count++;
+	status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
 	}
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-		"byte_len %X, datum_len %X, byte_gran %X\n",
-		byte_field_length, datum_count,obj_desc->common_field.access_byte_width));
-
 	/*
 	 * Clear the caller's buffer (the whole buffer length as given)
 	 * This is very important, especially in the cases where the buffer
@@ -942,12 +999,13 @@
  *
  * FUNCTION:    acpi_ex_insert_into_field
  *
- * PARAMETERS:  *obj_desc           - Field to be set
- *              Buffer              - Value to store
+ * PARAMETERS:  obj_desc            - Field to be written
+ *              Buffer              - Data to be written
+ *              buffer_length       - Length of Buffer
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Store the value into the given field
+ * DESCRIPTION: Store the Buffer contents into the given field
  *
  ******************************************************************************/
 
@@ -964,41 +1022,18 @@
 	acpi_integer                    merged_datum;
 	acpi_integer                    previous_raw_datum;
 	acpi_integer                    this_raw_datum;
-	u32                             byte_field_length;
 	u32                             datum_count;
 
 
 	ACPI_FUNCTION_TRACE ("ex_insert_into_field");
 
 
-	/*
-	 * Incoming buffer must be at least as long as the field, we do not
-	 * allow "partial" field writes.  We do not care if the buffer is
-	 * larger than the field, this typically happens when an integer is
-	 * written to a field that is actually smaller than an integer.
-	 */
-	byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
-			 obj_desc->common_field.bit_length);
-	if (buffer_length < byte_field_length) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-			"Buffer length %X too small for field %X\n",
-			buffer_length, byte_field_length));
+	/* Validate buffer, compute number of datums */
 
-		return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
+	status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
 	}
-
-	byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
-			 obj_desc->common_field.start_field_bit_offset +
-			 obj_desc->common_field.bit_length);
-
-	/* Convert byte count to datum count, round up if necessary */
-
-	datum_count = ACPI_ROUND_UP_TO (byte_field_length,
-			  obj_desc->common_field.access_byte_width);
-
-	ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
-		"Bytes %X, Datums %X, byte_gran %X\n",
-		byte_field_length, datum_count, obj_desc->common_field.access_byte_width));
 
 	/*
 	 * Break the request into up to three parts (similar to an I/O request):
diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/executer/exmisc.c	Sat Jul 17 03:30:00 2004
@@ -389,6 +389,8 @@
 	acpi_integer                    operand1)
 {
 
+	ACPI_FUNCTION_ENTRY ();
+
 
 	switch (opcode) {
 	case AML_ADD_OP:                /* Add (Operand0, Operand1, Result) */
@@ -452,15 +454,17 @@
  * FUNCTION:    acpi_ex_do_logical_op
  *
  * PARAMETERS:  Opcode              - AML opcode
- *              Operand0            - Integer operand #0
- *              Operand1            - Integer operand #1
+ *              obj_desc0           - operand #0
+ *              obj_desc1           - operand #1
  *
  * RETURN:      TRUE/FALSE result of the operation
  *
  * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
  *              functions here is to prevent a lot of pointer dereferencing
  *              to obtain the operands and to simplify the generation of the
- *              logical value.
+ *              logical value.  Both operands must already be validated as
+ *              1) Both the same type, and
+ *              2) Either Integer, Buffer, or String type.
  *
  *              Note: cleanest machine code seems to be produced by the code
  *              below, rather than using statements of the form:
@@ -471,54 +475,137 @@
 u8
 acpi_ex_do_logical_op (
 	u16                             opcode,
-	acpi_integer                    operand0,
-	acpi_integer                    operand1)
+	union acpi_operand_object       *obj_desc0,
+	union acpi_operand_object       *obj_desc1)
 {
+	acpi_integer                    operand0;
+	acpi_integer                    operand1;
+	u8                              *ptr0;
+	u8                              *ptr1;
+	u32                             length0;
+	u32                             length1;
+	u32                             i;
 
 
-	switch (opcode) {
+	ACPI_FUNCTION_ENTRY ();
 
-	case AML_LAND_OP:               /* LAnd (Operand0, Operand1) */
 
-		if (operand0 && operand1) {
-			return (TRUE);
-		}
-		break;
+	if (ACPI_GET_OBJECT_TYPE (obj_desc0) == ACPI_TYPE_INTEGER) {
+		/* Both operands are of type integer */
 
+		operand0 = obj_desc0->integer.value;
+		operand1 = obj_desc1->integer.value;
 
-	case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
+		switch (opcode) {
+		case AML_LAND_OP:               /* LAnd (Operand0, Operand1) */
 
-		if (operand0 == operand1) {
-			return (TRUE);
-		}
-		break;
+			if (operand0 && operand1) {
+				return (TRUE);
+			}
+			break;
 
+		case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
 
-	case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
+			if (operand0 == operand1) {
+				return (TRUE);
+			}
+			break;
 
-		if (operand0 > operand1) {
-			return (TRUE);
-		}
-		break;
+		case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
 
+			if (operand0 > operand1) {
+				return (TRUE);
+			}
+			break;
 
-	case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
+		case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
 
-		if (operand0 < operand1) {
-			return (TRUE);
-		}
-		break;
+			if (operand0 < operand1) {
+				return (TRUE);
+			}
+			break;
 
+		case AML_LOR_OP:                 /* LOr (Operand0, Operand1) */
 
-	case AML_LOR_OP:                 /* LOr (Operand0, Operand1) */
+			if (operand0 || operand1) {
+				return (TRUE);
+			}
+			break;
 
-		if (operand0 || operand1) {
-			return (TRUE);
+		default:
+			break;
 		}
-		break;
+	}
+	else {
+		/*
+		 * Case for Buffer/String objects.
+		 * NOTE: takes advantage of common Buffer/String object fields
+		 */
+		length0 = obj_desc0->buffer.length;
+		ptr0    = obj_desc0->buffer.pointer;
+
+		length1 = obj_desc1->buffer.length;
+		ptr1    = obj_desc1->buffer.pointer;
+
+		switch (opcode) {
+		case AML_LEQUAL_OP:             /* LEqual (Operand0, Operand1) */
+
+			/* Length and all bytes must be equal */
+
+			if (length0 != length1) {
+				return (FALSE);
+			}
+
+			for (i = 0; i < length0; i++) {
+				if (ptr0[i] != ptr1[i]) {
+					return (FALSE);
+				}
+			}
+			return (TRUE);
 
-	default:
-		break;
+		case AML_LGREATER_OP:           /* LGreater (Operand0, Operand1) */
+
+			/* Lexicographic compare:  Scan the 1-to-1 data */
+
+			for (i = 0; (i < length0) && (i < length1); i++) {
+				if (ptr0[i] > ptr1[i]) {
+					return (TRUE);
+				}
+			}
+
+			/* Bytes match, now check lengths */
+
+			if (length0 > length1) {
+				return (TRUE);
+			}
+
+			/* Length0 <= Length1 */
+
+			return (FALSE);
+
+		case AML_LLESS_OP:              /* LLess (Operand0, Operand1) */
+
+			/* Lexicographic compare:  Scan the 1-to-1 data */
+
+			for (i = 0; (i < length0) && (i < length1); i++) {
+				if (ptr0[i] < ptr1[i]) {
+					return (TRUE);
+				}
+			}
+
+			/* Bytes match, now check lengths */
+
+			if (length0 < length1) {
+				return (TRUE);
+			}
+
+			/* Length0 >= Length1 */
+
+			return (FALSE);
+
+		default:
+			break;
+		}
 	}
 
 	return (FALSE);
diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
--- a/drivers/acpi/executer/exmutex.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/executer/exmutex.c	Sat Jul 17 03:29:59 2004
@@ -54,7 +54,7 @@
  *
  * FUNCTION:    acpi_ex_unlink_mutex
  *
- * PARAMETERS:  *obj_desc           - The mutex to be unlinked
+ * PARAMETERS:  obj_desc            - The mutex to be unlinked
  *
  * RETURN:      Status
  *
@@ -73,6 +73,8 @@
 		return;
 	}
 
+	/* Doubly linked list */
+
 	if (obj_desc->mutex.next) {
 		(obj_desc->mutex.next)->mutex.prev = obj_desc->mutex.prev;
 	}
@@ -90,8 +92,8 @@
  *
  * FUNCTION:    acpi_ex_link_mutex
  *
- * PARAMETERS:  *obj_desc           - The mutex to be linked
- *              *list_head          - head of the "acquired_mutex" list
+ * PARAMETERS:  obj_desc            - The mutex to be linked
+ *              list_head           - head of the "acquired_mutex" list
  *
  * RETURN:      Status
  *
@@ -130,8 +132,8 @@
  *
  * FUNCTION:    acpi_ex_acquire_mutex
  *
- * PARAMETERS:  *time_desc          - The 'time to delay' object descriptor
- *              *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  time_desc           - The 'time to delay' object descriptor
+ *              obj_desc            - The object descriptor for this op
  *
  * RETURN:      Status
  *
@@ -173,9 +175,8 @@
 		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
 	}
 
-	/*
-	 * Support for multiple acquires by the owning thread
-	 */
+	/* Support for multiple acquires by the owning thread */
+
 	if (obj_desc->mutex.owner_thread) {
 		/* Special case for Global Lock, allow all threads */
 
@@ -199,10 +200,11 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* Have the mutex, update mutex and walk info */
+	/* Have the mutex: update mutex and walk info and save the sync_level */
 
-	obj_desc->mutex.owner_thread    = walk_state->thread;
+	obj_desc->mutex.owner_thread     = walk_state->thread;
 	obj_desc->mutex.acquisition_depth = 1;
+	obj_desc->mutex.original_sync_level = walk_state->thread->current_sync_level;
 
 	walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
 
@@ -218,7 +220,7 @@
  *
  * FUNCTION:    acpi_ex_release_mutex
  *
- * PARAMETERS:  *obj_desc           - The object descriptor for this op
+ * PARAMETERS:  obj_desc            - The object descriptor for this op
  *
  * RETURN:      Status
  *
@@ -281,9 +283,8 @@
 		return_ACPI_STATUS (AE_AML_MUTEX_ORDER);
 	}
 
-	/*
-	 * Match multiple Acquires with multiple Releases
-	 */
+	/* Match multiple Acquires with multiple Releases */
+
 	obj_desc->mutex.acquisition_depth--;
 	if (obj_desc->mutex.acquisition_depth != 0) {
 		/* Just decrement the depth and return */
@@ -299,10 +300,10 @@
 
 	status = acpi_ex_system_release_mutex (obj_desc);
 
-	/* Update the mutex and walk state */
+	/* Update the mutex and walk state, restore sync_level before acquire */
 
 	obj_desc->mutex.owner_thread = NULL;
-	walk_state->thread->current_sync_level = obj_desc->mutex.sync_level;
+	walk_state->thread->current_sync_level = obj_desc->mutex.original_sync_level;
 
 	return_ACPI_STATUS (status);
 }
@@ -312,7 +313,7 @@
  *
  * FUNCTION:    acpi_ex_release_all_mutexes
  *
- * PARAMETERS:  *mutex_list           - Head of the mutex list
+ * PARAMETERS:  mutex_list            - Head of the mutex list
  *
  * RETURN:      Status
  *
@@ -332,9 +333,8 @@
 	ACPI_FUNCTION_ENTRY ();
 
 
-	/*
-	 * Traverse the list of owned mutexes, releasing each one.
-	 */
+	/* Traverse the list of owned mutexes, releasing each one */
+
 	while (next) {
 		this = next;
 		next = this->mutex.next;
@@ -352,7 +352,11 @@
 
 		/* Mark mutex unowned */
 
-		this->mutex.owner_thread     = NULL;
+		this->mutex.owner_thread = NULL;
+
+		/* Update Thread sync_level (Last mutex is the important one) */
+
+		thread->current_sync_level = this->mutex.original_sync_level;
 	}
 }
 
diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
--- a/drivers/acpi/executer/exoparg2.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/executer/exoparg2.c	Sat Jul 17 03:29:59 2004
@@ -97,6 +97,7 @@
 {
 	union acpi_operand_object       **operand = &walk_state->operands[0];
 	struct acpi_namespace_node      *node;
+	u32                             value;
 	acpi_status                     status = AE_OK;
 
 
@@ -113,16 +114,46 @@
 
 		node = (struct acpi_namespace_node *) operand[0];
 
+		/* Second value is the notify value */
+
+		value = (u32) operand[1]->integer.value;
+
 		/* Notifies allowed on this object? */
 
 		if (!acpi_ev_is_notify_object (node)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unexpected notify object type [%s]\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Unexpected notify object type [%s]\n",
 					acpi_ut_get_type_name (node->type)));
 
 			status = AE_AML_OPERAND_TYPE;
 			break;
 		}
 
+#ifdef ACPI_GPE_NOTIFY_CHECK
+		/*
+		 * GPE method wake/notify check.  Here, we want to ensure that we
+		 * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx
+		 * GPE method during system runtime.  If we do, the GPE is marked
+		 * as "wake-only" and disabled.
+		 *
+		 * 1) Is the Notify() value == device_wake?
+		 * 2) Is this a GPE deferred method?  (An _Lxx or _Exx method)
+		 * 3) Did the original GPE happen at system runtime?
+		 *    (versus during wake)
+		 *
+		 * If all three cases are true, this is a wake-only GPE that should
+		 * be disabled at runtime.
+		 */
+		if (value == 2)     /* device_wake */ {
+			status = acpi_ev_check_for_wake_only_gpe (walk_state->gpe_event_info);
+			if (ACPI_FAILURE (status)) {
+				/* AE_WAKE_ONLY_GPE only error, means ignore this notify */
+
+				return_ACPI_STATUS (AE_OK)
+			}
+		}
+#endif
+
 		/*
 		 * Dispatch the notify to the appropriate handler
 		 * NOTE: the request is queued for execution after this method
@@ -130,8 +161,7 @@
 		 * from this thread -- because handlers may in turn run other
 		 * control methods.
 		 */
-		status = acpi_ev_queue_notify_request (node,
-				  (u32) operand[1]->integer.value);
+		status = acpi_ev_queue_notify_request (node, value);
 		break;
 
 
@@ -543,9 +573,17 @@
 	 * Execute the Opcode
 	 */
 	if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
+		/* Both operands must be of the same type */
+
+		if (ACPI_GET_OBJECT_TYPE (operand[0]) !=
+			ACPI_GET_OBJECT_TYPE (operand[1])) {
+			status = AE_AML_OPERAND_TYPE;
+			goto cleanup;
+		}
+
 		logical_result = acpi_ex_do_logical_op (walk_state->opcode,
-				 operand[0]->integer.value,
-				 operand[1]->integer.value);
+				 operand[0],
+				 operand[1]);
 		goto store_logical_result;
 	}
 
diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
--- a/drivers/acpi/executer/exresolv.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/executer/exresolv.c	Sat Jul 17 03:29:59 2004
@@ -187,15 +187,15 @@
 				return_ACPI_STATUS (status);
 			}
 
+			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] value_obj is %p\n",
+				stack_desc->reference.offset, obj_desc));
+
 			/*
 			 * Now we can delete the original Reference Object and
-			 * replace it with the resolve value
+			 * replace it with the resolved value
 			 */
 			acpi_ut_remove_reference (stack_desc);
 			*stack_ptr = obj_desc;
-
-			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %d] value_obj is %p\n",
-				stack_desc->reference.offset, obj_desc));
 			break;
 
 
diff -Nru a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c
--- a/drivers/acpi/executer/exstore.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/executer/exstore.c	Sat Jul 17 03:29:59 2004
@@ -102,7 +102,8 @@
 		 * Storing an object into a Named node.
 		 */
 		status = acpi_ex_store_object_to_node (source_desc,
-				 (struct acpi_namespace_node *) dest_desc, walk_state);
+				 (struct acpi_namespace_node *) dest_desc, walk_state,
+				 ACPI_IMPLICIT_CONVERSION);
 
 		return_ACPI_STATUS (status);
 	}
@@ -153,7 +154,7 @@
 		/* Storing an object into a Name "container" */
 
 		status = acpi_ex_store_object_to_node (source_desc, ref_desc->reference.object,
-				  walk_state);
+				  walk_state, ACPI_IMPLICIT_CONVERSION);
 		break;
 
 
@@ -399,6 +400,7 @@
  * PARAMETERS:  source_desc             - Value to be stored
  *              Node                    - Named object to receive the value
  *              walk_state              - Current walk state
+ *              implicit_conversion     - Perform implicit conversion (yes/no)
  *
  * RETURN:      Status
  *
@@ -421,7 +423,8 @@
 acpi_ex_store_object_to_node (
 	union acpi_operand_object       *source_desc,
 	struct acpi_namespace_node      *node,
-	struct acpi_walk_state          *walk_state)
+	struct acpi_walk_state          *walk_state,
+	u8                              implicit_conversion)
 {
 	acpi_status                     status = AE_OK;
 	union acpi_operand_object       *target_desc;
@@ -449,6 +452,14 @@
 	status = acpi_ex_resolve_object (&source_desc, target_type, walk_state);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
+	}
+
+	/* If no implicit conversion, drop into the default case below */
+
+	if (!implicit_conversion) {
+		/* Force execution of default (no implicit conversion) */
+
+		target_type = ACPI_TYPE_ANY;
 	}
 
 	/*
diff -Nru a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c
--- a/drivers/acpi/hardware/hwgpe.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/hardware/hwgpe.c	Sat Jul 17 03:29:59 2004
@@ -51,104 +51,24 @@
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_enable_gpe
+ * FUNCTION:    acpi_hw_write_gpe_enable_reg
  *
  * PARAMETERS:  gpe_event_info      - Info block for the GPE to be enabled
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable a single GPE.
+ * DESCRIPTION: Write a GPE enable register.  Note: The bit for this GPE must
+ *              already be cleared or set in the parent register
+ *              enable_for_run mask.
  *
  ******************************************************************************/
 
 acpi_status
-acpi_hw_enable_gpe (
-	struct acpi_gpe_event_info      *gpe_event_info)
-{
-	u32                             in_byte;
-	acpi_status                     status;
-
-
-	ACPI_FUNCTION_ENTRY ();
-
-
-	/*
-	 * Read the current value of the register, set the appropriate bit
-	 * to enable the GPE, and write out the new register.
-	 */
-	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_event_info->register_info->enable_address);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Write with the new GPE bit enabled */
-
-	status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask),
-			  &gpe_event_info->register_info->enable_address);
-
-	return (status);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_hw_enable_gpe_for_wakeup
- *
- * PARAMETERS:  gpe_event_info      - Info block for the GPE to be enabled
- *
- * RETURN:      None
- *
- * DESCRIPTION: Keep track of which GPEs the OS has requested not be
- *              disabled when going to sleep.
- *
- ******************************************************************************/
-
-void
-acpi_hw_enable_gpe_for_wakeup (
+acpi_hw_write_gpe_enable_reg (
 	struct acpi_gpe_event_info      *gpe_event_info)
 {
 	struct acpi_gpe_register_info   *gpe_register_info;
-
-
-	ACPI_FUNCTION_ENTRY ();
-
-
-	/* Get the info block for the entire GPE register */
-
-	gpe_register_info = gpe_event_info->register_info;
-	if (!gpe_register_info) {
-		return;
-	}
-
-	/*
-	 * Set the bit so we will not enable this GPE when sleeping (and disable
-	 * it upon wake)
-	 */
-	gpe_register_info->wake_enable |= gpe_event_info->bit_mask;
-	gpe_event_info->flags |= (ACPI_GPE_TYPE_WAKE | ACPI_GPE_ENABLED);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_hw_disable_gpe
- *
- * PARAMETERS:  gpe_event_info      - Info block for the GPE to be disabled
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Disable a single GPE.
- *
- ******************************************************************************/
-
-acpi_status
-acpi_hw_disable_gpe (
-	struct acpi_gpe_event_info      *gpe_event_info)
-{
-	u32                             in_byte;
 	acpi_status                     status;
-	struct acpi_gpe_register_info   *gpe_register_info;
 
 
 	ACPI_FUNCTION_ENTRY ();
@@ -158,67 +78,15 @@
 
 	gpe_register_info = gpe_event_info->register_info;
 	if (!gpe_register_info) {
-		return (AE_BAD_PARAMETER);
+		return (AE_NOT_EXIST);
 	}
 
-	/*
-	 * Read the current value of the register, clear the appropriate bit,
-	 * and write out the new register value to disable the GPE.
-	 */
-	status = acpi_hw_low_level_read (8, &in_byte,
-			  &gpe_register_info->enable_address);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
+	/* Write the entire GPE (runtime) enable register */
 
-	/* Write the byte with this GPE bit cleared */
-
-	status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)),
+	status = acpi_hw_low_level_write (8, gpe_register_info->enable_for_run,
 			  &gpe_register_info->enable_address);
-	if (ACPI_FAILURE (status)) {
-		return (status);
-	}
-
-	/* Make sure this GPE is disabled for wake, also */
-
-	acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
-	return (AE_OK);
-}
-
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_hw_disable_gpe_for_wakeup
- *
- * PARAMETERS:  gpe_event_info      - Info block for the GPE to be disabled
- *
- * RETURN:      None
- *
- * DESCRIPTION: Keep track of which GPEs the OS has requested not be
- *              disabled when going to sleep.
- *
- ******************************************************************************/
-
-void
-acpi_hw_disable_gpe_for_wakeup (
-	struct acpi_gpe_event_info      *gpe_event_info)
-{
-	struct acpi_gpe_register_info   *gpe_register_info;
-
-
-	ACPI_FUNCTION_ENTRY ();
-
-
-	/* Get the info block for the entire GPE register */
-
-	gpe_register_info = gpe_event_info->register_info;
-	if (!gpe_register_info) {
-		return;
-	}
 
-	/* Clear the bit so we will disable this when sleeping */
-
-	gpe_register_info->wake_enable &= ~(gpe_event_info->bit_mask);
+	return (status);
 }
 
 
@@ -248,7 +116,7 @@
 	 * Write a one to the appropriate bit in the status register to
 	 * clear this GPE.
 	 */
-	status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask,
+	status = acpi_hw_low_level_write (8, gpe_event_info->register_bit,
 			  &gpe_event_info->register_info->status_address);
 
 	return (status);
@@ -274,7 +142,7 @@
 	acpi_event_status               *event_status)
 {
 	u32                             in_byte;
-	u8                              bit_mask;
+	u8                              register_bit;
 	struct acpi_gpe_register_info   *gpe_register_info;
 	acpi_status                     status;
 	acpi_event_status               local_event_status = 0;
@@ -293,33 +161,28 @@
 
 	/* Get the register bitmask for this GPE */
 
-	bit_mask = gpe_event_info->bit_mask;
-
-	/* GPE Enabled? */
+	register_bit = gpe_event_info->register_bit;
 
-	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address);
-	if (ACPI_FAILURE (status)) {
-		goto unlock_and_exit;
-	}
+	/* GPE currently enabled? (enabled for runtime?) */
 
-	if (bit_mask & in_byte) {
+	if (register_bit & gpe_register_info->enable_for_run) {
 		local_event_status |= ACPI_EVENT_FLAG_ENABLED;
 	}
 
-	/* GPE Enabled for wake? */
+	/* GPE enabled for wake? */
 
-	if (bit_mask & gpe_register_info->wake_enable) {
+	if (register_bit & gpe_register_info->enable_for_wake) {
 		local_event_status |= ACPI_EVENT_FLAG_WAKE_ENABLED;
 	}
 
-	/* GPE active (set)? */
+	/* GPE currently active (status bit == 1)? */
 
 	status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address);
 	if (ACPI_FAILURE (status)) {
 		goto unlock_and_exit;
 	}
 
-	if (bit_mask & in_byte) {
+	if (register_bit & in_byte) {
 		local_event_status |= ACPI_EVENT_FLAG_SET;
 	}
 
@@ -411,64 +274,43 @@
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_prepare_gpe_block_for_sleep
+ * FUNCTION:    acpi_hw_enable_runtime_gpe_block
  *
  * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
  *              gpe_block           - Gpe Block info
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable all runtime GPEs and enable all wakeup GPEs -- within
- *              a single GPE block
+ * DESCRIPTION: Enable all "runtime" GPEs within a GPE block. (Includes
+ *              combination wake/run GPEs.)
  *
  ******************************************************************************/
 
-static acpi_status
-acpi_hw_prepare_gpe_block_for_sleep (
+acpi_status
+acpi_hw_enable_runtime_gpe_block (
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
 	struct acpi_gpe_block_info      *gpe_block)
 {
 	u32                             i;
-	struct acpi_gpe_register_info   *gpe_register_info;
-	u32                             in_value;
 	acpi_status                     status;
 
 
-	/* Get the register info for the entire GPE block */
-
-	gpe_register_info = gpe_block->register_info;
+	/* NOTE: assumes that all GPEs are currently disabled */
 
 	/* Examine each GPE Register within the block */
 
 	for (i = 0; i < gpe_block->register_count; i++) {
-		/*
-		 * Read the enabled/disabled status of all GPEs. We
-		 * will be using it to restore all the GPEs later.
-		 *
-		 * NOTE:  Wake GPEs are are ALL disabled at this time, so when we wake
-		 * and restore this register, they will be automatically disabled.
-		 */
-		status = acpi_hw_low_level_read (8, &in_value,
-				 &gpe_register_info->enable_address);
-		if (ACPI_FAILURE (status)) {
-			return (status);
+		if (!gpe_block->register_info[i].enable_for_run) {
+			continue;
 		}
 
-		gpe_register_info->enable = (u8) in_value;
+		/* Enable all "runtime" GPEs in this register */
 
-		/*
-		 * 1) Disable all runtime GPEs
-		 * 2) Enable all wakeup GPEs
-		 */
-		status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable,
-				&gpe_register_info->enable_address);
+		status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_run,
+				 &gpe_block->register_info[i].enable_address);
 		if (ACPI_FAILURE (status)) {
 			return (status);
 		}
-
-		/* Point to next GPE register */
-
-		gpe_register_info++;
 	}
 
 	return (AE_OK);
@@ -477,122 +319,125 @@
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_prepare_gpes_for_sleep
+ * FUNCTION:    acpi_hw_enable_wakeup_gpe_block
  *
- * PARAMETERS:  None
+ * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
+ *              gpe_block           - Gpe Block info
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Disable all runtime GPEs, enable all wake GPEs.
- *              Called with interrupts disabled. The interrupt handler also
- *              modifies gpe_register_info->Enable, so it should not be
- *              given the chance to run until after the runtime GPEs are
- *              re-enabled.
+ * DESCRIPTION: Enable all "wake" GPEs within a GPE block.  (Includes
+ *              combination wake/run GPEs.)
  *
  ******************************************************************************/
 
 acpi_status
-acpi_hw_prepare_gpes_for_sleep (
-	void)
+acpi_hw_enable_wakeup_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block)
 {
+	u32                             i;
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_ENTRY ();
+	/* Examine each GPE Register within the block */
 
+	for (i = 0; i < gpe_block->register_count; i++) {
+		if (!gpe_block->register_info[i].enable_for_wake) {
+			continue;
+		}
 
-	status = acpi_ev_walk_gpe_list (acpi_hw_prepare_gpe_block_for_sleep);
-	return (status);
+		/* Enable all "wake" GPEs in this register */
+
+		status = acpi_hw_low_level_write (8, gpe_block->register_info[i].enable_for_wake,
+				 &gpe_block->register_info[i].enable_address);
+		if (ACPI_FAILURE (status)) {
+			return (status);
+		}
+	}
+
+	return (AE_OK);
 }
 
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_restore_gpe_block_on_wake
+ * FUNCTION:    acpi_hw_disable_all_gpes
  *
- * PARAMETERS:  gpe_xrupt_info      - GPE Interrupt info
- *              gpe_block           - Gpe Block info
+ * PARAMETERS:  Flags           - ACPI_NOT_ISR or ACPI_ISR
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in one
- *              GPE block
+ * DESCRIPTION: Disable and clear all GPEs
  *
  ******************************************************************************/
 
-static acpi_status
-acpi_hw_restore_gpe_block_on_wake (
-	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
-	struct acpi_gpe_block_info      *gpe_block)
+acpi_status
+acpi_hw_disable_all_gpes (
+	u32                             flags)
 {
-	u32                             i;
-	struct acpi_gpe_register_info   *gpe_register_info;
 	acpi_status                     status;
 
 
-	/* This callback processes one entire GPE block */
+	ACPI_FUNCTION_TRACE ("hw_disable_all_gpes");
 
-	/* Get the register info for the entire GPE block */
 
-	gpe_register_info = gpe_block->register_info;
+	status = acpi_ev_walk_gpe_list (acpi_hw_disable_gpe_block, flags);
+	status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, flags);
+	return_ACPI_STATUS (status);
+}
 
-	/* Examine each GPE register within the block */
 
-	for (i = 0; i < gpe_block->register_count; i++) {
-		/* Clear the entire status register */
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_enable_all_runtime_gpes
+ *
+ * PARAMETERS:  Flags           - ACPI_NOT_ISR or ACPI_ISR
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Enable all GPEs of the given type
+ *
+ ******************************************************************************/
 
-		status = acpi_hw_low_level_write (8, 0xFF,
-				 &gpe_block->register_info[i].status_address);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
+acpi_status
+acpi_hw_enable_all_runtime_gpes (
+	u32                             flags)
+{
+	acpi_status                     status;
 
-		/*
-		 * Restore the GPE Enable register, which will do the following:
-		 *
-		 * 1) Disable all wakeup GPEs
-		 * 2) Enable all runtime GPEs
-		 *
-		 *  (On sleep, we saved the enabled status of all GPEs)
-		 */
-		status = acpi_hw_low_level_write (8, gpe_register_info->enable,
-				 &gpe_register_info->enable_address);
-		if (ACPI_FAILURE (status)) {
-			return (status);
-		}
 
-		/* Point to next GPE register */
+	ACPI_FUNCTION_TRACE ("hw_enable_all_runtime_gpes");
 
-		gpe_register_info++;
-	}
 
-	return (AE_OK);
+	status = acpi_ev_walk_gpe_list (acpi_hw_enable_runtime_gpe_block, flags);
+	return_ACPI_STATUS (status);
 }
 
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_hw_restore_gpes_on_wake
+ * FUNCTION:    acpi_hw_enable_all_wakeup_gpes
  *
- * PARAMETERS:  None
+ * PARAMETERS:  Flags           - ACPI_NOT_ISR or ACPI_ISR
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Enable all runtime GPEs and disable all wake GPEs -- in all
- *              GPE blocks
+ * DESCRIPTION: Enable all GPEs of the given type
  *
  ******************************************************************************/
 
 acpi_status
-acpi_hw_restore_gpes_on_wake (
-	void)
+acpi_hw_enable_all_wakeup_gpes (
+	u32                             flags)
 {
 	acpi_status                     status;
 
 
-	ACPI_FUNCTION_ENTRY ();
+	ACPI_FUNCTION_TRACE ("hw_enable_all_wakeup_gpes");
 
 
-	status = acpi_ev_walk_gpe_list (acpi_hw_restore_gpe_block_on_wake);
-	return (status);
+	status = acpi_ev_walk_gpe_list (acpi_hw_enable_wakeup_gpe_block, flags);
+	return_ACPI_STATUS (status);
 }
+
diff -Nru a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
--- a/drivers/acpi/hardware/hwregs.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/hardware/hwregs.c	Sat Jul 17 03:30:00 2004
@@ -61,6 +61,7 @@
  * RETURN:      none
  *
  * DESCRIPTION: Clears all fixed and general purpose status bits
+ *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  *
  ******************************************************************************/
 
@@ -103,7 +104,7 @@
 
 	/* Clear the GPE Bits in all GPE registers in all GPE blocks */
 
-	status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block);
+	status = acpi_ev_walk_gpe_list (acpi_hw_clear_gpe_block, ACPI_ISR);
 
 unlock_and_exit:
 	if (flags & ACPI_MTX_LOCK) {
@@ -135,7 +136,7 @@
 	u8                              *sleep_type_b)
 {
 	acpi_status                     status = AE_OK;
-	union acpi_operand_object       *obj_desc;
+	struct acpi_parameter_info      info;
 
 
 	ACPI_FUNCTION_TRACE ("acpi_get_sleep_type_data");
@@ -152,8 +153,9 @@
 	/*
 	 * Evaluate the namespace object containing the values for this state
 	 */
+	info.parameters = NULL;
 	status = acpi_ns_evaluate_by_name ((char *) acpi_gbl_sleep_state_names[sleep_state],
-			  NULL, &obj_desc);
+			  &info);
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%s while evaluating sleep_state [%s]\n",
 			acpi_format_exception (status), acpi_gbl_sleep_state_names[sleep_state]));
@@ -163,48 +165,50 @@
 
 	/* Must have a return object */
 
-	if (!obj_desc) {
+	if (!info.return_object) {
 		ACPI_REPORT_ERROR (("Missing Sleep State object\n"));
 		status = AE_NOT_EXIST;
 	}
 
 	/* It must be of type Package */
 
-	else if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_PACKAGE) {
+	else if (ACPI_GET_OBJECT_TYPE (info.return_object) != ACPI_TYPE_PACKAGE) {
 		ACPI_REPORT_ERROR (("Sleep State object not a Package\n"));
 		status = AE_AML_OPERAND_TYPE;
 	}
 
 	/* The package must have at least two elements */
 
-	else if (obj_desc->package.count < 2) {
+	else if (info.return_object->package.count < 2) {
 		ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
 		status = AE_AML_NO_OPERAND;
 	}
 
 	/* The first two elements must both be of type Integer */
 
-	else if ((ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[0]) != ACPI_TYPE_INTEGER) ||
-			 (ACPI_GET_OBJECT_TYPE (obj_desc->package.elements[1]) != ACPI_TYPE_INTEGER)) {
+	else if ((ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[0]) != ACPI_TYPE_INTEGER) ||
+			 (ACPI_GET_OBJECT_TYPE (info.return_object->package.elements[1]) != ACPI_TYPE_INTEGER)) {
 		ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n",
-			acpi_ut_get_object_type_name (obj_desc->package.elements[0]),
-			acpi_ut_get_object_type_name (obj_desc->package.elements[1])));
+			acpi_ut_get_object_type_name (info.return_object->package.elements[0]),
+			acpi_ut_get_object_type_name (info.return_object->package.elements[1])));
 		status = AE_AML_OPERAND_TYPE;
 	}
 	else {
 		/*
 		 * Valid _Sx_ package size, type, and value
 		 */
-		*sleep_type_a = (u8) (obj_desc->package.elements[0])->integer.value;
-		*sleep_type_b = (u8) (obj_desc->package.elements[1])->integer.value;
+		*sleep_type_a = (u8) (info.return_object->package.elements[0])->integer.value;
+		*sleep_type_b = (u8) (info.return_object->package.elements[1])->integer.value;
 	}
 
 	if (ACPI_FAILURE (status)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
-			acpi_gbl_sleep_state_names[sleep_state], obj_desc, acpi_ut_get_object_type_name (obj_desc)));
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+			"While evaluating sleep_state [%s], bad Sleep object %p type %s\n",
+			acpi_gbl_sleep_state_names[sleep_state], info.return_object,
+			acpi_ut_get_object_type_name (info.return_object)));
 	}
 
-	acpi_ut_remove_reference (obj_desc);
+	acpi_ut_remove_reference (info.return_object);
 	return_ACPI_STATUS (status);
 }
 
diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
--- a/drivers/acpi/hardware/hwsleep.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/hardware/hwsleep.c	Sat Jul 17 03:29:59 2004
@@ -265,19 +265,21 @@
 	sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
 	sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
 
-	if (sleep_state != ACPI_STATE_S5) {
-		/* Clear wake status */
+	/* Clear wake status */
 
-		status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
+	status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
 
-		status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
-		if (ACPI_FAILURE (status)) {
-			return_ACPI_STATUS (status);
-		}
+	/* Clear all fixed and general purpose status bits */
 
+	status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	if (sleep_state != ACPI_STATE_S5) {
 		/* Disable BM arbitration */
 
 		status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
@@ -287,10 +289,16 @@
 	}
 
 	/*
-	 * 1) Disable all runtime GPEs
+	 * 1) Disable/Clear all GPEs
 	 * 2) Enable all wakeup GPEs
 	 */
-	status = acpi_hw_prepare_gpes_for_sleep ();
+	status = acpi_hw_disable_all_gpes (ACPI_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	acpi_gbl_system_awake_and_running = FALSE;
+
+	status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -420,10 +428,16 @@
 	}
 
 	/*
-	 * 1) Disable all runtime GPEs
+	 * 1) Disable/Clear all GPEs
 	 * 2) Enable all wakeup GPEs
 	 */
-	status = acpi_hw_prepare_gpes_for_sleep ();
+	status = acpi_hw_disable_all_gpes (ACPI_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	acpi_gbl_system_awake_and_running = FALSE;
+
+	status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
@@ -453,6 +467,7 @@
  * RETURN:      Status
  *
  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
+ *              Called with interrupts ENABLED.
  *
  ******************************************************************************/
 
@@ -540,19 +555,25 @@
 
 	/*
 	 * Restore the GPEs:
-	 * 1) Disable all wakeup GPEs
+	 * 1) Disable/Clear all GPEs
 	 * 2) Enable all runtime GPEs
 	 */
-	status = acpi_hw_restore_gpes_on_wake ();
+	status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+	acpi_gbl_system_awake_and_running = TRUE;
+
+	status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
 	/* Enable power button */
 
-	acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
+	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
 			1, ACPI_MTX_DO_NOT_LOCK);
-	acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
+	(void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
 			1, ACPI_MTX_DO_NOT_LOCK);
 
 	/* Enable BM arbitration */
diff -Nru a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/motherboard.c	Sat Jul 17 03:30:00 2004
@@ -0,0 +1,161 @@
+/* 
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("acpi_motherboard")
+
+/* Dell use PNP0C01 instead of PNP0C02 */
+#define ACPI_MB_HID1			"PNP0C01"
+#define ACPI_MB_HID2			"PNP0C02"
+
+/**
+ * Doesn't care about legacy IO ports, only IO ports beyond 0x1000 are reserved
+ * Doesn't care about the failure of 'request_region', since other may reserve 
+ * the io ports as well
+ */
+#define IS_RESERVED_ADDR(base, len) \
+	(((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \
+	&& ((base) + (len) > PCIBIOS_MIN_IO))
+
+static acpi_status
+acpi_reserve_io_ranges (struct acpi_resource *res, void *data)
+{
+	ACPI_FUNCTION_TRACE("acpi_reserve_io_ranges");
+
+	if (res->id == ACPI_RSTYPE_IO) {
+		struct acpi_resource_io *io_res = &res->data.io;
+
+		if (io_res->min_base_address != io_res->max_base_address)
+			return AE_OK;
+		if (IS_RESERVED_ADDR(io_res->min_base_address, io_res->range_length)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
+				io_res->min_base_address, 
+				io_res->min_base_address + io_res->range_length));
+			request_region(io_res->min_base_address, 
+				io_res->range_length, "motherboard");
+		}
+	}else if (res->id == ACPI_RSTYPE_FIXED_IO) {
+		struct acpi_resource_fixed_io *fixed_io_res = &res->data.fixed_io;
+
+		if (IS_RESERVED_ADDR(fixed_io_res->base_address, fixed_io_res->range_length)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Motherboard resources 0x%08x - 0x%08x\n",
+				fixed_io_res->base_address, 
+				fixed_io_res->base_address + fixed_io_res->range_length));
+			request_region(fixed_io_res->base_address, 
+				fixed_io_res->range_length, "motherboard");
+		}
+	}else {
+		/* Memory mapped IO? */
+	}
+
+	return AE_OK;
+}
+
+static int acpi_motherboard_add (struct acpi_device *device)
+{
+	if (!device)
+		return -EINVAL;
+	acpi_walk_resources(device->handle, METHOD_NAME__CRS, 
+		acpi_reserve_io_ranges, NULL);
+
+	return 0;
+}
+
+static struct acpi_driver acpi_motherboard_driver1 = {
+	.name =		"motherboard",
+	.class =	"",
+	.ids =		ACPI_MB_HID1,
+	.ops =	{
+		.add =		acpi_motherboard_add,
+	},
+};
+
+static struct acpi_driver acpi_motherboard_driver2 = {
+	.name =		"motherboard",
+	.class =	"",
+	.ids =		ACPI_MB_HID2,
+	.ops =	{
+		.add =		acpi_motherboard_add,
+	},
+};
+
+static void __init
+acpi_reserve_resources (void)
+{
+	if (acpi_gbl_FADT->xpm1a_evt_blk.address && acpi_gbl_FADT->pm1_evt_len)
+		request_region(acpi_gbl_FADT->xpm1a_evt_blk.address, 
+			acpi_gbl_FADT->pm1_evt_len, "PM1a_EVT_BLK");
+
+	if (acpi_gbl_FADT->xpm1b_evt_blk.address && acpi_gbl_FADT->pm1_evt_len)
+		request_region(acpi_gbl_FADT->xpm1b_evt_blk.address,
+			acpi_gbl_FADT->pm1_evt_len, "PM1b_EVT_BLK");
+
+	if (acpi_gbl_FADT->xpm1a_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len)
+		request_region(acpi_gbl_FADT->xpm1a_cnt_blk.address, 
+			acpi_gbl_FADT->pm1_cnt_len, "PM1a_CNT_BLK");
+
+	if (acpi_gbl_FADT->xpm1b_cnt_blk.address && acpi_gbl_FADT->pm1_cnt_len)
+		request_region(acpi_gbl_FADT->xpm1b_cnt_blk.address, 
+			acpi_gbl_FADT->pm1_cnt_len, "PM1b_CNT_BLK");
+
+	if (acpi_gbl_FADT->xpm_tmr_blk.address && acpi_gbl_FADT->pm_tm_len == 4)
+		request_region(acpi_gbl_FADT->xpm_tmr_blk.address,
+			4, "PM_TMR");
+
+	if (acpi_gbl_FADT->xpm2_cnt_blk.address && acpi_gbl_FADT->pm2_cnt_len)
+		request_region(acpi_gbl_FADT->xpm2_cnt_blk.address,
+			acpi_gbl_FADT->pm2_cnt_len, "PM2_CNT_BLK");
+
+	/* Length of GPE blocks must be a non-negative multiple of 2 */
+
+	if (acpi_gbl_FADT->xgpe0_blk.address && acpi_gbl_FADT->gpe0_blk_len &&
+			!(acpi_gbl_FADT->gpe0_blk_len & 0x1))
+		request_region(acpi_gbl_FADT->xgpe0_blk.address,
+			acpi_gbl_FADT->gpe0_blk_len, "GPE0_BLK");
+
+	if (acpi_gbl_FADT->xgpe1_blk.address && acpi_gbl_FADT->gpe1_blk_len &&
+			!(acpi_gbl_FADT->gpe1_blk_len & 0x1))
+		request_region(acpi_gbl_FADT->xgpe1_blk.address,
+			acpi_gbl_FADT->gpe1_blk_len, "GPE1_BLK");
+}
+
+static int __init acpi_motherboard_init(void)
+{
+	acpi_bus_register_driver(&acpi_motherboard_driver1);
+	acpi_bus_register_driver(&acpi_motherboard_driver2);
+	/* 
+	 * Guarantee motherboard IO reservation first
+	 * This module must run after scan.c
+	 */
+	if (!acpi_disabled)
+		acpi_reserve_resources ();
+	return 0;
+}
+
+subsys_initcall(acpi_motherboard_init);
diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
--- a/drivers/acpi/namespace/nsaccess.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/namespace/nsaccess.c	Sat Jul 17 03:30:00 2004
@@ -193,7 +193,7 @@
 			case ACPI_TYPE_MUTEX:
 
 				obj_desc->mutex.node = new_node;
-				obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL
+				obj_desc->mutex.sync_level = (u8) ACPI_STRTOUL
 						  (val, NULL, 10);
 
 				if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
--- a/drivers/acpi/namespace/nsalloc.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/namespace/nsalloc.c	Sat Jul 17 03:29:59 2004
@@ -267,7 +267,7 @@
 	else {
 #ifdef ACPI_ALPHABETIC_NAMESPACE
 		/*
-		 * Walk the list whilst searching for the the correct
+		 * Walk the list whilst searching for the correct
 		 * alphabetic placement.
 		 */
 		previous_child_node = NULL;
diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
--- a/drivers/acpi/namespace/nseval.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/namespace/nseval.c	Sat Jul 17 03:29:59 2004
@@ -77,13 +77,10 @@
 
 acpi_status
 acpi_ns_evaluate_relative (
-	struct acpi_namespace_node      *handle,
 	char                            *pathname,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object)
+	struct acpi_parameter_info      *info)
 {
 	acpi_status                     status;
-	struct acpi_namespace_node      *prefix_node;
 	struct acpi_namespace_node      *node = NULL;
 	union acpi_generic_state        *scope_info;
 	char                            *internal_path = NULL;
@@ -95,7 +92,7 @@
 	/*
 	 * Must have a valid object handle
 	 */
-	if (!handle) {
+	if (!info || !info->node) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
@@ -118,8 +115,8 @@
 		goto cleanup;
 	}
 
-	prefix_node = acpi_ns_map_handle_to_node (handle);
-	if (!prefix_node) {
+	info->node = acpi_ns_map_handle_to_node (info->node);
+	if (!info->node) {
 		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		status = AE_BAD_PARAMETER;
 		goto cleanup;
@@ -127,7 +124,7 @@
 
 	/* Lookup the name in the namespace */
 
-	scope_info->scope.node = prefix_node;
+	scope_info->scope.node = info->node;
 	status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
 			 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
 			 &node);
@@ -147,7 +144,8 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
 		pathname, node, acpi_ns_get_attached_object (node)));
 
-	status = acpi_ns_evaluate_by_handle (node, params, return_object);
+	info->node = node;
+	status = acpi_ns_evaluate_by_handle (info);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
 		pathname));
@@ -166,6 +164,7 @@
  * FUNCTION:    acpi_ns_evaluate_by_name
  *
  * PARAMETERS:  Pathname            - Fully qualified pathname to the object
+ *              Info                - Contains:
  *              return_object       - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
  *              Params              - List of parameters to pass to the method,
@@ -184,11 +183,9 @@
 acpi_status
 acpi_ns_evaluate_by_name (
 	char                            *pathname,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object)
+	struct acpi_parameter_info      *info)
 {
 	acpi_status                     status;
-	struct acpi_namespace_node      *node = NULL;
 	char                            *internal_path = NULL;
 
 
@@ -211,7 +208,7 @@
 
 	status = acpi_ns_lookup (NULL, internal_path, ACPI_TYPE_ANY,
 			 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
-			 &node);
+			 &info->node);
 
 	(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 
@@ -226,9 +223,9 @@
 	 * to evaluate it.
 	 */
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
-		pathname, node, acpi_ns_get_attached_object (node)));
+		pathname, info->node, acpi_ns_get_attached_object (info->node)));
 
-	status = acpi_ns_evaluate_by_handle (node, params, return_object);
+	status = acpi_ns_evaluate_by_handle (info);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
 		pathname));
@@ -254,6 +251,7 @@
  *              Params              - List of parameters to pass to the method,
  *                                    terminated by NULL.  Params itself may be
  *                                    NULL if no parameters are being passed.
+ *              param_type          - Type of Parameter list
  *              return_object       - Where to put method's return value (if
  *                                    any).  If NULL, no value is returned.
  *
@@ -267,13 +265,9 @@
 
 acpi_status
 acpi_ns_evaluate_by_handle (
-	struct acpi_namespace_node      *handle,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object)
+	struct acpi_parameter_info      *info)
 {
-	struct acpi_namespace_node      *node;
 	acpi_status                     status;
-	union acpi_operand_object       *local_return_object;
 
 
 	ACPI_FUNCTION_TRACE ("ns_evaluate_by_handle");
@@ -287,15 +281,13 @@
 
 	/* Parameter Validation */
 
-	if (!handle) {
+	if (!info) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	if (return_object) {
-		/* Initialize the return value to an invalid object */
+	/* Initialize the return value to an invalid object */
 
-		*return_object = NULL;
-	}
+	info->return_object = NULL;
 
 	/* Get the prefix handle and Node */
 
@@ -304,8 +296,8 @@
 		return_ACPI_STATUS (status);
 	}
 
-	node = acpi_ns_map_handle_to_node (handle);
-	if (!node) {
+	info->node = acpi_ns_map_handle_to_node (info->node);
+	if (!info->node) {
 		(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
@@ -315,8 +307,8 @@
 	 * so that proper scoping context will be established
 	 * before execution.
 	 */
-	if (acpi_ns_get_type (node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
-		node = ACPI_CAST_PTR (struct acpi_namespace_node, node->object);
+	if (acpi_ns_get_type (info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
+		info->node = ACPI_CAST_PTR (struct acpi_namespace_node, info->node->object);
 	}
 
 	/*
@@ -328,19 +320,18 @@
 	 * In both cases, the namespace is unlocked by the
 	 *  acpi_ns* procedure
 	 */
-	if (acpi_ns_get_type (node) == ACPI_TYPE_METHOD) {
+	if (acpi_ns_get_type (info->node) == ACPI_TYPE_METHOD) {
 		/*
 		 * Case 1) We have an actual control method to execute
 		 */
-		status = acpi_ns_execute_control_method (node, params,
-				 &local_return_object);
+		status = acpi_ns_execute_control_method (info);
 	}
 	else {
 		/*
 		 * Case 2) Object is NOT a method, just return its
 		 * current value
 		 */
-		status = acpi_ns_get_object_value (node, &local_return_object);
+		status = acpi_ns_get_object_value (info);
 	}
 
 	/*
@@ -348,20 +339,6 @@
 	 * be dealt with
 	 */
 	if (status == AE_CTRL_RETURN_VALUE) {
-		/*
-		 * If the Method returned a value and the caller
-		 * provided a place to store a returned value, Copy
-		 * the returned value to the object descriptor provided
-		 * by the caller.
-		 */
-		if (return_object) {
-			/*
-			 * Valid return object, copy the pointer to
-			 * the returned object
-			 */
-			*return_object = local_return_object;
-		}
-
 		/* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
 
 		status = AE_OK;
@@ -396,9 +373,7 @@
 
 acpi_status
 acpi_ns_execute_control_method (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc)
+	struct acpi_parameter_info      *info)
 {
 	acpi_status                     status;
 	union acpi_operand_object       *obj_desc;
@@ -409,7 +384,7 @@
 
 	/* Verify that there is a method associated with this object */
 
-	obj_desc = acpi_ns_get_attached_object (method_node);
+	obj_desc = acpi_ns_get_attached_object (info->node);
 	if (!obj_desc) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
 
@@ -417,7 +392,7 @@
 		return_ACPI_STATUS (AE_NULL_OBJECT);
 	}
 
-	ACPI_DUMP_PATHNAME (method_node, "Execute Method:",
+	ACPI_DUMP_PATHNAME (info->node, "Execute Method:",
 		ACPI_LV_INFO, _COMPONENT);
 
 	ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
@@ -444,7 +419,7 @@
 		return_ACPI_STATUS (status);
 	}
 
-	status = acpi_psx_execute (method_node, params, return_obj_desc);
+	status = acpi_psx_execute (info);
 	acpi_ex_exit_interpreter ();
 
 	return_ACPI_STATUS (status);
@@ -468,11 +443,10 @@
 
 acpi_status
 acpi_ns_get_object_value (
-	struct acpi_namespace_node      *node,
-	union acpi_operand_object       **return_obj_desc)
+	struct acpi_parameter_info      *info)
 {
 	acpi_status                     status = AE_OK;
-	struct acpi_namespace_node      *resolved_node = node;
+	struct acpi_namespace_node      *resolved_node = info->node;
 
 
 	ACPI_FUNCTION_TRACE ("ns_get_object_value");
@@ -518,9 +492,9 @@
 
 		if (ACPI_SUCCESS (status)) {
 			status = AE_CTRL_RETURN_VALUE;
-			*return_obj_desc = ACPI_CAST_PTR (union acpi_operand_object, resolved_node);
+			info->return_object = ACPI_CAST_PTR (union acpi_operand_object, resolved_node);
 			ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
-				*return_obj_desc, acpi_ut_get_object_type_name (*return_obj_desc)));
+				info->return_object, acpi_ut_get_object_type_name (info->return_object)));
 		}
 	}
 
diff -Nru a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c
--- a/drivers/acpi/namespace/nsinit.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/namespace/nsinit.c	Sat Jul 17 03:29:59 2004
@@ -149,7 +149,7 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* Walk namespace for all objects of type Device or Processor */
+	/* Walk namespace for all objects */
 
 	status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 			  ACPI_UINT32_MAX, TRUE, acpi_ns_init_one_device, &info, NULL);
@@ -337,25 +337,29 @@
 	void                            *context,
 	void                            **return_value)
 {
-	acpi_status                     status;
-	struct acpi_namespace_node     *node;
-	u32                             flags;
 	struct acpi_device_walk_info   *info = (struct acpi_device_walk_info *) context;
+	struct acpi_parameter_info      pinfo;
+	u32                             flags;
+	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE ("ns_init_one_device");
 
 
-	node = acpi_ns_map_handle_to_node (obj_handle);
-	if (!node) {
+	pinfo.parameters = NULL;
+	pinfo.parameter_type = ACPI_PARAM_ARGS;
+
+	pinfo.node = acpi_ns_map_handle_to_node (obj_handle);
+	if (!pinfo.node) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
 	/*
-	 * We will run _STA/_INI on Devices and Processors only
+	 * We will run _STA/_INI on Devices, Processors and thermal_zones only
 	 */
-	if ((node->type != ACPI_TYPE_DEVICE) &&
-		(node->type != ACPI_TYPE_PROCESSOR)) {
+	if ((pinfo.node->type != ACPI_TYPE_DEVICE)      &&
+		(pinfo.node->type != ACPI_TYPE_PROCESSOR)   &&
+		(pinfo.node->type != ACPI_TYPE_THERMAL)) {
 		return_ACPI_STATUS (AE_OK);
 	}
 
@@ -368,17 +372,17 @@
 	/*
 	 * Run _STA to determine if we can run _INI on the device.
 	 */
-	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, node, "_STA"));
-	status = acpi_ut_execute_STA (node, &flags);
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_STA"));
+	status = acpi_ut_execute_STA (pinfo.node, &flags);
 
 	if (ACPI_FAILURE (status)) {
-		if (node->type == ACPI_TYPE_DEVICE) {
+		if (pinfo.node->type == ACPI_TYPE_DEVICE) {
 			/* Ignore error and move on to next device */
 
 			return_ACPI_STATUS (AE_OK);
 		}
 
-		/* _STA is not required for Processor objects */
+		/* _STA is not required for Processor or thermal_zone objects */
 	}
 	else {
 		info->num_STA++;
@@ -393,22 +397,22 @@
 	/*
 	 * The device is present. Run _INI.
 	 */
-	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, obj_handle, "_INI"));
-	status = acpi_ns_evaluate_relative (obj_handle, "_INI", NULL, NULL);
+	ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, pinfo.node, "_INI"));
+	status = acpi_ns_evaluate_relative ("_INI", &pinfo);
 	if (ACPI_FAILURE (status)) {
 		/* No _INI (AE_NOT_FOUND) means device requires no initialization */
 
 		if (status != AE_NOT_FOUND) {
 			/* Ignore error and move on to next device */
 
-	#ifdef ACPI_DEBUG_OUTPUT
-			char                *scope_name = acpi_ns_get_external_pathname (obj_handle);
+#ifdef ACPI_DEBUG_OUTPUT
+			char                *scope_name = acpi_ns_get_external_pathname (pinfo.node);
 
 			ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%s._INI failed: %s\n",
 					scope_name, acpi_format_exception (status)));
 
 			ACPI_MEM_FREE (scope_name);
-	#endif
+#endif
 		}
 
 		status = AE_OK;
@@ -422,7 +426,7 @@
 	if (acpi_gbl_init_handler) {
 		/* External initialization handler is present, call it */
 
-		status = acpi_gbl_init_handler (obj_handle, ACPI_INIT_DEVICE_INI);
+		status = acpi_gbl_init_handler (pinfo.node, ACPI_INIT_DEVICE_INI);
 	}
 
 
diff -Nru a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c
--- a/drivers/acpi/namespace/nsparse.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/namespace/nsparse.c	Sat Jul 17 03:29:59 2004
@@ -94,8 +94,9 @@
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-	status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL, table_desc->aml_start,
-			  table_desc->aml_length, NULL, NULL, pass_number);
+	status = acpi_ds_init_aml_walk (walk_state, parse_root, NULL,
+			  table_desc->aml_start, table_desc->aml_length,
+			  NULL, pass_number);
 	if (ACPI_FAILURE (status)) {
 		acpi_ds_delete_walk_state (walk_state);
 		return_ACPI_STATUS (status);
diff -Nru a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
--- a/drivers/acpi/namespace/nsxfeval.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/namespace/nsxfeval.c	Sat Jul 17 03:30:00 2004
@@ -174,8 +174,7 @@
 {
 	acpi_status                     status;
 	acpi_status                     status2;
-	union acpi_operand_object       **internal_params = NULL;
-	union acpi_operand_object       *internal_return_obj = NULL;
+	struct acpi_parameter_info      info;
 	acpi_size                       buffer_space_needed;
 	u32                             i;
 
@@ -183,6 +182,11 @@
 	ACPI_FUNCTION_TRACE ("acpi_evaluate_object");
 
 
+	info.node = handle;
+	info.parameters = NULL;
+	info.return_object = NULL;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
 	/*
 	 * If there are parameters to be passed to the object
 	 * (which must be a control method), the external objects
@@ -193,9 +197,10 @@
 		 * Allocate a new parameter block for the internal objects
 		 * Add 1 to count to allow for null terminated internal list
 		 */
-		internal_params = ACPI_MEM_CALLOCATE (((acpi_size) external_params->count + 1) *
-				  sizeof (void *));
-		if (!internal_params) {
+		info.parameters = ACPI_MEM_CALLOCATE (
+				 ((acpi_size) external_params->count + 1) *
+				 sizeof (void *));
+		if (!info.parameters) {
 			return_ACPI_STATUS (AE_NO_MEMORY);
 		}
 
@@ -205,15 +210,16 @@
 		 */
 		for (i = 0; i < external_params->count; i++) {
 			status = acpi_ut_copy_eobject_to_iobject (&external_params->pointer[i],
-					  &internal_params[i]);
+					  &info.parameters[i]);
 			if (ACPI_FAILURE (status)) {
-				acpi_ut_delete_internal_object_list (internal_params);
+				acpi_ut_delete_internal_object_list (info.parameters);
 				return_ACPI_STATUS (status);
 			}
 		}
-		internal_params[external_params->count] = NULL;
+		info.parameters[external_params->count] = NULL;
 	}
 
+
 	/*
 	 * Three major cases:
 	 * 1) Fully qualified pathname
@@ -225,8 +231,7 @@
 		/*
 		 *  The path is fully qualified, just evaluate by name
 		 */
-		status = acpi_ns_evaluate_by_name (pathname, internal_params,
-				 &internal_return_obj);
+		status = acpi_ns_evaluate_by_name (pathname, &info);
 	}
 	else if (!handle) {
 		/*
@@ -256,15 +261,13 @@
 			 * The null pathname case means the handle is for
 			 * the actual object to be evaluated
 			 */
-			status = acpi_ns_evaluate_by_handle (handle, internal_params,
-					  &internal_return_obj);
+			status = acpi_ns_evaluate_by_handle (&info);
 		}
 		else {
 		   /*
 			* Both a Handle and a relative Pathname
 			*/
-			status = acpi_ns_evaluate_relative (handle, pathname, internal_params,
-					  &internal_return_obj);
+			status = acpi_ns_evaluate_relative (pathname, &info);
 		}
 	}
 
@@ -274,11 +277,11 @@
 	 * copy the return value to an external object.
 	 */
 	if (return_buffer) {
-		if (!internal_return_obj) {
+		if (!info.return_object) {
 			return_buffer->length = 0;
 		}
 		else {
-			if (ACPI_GET_DESCRIPTOR_TYPE (internal_return_obj) == ACPI_DESC_TYPE_NAMED) {
+			if (ACPI_GET_DESCRIPTOR_TYPE (info.return_object) == ACPI_DESC_TYPE_NAMED) {
 				/*
 				 * If we received a NS Node as a return object, this means that
 				 * the object we are evaluating has nothing interesting to
@@ -288,7 +291,7 @@
 				 * support for various types at a later date if necessary.
 				 */
 				status = AE_TYPE;
-				internal_return_obj = NULL; /* No need to delete a NS Node */
+				info.return_object = NULL;  /* No need to delete a NS Node */
 				return_buffer->length = 0;
 			}
 
@@ -297,7 +300,7 @@
 				 * Find out how large a buffer is needed
 				 * to contain the returned object
 				 */
-				status = acpi_ut_get_object_size (internal_return_obj,
+				status = acpi_ut_get_object_size (info.return_object,
 						   &buffer_space_needed);
 				if (ACPI_SUCCESS (status)) {
 					/* Validate/Allocate/Clear caller buffer */
@@ -309,13 +312,14 @@
 						 */
 						ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 							"Needed buffer size %X, %s\n",
-							(u32) buffer_space_needed, acpi_format_exception (status)));
+							(u32) buffer_space_needed,
+							acpi_format_exception (status)));
 					}
 					else {
 						/*
 						 *  We have enough space for the object, build it
 						 */
-						status = acpi_ut_copy_iobject_to_eobject (internal_return_obj,
+						status = acpi_ut_copy_iobject_to_eobject (info.return_object,
 								  return_buffer);
 					}
 				}
@@ -323,7 +327,7 @@
 		}
 	}
 
-	if (internal_return_obj) {
+	if (info.return_object) {
 		/*
 		 * Delete the internal return object.  NOTE: Interpreter
 		 * must be locked to avoid race condition.
@@ -334,7 +338,7 @@
 			 * Delete the internal return object. (Or at least
 			 * decrement the reference count by one)
 			 */
-			acpi_ut_remove_reference (internal_return_obj);
+			acpi_ut_remove_reference (info.return_object);
 			acpi_ex_exit_interpreter ();
 		}
 	}
@@ -342,10 +346,10 @@
 	/*
 	 * Free the input parameter list (if we created one),
 	 */
-	if (internal_params) {
+	if (info.parameters) {
 		/* Free the allocated parameter block */
 
-		acpi_ut_delete_internal_object_list (internal_params);
+		acpi_ut_delete_internal_object_list (info.parameters);
 	}
 
 	return_ACPI_STATUS (status);
diff -Nru a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
--- a/drivers/acpi/namespace/nsxfname.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/namespace/nsxfname.c	Sat Jul 17 03:29:59 2004
@@ -281,7 +281,7 @@
 	if (info.type == ACPI_TYPE_DEVICE) {
 		/*
 		 * Get extra info for ACPI Devices objects only:
-		 * Run the Device _HID, _UID, _CID, _STA, and _ADR methods.
+		 * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
 		 *
 		 * Note: none of these methods are required, so they may or may
 		 * not be present for this device.  The Info.Valid bitfield is used
@@ -330,7 +330,7 @@
 
 		status = acpi_ut_execute_sxds (node, info.highest_dstates);
 		if (ACPI_SUCCESS (status)) {
-			info.valid |= ACPI_VALID_STA;
+			info.valid |= ACPI_VALID_SXDS;
 		}
 
 		status = AE_OK;
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/osl.c	Sat Jul 17 03:30:00 2004
@@ -51,7 +51,7 @@
 
 struct acpi_os_dpc
 {
-    OSD_EXECUTION_CALLBACK  function;
+    acpi_osd_exec_callback  function;
     void		    *context;
 };
 
@@ -64,7 +64,7 @@
 #endif /*ENABLE_DEBUGGER*/
 
 static unsigned int acpi_irq_irq;
-static OSD_HANDLER acpi_irq_handler;
+static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
 
@@ -246,7 +246,7 @@
 }
 
 acpi_status
-acpi_os_install_interrupt_handler(u32 gsi, OSD_HANDLER handler, void *context)
+acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, void *context)
 {
 	unsigned int irq;
 
@@ -274,7 +274,7 @@
 }
 
 acpi_status
-acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
+acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
 {
 	if (irq) {
 		free_irq(irq, acpi_irq);
@@ -624,7 +624,7 @@
 acpi_status
 acpi_os_queue_for_execution(
 	u32			priority,
-	OSD_EXECUTION_CALLBACK	function,
+	acpi_osd_exec_callback	function,
 	void			*context)
 {
 	acpi_status 		status = AE_OK;
@@ -1066,15 +1066,15 @@
  * Run-time events on the same GPE this flag is available
  * to tell Linux to keep the wake-time GPEs enabled at run-time.
  */
-static int __init
-acpi_leave_gpes_disabled_setup(char *str)
+int __init
+acpi_wake_gpes_always_on_setup(char *str)
 {
-	printk(KERN_INFO PREFIX "leave wake GPEs disabled\n");
+	printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
 
-	acpi_gbl_leave_wake_gpes_disabled = TRUE;
+	acpi_gbl_leave_wake_gpes_disabled = FALSE;
 
 	return 1;
 }
 
-__setup("acpi_leave_gpes_disabled", acpi_leave_gpes_disabled_setup);
+__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
 
diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
--- a/drivers/acpi/parser/psopcode.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/parser/psopcode.c	Sat Jul 17 03:29:59 2004
@@ -251,7 +251,7 @@
 #define ARGI_CREATE_FIELD_OP            ARGI_LIST4 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_INTEGER,      ARGI_REFERENCE)
 #define ARGI_CREATE_QWORD_FIELD_OP      ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
 #define ARGI_CREATE_WORD_FIELD_OP       ARGI_LIST3 (ARGI_BUFFER,     ARGI_INTEGER,       ARGI_REFERENCE)
-#define ARGI_DATA_REGION_OP             ARGI_LIST3 (ARGI_STRING,     ARGI_STRING,       ARGI_STRING)
+#define ARGI_DATA_REGION_OP             ARGI_LIST3 (ARGI_STRING,     ARGI_STRING,        ARGI_STRING)
 #define ARGI_DEBUG_OP                   ARG_NONE
 #define ARGI_DECREMENT_OP               ARGI_LIST1 (ARGI_INTEGER_REF)
 #define ARGI_DEREF_OF_OP                ARGI_LIST1 (ARGI_REF_OR_STRING)
@@ -270,10 +270,10 @@
 #define ARGI_INDEX_FIELD_OP             ARGI_INVALID_OPCODE
 #define ARGI_INDEX_OP                   ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER,       ARGI_TARGETREF)
 #define ARGI_LAND_OP                    ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_LEQUAL_OP                  ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
-#define ARGI_LGREATER_OP                ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_LEQUAL_OP                  ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
+#define ARGI_LGREATER_OP                ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
 #define ARGI_LGREATEREQUAL_OP           ARGI_INVALID_OPCODE
-#define ARGI_LLESS_OP                   ARGI_LIST2 (ARGI_INTEGER,    ARGI_INTEGER)
+#define ARGI_LLESS_OP                   ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA)
 #define ARGI_LLESSEQUAL_OP              ARGI_INVALID_OPCODE
 #define ARGI_LNOT_OP                    ARGI_LIST1 (ARGI_INTEGER)
 #define ARGI_LNOTEQUAL_OP               ARGI_INVALID_OPCODE
diff -Nru a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
--- a/drivers/acpi/parser/psxface.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/parser/psxface.c	Sat Jul 17 03:29:59 2004
@@ -57,7 +57,7 @@
  *
  * FUNCTION:    acpi_psx_execute
  *
- * PARAMETERS:  method_node         - A method object containing both the AML
+ * PARAMETERS:  Info->Node          - A method object containing both the AML
  *                                    address and length.
  *              **Params            - List of parameters to pass to method,
  *                                    terminated by NULL. Params itself may be
@@ -73,9 +73,7 @@
 
 acpi_status
 acpi_psx_execute (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc)
+	struct acpi_parameter_info      *info)
 {
 	acpi_status                     status;
 	union acpi_operand_object       *obj_desc;
@@ -89,29 +87,30 @@
 
 	/* Validate the Node and get the attached object */
 
-	if (!method_node) {
+	if (!info || !info->node) {
 		return_ACPI_STATUS (AE_NULL_ENTRY);
 	}
 
-	obj_desc = acpi_ns_get_attached_object (method_node);
+	obj_desc = acpi_ns_get_attached_object (info->node);
 	if (!obj_desc) {
 		return_ACPI_STATUS (AE_NULL_OBJECT);
 	}
 
 	/* Init for new method, wait on concurrency semaphore */
 
-	status = acpi_ds_begin_method_execution (method_node, obj_desc, NULL);
+	status = acpi_ds_begin_method_execution (info->node, obj_desc, NULL);
 	if (ACPI_FAILURE (status)) {
 		return_ACPI_STATUS (status);
 	}
 
-	if (params) {
+	if ((info->parameter_type == ACPI_PARAM_ARGS) &&
+		(info->parameters)) {
 		/*
 		 * The caller "owns" the parameters, so give each one an extra
 		 * reference
 		 */
-		for (i = 0; params[i]; i++) {
-			acpi_ut_add_reference (params[i]);
+		for (i = 0; info->parameters[i]; i++) {
+			acpi_ut_add_reference (info->parameters[i]);
 		}
 	}
 
@@ -121,7 +120,7 @@
 	 */
 	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
 		"**** Begin Method Parse **** Entry=%p obj=%p\n",
-		method_node, obj_desc));
+		info->node, obj_desc));
 
 	/* Create and init a Root Node */
 
@@ -147,8 +146,9 @@
 		goto cleanup2;
 	}
 
-	status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
-			  obj_desc->method.aml_length, NULL, NULL, 1);
+	status = acpi_ds_init_aml_walk (walk_state, op, info->node,
+			  obj_desc->method.aml_start,
+			  obj_desc->method.aml_length, NULL, 1);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup3;
 	}
@@ -159,7 +159,6 @@
 	acpi_ps_delete_parse_tree (op);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup1; /* Walk state is already deleted */
-
 	}
 
 	/*
@@ -167,7 +166,7 @@
 	 */
 	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
 		"**** Begin Method Execution **** Entry=%p obj=%p\n",
-		method_node, obj_desc));
+		info->node, obj_desc));
 
 	/* Create and init a Root Node */
 
@@ -179,8 +178,8 @@
 
 	/* Init new op with the method name and pointer back to the NS node */
 
-	acpi_ps_set_name (op, method_node->name.integer);
-	op->common.node = method_node;
+	acpi_ps_set_name (op, info->node->name.integer);
+	op->common.node = info->node;
 
 	/* Create and initialize a new walk state */
 
@@ -190,8 +189,9 @@
 		goto cleanup2;
 	}
 
-	status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start,
-			  obj_desc->method.aml_length, params, return_obj_desc, 3);
+	status = acpi_ds_init_aml_walk (walk_state, op, info->node,
+			  obj_desc->method.aml_start,
+			  obj_desc->method.aml_length, info, 3);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup3;
 	}
@@ -210,13 +210,14 @@
 	acpi_ps_delete_parse_tree (op);
 
 cleanup1:
-	if (params) {
+	if ((info->parameter_type == ACPI_PARAM_ARGS) &&
+		(info->parameters)) {
 		/* Take away the extra reference that we gave the parameters above */
 
-		for (i = 0; params[i]; i++) {
+		for (i = 0; info->parameters[i]; i++) {
 			/* Ignore errors, just do them all */
 
-			(void) acpi_ut_update_object_reference (params[i], REF_DECREMENT);
+			(void) acpi_ut_update_object_reference (info->parameters[i], REF_DECREMENT);
 		}
 	}
 
@@ -228,10 +229,10 @@
 	 * If the method has returned an object, signal this to the caller with
 	 * a control exception code
 	 */
-	if (*return_obj_desc) {
+	if (info->return_object) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Method returned obj_desc=%p\n",
-			*return_obj_desc));
-		ACPI_DUMP_STACK_ENTRY (*return_obj_desc);
+			info->return_object));
+		ACPI_DUMP_STACK_ENTRY (info->return_object);
 
 		status = AE_CTRL_RETURN_VALUE;
 	}
diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c
--- a/drivers/acpi/power.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/power.c	Sat Jul 17 03:29:59 2004
@@ -288,6 +288,86 @@
 	return_VALUE(0);
 }
 
+/*
+ * Prepare a wakeup device, two steps (Ref ACPI 2.0:P229):
+ * 1. Power on the power resources required for the wakeup device 
+ * 2. Enable _PSW (power state wake) for the device if present
+ */
+int acpi_enable_wakeup_device_power (struct acpi_device *dev)
+{
+	union acpi_object 		arg = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg};
+	acpi_status			status = AE_OK;
+	int					i;
+	int 					ret = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_power");
+	if (!dev || !dev->wakeup.flags.valid)
+		return -1;
+
+	arg.integer.value = 1;
+	/* Open power resource */
+	for (i = 0; i < dev->wakeup.resources.count; i++) {
+		ret = acpi_power_on(dev->wakeup.resources.handles[i]);
+		if (ret) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Error transition power state\n"));
+			dev->wakeup.flags.valid = 0;
+			return -1;
+		}
+	}
+
+	/* Execute PSW */
+	status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n"));
+		dev->wakeup.flags.valid = 0;
+		ret = -1;
+	}
+
+	return ret;
+}
+
+/*
+ * Shutdown a wakeup device, counterpart of above method
+ * 1. Disable _PSW (power state wake)
+ * 2. Shutdown down the power resources
+ */
+int acpi_disable_wakeup_device_power (struct acpi_device *dev)
+{
+	union acpi_object 		arg = {ACPI_TYPE_INTEGER};
+	struct acpi_object_list	arg_list = {1, &arg};
+	acpi_status			status = AE_OK;
+	int					i;
+	int 					ret = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device_power");
+
+	if (!dev || !dev->wakeup.flags.valid)
+		return -1;
+
+	arg.integer.value = 0;	
+	/* Execute PSW */
+	status = acpi_evaluate_object(dev->handle, "_PSW", &arg_list, NULL);
+	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluate _PSW\n"));
+		dev->wakeup.flags.valid = 0;
+		return -1;
+	}
+
+	/* Close power resource */
+	for (i = 0; i < dev->wakeup.resources.count; i++) {
+		ret = acpi_power_off_device(dev->wakeup.resources.handles[i]);
+		if (ret) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
+				"Error transition power state\n"));
+			dev->wakeup.flags.valid = 0;
+			return -1;
+		}
+	}
+
+	return ret;
+}
 
 /* --------------------------------------------------------------------------
                              Device Power Management
diff -Nru a/drivers/acpi/processor.c b/drivers/acpi/processor.c
--- a/drivers/acpi/processor.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/processor.c	Sat Jul 17 03:29:59 2004
@@ -44,6 +44,9 @@
 #include <asm/system.h>
 #include <asm/delay.h>
 #include <asm/uaccess.h>
+#include <asm/processor.h>
+#include <asm/smp.h>
+#include <asm/acpi.h>
 
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -859,7 +862,6 @@
  * _PCT and _PSS structures are read out and written into struct
  * acpi_processor_performance.
  */
-
 static int acpi_processor_set_pdc (struct acpi_processor *pr)
 {
 	acpi_status             status = AE_OK;
@@ -1047,6 +1049,8 @@
 	if (!pr || !pr->performance || !pr->handle)
 		return_VALUE(-EINVAL);
 
+	acpi_processor_set_pdc(pr);
+
 	status = acpi_get_handle(pr->handle, "_PCT", &handle);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 
@@ -1054,8 +1058,6 @@
 		return_VALUE(-ENODEV);
 	}
 
-	acpi_processor_set_pdc(pr);
-
 	result = acpi_processor_get_performance_control(pr);
 	if (result)
 		return_VALUE(result);
@@ -2146,6 +2148,37 @@
 	return_VALUE(0);
 }
 
+/* Use the acpiid in MADT to map cpus in case of SMP */
+#ifndef CONFIG_SMP
+#define convert_acpiid_to_cpu(acpi_id) (0xff)
+#else
+
+#ifdef CONFIG_IA64
+#define arch_acpiid_to_apicid 	ia64_acpiid_to_sapicid
+#define arch_cpu_to_apicid 	ia64_cpu_to_sapicid
+#define ARCH_BAD_APICID		(0xffff)
+#else
+#define arch_acpiid_to_apicid 	x86_acpiid_to_apicid
+#define arch_cpu_to_apicid 	x86_cpu_to_apicid
+#define ARCH_BAD_APICID		(0xff)
+#endif
+
+static u8 convert_acpiid_to_cpu(u8 acpi_id)
+{
+	u16 apic_id;
+	int i;
+	
+	apic_id = arch_acpiid_to_apicid[acpi_id];
+	if (apic_id == ARCH_BAD_APICID)
+		return -1;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (arch_cpu_to_apicid[i] == apic_id)
+			return i;
+	}
+	return -1;
+}
+#endif
 
 /* --------------------------------------------------------------------------
                                  Driver Interface
@@ -2158,7 +2191,8 @@
 	acpi_status		status = 0;
 	union acpi_object	object = {0};
 	struct acpi_buffer	buffer = {sizeof(union acpi_object), &object};
-	static int		cpu_index = 0;
+	u8			cpu_index;
+	static int		cpu0_initialized;
 
 	ACPI_FUNCTION_TRACE("acpi_processor_get_info");
 
@@ -2168,13 +2202,6 @@
 	if (num_online_cpus() > 1)
 		errata.smp = TRUE;
 
-	/*
-	 *  Extra Processor objects may be enumerated on MP systems with
-	 *  less than the max # of CPUs. They should be ignored.
-	 */
-	if ((cpu_index + 1) > num_online_cpus())
-		return_VALUE(-ENODEV);
-
 	acpi_processor_errata(pr);
 
 	/*
@@ -2206,9 +2233,27 @@
 	 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
 	 *	>>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
 	 */
-	pr->id = cpu_index++;
 	pr->acpi_id = object.processor.proc_id;
 
+	cpu_index = convert_acpiid_to_cpu(pr->acpi_id);
+
+	if ( !cpu0_initialized && (cpu_index == 0xff)) {
+		/* Handle UP system running SMP kernel, with no LAPIC in MADT */
+		cpu_index = 0;
+	} else if (cpu_index > num_online_cpus()) {
+		/*
+		 *  Extra Processor objects may be enumerated on MP systems with
+		 *  less than the max # of CPUs. They should be ignored.
+		 */
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error getting cpuindex for acpiid 0x%x\n",
+			pr->acpi_id));
+		return_VALUE(-ENODEV);
+	}
+	cpu0_initialized = 1;
+
+	pr->id = cpu_index;
+
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, 
 		pr->acpi_id));
 
@@ -2234,7 +2279,6 @@
 		 * (In particular, allocating the IO range for Cardbus)
 		 */
 		request_region(pr->throttling.address, 6, "ACPI CPU throttle");
-		request_region(acpi_fadt.xpm_tmr_blk.address, 4, "ACPI timer");
 	}
 
 	acpi_processor_get_power_info(pr);
diff -Nru a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
--- a/drivers/acpi/resources/rsutils.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/resources/rsutils.c	Sat Jul 17 03:29:59 2004
@@ -289,6 +289,7 @@
 	acpi_handle                     handle,
 	struct acpi_buffer              *in_buffer)
 {
+	struct acpi_parameter_info      info;
 	union acpi_operand_object       *params[2];
 	acpi_status                     status;
 	struct acpi_buffer              buffer;
@@ -329,10 +330,14 @@
 	params[0]->common.flags   = AOPOBJ_DATA_VALID;
 	params[1] = NULL;
 
+	info.node = handle;
+	info.parameters = params;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
 	/*
 	 * Execute the method, no return value
 	 */
-	status = acpi_ns_evaluate_relative (handle, "_SRS", params, NULL);
+	status = acpi_ns_evaluate_relative ("_SRS", &info);
 
 	/*
 	 * Clean up and return the status from acpi_ns_evaluate_relative
diff -Nru a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
--- a/drivers/acpi/resources/rsxface.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/resources/rsxface.c	Sat Jul 17 03:29:59 2004
@@ -259,7 +259,8 @@
 	/* Setup pointers */
 
 	resource  = (struct acpi_resource *) buffer.pointer;
-	buffer_end = (struct acpi_resource *) ((u8 *) buffer.pointer + buffer.length);
+	buffer_end = ACPI_CAST_PTR (struct acpi_resource,
+			  ((u8 *) buffer.pointer + buffer.length));
 
 	/* Walk the resource list */
 
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/scan.c	Sat Jul 17 03:29:59 2004
@@ -23,7 +23,8 @@
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 
 static LIST_HEAD(acpi_device_list);
-static spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED;
+LIST_HEAD(acpi_wakeup_device_list);
 
 static void acpi_device_release(struct kobject * kobj)
 {
@@ -115,9 +116,6 @@
 	status = acpi_get_handle(device->handle, "_IRC", &handle);
 	if (ACPI_SUCCESS(status))
 		device->power.flags.inrush_current = 1;
-	status = acpi_get_handle(device->handle, "_PRW", &handle);
-	if (ACPI_SUCCESS(status))
-		device->power.flags.wake_capable = 1;
 
 	/*
 	 * Enumerate supported power management states
@@ -163,6 +161,125 @@
 	return 0;
 }
 
+static int
+acpi_match_ids (
+	struct acpi_device	*device,
+	char			*ids)
+{
+	int error = 0;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+
+	if (device->flags.hardware_id)
+		if (strstr(ids, device->pnp.hardware_id))
+			goto Done;
+
+	if (device->flags.compatible_ids) {
+		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
+		int i;
+
+		/* compare multiple _CID entries against driver ids */
+		for (i = 0; i < cid_list->count; i++)
+		{
+			if (strstr(ids, cid_list->id[i].value))
+				goto Done;
+		}
+	}
+	error = -ENOENT;
+
+ Done:
+	if (buffer.pointer)
+		acpi_os_free(buffer.pointer);
+	return error;
+}
+
+static acpi_status
+acpi_bus_extract_wakeup_device_power_package (
+	struct acpi_device	*device,
+	union acpi_object	*package)
+{
+	int 	 i = 0;
+	union acpi_object	*element = NULL;
+
+	if (!device || !package || (package->package.count < 2))
+		return AE_BAD_PARAMETER;
+
+	element = &(package->package.elements[0]);
+	if (element->type == ACPI_TYPE_PACKAGE) {
+		if ((element->package.count < 2) ||
+			(element->package.elements[0].type != ACPI_TYPE_LOCAL_REFERENCE) ||
+			(element->package.elements[1].type != ACPI_TYPE_INTEGER))
+			return AE_BAD_DATA;
+		device->wakeup.gpe_device = element->package.elements[0].reference.handle;
+		device->wakeup.gpe_number = (u32)element->package.elements[1].integer.value;
+	}else if (element->type == ACPI_TYPE_INTEGER) {
+		device->wakeup.gpe_number = element->integer.value;
+	}else
+		return AE_BAD_DATA;
+
+	element = &(package->package.elements[1]);
+	if (element->type != ACPI_TYPE_INTEGER) {
+		return AE_BAD_DATA;
+	}
+	device->wakeup.sleep_state = element->integer.value;
+
+	if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
+		return AE_NO_MEMORY;
+	}
+	device->wakeup.resources.count = package->package.count - 2;
+	for (i=0; i < device->wakeup.resources.count; i++) {
+		element = &(package->package.elements[i + 2]);
+		if (element->type != ACPI_TYPE_ANY ) {
+			return AE_BAD_DATA;
+		}
+
+		device->wakeup.resources.handles[i] = element->reference.handle;
+	}
+
+	return AE_OK;
+}
+
+static int
+acpi_bus_get_wakeup_device_flags (
+	struct acpi_device	*device)
+{
+	acpi_status	status = 0;
+	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object	*package = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_bus_get_wakeup_flags");
+
+	/* _PRW */
+	status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _PRW\n"));
+		goto end;
+	}
+
+	package = (union acpi_object *) buffer.pointer;
+	status = acpi_bus_extract_wakeup_device_power_package(device, package);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _PRW package\n"));
+		goto end;
+	}
+
+	acpi_os_free(buffer.pointer);
+
+	device->wakeup.flags.valid = 1;
+	/* Power button, Lid switch always enable wakeup*/
+	if (!acpi_match_ids(device, "PNP0C0D,PNP0C0C,PNP0C0E"))
+		device->wakeup.flags.run_wake = 1;
+
+	/* TBD: lock */
+	INIT_LIST_HEAD(&device->wakeup_list);
+	spin_lock(&acpi_device_lock);
+	list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
+	spin_unlock(&acpi_device_lock);
+
+end:
+	if (ACPI_FAILURE(status))
+		device->flags.wake_capable = 0;
+	return 0;
+}
 
 /* --------------------------------------------------------------------------
                               Performance Management
@@ -195,30 +312,7 @@
 	struct acpi_device	*device,
 	struct acpi_driver	*driver)
 {
-	int error = 0;
-	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-
-	if (device->flags.hardware_id)
-		if (strstr(driver->ids, device->pnp.hardware_id))
-			goto Done;
-
-	if (device->flags.compatible_ids) {
-		struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
-		int i;
-
-		/* compare multiple _CID entries against driver ids */
-		for (i = 0; i < cid_list->count; i++)
-		{
-			if (strstr(driver->ids, cid_list->id[i].value))
-				goto Done;
-		}
-	}
-	error = -ENOENT;
-
- Done:
-	if (buffer.pointer)
-		acpi_os_free(buffer.pointer);
-	return error;
+	return acpi_match_ids(device, driver->ids);
 }
 
 
@@ -469,6 +563,11 @@
 	if (ACPI_SUCCESS(status))
 		device->flags.power_manageable = 1;
 
+	/* Presence of _PRW indicates wake capable */
+	status = acpi_get_handle(device->handle, "_PRW", &temp);
+	if (ACPI_SUCCESS(status))
+		device->flags.wake_capable = 1;
+
 	/* TBD: Peformance management */
 
 	return_VALUE(0);
@@ -736,6 +835,16 @@
 	 */
 	if (device->flags.power_manageable) {
 		result = acpi_bus_get_power_flags(device);
+		if (result)
+			goto end;
+	}
+
+ 	/*
+	 * Wakeup device management
+	 *-----------------------
+	 */
+	if (device->flags.wake_capable) {
+		result = acpi_bus_get_wakeup_device_flags(device);
 		if (result)
 			goto end;
 	}
diff -Nru a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile
--- a/drivers/acpi/sleep/Makefile	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/sleep/Makefile	Sat Jul 17 03:29:59 2004
@@ -1,5 +1,5 @@
 obj-y					:= poweroff.o
-obj-$(CONFIG_ACPI_SLEEP)		+= main.o
+obj-$(CONFIG_ACPI_SLEEP)		+= main.o wakeup.o
 obj-$(CONFIG_ACPI_SLEEP_PROC_FS)	+= proc.o
 
 EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/sleep/main.c	Sat Jul 17 03:29:59 2004
@@ -32,16 +32,16 @@
 
 /**
  *	acpi_pm_prepare - Do preliminary suspend work.
- *	@state:		suspend state we're entering.
+ *	@pm_state:		suspend state we're entering.
  *
  *	Make sure we support the state. If we do, and we need it, set the
  *	firmware waking vector and do arch-specific nastiness to get the 
  *	wakeup code to the waking vector. 
  */
 
-static int acpi_pm_prepare(u32 state)
+static int acpi_pm_prepare(u32 pm_state)
 {
-	u32 acpi_state = acpi_suspend_states[state];
+	u32 acpi_state = acpi_suspend_states[pm_state];
 
 	if (!sleep_states[acpi_state])
 		return -EPERM;
@@ -49,13 +49,14 @@
 	/* do we have a wakeup address for S2 and S3? */
 	/* Here, we support only S4BIOS, those we set the wakeup address */
 	/* S4OS is only supported for now via swsusp.. */
-	if (state == PM_SUSPEND_MEM || state == PM_SUSPEND_DISK) {
+	if (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) {
 		if (!acpi_wakeup_address)
 			return -EFAULT;
 		acpi_set_firmware_waking_vector(
 			(acpi_physical_address) acpi_wakeup_address);
 	}
 	ACPI_FLUSH_CPU_CACHE();
+	acpi_enable_wakeup_device_prep(acpi_state);
 	acpi_enter_sleep_state_prep(acpi_state);
 	return 0;
 }
@@ -63,23 +64,23 @@
 
 /**
  *	acpi_pm_enter - Actually enter a sleep state.
- *	@state:		State we're entering.
+ *	@pm_state:		State we're entering.
  *
  *	Flush caches and go to sleep. For STR or STD, we have to call 
  *	arch-specific assembly, which in turn call acpi_enter_sleep_state().
  *	It's unfortunate, but it works. Please fix if you're feeling frisky.
  */
 
-static int acpi_pm_enter(u32 state)
+static int acpi_pm_enter(u32 pm_state)
 {
 	acpi_status status = AE_OK;
 	unsigned long flags = 0;
-	u32 acpi_state = acpi_suspend_states[state];
+	u32 acpi_state = acpi_suspend_states[pm_state];
 
 	ACPI_FLUSH_CPU_CACHE();
 
 	/* Do arch specific saving of state. */
-	if (state > PM_SUSPEND_STANDBY) {
+	if (pm_state > PM_SUSPEND_STANDBY) {
 		int error = acpi_save_state_mem();
 		if (error)
 			return error;
@@ -87,7 +88,8 @@
 
 
 	local_irq_save(flags);
-	switch (state)
+	acpi_enable_wakeup_device(acpi_state);
+	switch (pm_state)
 	{
 	case PM_SUSPEND_STANDBY:
 		barrier();
@@ -115,7 +117,7 @@
 	 * And, in the case of the latter, the memory image should have already
 	 * been loaded from disk.
 	 */
-	if (state > PM_SUSPEND_STANDBY)
+	if (pm_state > PM_SUSPEND_STANDBY)
 		acpi_restore_state_mem();
 
 
@@ -125,15 +127,18 @@
 
 /**
  *	acpi_pm_finish - Finish up suspend sequence.
- *	@state:		State we're coming out of.
+ *	@pm_state:		State we're coming out of.
  *
  *	This is called after we wake back up (or if entering the sleep state
  *	failed). 
  */
 
-static int acpi_pm_finish(u32 state)
+static int acpi_pm_finish(u32 pm_state)
 {
-	acpi_leave_sleep_state(state);
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	acpi_leave_sleep_state(acpi_state);
+	acpi_disable_wakeup_device(acpi_state);
 
 	/* reset firmware waking vector */
 	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
@@ -174,7 +179,7 @@
 		return 0;
 
 	printk(KERN_INFO PREFIX "(supports");
-	for (i=0; i<ACPI_S_STATE_COUNT; i++) {
+	for (i=0; i < ACPI_S_STATE_COUNT; i++) {
 		acpi_status status;
 		u8 type_a, type_b;
 		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
diff -Nru a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
--- a/drivers/acpi/sleep/proc.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/sleep/proc.c	Sat Jul 17 03:29:59 2004
@@ -15,6 +15,7 @@
 
 #define ACPI_SYSTEM_FILE_SLEEP		"sleep"
 #define ACPI_SYSTEM_FILE_ALARM		"alarm"
+#define ACPI_SYSTEM_FILE_WAKEUP_DEVICE   "wakeup"
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME		("sleep")
@@ -352,6 +353,84 @@
 	return_VALUE(result ? result : count);
 }
 
+extern struct list_head	acpi_wakeup_device_list;
+extern spinlock_t acpi_device_lock;
+
+static int
+acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
+{
+	struct list_head * node, * next;
+
+	seq_printf(seq, "Device	Sleep state	Status\n");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
+
+		if (!dev->wakeup.flags.valid)
+			continue;
+		spin_unlock(&acpi_device_lock);
+		if (dev->wakeup.flags.run_wake)
+			seq_printf(seq, "%4s	%4d		%8s\n",
+				dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
+				dev->wakeup.state.enabled ? "*enabled" : "*disabled");
+		else
+			seq_printf(seq, "%4s	%4d		%8s\n",
+				dev->pnp.bus_id, (u32) dev->wakeup.sleep_state,
+				dev->wakeup.state.enabled ? "enabled" : "disabled");
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+	return 0;
+}
+
+static int
+acpi_system_write_wakeup_device (
+	struct file		*file,
+	const char		*buffer,
+	size_t			count,
+	loff_t			*ppos)
+{
+	struct list_head * node, * next;
+	char		strbuf[5];
+	char		str[5] = "";
+	int 		len = count;
+
+	if (len > 4) len = 4;
+
+	if (copy_from_user(strbuf, buffer, len))
+		return -EFAULT;
+	strbuf[len] = '\0';
+	sscanf(strbuf, "%s", str);
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, struct acpi_device, wakeup_list);
+		if (!dev->wakeup.flags.valid)
+			continue;
+
+		if (!strncmp(dev->pnp.bus_id, str, 4)) {
+			dev->wakeup.state.enabled = dev->wakeup.state.enabled ? 0:1;
+			break;
+		}
+	}
+	spin_unlock(&acpi_device_lock);
+	return count;
+}
+
+static int
+acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, acpi_system_wakeup_device_seq_show, PDE(inode)->data);
+}
+
+static struct file_operations acpi_system_wakeup_device_fops = {
+	.open		= acpi_system_wakeup_device_open_fs,
+	.read		= seq_read,
+	.write		= acpi_system_write_wakeup_device,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
 static struct file_operations acpi_system_sleep_fops = {
 	.open		= acpi_system_sleep_open_fs,
@@ -388,6 +467,13 @@
 		S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
 	if (entry)
 		entry->proc_fops = &acpi_system_alarm_fops;
+
+	/* 'wakeup device' [R/W]*/
+	entry = create_proc_entry(ACPI_SYSTEM_FILE_WAKEUP_DEVICE,
+				  S_IFREG|S_IRUGO|S_IWUSR, acpi_root_dir);
+	if (entry)
+		entry->proc_fops = &acpi_system_wakeup_device_fops;
+
 	return 0;
 }
 
diff -Nru a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
--- a/drivers/acpi/sleep/sleep.h	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/sleep/sleep.h	Sat Jul 17 03:29:59 2004
@@ -2,3 +2,6 @@
 extern u8 sleep_states[];
 extern int acpi_suspend (u32 state);
 
+extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
+extern void acpi_enable_wakeup_device(u8 sleep_state);
+extern void acpi_disable_wakeup_device(u8 sleep_state);
diff -Nru a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/acpi/sleep/wakeup.c	Sat Jul 17 03:30:00 2004
@@ -0,0 +1,179 @@
+/*
+ * wakeup.c - support wakeup devices
+ */
+
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <acpi/acevents.h>
+#include "sleep.h"
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME		("wakeup_devices")
+
+/**
+ * acpi_enable_wakeup_device_prep - prepare wakeup devices
+ *	@sleep_state:	ACPI state
+ * Enable all wakup devices power if the devices' wakeup level
+ * is higher than requested sleep level
+ */
+extern struct list_head	acpi_wakeup_device_list;
+extern spinlock_t acpi_device_lock;
+
+void
+acpi_enable_wakeup_device_prep(
+	u8		sleep_state)
+{
+	struct list_head * node, * next;
+
+	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+		
+		if (!dev->wakeup.flags.valid || 
+			!dev->wakeup.state.enabled ||
+			(sleep_state > (u32) dev->wakeup.sleep_state))
+			continue;
+
+		spin_unlock(&acpi_device_lock);
+		acpi_enable_wakeup_device_power(dev);
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+}
+
+/**
+ * acpi_enable_wakeup_device - enable wakeup devices
+ *	@sleep_state:	ACPI state
+ * Enable all wakup devices's GPE
+ */
+void
+acpi_enable_wakeup_device(
+	u8		sleep_state)
+{
+	struct list_head * node, * next;
+
+	/* 
+	 * Caution: this routine must be invoked when interrupt is disabled 
+	 * Refer ACPI2.0: P212
+	 */
+	ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+
+		/* If users want to disable run-wake GPE,
+		 * we only disable it for wake and leave it for runtime
+		 */
+		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+			spin_unlock(&acpi_device_lock);
+			acpi_set_gpe_type(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME);
+			/* Re-enable it, since set_gpe_type will disable it */
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_ISR);
+			spin_lock(&acpi_device_lock);
+			continue;
+		}
+
+		if (!dev->wakeup.flags.valid ||
+			!dev->wakeup.state.enabled ||
+			(sleep_state > (u32) dev->wakeup.sleep_state))
+			continue;
+
+		spin_unlock(&acpi_device_lock);
+		/* run-wake GPE has been enabled */
+		if (!dev->wakeup.flags.run_wake)
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_ISR);
+		dev->wakeup.state.active = 1;
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+}
+
+/**
+ * acpi_disable_wakeup_device - disable devices' wakeup capability
+ *	@sleep_state:	ACPI state
+ * Disable all wakup devices's GPE and wakeup capability
+ */
+void
+acpi_disable_wakeup_device (
+	u8		sleep_state)
+{
+	struct list_head * node, * next;
+
+	ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+
+		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+			spin_unlock(&acpi_device_lock);
+			acpi_set_gpe_type(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+			/* Re-enable it, since set_gpe_type will disable it */
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+			spin_lock(&acpi_device_lock);
+			continue;
+		}
+
+		if (!dev->wakeup.flags.valid || 
+			!dev->wakeup.state.active ||
+			(sleep_state > (u32) dev->wakeup.sleep_state))
+			continue;
+
+		spin_unlock(&acpi_device_lock);
+		acpi_disable_wakeup_device_power(dev);
+		/* Never disable run-wake GPE */
+		if (!dev->wakeup.flags.run_wake) {
+			acpi_disable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+			acpi_clear_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+		}
+		dev->wakeup.state.active = 0;
+		spin_lock(&acpi_device_lock);
+	}
+	spin_unlock(&acpi_device_lock);
+}
+
+static int __init acpi_wakeup_device_init(void)
+{
+	struct list_head * node, * next;
+
+	printk("ACPI wakeup devices: \n");
+
+	spin_lock(&acpi_device_lock);
+	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
+		struct acpi_device * dev = container_of(node, 
+			struct acpi_device, wakeup_list);
+		
+		/* In case user doesn't load button driver */
+		if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
+			spin_unlock(&acpi_device_lock);
+			acpi_set_gpe_type(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_GPE_TYPE_WAKE_RUN);
+			acpi_enable_gpe(dev->wakeup.gpe_device, 
+				dev->wakeup.gpe_number, ACPI_NOT_ISR);
+			dev->wakeup.state.enabled = 1;
+			spin_lock(&acpi_device_lock);
+		}
+		printk("%4s ", dev->pnp.bus_id);
+	}
+	spin_unlock(&acpi_device_lock);
+	printk("\n");
+
+	return 0;
+}
+
+late_initcall(acpi_wakeup_device_init);
diff -Nru a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
--- a/drivers/acpi/tables/tbxfroot.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/tables/tbxfroot.c	Sat Jul 17 03:29:59 2004
@@ -115,17 +115,14 @@
  *              Instance        - the non zero instance of the table, allows
  *                                support for multiple tables of the same type
  *              Flags           - Physical/Virtual support
- *              ret_buffer      - pointer to a structure containing a buffer to
- *                                receive the table
+ *              table_pointer   - Where a buffer containing the table is
+ *                                returned
  *
  * RETURN:      Status
  *
- * DESCRIPTION: This function is called to get an ACPI table.  The caller
- *              supplies an out_buffer large enough to contain the entire ACPI
- *              table.  Upon completion
- *              the out_buffer->Length field will indicate the number of bytes
- *              copied into the out_buffer->buf_ptr buffer. This table will be
- *              a complete table including the header.
+ * DESCRIPTION: This function is called to get an ACPI table. A buffer is
+ *              allocated for the table and returned in table_pointer.
+ *              This table will be a complete table including the header.
  *
  ******************************************************************************/
 
@@ -136,12 +133,11 @@
 	u32                             flags,
 	struct acpi_table_header        **table_pointer)
 {
-	struct acpi_pointer             rsdp_address;
-	struct acpi_pointer             address;
 	acpi_status                     status;
-	struct acpi_table_header        header;
-	struct acpi_table_desc          table_info;
-	struct acpi_table_desc          rsdt_info;
+	struct acpi_pointer             address;
+	struct acpi_table_header        *header = NULL;
+	struct acpi_table_desc          *table_info = NULL;
+	struct acpi_table_desc          *rsdt_info;
 	u32                             table_count;
 	u32                             i;
 	u32                             j;
@@ -152,45 +148,41 @@
 
 	/*
 	 * Ensure that at least the table manager is initialized.  We don't
-	 * require that the entire ACPI subsystem is up for this interface
-	 */
-
-	/*
-	 *  If we have a buffer, we must have a length too
+	 * require that the entire ACPI subsystem is up for this interface.
+	 * If we have a buffer, we must have a length too
 	 */
-	if ((instance == 0)                 ||
-		(!signature)                    ||
+	if ((instance == 0)     ||
+		(!signature)        ||
 		(!table_pointer)) {
 		return_ACPI_STATUS (AE_BAD_PARAMETER);
 	}
 
-	rsdt_info.pointer = NULL;
+	/* Ensure that we have a RSDP */
 
 	if (!acpi_gbl_RSDP) {
 		/* Get the RSDP */
 
-		status = acpi_os_get_root_pointer (flags, &rsdp_address);
+		status = acpi_os_get_root_pointer (flags, &address);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP  not found\n"));
+			ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "RSDP not found\n"));
 			return_ACPI_STATUS (AE_NO_ACPI_TABLES);
 		}
 
 		/* Map and validate the RSDP */
 
 		if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
-			status = acpi_os_map_memory (rsdp_address.pointer.physical, sizeof (struct rsdp_descriptor),
+			status = acpi_os_map_memory (address.pointer.physical, sizeof (struct rsdp_descriptor),
 					  (void *) &acpi_gbl_RSDP);
 			if (ACPI_FAILURE (status)) {
 				return_ACPI_STATUS (status);
 			}
 		}
 		else {
-			acpi_gbl_RSDP = rsdp_address.pointer.logical;
+			acpi_gbl_RSDP = address.pointer.logical;
 		}
 
-		/*
-		 *  The signature and checksum must both be correct
-		 */
+		/* The signature and checksum must both be correct */
+
 		if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) {
 			/* Nope, BAD Signature */
 
@@ -204,10 +196,9 @@
 		}
 	}
 
-	/* Get the RSDT and validate it */
+	/* Get the RSDT address via the RSDP */
 
 	acpi_tb_get_rsdt_address (&address);
-
 	ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
 		"RSDP located at %p, RSDT physical=%8.8X%8.8X \n",
 		acpi_gbl_RSDP,
@@ -217,20 +208,40 @@
 
 	address.pointer_type |= flags;
 
-	status = acpi_tb_get_table (&address, &rsdt_info);
+	/* Get and validate the RSDT */
+
+	rsdt_info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+	if (!rsdt_info) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	status = acpi_tb_get_table (&address, rsdt_info);
 	if (ACPI_FAILURE (status)) {
-		return_ACPI_STATUS (status);
+		goto cleanup;
 	}
 
-	status = acpi_tb_validate_rsdt (rsdt_info.pointer);
+	status = acpi_tb_validate_rsdt (rsdt_info->pointer);
 	if (ACPI_FAILURE (status)) {
 		goto cleanup;
 	}
 
-	/* Get the number of table pointers within the RSDT */
+	/* Allocate a scratch table header and table descriptor */
 
-	table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info.pointer);
+	header = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_header));
+	if (!header) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
 
+	table_info = ACPI_MEM_ALLOCATE (sizeof (struct acpi_table_desc));
+	if (!table_info) {
+		status = AE_NO_MEMORY;
+		goto cleanup;
+	}
+
+	/* Get the number of table pointers within the RSDT */
+
+	table_count = acpi_tb_get_table_count (acpi_gbl_RSDP, rsdt_info->pointer);
 	address.pointer_type = acpi_gbl_table_flags | flags;
 
 	/*
@@ -241,35 +252,36 @@
 		/* Get the next table pointer, handle RSDT vs. XSDT */
 
 		if (acpi_gbl_RSDP->revision < 2) {
-			address.pointer.value = (ACPI_CAST_PTR (RSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i];
+			address.pointer.value = (ACPI_CAST_PTR (
+				RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
 		}
 		else {
-			address.pointer.value =
-				(ACPI_CAST_PTR (XSDT_DESCRIPTOR, rsdt_info.pointer))->table_offset_entry[i];
+			address.pointer.value = (ACPI_CAST_PTR (
+				XSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
 		}
 
 		/* Get the table header */
 
-		status = acpi_tb_get_table_header (&address, &header);
+		status = acpi_tb_get_table_header (&address, header);
 		if (ACPI_FAILURE (status)) {
 			goto cleanup;
 		}
 
 		/* Compare table signatures and table instance */
 
-		if (!ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
+		if (!ACPI_STRNCMP (header->signature, signature, ACPI_NAME_SIZE)) {
 			/* An instance of the table was found */
 
 			j++;
 			if (j >= instance) {
 				/* Found the correct instance, get the entire table */
 
-				status = acpi_tb_get_table_body (&address, &header, &table_info);
+				status = acpi_tb_get_table_body (&address, header, table_info);
 				if (ACPI_FAILURE (status)) {
 					goto cleanup;
 				}
 
-				*table_pointer = table_info.pointer;
+				*table_pointer = table_info->pointer;
 				goto cleanup;
 			}
 		}
@@ -281,7 +293,15 @@
 
 
 cleanup:
-	acpi_os_unmap_memory (rsdt_info.pointer, (acpi_size) rsdt_info.pointer->length);
+	acpi_os_unmap_memory (rsdt_info->pointer, (acpi_size) rsdt_info->pointer->length);
+	ACPI_MEM_FREE (rsdt_info);
+
+	if (header) {
+		ACPI_MEM_FREE (header);
+	}
+	if (table_info) {
+		ACPI_MEM_FREE (table_info);
+	}
 	return_ACPI_STATUS (status);
 }
 
@@ -389,14 +409,17 @@
  *              Flags                   - Current memory mode (logical vs.
  *                                        physical addressing)
  *
- * RETURN:      Status
+ * RETURN:      Status, RSDP physical address
  *
  * DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor
  *              pointer structure.  If it is found, set *RSDP to point to it.
  *
- *              NOTE: The RSDp must be either in the first 1_k of the Extended
- *              BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
- *              5.2.2; assertion #421).
+ *              NOTE1: The RSDp must be either in the first 1_k of the Extended
+ *              BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
+ *              Only a 32-bit physical address is necessary.
+ *
+ *              NOTE2: This function is always available, regardless of the
+ *              initialization state of the rest of ACPI.
  *
  ******************************************************************************/
 
@@ -407,8 +430,8 @@
 {
 	u8                              *table_ptr;
 	u8                              *mem_rover;
-	u64                             phys_addr;
-	acpi_status                     status = AE_OK;
+	u32                             physical_address;
+	acpi_status                     status;
 
 
 	ACPI_FUNCTION_TRACE ("tb_find_rsdp");
@@ -419,36 +442,57 @@
 	 */
 	if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
 		/*
-		 * 1) Search EBDA (low memory) paragraphs
+		 * 1a) Get the location of the EBDA
 		 */
-		status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE,
+		status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
+				  ACPI_EBDA_PTR_LENGTH,
 				  (void *) &table_ptr);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
-				ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE));
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n",
+				ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
 			return_ACPI_STATUS (status);
 		}
 
-		mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE);
-		acpi_os_unmap_memory (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE);
+		ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
+		physical_address <<= 4;                 /* Convert segment to physical address */
+		acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
+
+		/* EBDA present? */
+
+		if (physical_address > 0x400) {
+			/*
+			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+			 */
+			status = acpi_os_map_memory ((acpi_physical_address) physical_address,
+					  ACPI_EBDA_WINDOW_SIZE,
+					  (void *) &table_ptr);
+			if (ACPI_FAILURE (status)) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n",
+					physical_address, ACPI_EBDA_WINDOW_SIZE));
+				return_ACPI_STATUS (status);
+			}
 
-		if (mem_rover) {
-			/* Found it, return the physical address */
+			mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
+			acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
 
-			phys_addr = ACPI_LO_RSDP_WINDOW_BASE;
-			phys_addr += ACPI_PTR_DIFF (mem_rover,table_ptr);
+			if (mem_rover) {
+				/* Found it, return the physical address */
 
-			table_info->physical_address = phys_addr;
-			return_ACPI_STATUS (AE_OK);
+				physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
+
+				table_info->physical_address = (acpi_physical_address) physical_address;
+				return_ACPI_STATUS (AE_OK);
+			}
 		}
 
 		/*
-		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
 		 */
-		status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE,
+		status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
+				  ACPI_HI_RSDP_WINDOW_SIZE,
 				  (void *) &table_ptr);
 		if (ACPI_FAILURE (status)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
+			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n",
 				ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
 			return_ACPI_STATUS (status);
 		}
@@ -459,10 +503,9 @@
 		if (mem_rover) {
 			/* Found it, return the physical address */
 
-			phys_addr = ACPI_HI_RSDP_WINDOW_BASE;
-			phys_addr += ACPI_PTR_DIFF (mem_rover, table_ptr);
+			physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
 
-			table_info->physical_address = phys_addr;
+			table_info->physical_address = (acpi_physical_address) physical_address;
 			return_ACPI_STATUS (AE_OK);
 		}
 	}
@@ -472,19 +515,29 @@
 	 */
 	else {
 		/*
-		 * 1) Search EBDA (low memory) paragraphs
+		 * 1a) Get the location of the EBDA
 		 */
-		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE),
-				  ACPI_LO_RSDP_WINDOW_SIZE);
-		if (mem_rover) {
-			/* Found it, return the physical address */
+		ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
+		physical_address <<= 4;     /* Convert segment to physical address */
 
-			table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
-			return_ACPI_STATUS (AE_OK);
+		/* EBDA present? */
+
+		if (physical_address > 0x400) {
+			/*
+			 * 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
+			 */
+			mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
+					  ACPI_EBDA_WINDOW_SIZE);
+			if (mem_rover) {
+				/* Found it, return the physical address */
+
+				table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
+				return_ACPI_STATUS (AE_OK);
+			}
 		}
 
 		/*
-		 * 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
+		 * 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
 		 */
 		mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
 				  ACPI_HI_RSDP_WINDOW_SIZE);
diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
--- a/drivers/acpi/thermal.c	Sat Jul 17 03:30:00 2004
+++ b/drivers/acpi/thermal.c	Sat Jul 17 03:30:00 2004
@@ -60,6 +60,7 @@
 #define ACPI_THERMAL_NOTIFY_HOT		0xF1
 #define ACPI_THERMAL_MODE_ACTIVE	0x00
 #define ACPI_THERMAL_MODE_PASSIVE	0x01
+#define ACPI_THERMAL_MODE_CRT   	0xff
 #define ACPI_THERMAL_PATH_POWEROFF	"/sbin/poweroff"
 
 #define ACPI_THERMAL_MAX_ACTIVE	10
@@ -289,13 +290,6 @@
 	status = acpi_get_handle(tz->handle, "_SCP", &handle);
 	if (ACPI_FAILURE(status)) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
-		status = acpi_get_handle(tz->handle, "_PSV", &handle);
-		if(!ACPI_FAILURE(status)) {
-			tz->cooling_mode = 1;
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", 
-				mode?"passive":"active"));
-			return_VALUE(0);
-		}
 		return_VALUE(-ENODEV);
 	}
 
@@ -899,8 +893,10 @@
 	struct seq_file		*m = (struct seq_file *)file->private_data;
 	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;
 
-	char			limit_string[25] = {'\0'};
-	int			critical, hot, passive, active0, active1;
+	char			limit_string[65] = {'\0'};
+	int			num, critical, hot, passive;
+	int			active[ACPI_THERMAL_MAX_ACTIVE];
+	int			i = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
 
@@ -916,7 +912,11 @@
 	
 	limit_string[count] = '\0';
 
-	if (sscanf(limit_string, "%d:%d:%d:%d:%d", &critical, &hot, &passive, &active0, &active1) != 5) {
+	num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+				&critical, &hot, &passive,
+				&active[0], &active[1], &active[2], &active[3], &active[4],
+				&active[5], &active[6], &active[7], &active[8], &active[9]);
+	if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
 		return_VALUE(-EINVAL);
 	}
@@ -924,8 +924,11 @@
 	tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);
 	tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot);
 	tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive);
-	tz->trips.active[0].temperature = CELSIUS_TO_KELVIN(active0);
-	tz->trips.active[1].temperature = CELSIUS_TO_KELVIN(active1);
+	for (i = 0; i < num - 3; i++) {
+		if (!(tz->trips.active[i].flags.valid))
+			break;
+		tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
+	}
 	
 	return_VALUE(count);
 }
@@ -941,12 +944,14 @@
 		goto end;
 
 	if (!tz->flags.cooling_mode) {
-		seq_puts(seq, "<not supported>\n");
-		goto end;
+		seq_puts(seq, "<setting not supported>\n");
 	}
 
-	seq_printf(seq, "cooling mode:            %s\n",
-		tz->cooling_mode?"passive":"active");
+	if ( tz->cooling_mode == ACPI_THERMAL_MODE_CRT )
+		seq_printf(seq, "cooling mode:	critical\n");
+	else
+		seq_printf(seq, "cooling mode:	%s\n",
+			tz->cooling_mode?"passive":"active");
 
 end:
 	return 0;
@@ -988,6 +993,8 @@
 	if (result)
 		return_VALUE(result);
 
+	acpi_thermal_check(tz);
+
 	return_VALUE(count);
 }
 
@@ -1225,15 +1232,33 @@
 	if (result)
 		return_VALUE(result);
 
-	/* Set the cooling mode [_SCP] to active cooling (default) */
-	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
-	if (!result)
-		tz->flags.cooling_mode = 1;
-
 	/* Get trip points [_CRT, _PSV, etc.] (required) */
 	result = acpi_thermal_get_trip_points(tz);
 	if (result)
 		return_VALUE(result);
+
+	/* Set the cooling mode [_SCP] to active cooling (default) */
+	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
+	if (!result) 
+		tz->flags.cooling_mode = 1;
+	else { 
+		/* Oh,we have not _SCP method.
+		   Generally show cooling_mode by _ACx, _PSV,spec 12.2*/
+		tz->flags.cooling_mode = 0;
+		if ( tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) {
+			if ( tz->trips.passive.temperature > tz->trips.active[0].temperature )
+				tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
+			else 
+				tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
+		} else if ( !tz->trips.active[0].flags.valid && tz->trips.passive.flags.valid ) {
+			tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
+		} else if ( tz->trips.active[0].flags.valid && !tz->trips.passive.flags.valid ) {
+			tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
+		} else {
+			/* _ACx and _PSV are optional, but _CRT is required */
+			tz->cooling_mode = ACPI_THERMAL_MODE_CRT;
+		}
+	}
 
 	/* Get default polling frequency [_TZP] (optional) */
 	if (tzp)
diff -Nru a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
--- a/drivers/acpi/utilities/utalloc.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/utilities/utalloc.c	Sat Jul 17 03:29:59 2004
@@ -259,8 +259,8 @@
  *
  * FUNCTION:    acpi_ut_initialize_buffer
  *
- * PARAMETERS:  required_length     - Length needed
- *              Buffer              - Buffer to be validated
+ * PARAMETERS:  Buffer              - Buffer to be validated
+ *              required_length     - Length needed
  *
  * RETURN:      Status
  *
@@ -603,7 +603,8 @@
  *
  * FUNCTION:    acpi_ut_find_allocation
  *
- * PARAMETERS:  Allocation             - Address of allocated memory
+ * PARAMETERS:  list_id                 - Memory list to search
+ *              Allocation              - Address of allocated memory
  *
  * RETURN:      A list element if found; NULL otherwise.
  *
@@ -646,7 +647,8 @@
  *
  * FUNCTION:    acpi_ut_track_allocation
  *
- * PARAMETERS:  Allocation          - Address of allocated memory
+ * PARAMETERS:  list_id             - Memory list to search
+ *              Allocation          - Address of allocated memory
  *              Size                - Size of the allocation
  *              alloc_type          - MEM_MALLOC or MEM_CALLOC
  *              Component           - Component type of caller
@@ -733,7 +735,8 @@
  *
  * FUNCTION:    acpi_ut_remove_allocation
  *
- * PARAMETERS:  Allocation          - Address of allocated memory
+ * PARAMETERS:  list_id             - Memory list to search
+ *              Allocation          - Address of allocated memory
  *              Component           - Component type of caller
  *              Module              - Source file name of caller
  *              Line                - Line number of caller
diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/utilities/uteval.c	Sat Jul 17 03:29:59 2004
@@ -133,7 +133,7 @@
 	u32                             expected_return_btypes,
 	union acpi_operand_object       **return_desc)
 {
-	union acpi_operand_object       *obj_desc;
+	struct acpi_parameter_info      info;
 	acpi_status                     status;
 	u32                             return_btype;
 
@@ -141,9 +141,13 @@
 	ACPI_FUNCTION_TRACE ("ut_evaluate_object");
 
 
+	info.node = prefix_node;
+	info.parameters = NULL;
+	info.parameter_type = ACPI_PARAM_ARGS;
+
 	/* Evaluate the object/method */
 
-	status = acpi_ns_evaluate_relative (prefix_node, path, NULL, &obj_desc);
+	status = acpi_ns_evaluate_relative (path, &info);
 	if (ACPI_FAILURE (status)) {
 		if (status == AE_NOT_FOUND) {
 			ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
@@ -159,7 +163,7 @@
 
 	/* Did we get a return object? */
 
-	if (!obj_desc) {
+	if (!info.return_object) {
 		if (expected_return_btypes) {
 			ACPI_REPORT_METHOD_ERROR ("No object was returned from",
 				prefix_node, path, AE_NOT_EXIST);
@@ -172,7 +176,7 @@
 
 	/* Map the return object type to the bitmapped type */
 
-	switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
+	switch (ACPI_GET_OBJECT_TYPE (info.return_object)) {
 	case ACPI_TYPE_INTEGER:
 		return_btype = ACPI_BTYPE_INTEGER;
 		break;
@@ -202,17 +206,17 @@
 
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
 			"Type returned from %s was incorrect: %X\n",
-			path, ACPI_GET_OBJECT_TYPE (obj_desc)));
+			path, ACPI_GET_OBJECT_TYPE (info.return_object)));
 
 		/* On error exit, we must delete the return object */
 
-		acpi_ut_remove_reference (obj_desc);
+		acpi_ut_remove_reference (info.return_object);
 		return_ACPI_STATUS (AE_TYPE);
 	}
 
 	/* Object type is OK, return it */
 
-	*return_desc = obj_desc;
+	*return_desc = info.return_object;
 	return_ACPI_STATUS (AE_OK);
 }
 
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/utilities/utglobal.c	Sat Jul 17 03:29:59 2004
@@ -171,27 +171,40 @@
 
 const u8                            acpi_gbl_decode_to8bit [8] = {1,2,4,8,16,32,64,128};
 
-const char                          *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
-			  "\\_S0_",
-			  "\\_S1_",
-			  "\\_S2_",
-			  "\\_S3_",
-			  "\\_S4_",
-			  "\\_S5_"};
-
-const char                          *acpi_gbl_highest_dstate_names[4] = {
-					   "_S1D",
-					   "_S2D",
-					   "_S3D",
-					   "_S4D"};
-
-/* Strings supported by the _OSI predefined (internal) method */
-
-const char                          *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = {
-							 "Linux",
-							 "Windows 2000",
-							 "Windows 2001",
-							 "Windows 2001.1"};
+const char                          *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] =
+{
+	"\\_S0_",
+	"\\_S1_",
+	"\\_S2_",
+	"\\_S3_",
+	"\\_S4_",
+	"\\_S5_"
+};
+
+const char                          *acpi_gbl_highest_dstate_names[4] =
+{
+	"_S1D",
+	"_S2D",
+	"_S3D",
+	"_S4D"
+};
+
+/*
+ * Strings supported by the _OSI predefined (internal) method.
+ * When adding strings, be sure to update ACPI_NUM_OSI_STRINGS.
+ */
+const char                          *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
+{
+	"Linux",
+	"Windows 2000",
+	"Windows 2001",
+	"Windows 2001.1",
+	"Windows 2001 SP0",
+	"Windows 2001 SP1",
+	"Windows 2001 SP2",
+	"Windows 2001 SP3",
+	"Windows 2001 SP4"
+};
 
 
 /******************************************************************************
@@ -213,7 +226,7 @@
 	{"_PR_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
 	{"_SB_",    ACPI_TYPE_DEVICE,           NULL},
 	{"_SI_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
-	{"_TZ_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
+	{"_TZ_",    ACPI_TYPE_THERMAL,          NULL},
 	{"_REV",    ACPI_TYPE_INTEGER,          "2"},
 	{"_OS_",    ACPI_TYPE_STRING,           ACPI_OS_NAME},
 	{"_GL_",    ACPI_TYPE_MUTEX,            "0"},
@@ -561,26 +574,37 @@
 	struct acpi_namespace_node      *node = (struct acpi_namespace_node *) object;
 
 
+	/* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
+
 	if (!object)
 	{
-		return ("NULL NODE");
+		return ("NULL");
 	}
 
-	if (object == ACPI_ROOT_OBJECT)
+	/* Check for Root node */
+
+	if ((object == ACPI_ROOT_OBJECT) ||
+		(object == acpi_gbl_root_node))
 	{
-		node = acpi_gbl_root_node;
+		return ("\"\\\" ");
 	}
 
+	/* Descriptor must be a namespace node */
+
 	if (node->descriptor != ACPI_DESC_TYPE_NAMED)
 	{
-		return ("****");
+		return ("####");
 	}
 
+	/* Name must be a valid ACPI name */
+
 	if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii))
 	{
-		return ("----");
+		return ("????");
 	}
 
+	/* Return the name */
+
 	return (node->name.ascii);
 }
 
@@ -783,10 +807,6 @@
 
 	ACPI_FUNCTION_TRACE ("ut_init_globals");
 
-	/* Runtime configuration */
-
-	acpi_gbl_create_osi_method = TRUE;
-	acpi_gbl_all_methods_serialized = FALSE;
 
 	/* Memory allocation and cache lists */
 
@@ -880,6 +900,7 @@
 	/* Hardware oriented */
 
 	acpi_gbl_events_initialized         = FALSE;
+	acpi_gbl_system_awake_and_running   = TRUE;
 
 	/* Namespace */
 
diff -Nru a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c
--- a/drivers/acpi/utilities/utxface.c	Sat Jul 17 03:29:59 2004
+++ b/drivers/acpi/utilities/utxface.c	Sat Jul 17 03:29:59 2004
@@ -157,9 +157,8 @@
 		}
 	}
 
-	/*
-	 * Enable ACPI mode
-	 */
+	/* Enable ACPI mode */
+
 	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
 
@@ -173,7 +172,21 @@
 	}
 
 	/*
-	 * Initialize ACPI Event handling
+	 * Install the default op_region handlers. These are installed unless
+	 * other handlers have already been installed via the
+	 * install_address_space_handler interface.
+	 */
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+
+		status = acpi_ev_install_region_handlers ();
+		if (ACPI_FAILURE (status)) {
+			return_ACPI_STATUS (status);
+		}
+	}
+
+	/*
+	 * Initialize ACPI Event handling (Fixed and General Purpose)
 	 *
 	 * NOTE: We must have the hardware AND events initialized before we can execute
 	 * ANY control methods SAFELY.  Any control method can require ACPI hardware
@@ -182,18 +195,18 @@
 	if (!(flags & ACPI_NO_EVENT_INIT)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI events\n"));
 
-		status = acpi_ev_initialize ();
+		status = acpi_ev_initialize_events ();
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
 	}
 
-	/* Install the SCI handler, Global Lock handler, and GPE handlers */
+	/* Install the SCI handler and Global Lock handler */
 
 	if (!(flags & ACPI_NO_HANDLER_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL handlers\n"));
 
-		status = acpi_ev_handler_initialize ();
+		status = acpi_ev_install_xrupt_handlers ();
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -226,18 +239,16 @@
 
 
 	/*
-	 * Install the default op_region handlers. These are installed unless
-	 * other handlers have already been installed via the
-	 * install_address_space_handler interface.
+	 * Run all _REG methods
 	 *
-	 * NOTE: This will cause _REG methods to be run.  Any objects accessed
+	 * NOTE: Any objects accessed
 	 * by the _REG methods will be automatically initialized, even if they
 	 * contain executable AML (see call to acpi_ns_initialize_objects below).
 	 */
 	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Executing _REG op_region methods\n"));
 
-		status = acpi_ev_init_address_spaces ();
+		status = acpi_ev_initialize_op_regions ();
 		if (ACPI_FAILURE (status)) {
 			return_ACPI_STATUS (status);
 		}
@@ -249,7 +260,7 @@
 	 * objects: operation_regions, buffer_fields, Buffers, and Packages.
 	 */
 	if (!(flags & ACPI_NO_OBJECT_INIT)) {
-		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n"));
+		ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Completing Initialization of ACPI Objects\n"));
 
 		status = acpi_ns_initialize_objects ();
 		if (ACPI_FAILURE (status)) {
diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- a/include/acpi/acconfig.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acconfig.h	Sat Jul 17 03:29:59 2004
@@ -64,11 +64,21 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20040326
+#define ACPI_CA_VERSION                 0x20040715
+
+/*
+ * OS name, used for the _OS object.  The _OS object is essentially obsolete,
+ * but there is a large base of ASL/AML code in existing machines that check
+ * for the string below.  The use of this string usually guarantees that
+ * the ASL will execute down the most tested code path.  Also, there is some
+ * code that will not execute the _OSI method unless _OS matches the string
+ * below.  Therefore, change this string at your own risk.
+ */
+#define ACPI_OS_NAME                    "Microsoft Windows NT"
 
 /* Maximum objects in the various object caches */
 
-#define ACPI_MAX_STATE_CACHE_DEPTH      64          /* State objects for stacks */
+#define ACPI_MAX_STATE_CACHE_DEPTH      64          /* State objects */
 #define ACPI_MAX_PARSE_CACHE_DEPTH      96          /* Parse tree objects */
 #define ACPI_MAX_EXTPARSE_CACHE_DEPTH   64          /* Parse tree objects */
 #define ACPI_MAX_OBJECT_CACHE_DEPTH     64          /* Interpreter operand objects */
@@ -152,10 +162,11 @@
 
 /* Constants used in searching for the RSDP in low memory */
 
-#define ACPI_LO_RSDP_WINDOW_BASE        0           /* Physical Address */
-#define ACPI_HI_RSDP_WINDOW_BASE        0xE0000     /* Physical Address */
-#define ACPI_LO_RSDP_WINDOW_SIZE        0x400
-#define ACPI_HI_RSDP_WINDOW_SIZE        0x20000
+#define ACPI_EBDA_PTR_LOCATION          0x0000040E     /* Physical Address */
+#define ACPI_EBDA_PTR_LENGTH            2
+#define ACPI_EBDA_WINDOW_SIZE           1024
+#define ACPI_HI_RSDP_WINDOW_BASE        0x000E0000     /* Physical Address */
+#define ACPI_HI_RSDP_WINDOW_SIZE        0x00020000
 #define ACPI_RSDP_SCAN_STEP             16
 
 /* Operation regions */
@@ -187,7 +198,7 @@
 
 /* Number of strings associated with the _OSI reserved method */
 
-#define ACPI_NUM_OSI_STRINGS            4
+#define ACPI_NUM_OSI_STRINGS            9
 
 
 /******************************************************************************
diff -Nru a/include/acpi/acdebug.h b/include/acpi/acdebug.h
--- a/include/acpi/acdebug.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acdebug.h	Sat Jul 17 03:29:59 2004
@@ -106,6 +106,10 @@
  * dbcmds - debug commands and output routines
  */
 
+acpi_status
+acpi_db_disassemble_method (
+	char                            *name);
+
 void
 acpi_db_display_table_info (
 	char                            *table_arg);
@@ -163,6 +167,10 @@
 void
 acpi_db_set_scope (
 	char                            *name);
+
+acpi_status
+acpi_db_sleep (
+	char                            *object_arg);
 
 void
 acpi_db_find_references (
diff -Nru a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
--- a/include/acpi/acdisasm.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acdisasm.h	Sat Jul 17 03:29:59 2004
@@ -52,6 +52,13 @@
 #define BLOCK_BRACE             2
 #define BLOCK_COMMA_LIST        4
 
+struct acpi_external_list
+{
+	char                                *path;
+	struct acpi_external_list           *next;
+};
+
+extern struct acpi_external_list        *acpi_gbl_external_list;
 extern const char                       *acpi_gbl_io_decode[2];
 extern const char                       *acpi_gbl_word_decode[4];
 extern const char                       *acpi_gbl_consume_decode[2];
@@ -398,5 +405,13 @@
 	u32                             length,
 	u32                             level);
 
+
+/*
+ * dmutils
+ */
+
+void
+acpi_dm_add_to_external_list (
+	char                            *path);
 
 #endif  /* __ACDISASM_H__ */
diff -Nru a/include/acpi/acdispat.h b/include/acpi/acdispat.h
--- a/include/acpi/acdispat.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acdispat.h	Sat Jul 17 03:29:59 2004
@@ -437,8 +437,7 @@
 	struct acpi_namespace_node      *method_node,
 	u8                              *aml_start,
 	u32                             aml_length,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc,
+	struct acpi_parameter_info      *info,
 	u32                             pass_number);
 
 acpi_status
diff -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h
--- a/include/acpi/acevents.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acevents.h	Sat Jul 17 03:29:59 2004
@@ -46,11 +46,11 @@
 
 
 acpi_status
-acpi_ev_initialize (
+acpi_ev_initialize_events (
 	void);
 
 acpi_status
-acpi_ev_handler_initialize (
+acpi_ev_install_xrupt_handlers (
 	void);
 
 
@@ -111,12 +111,27 @@
 
 acpi_status
 acpi_ev_walk_gpe_list (
-	ACPI_GPE_CALLBACK       gpe_walk_callback);
+	ACPI_GPE_CALLBACK       gpe_walk_callback,
+	u32                             flags);
 
 u8
 acpi_ev_valid_gpe_event (
 	struct acpi_gpe_event_info      *gpe_event_info);
 
+acpi_status
+acpi_ev_update_gpe_enable_masks (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              type);
+
+acpi_status
+acpi_ev_enable_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              write_to_hardware);
+
+acpi_status
+acpi_ev_disable_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info);
+
 struct acpi_gpe_event_info *
 acpi_ev_get_gpe_event_info (
 	acpi_handle                     gpe_device,
@@ -139,6 +154,11 @@
 acpi_ev_delete_gpe_block (
 	struct acpi_gpe_block_info      *gpe_block);
 
+acpi_status
+acpi_ev_delete_gpe_handlers (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block);
+
 u32
 acpi_ev_gpe_dispatch (
 	struct acpi_gpe_event_info      *gpe_event_info,
@@ -148,12 +168,25 @@
 acpi_ev_gpe_detect (
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_list);
 
+acpi_status
+acpi_ev_set_gpe_type (
+	struct acpi_gpe_event_info      *gpe_event_info,
+	u8                              type);
+
+acpi_status
+acpi_ev_check_for_wake_only_gpe (
+	struct acpi_gpe_event_info      *gpe_event_info);
+
 /*
  * Evregion - Address Space handling
  */
 
 acpi_status
-acpi_ev_init_address_spaces (
+acpi_ev_install_region_handlers (
+	void);
+
+acpi_status
+acpi_ev_initialize_op_regions (
 	void);
 
 acpi_status
@@ -181,6 +214,19 @@
 acpi_ev_detach_region (
 	union acpi_operand_object      *region_obj,
 	u8                              acpi_ns_is_locked);
+
+acpi_status
+acpi_ev_install_space_handler (
+	struct acpi_namespace_node      *node,
+	acpi_adr_space_type             space_id,
+	acpi_adr_space_handler          handler,
+	acpi_adr_space_setup            setup,
+	void                            *context);
+
+acpi_status
+acpi_ev_execute_reg_methods (
+	struct acpi_namespace_node      *node,
+	acpi_adr_space_type             space_id);
 
 acpi_status
 acpi_ev_execute_reg_method (
diff -Nru a/include/acpi/acexcep.h b/include/acpi/acexcep.h
--- a/include/acpi/acexcep.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acexcep.h	Sat Jul 17 03:29:59 2004
@@ -95,8 +95,9 @@
 #define AE_LOGICAL_ADDRESS              (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
 #define AE_ABORT_METHOD                 (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
 #define AE_SAME_HANDLER                 (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
+#define AE_WAKE_ONLY_GPE                (acpi_status) (0x001E | AE_CODE_ENVIRONMENTAL)
 
-#define AE_CODE_ENV_MAX                 0x001D
+#define AE_CODE_ENV_MAX                 0x001E
 
 /*
  * Programmer exceptions
@@ -222,7 +223,8 @@
 	"AE_NO_GLOBAL_LOCK",
 	"AE_LOGICAL_ADDRESS",
 	"AE_ABORT_METHOD",
-	"AE_SAME_HANDLER"
+	"AE_SAME_HANDLER",
+	"AE_WAKE_ONLY_GPE"
 };
 
 char const   *acpi_gbl_exception_names_pgm[] =
diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h
--- a/include/acpi/acglobal.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acglobal.h	Sat Jul 17 03:29:59 2004
@@ -46,15 +46,17 @@
 
 
 /*
- * Ensure that the globals are actually defined only once.
+ * Ensure that the globals are actually defined and initialized only once.
  *
- * The use of these defines allows a single list of globals (here) in order
+ * The use of these macros allows a single list of globals (here) in order
  * to simplify maintenance of the code.
  */
 #ifdef DEFINE_ACPI_GLOBALS
 #define ACPI_EXTERN
+#define ACPI_INIT_GLOBAL(a,b) a=b
 #else
 #define ACPI_EXTERN extern
+#define ACPI_INIT_GLOBAL(a,b) a
 #endif
 
 /*
@@ -64,6 +66,7 @@
 ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1a_enable;
 ACPI_EXTERN struct acpi_generic_address         acpi_gbl_xpm1b_enable;
 
+
 /*****************************************************************************
  *
  * Debug support
@@ -79,15 +82,42 @@
 
 extern      u32                                 acpi_gbl_nesting_level;
 
+
 /*****************************************************************************
  *
- * Runtime configuration
+ * Runtime configuration (static defaults that can be overriden at runtime)
  *
  ****************************************************************************/
 
-ACPI_EXTERN u8                                  acpi_gbl_create_osi_method;
-ACPI_EXTERN u8                                  acpi_gbl_all_methods_serialized;
-ACPI_EXTERN u8                                  acpi_gbl_leave_wake_gpes_disabled;
+/*
+ * Enable "slack" in the AML interpreter?  Default is FALSE, and the
+ * interpreter strictly follows the ACPI specification.  Setting to TRUE
+ * allows the interpreter to forgive certain bad AML constructs.
+ */
+ACPI_EXTERN u8       ACPI_INIT_GLOBAL (acpi_gbl_enable_interpeter_slack, FALSE);
+
+/*
+ * Automatically serialize ALL control methods? Default is FALSE, meaning
+ * to use the Serialized/not_serialized method flags on a per method basis.
+ * Only change this if the ASL code is poorly written and cannot handle
+ * reentrancy even though methods are marked "not_serialized".
+ */
+ACPI_EXTERN u8       ACPI_INIT_GLOBAL (acpi_gbl_all_methods_serialized, FALSE);
+
+/*
+ * Create the predefined _OSI method in the namespace? Default is TRUE
+ * because ACPI CA is fully compatible with other ACPI implementations.
+ * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior.
+ */
+ACPI_EXTERN u8       ACPI_INIT_GLOBAL (acpi_gbl_create_osi_method, TRUE);
+
+/*
+ * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and
+ * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only
+ * be enabled just before going to sleep.
+ */
+ACPI_EXTERN u8       ACPI_INIT_GLOBAL (acpi_gbl_leave_wake_gpes_disabled, TRUE);
+
 
 /*****************************************************************************
  *
@@ -102,7 +132,6 @@
  *
  * These tables are single-table only; meaning that there can be at most one
  * of each in the system.  Each global points to the actual table.
- *
  */
 ACPI_EXTERN u32                                 acpi_gbl_table_flags;
 ACPI_EXTERN u32                                 acpi_gbl_rsdt_table_count;
@@ -170,6 +199,7 @@
 ACPI_EXTERN u8                                  acpi_gbl_acpi_hardware_present;
 ACPI_EXTERN u8                                  acpi_gbl_global_lock_present;
 ACPI_EXTERN u8                                  acpi_gbl_events_initialized;
+ACPI_EXTERN u8                                  acpi_gbl_system_awake_and_running;
 
 extern u8                                       acpi_gbl_shutdown;
 extern u32                                      acpi_gbl_startup_flags;
diff -Nru a/include/acpi/achware.h b/include/acpi/achware.h
--- a/include/acpi/achware.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/achware.h	Sat Jul 17 03:29:59 2004
@@ -114,15 +114,7 @@
 /* GPE support */
 
 acpi_status
-acpi_hw_enable_gpe (
-	struct acpi_gpe_event_info      *gpe_event_info);
-
-void
-acpi_hw_enable_gpe_for_wakeup (
-	struct acpi_gpe_event_info      *gpe_event_info);
-
-acpi_status
-acpi_hw_disable_gpe (
+acpi_hw_write_gpe_enable_reg (
 	struct acpi_gpe_event_info      *gpe_event_info);
 
 acpi_status
@@ -130,10 +122,6 @@
 	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
 	struct acpi_gpe_block_info      *gpe_block);
 
-void
-acpi_hw_disable_gpe_for_wakeup (
-	struct acpi_gpe_event_info      *gpe_event_info);
-
 acpi_status
 acpi_hw_clear_gpe (
 	struct acpi_gpe_event_info      *gpe_event_info);
@@ -149,12 +137,26 @@
 	acpi_event_status               *event_status);
 
 acpi_status
-acpi_hw_prepare_gpes_for_sleep (
-	void);
+acpi_hw_disable_all_gpes (
+	u32                             flags);
+
+acpi_status
+acpi_hw_enable_all_runtime_gpes (
+	u32                             flags);
 
 acpi_status
-acpi_hw_restore_gpes_on_wake (
-	void);
+acpi_hw_enable_all_wakeup_gpes (
+	u32                             flags);
+
+acpi_status
+acpi_hw_enable_runtime_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block);
+
+acpi_status
+acpi_hw_enable_wakeup_gpe_block (
+	struct acpi_gpe_xrupt_info      *gpe_xrupt_info,
+	struct acpi_gpe_block_info      *gpe_block);
 
 
 /* ACPI Timer prototypes */
diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h
--- a/include/acpi/acinterp.h	Sat Jul 17 03:30:00 2004
+++ b/include/acpi/acinterp.h	Sat Jul 17 03:30:00 2004
@@ -118,6 +118,12 @@
  */
 
 acpi_status
+acpi_ex_common_buffer_setup (
+	union acpi_operand_object       *obj_desc,
+	u32                             buffer_length,
+	u32                             *datum_count);
+
+acpi_status
 acpi_ex_extract_from_field (
 	union acpi_operand_object       *obj_desc,
 	void                            *buffer,
@@ -240,8 +246,8 @@
 u8
 acpi_ex_do_logical_op (
 	u16                             opcode,
-	acpi_integer                    operand0,
-	acpi_integer                    operand1);
+	union acpi_operand_object       *obj_desc,
+	union acpi_operand_object       *obj_desc2);
 
 acpi_integer
 acpi_ex_do_math_op (
@@ -563,8 +569,11 @@
 acpi_ex_store_object_to_node (
 	union acpi_operand_object       *source_desc,
 	struct acpi_namespace_node      *node,
-	struct acpi_walk_state          *walk_state);
+	struct acpi_walk_state          *walk_state,
+	u8                              implicit_conversion);
 
+#define ACPI_IMPLICIT_CONVERSION        TRUE
+#define ACPI_NO_IMPLICIT_CONVERSION     FALSE
 
 /*
  * exstoren
diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h
--- a/include/acpi/aclocal.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/aclocal.h	Sat Jul 17 03:29:59 2004
@@ -189,8 +189,6 @@
 	u8                                  type;           /* Type associated with this name */
 	u16                                 owner_id;
 	union acpi_name_union               name;           /* ACPI Name, always 4 chars per ACPI spec */
-
-
 	union acpi_operand_object           *object;        /* Pointer to attached ACPI object (optional) */
 	struct acpi_namespace_node          *child;         /* First child */
 	struct acpi_namespace_node          *peer;          /* Next peer*/
@@ -211,10 +209,8 @@
 #define ANOBJ_METHOD_LOCAL              0x10
 #define ANOBJ_METHOD_NO_RETVAL          0x20
 #define ANOBJ_METHOD_SOME_NO_RETVAL     0x40
-
 #define ANOBJ_IS_BIT_OFFSET             0x80
 
-
 /*
  * ACPI Table Descriptor.  One per ACPI table
  */
@@ -309,16 +305,31 @@
  *
  ****************************************************************************/
 
-/* Information about a GPE, one per each GPE in an array */
+/* Dispatch info for each GPE -- either a method or handler, cannot be both */
 
-struct acpi_gpe_event_info
+struct acpi_handler_info
 {
-	struct acpi_namespace_node              *method_node;   /* Method node for this GPE level */
-	acpi_gpe_handler                        handler;        /* Address of handler, if any */
+	acpi_event_handler                      address;        /* Address of handler, if any */
 	void                                    *context;       /* Context to be passed to handler */
+	struct acpi_namespace_node              *method_node;   /* Method node for this GPE level (saved) */
+};
+
+union acpi_gpe_dispatch_info
+{
+	struct acpi_namespace_node              *method_node;   /* Method node for this GPE level */
+	struct acpi_handler_info                *handler;
+};
+
+/*
+ * Information about a GPE, one per each GPE in an array.
+ * NOTE: Important to keep this struct as small as possible.
+ */
+struct acpi_gpe_event_info
+{
+	union acpi_gpe_dispatch_info    dispatch;       /* Either Method or Handler */
 	struct acpi_gpe_register_info           *register_info; /* Backpointer to register info */
-	u8                                      flags;          /* Level or Edge */
-	u8                                      bit_mask;       /* This GPE within the register */
+	u8                                      flags;          /* Misc info about this GPE */
+	u8                                      register_bit;   /* This GPE bit within the register */
 };
 
 /* Information about a GPE register pair, one per each status/enable pair in an array */
@@ -327,9 +338,8 @@
 {
 	struct acpi_generic_address             status_address; /* Address of status reg */
 	struct acpi_generic_address             enable_address; /* Address of enable reg */
-	u8                                      status;         /* Current value of status reg */
-	u8                                      enable;         /* Current value of enable reg */
-	u8                                      wake_enable;    /* Mask of bits to keep enabled when sleeping */
+	u8                                      enable_for_wake; /* GPEs to keep enabled when sleeping */
+	u8                                      enable_for_run; /* GPEs to keep enabled when running */
 	u8                                      base_gpe_number; /* Base GPE number for this register */
 };
 
@@ -339,6 +349,7 @@
  */
 struct acpi_gpe_block_info
 {
+	struct acpi_namespace_node              *node;
 	struct acpi_gpe_block_info              *previous;
 	struct acpi_gpe_block_info              *next;
 	struct acpi_gpe_xrupt_info              *xrupt_block;   /* Backpointer to interrupt block */
@@ -502,7 +513,7 @@
 	struct acpi_walk_state              *walk_state_list;       /* Head of list of walk_states for this thread */
 	union acpi_operand_object           *acquired_mutex_list;   /* List of all currently acquired mutexes */
 	u32                                 thread_id;              /* Running thread ID */
-	u16                                 current_sync_level;     /* Mutex Sync (nested acquire) level */
+	u8                                  current_sync_level;     /* Mutex Sync (nested acquire) level */
 };
 
 
diff -Nru a/include/acpi/acmacros.h b/include/acpi/acmacros.h
--- a/include/acpi/acmacros.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acmacros.h	Sat Jul 17 03:29:59 2004
@@ -53,6 +53,9 @@
 #define ACPI_LOBYTE(l)                  ((u8)(u16)(l))
 #define ACPI_HIBYTE(l)                  ((u8)((((u16)(l)) >> 8) & 0xFF))
 
+#define ACPI_SET_BIT(target,bit)        ((target) |= (bit))
+#define ACPI_CLEAR_BIT(target,bit)      ((target) &= ~(bit))
+
 
 #if ACPI_MACHINE_WIDTH == 16
 
@@ -97,7 +100,7 @@
  * printf() format helpers
  */
 
-/* Split 64-bit integer into two 32-bit values. use with %8,8_x%8.8X */
+/* Split 64-bit integer into two 32-bit values. Use with %8.8X%8.8X */
 
 #define ACPI_FORMAT_UINT64(i)           ACPI_HIDWORD(i),ACPI_LODWORD(i)
 
diff -Nru a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h
--- a/include/acpi/acnamesp.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acnamesp.h	Sat Jul 17 03:29:59 2004
@@ -278,33 +278,25 @@
 
 acpi_status
 acpi_ns_evaluate_by_handle (
-	struct acpi_namespace_node      *prefix_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object);
+	struct acpi_parameter_info      *info);
 
 acpi_status
 acpi_ns_evaluate_by_name (
 	char                            *pathname,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object);
+	struct acpi_parameter_info      *info);
 
 acpi_status
 acpi_ns_evaluate_relative (
-	struct acpi_namespace_node      *prefix_node,
 	char                            *pathname,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_object);
+	struct acpi_parameter_info      *info);
 
 acpi_status
 acpi_ns_execute_control_method (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc);
+	struct acpi_parameter_info      *info);
 
 acpi_status
 acpi_ns_get_object_value (
-	struct acpi_namespace_node      *object_node,
-	union acpi_operand_object       **return_obj_desc);
+	struct acpi_parameter_info      *info);
 
 
 /*
diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h
--- a/include/acpi/acobject.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acobject.h	Sat Jul 17 03:29:59 2004
@@ -204,13 +204,14 @@
 struct acpi_object_mutex
 {
 	ACPI_OBJECT_COMMON_HEADER
-	u16                                     sync_level;
-	u16                                     acquisition_depth;
-	struct acpi_thread_state                *owner_thread;
-	void                                    *semaphore;
+	u8                                      sync_level;         /* 0-15, specified in Mutex() call */
+	u16                                     acquisition_depth;  /* Allow multiple Acquires, same thread */
+	struct acpi_thread_state                *owner_thread;      /* Current owner of the mutex */
+	void                                    *semaphore;         /* Actual OS synchronization object */
 	union acpi_operand_object               *prev;              /* Link for list of acquired mutexes */
 	union acpi_operand_object               *next;              /* Link for list of acquired mutexes */
-	struct acpi_namespace_node              *node;              /* containing object */
+	struct acpi_namespace_node              *node;              /* Containing namespace node */
+	u8                                      original_sync_level; /* Owner's original sync level (0-15) */
 };
 
 
@@ -220,7 +221,7 @@
 
 	u8                                      space_id;
 	union acpi_operand_object               *handler;           /* Handler for region access */
-	struct acpi_namespace_node              *node;              /* containing object */
+	struct acpi_namespace_node              *node;              /* Containing namespace node */
 	union acpi_operand_object               *next;
 	u32                                     length;
 	acpi_physical_address                   address;
diff -Nru a/include/acpi/acparser.h b/include/acpi/acparser.h
--- a/include/acpi/acparser.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acparser.h	Sat Jul 17 03:29:59 2004
@@ -73,9 +73,7 @@
 
 acpi_status
 acpi_psx_execute (
-	struct acpi_namespace_node      *method_node,
-	union acpi_operand_object       **params,
-	union acpi_operand_object       **return_obj_desc);
+	struct acpi_parameter_info      *info);
 
 
 /******************************************************************************
diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
--- a/include/acpi/acpi_bus.h	Sat Jul 17 03:30:00 2004
+++ b/include/acpi/acpi_bus.h	Sat Jul 17 03:30:00 2004
@@ -157,7 +157,8 @@
 	u32			suprise_removal_ok:1;
 	u32			power_manageable:1;
 	u32			performance_manageable:1;
-	u32			reserved:21;
+	u32			wake_capable:1; /* Wakeup(_PRW) supported? */
+	u32			reserved:20;
 };
 
 
@@ -203,10 +204,8 @@
 	u32			explicit_get:1;		     /* _PSC present? */
 	u32			power_resources:1;	   /* Power resources */
 	u32			inrush_current:1;	  /* Serialize Dx->D0 */
-	u32			wake_capable:1;		 /* Wakeup supported? */
-	u32			wake_enabled:1;		/* Enabled for wakeup */
 	u32			power_removed:1;	   /* Optimize Dx->D0 */
-	u32			reserved:26;
+	u32			reserved:28;
 };
 
 struct acpi_device_power_state {
@@ -250,6 +249,25 @@
 	struct acpi_device_perf_state *states;
 };
 
+/* Wakeup Management */
+struct acpi_device_wakeup_flags {
+	u8	valid:1; /* Can successfully enable wakeup? */
+	u8	run_wake:1; /* Run-Wake GPE devices */
+};
+
+struct acpi_device_wakeup_state {
+	u8	enabled:1;
+	u8	active:1;
+};
+
+struct acpi_device_wakeup {
+	acpi_handle		gpe_device;
+	acpi_integer		gpe_number;;
+	acpi_integer		sleep_state;
+	struct acpi_handle_list	resources;
+	struct acpi_device_wakeup_state	state;
+	struct acpi_device_wakeup_flags	flags;
+};
 
 /* Device */
 
@@ -258,11 +276,13 @@
 	struct acpi_device	*parent;
 	struct list_head	children;
 	struct list_head	node;
+	struct list_head	wakeup_list;
 	struct list_head	g_list;
 	struct acpi_device_status status;
 	struct acpi_device_flags flags;
 	struct acpi_device_pnp	pnp;
 	struct acpi_device_power power;
+	struct acpi_device_wakeup wakeup;
 	struct acpi_device_perf	performance;
 	struct acpi_device_dir	dir;
 	struct acpi_device_ops	ops;
diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- a/include/acpi/acpi_drivers.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acpi_drivers.h	Sat Jul 17 03:29:59 2004
@@ -81,7 +81,8 @@
    -------------------------------------------------------------------------- */
 
 #ifdef CONFIG_ACPI_POWER
-
+int acpi_enable_wakeup_device_power (struct acpi_device *dev);
+int acpi_disable_wakeup_device_power (struct acpi_device *dev);
 int acpi_power_get_inferred_state (struct acpi_device *device);
 int acpi_power_transition (struct acpi_device *device, int state);
 #endif
diff -Nru a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
--- a/include/acpi/acpiosxf.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acpiosxf.h	Sat Jul 17 03:29:59 2004
@@ -189,13 +189,13 @@
 acpi_status
 acpi_os_install_interrupt_handler (
 	u32                             gsi,
-	OSD_HANDLER                     service_routine,
+	acpi_osd_handler                service_routine,
 	void                            *context);
 
 acpi_status
 acpi_os_remove_interrupt_handler (
-	u32                             interrupt_number,
-	OSD_HANDLER                     service_routine);
+	u32                             gsi,
+	acpi_osd_handler                service_routine);
 
 
 /*
@@ -209,7 +209,7 @@
 acpi_status
 acpi_os_queue_for_execution (
 	u32                             priority,
-	OSD_EXECUTION_CALLBACK  function,
+	acpi_osd_exec_callback          function,
 	void                            *context);
 
 void
@@ -262,25 +262,28 @@
 
 /*
  * Platform and hardware-independent PCI configuration space access
+ * Note: Can't use "Register" as a parameter, changed to "Reg" --
+ * certain compilers complain.
  */
 
 acpi_status
 acpi_os_read_pci_configuration (
 	struct acpi_pci_id              *pci_id,
-	u32                             register,
+	u32                             reg,
 	void                            *value,
 	u32                             width);
 
 acpi_status
 acpi_os_write_pci_configuration (
 	struct acpi_pci_id              *pci_id,
-	u32                             register,
+	u32                             reg,
 	acpi_integer                    value,
 	u32                             width);
 
 /*
  * Interim function needed for PCI IRQ routing
  */
+
 void
 acpi_os_derive_pci_id(
 	acpi_handle                     rhandle,
diff -Nru a/include/acpi/acpixf.h b/include/acpi/acpixf.h
--- a/include/acpi/acpixf.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acpixf.h	Sat Jul 17 03:29:59 2004
@@ -296,7 +296,7 @@
 	acpi_handle                     gpe_device,
 	u32                             gpe_number,
 	u32                             type,
-	acpi_gpe_handler                handler,
+	acpi_event_handler              address,
 	void                            *context);
 
 acpi_status
@@ -312,7 +312,7 @@
 acpi_remove_gpe_handler (
 	acpi_handle                     gpe_device,
 	u32                             gpe_number,
-	acpi_gpe_handler                handler);
+	acpi_event_handler              address);
 
 acpi_status
 acpi_enable_event (
@@ -332,6 +332,12 @@
 acpi_get_event_status (
 	u32                             event,
 	acpi_event_status               *event_status);
+
+acpi_status
+acpi_set_gpe_type (
+	acpi_handle                     gpe_device,
+	u32                             gpe_number,
+	u8                              type);
 
 acpi_status
 acpi_enable_gpe (
diff -Nru a/include/acpi/acstruct.h b/include/acpi/acstruct.h
--- a/include/acpi/acstruct.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/acstruct.h	Sat Jul 17 03:29:59 2004
@@ -69,13 +69,14 @@
 struct acpi_walk_state
 {
 	u8                                  data_type;                          /* To differentiate various internal objs MUST BE FIRST!*/\
+	u8                                  walk_type;
 	acpi_owner_id                       owner_id;                           /* Owner of objects created during the walk */
 	u8                                  last_predicate;                     /* Result of last predicate */
+	u8                                  reserved;                           /* For alignment */
 	u8                                  current_result;                     /* */
 	u8                                  next_op_info;                       /* Info about next_op */
 	u8                                  num_operands;                       /* Stack pointer for Operands[] array */
 	u8                                  return_used;
-	u8                                  walk_type;
 	u16                                 opcode;                             /* Current AML opcode */
 	u8                                  scope_depth;
 	u8                                  reserved1;
@@ -91,7 +92,8 @@
 	struct acpi_namespace_node          arguments[ACPI_METHOD_NUM_ARGS];    /* Control method arguments */
 	union acpi_operand_object           **caller_return_desc;
 	union acpi_generic_state            *control_state;                     /* List of control states (nested IFs) */
-	struct acpi_namespace_node          *deferred_node;                      /* Used when executing deferred opcodes */
+	struct acpi_namespace_node          *deferred_node;                     /* Used when executing deferred opcodes */
+	struct acpi_gpe_event_info          *gpe_event_info;                    /* Info for GPE (_Lxx/_Exx methods only */
 	struct acpi_namespace_node          local_variables[ACPI_METHOD_NUM_LOCALS];    /* Control method locals */
 	struct acpi_namespace_node          *method_call_node;                  /* Called method Node*/
 	union acpi_parse_object             *method_call_op;                    /* method_call Op if running a method */
@@ -198,6 +200,23 @@
 
 	} mid;
 };
+
+
+/* Internal method parameter list */
+
+struct acpi_parameter_info
+{
+	struct acpi_namespace_node      *node;
+	union acpi_operand_object       **parameters;
+	union acpi_operand_object       *return_object;
+	u8                              parameter_type;
+	u8                              return_object_type;
+};
+
+/* Types for parameter_type above */
+
+#define ACPI_PARAM_ARGS                 0
+#define ACPI_PARAM_GPE                  1
 
 
 #endif
diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h
--- a/include/acpi/actbl.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/actbl.h	Sat Jul 17 03:29:59 2004
@@ -288,19 +288,6 @@
 };
 
 
-/*
- * High performance timer
- */
-struct hpet_table
-{
-	ACPI_TABLE_HEADER_DEF
-	u32                             hardware_id;
-	u32                             base_address [3];
-	u8                              hpet_number;
-	u16                             clock_tick;
-	u8                              attributes;
-};
-
 #pragma pack()
 
 
@@ -343,5 +330,21 @@
 #include "actbl1.h"   /* Acpi 1.0 table definitions */
 #include "actbl2.h"   /* Acpi 2.0 table definitions */
 
+
+#pragma pack(1)
+/*
+ * High performance timer
+ */
+struct hpet_table
+{
+	ACPI_TABLE_HEADER_DEF
+	u32                             hardware_id;
+	struct acpi_generic_address     base_address;
+	u8                              hpet_number;
+	u16                             clock_tick;
+	u8                              attributes;
+};
+
+#pragma pack()
 
 #endif /* __ACTBL_H__ */
diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h
--- a/include/acpi/actypes.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/actypes.h	Sat Jul 17 03:29:59 2004
@@ -557,34 +557,56 @@
 #define ACPI_GPE_MAX                    0xFF
 #define ACPI_NUM_GPE                    256
 
+#define ACPI_GPE_ENABLE                 0
+#define ACPI_GPE_DISABLE                1
+
+
 /*
  * GPE info flags - Per GPE
- * +---------+-+-+-+
- * |Bits 8:3 |2|1|0|
- * +---------+-+-+-+
- *          | | | |
- *          | | | +- Edge or Level Triggered
- *          | | +--- Type: Wake or Runtime
- *          | +----- Enabled for wake?
- *          +--------<Reserved>
- */
-#define ACPI_GPE_XRUPT_TYPE_MASK        (u8) 1
-#define ACPI_GPE_LEVEL_TRIGGERED        (u8) 1
-#define ACPI_GPE_EDGE_TRIGGERED         (u8) 0
-
-#define ACPI_GPE_TYPE_MASK              (u8) 2
-#define ACPI_GPE_TYPE_WAKE              (u8) 2
-#define ACPI_GPE_TYPE_RUNTIME           (u8) 0       /* Default */
-
-#define ACPI_GPE_ENABLE_MASK            (u8) 4
-#define ACPI_GPE_ENABLED                (u8) 4
-#define ACPI_GPE_DISABLED               (u8) 0       /* Default */
+ * +-+-+-+---+---+-+
+ * |7|6|5|4:3|2:1|0|
+ * +-+-+-+---+---+-+
+ *  | | |  |   |  |
+ *  | | |  |   |  +--- Interrupt type: Edge or Level Triggered
+ *  | | |  |   +--- Type: Wake-only, Runtime-only, or wake/runtime
+ *  | | |  +--- Type of dispatch -- to method, handler, or none
+ *  | | +--- Enabled for runtime?
+ *  | +--- Enabled for wake?
+ *  +--- System state when GPE ocurred (running/waking)
+ */
+#define ACPI_GPE_XRUPT_TYPE_MASK        (u8) 0x01
+#define ACPI_GPE_LEVEL_TRIGGERED        (u8) 0x01
+#define ACPI_GPE_EDGE_TRIGGERED         (u8) 0x00
+
+#define ACPI_GPE_TYPE_MASK              (u8) 0x06
+#define ACPI_GPE_TYPE_WAKE_RUN          (u8) 0x06
+#define ACPI_GPE_TYPE_WAKE              (u8) 0x02
+#define ACPI_GPE_TYPE_RUNTIME           (u8) 0x04    /* Default */
+
+#define ACPI_GPE_DISPATCH_MASK          (u8) 0x18
+#define ACPI_GPE_DISPATCH_HANDLER       (u8) 0x08
+#define ACPI_GPE_DISPATCH_METHOD        (u8) 0x10
+#define ACPI_GPE_DISPATCH_NOT_USED      (u8) 0x00    /* Default */
+
+#define ACPI_GPE_RUN_ENABLE_MASK        (u8) 0x20
+#define ACPI_GPE_RUN_ENABLED            (u8) 0x20
+#define ACPI_GPE_RUN_DISABLED           (u8) 0x00    /* Default */
+
+#define ACPI_GPE_WAKE_ENABLE_MASK       (u8) 0x40
+#define ACPI_GPE_WAKE_ENABLED           (u8) 0x40
+#define ACPI_GPE_WAKE_DISABLED          (u8) 0x00    /* Default */
+
+#define ACPI_GPE_ENABLE_MASK            (u8) 0x60    /* Both run/wake */
+
+#define ACPI_GPE_SYSTEM_MASK            (u8) 0x80
+#define ACPI_GPE_SYSTEM_RUNNING         (u8) 0x80
+#define ACPI_GPE_SYSTEM_WAKING          (u8) 0x00
 
 /*
  * Flags for GPE and Lock interfaces
  */
-#define ACPI_EVENT_WAKE_ENABLE          0x2
-#define ACPI_EVENT_WAKE_DISABLE         0x2
+#define ACPI_EVENT_WAKE_ENABLE          0x2             /* acpi_gpe_enable */
+#define ACPI_EVENT_WAKE_DISABLE         0x2             /* acpi_gpe_disable */
 
 #define ACPI_NOT_ISR                    0x1
 #define ACPI_ISR                        0x0
@@ -592,9 +614,10 @@
 
 /* Notify types */
 
-#define ACPI_SYSTEM_NOTIFY              0
-#define ACPI_DEVICE_NOTIFY              1
-#define ACPI_MAX_NOTIFY_HANDLER_TYPE    1
+#define ACPI_SYSTEM_NOTIFY              0x1
+#define ACPI_DEVICE_NOTIFY              0x2
+#define ACPI_ALL_NOTIFY                 0x3
+#define ACPI_MAX_NOTIFY_HANDLER_TYPE    0x3
 
 #define ACPI_MAX_SYS_NOTIFY             0x7f
 
@@ -775,11 +798,11 @@
  */
 
 typedef u32
-(ACPI_SYSTEM_XFACE *OSD_HANDLER) (
+(ACPI_SYSTEM_XFACE *acpi_osd_handler) (
 	void                            *context);
 
 typedef void
-(ACPI_SYSTEM_XFACE *OSD_EXECUTION_CALLBACK) (
+(ACPI_SYSTEM_XFACE *acpi_osd_exec_callback) (
 	void                            *context);
 
 /*
@@ -790,10 +813,6 @@
 	void                                *context);
 
 typedef
-void (*acpi_gpe_handler) (
-	void                                *context);
-
-typedef
 void (*acpi_notify_handler) (
 	acpi_handle                         device,
 	u32                                 value,
@@ -880,6 +899,7 @@
 #define ACPI_VALID_HID                  0x0004
 #define ACPI_VALID_UID                  0x0008
 #define ACPI_VALID_CID                  0x0010
+#define ACPI_VALID_SXDS                 0x0020
 
 
 #define ACPI_COMMON_OBJ_INFO \
@@ -899,12 +919,12 @@
 {
 	ACPI_COMMON_OBJ_INFO;
 
-	u8                                  highest_dstates[4]; /* _sx_d values 0xFF indicates not valid */
 	u32                                 valid;              /* Indicates which fields below are valid */
 	u32                                 current_status;     /* _STA value */
 	acpi_integer                        address;            /* _ADR value if any */
 	struct acpi_device_id               hardware_id;        /* _HID value if any */
 	struct acpi_device_id               unique_id;          /* _UID value if any */
+	u8                                  highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
 	struct acpi_compatible_id_list      compatibility_id;   /* List of _CIDs if any */
 };
 
diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
--- a/include/acpi/platform/acenv.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/platform/acenv.h	Sat Jul 17 03:29:59 2004
@@ -152,12 +152,8 @@
 #define COMPILER_DEPENDENT_INT64   long long
 #define COMPILER_DEPENDENT_UINT64  unsigned long long
 
-
-/* Name of host operating system (returned by the _OS_ namespace object) */
-
-#define ACPI_OS_NAME         "Intel ACPI/CA Core Subsystem"
-
-/* This macro is used to tag functions as "printf-like" because
+/*
+ * This macro is used to tag functions as "printf-like" because
  * some compilers can catch printf format string problems. MSVC
  * doesn't, so this is proprocessed away.
  */
diff -Nru a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
--- a/include/acpi/platform/aclinux.h	Sat Jul 17 03:29:59 2004
+++ b/include/acpi/platform/aclinux.h	Sat Jul 17 03:29:59 2004
@@ -44,8 +44,6 @@
 #ifndef __ACLINUX_H__
 #define __ACLINUX_H__
 
-#define ACPI_OS_NAME                "Linux"
-
 #define ACPI_USE_SYSTEM_CLIBRARY
 #define ACPI_USE_DO_WHILE_0
 
diff -Nru a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
--- a/include/asm-i386/acpi.h	Sat Jul 17 03:30:00 2004
+++ b/include/asm-i386/acpi.h	Sat Jul 17 03:30:00 2004
@@ -102,6 +102,12 @@
         :"0"(n_hi), "1"(n_lo))
 
 
+/*
+ * Refer Intel ACPI _PDC support document for bit definitions
+ */
+#define ACPI_PDC_EST_CAPABILITY_SMP 	0xa
+#define ACPI_PDC_EST_CAPABILITY_MSR	0x1
+
 #ifdef CONFIG_ACPI_BOOT 
 extern int acpi_lapic;
 extern int acpi_ioapic;
@@ -177,6 +183,8 @@
 extern void acpi_reserve_bootmem(void);
 
 #endif /*CONFIG_ACPI_SLEEP*/
+
+extern u8 x86_acpiid_to_apicid[];
 
 #endif /*__KERNEL__*/
 
diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h
--- a/include/asm-i386/smp.h	Sat Jul 17 03:29:59 2004
+++ b/include/asm-i386/smp.h	Sat Jul 17 03:29:59 2004
@@ -43,6 +43,7 @@
 extern void zap_low_mappings (void);
 
 #define MAX_APICID 256
+extern u8 x86_cpu_to_apicid[];
 
 /*
  * This function is needed by all SMP systems. It must _always_ be valid
diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
--- a/include/asm-ia64/acpi.h	Sat Jul 17 03:30:00 2004
+++ b/include/asm-ia64/acpi.h	Sat Jul 17 03:30:00 2004
@@ -105,6 +105,8 @@
 extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
 #endif
 
+extern u16 ia64_acpiid_to_sapicid[];
+
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
diff -Nru a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
--- a/include/asm-x86_64/acpi.h	Sat Jul 17 03:29:59 2004
+++ b/include/asm-x86_64/acpi.h	Sat Jul 17 03:29:59 2004
@@ -163,6 +163,8 @@
 #define BROKEN_ACPI_Sx		0x0001
 #define BROKEN_INIT_AFTER_S1	0x0002
 
+extern u8 x86_acpiid_to_apicid[];
+
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/

--------------040003000608000701070207
Content-Type: application/x-sh;
 name="sleep.sh"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sleep.sh"

#!/bin/bash
if test -f /proc/acpi/wakeup; then
 if grep LID /proc/acpi/wakeup | grep -i enabled; then
modprobe -r ehci_hcd
modprobe -r e100
modprobe -r uhci_hcd
/etc/init.d/alsa stop
sync
echo -n mem > /sys/power/state

/etc/init.d/alsa start
echo 1400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
/etc/init.d/cpufreqd restart
modprobe e100
modprobe uhci_hcd
modprobe ehci_hcd
/etc/init.d/networking restart
else
 echo LID > /proc/acpi/wakeup
 modprobe -r ehci_hcd
 modprobe -r e100
 modprobe -r uhci_hcd
 /etc/init.d/alsa stop
 sync
 echo -n mem > /sys/power/state

 /etc/init.d/alsa start
 echo 1400000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
 /etc/init.d/cpufreqd restart
 modprobe e100
 /etc/init.d/networking restart
 modprobe uhci_hcd
 modprobe ehci_hcd
 fi 
fi


--------------040003000608000701070207--

--------------enigDDF9DA33E392CCF1F0890705
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFBY9ON2gfPYxqZWpsRAh18AKCA91tafiGgF8I+0R1zxEXJt2h/rACfZtMs
CvX4qd5nQIxWUlW+AMVkY8Q=
=PeBP
-----END PGP SIGNATURE-----

--------------enigDDF9DA33E392CCF1F0890705--