bk://linux-acpi.bkbits.net/to-akpm
len.brown@intel.com|ChangeSet|20050323230208|21119 len.brown

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/30 17:01:09-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# drivers/usb/core/hcd-pci.c
#   2005/03/30 17:01:04-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/30 12:04:27-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# include/linux/device.h
#   2005/03/30 12:04:21-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/30 12:04:21-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pci/pci.c
#   2005/03/30 12:04:21-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/28 22:15:43-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# kernel/power/main.c
#   2005/03/28 22:15:34-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/28 22:15:34-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/23 16:16:03-05:00 len.brown@intel.com 
#   [ACPI] gut acpi_pci_choose_state() to avoid conflict
#   with pending pm_message_t re-definition.
#   
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pci/pci-acpi.c
#   2005/03/23 16:15:52-05:00 len.brown@intel.com +3 -14
#   gut acpi_pci_choose_state()
# 
# ChangeSet
#   2005/03/19 00:46:50-08:00 akpm@bix.(none) 
#   Merge bk://linux-acpi.bkbits.net/to-akpm
#   into bix.(none):/usr/src/bk-acpi
# 
# drivers/acpi/Kconfig
#   2005/03/19 00:46:41-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/19 01:54:47-05:00 len.brown@intel.com 
#   [ACPI] fix EC access width
#   http://bugzilla.kernel.org/show_bug.cgi?id=4346
#   
#   From: David Shaohua Li and Luming Yu
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/ec.c
#   2005/03/10 21:18:26-05:00 len.brown@intel.com +14 -18
#   fix EC access width
# 
# ChangeSet
#   2005/03/19 01:12:46-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-latest-next
#   into intel.com:/home/lenb/bk/to-akpm
# 
# drivers/acpi/Kconfig
#   2005/03/19 01:12:42-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/19 01:10:05-05:00 len.brown@intel.com 
#   [ACPI] Enable EC Burst Mode
#   
#   Fixes several Embedded Controller issues, including
#   button failure and battery status AE_TIME failure.
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3851
#   
#   Based on patch by: Andi Kleen <ak@suse.de>
#   Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
#   Signed-off-by: Luming Yu <luming.yu@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/ec.c
#   2005/03/19 01:09:54-05:00 len.brown@intel.com +276 -114
#   Enable EC Burst Mode
# 
# ChangeSet
#   2005/03/19 00:16:18-05:00 len.brown@intel.com 
#   [ACPI] pci_set_power_state() now calls
#   	platform_pci_set_power_state()
#   		and ACPI can answer
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=4277
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pci/pci.h
#   2005/03/03 04:20:56-05:00 len.brown@intel.com +1 -0
#   pci_set_power_state() now calls platform_pci_set_power_state()
# 
# drivers/pci/pci.c
#   2005/03/03 04:20:56-05:00 len.brown@intel.com +9 -2
#   pci_set_power_state() now calls platform_pci_set_power_state()
# 
# drivers/pci/pci-acpi.c
#   2005/03/03 04:28:23-05:00 len.brown@intel.com +19 -0
#   pci_set_power_state() now calls platform_pci_set_power_state()
# 
# drivers/acpi/bus.c
#   2005/03/03 04:20:56-05:00 len.brown@intel.com +7 -1
#   pci_set_power_state() now calls platform_pci_set_power_state()
# 
# ChangeSet
#   2005/03/19 00:15:48-05:00 len.brown@intel.com 
#   [ACPI] PCI can now get suspend state from firmware
#   
#   pci_choose_state() can now call
#   	platform_pci_choose_state()
#   		and ACPI can answer
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=4277
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pci/pci.h
#   2005/03/19 00:15:24-05:00 len.brown@intel.com +3 -0
#   add platform_pci_choose_state()
# 
# drivers/pci/pci.c
#   2005/03/19 00:15:24-05:00 len.brown@intel.com +7 -0
#   add platform_pci_choose_state()
# 
# drivers/pci/pci-acpi.c
#   2005/03/19 00:15:24-05:00 len.brown@intel.com +46 -1
#   add platform_pci_choose_state()
# 
# ChangeSet
#   2005/03/18 18:53:36-05:00 len.brown@intel.com 
#   [ACPI] Bind ACPI and PCI devices
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=4277
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pci/pci-acpi.c
#   2005/03/18 18:53:22-05:00 len.brown@intel.com +54 -3
#   Bind PCI to ACPI
# 
# ChangeSet
#   2005/03/18 18:45:35-05:00 len.brown@intel.com 
#   [ACPI] Bind PCI devices with ACPI devices
#   
#   Implement the framework for binding physical devices
#   with ACPI devices. A physical bus like PCI bus
#   should create a 'acpi_bus_type', with:
#   
#   .find_device:
#           For device which has parent such as normal PCI devices.
#   
#   .find_bridge:
#           It's for special devices, such as PCI root bridge
#   	or IDE controller.  Such devices generally haven't a
#   	parent or ->bus. We use the special method
#   	to get an ACPI handle.
#   
#   Uses new field in struct device: firmware_data
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=4277
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/glue.c
#   2005/03/18 18:45:25-05:00 len.brown@intel.com +362 -0
# 
# include/linux/device.h
#   2005/03/18 18:45:25-05:00 len.brown@intel.com +4 -2
#   Bind PCI and ACPI devices
# 
# include/acpi/acpi_bus.h
#   2005/03/18 18:45:25-05:00 len.brown@intel.com +21 -0
#   Bind PCI and ACPI devices
# 
# drivers/acpi/ibm_acpi.c
#   2005/03/18 18:45:25-05:00 len.brown@intel.com +2 -2
#   Bind PCI and ACPI devices
# 
# drivers/acpi/glue.c
#   2005/03/18 18:45:25-05:00 len.brown@intel.com +0 -0
#   BitKeeper file /home/lenb/src/26-latest-next/drivers/acpi/glue.c
# 
# drivers/acpi/Makefile
#   2005/03/18 18:45:25-05:00 len.brown@intel.com +1 -1
#   Bind PCI and ACPI devices
# 
# ChangeSet
#   2005/03/18 18:03:45-05:00 len.brown@intel.com 
#   [ACPI] generic Hot Key support
#   
#   See Documentation/acpi-hotkey.txt
#   
#   Use cmdline "acpi_specific_hotkey" to enable
#   legacy platform specific drivers.
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3887
#   
#   Signed-off-by: Luming Yu <luming.yu@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/hotkey.c
#   2005/03/18 18:03:33-05:00 len.brown@intel.com +1018 -0
# 
# drivers/acpi/hotkey.c
#   2005/03/18 18:03:33-05:00 len.brown@intel.com +0 -0
#   BitKeeper file /home/lenb/src/26-latest-next/drivers/acpi/hotkey.c
# 
# Documentation/acpi-hotkey.txt
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +35 -0
# 
# include/acpi/acpi_drivers.h
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +5 -0
#   Generic Hot Key support
# 
# drivers/acpi/toshiba_acpi.c
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +5 -0
#   Generic Hot Key support
# 
# drivers/acpi/osl.c
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +12 -0
#   Generic Hot Key support
# 
# drivers/acpi/ibm_acpi.c
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +4 -0
#   Generic Hot Key support
# 
# drivers/acpi/asus_acpi.c
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +4 -0
#   Generic Hot Key support
# 
# drivers/acpi/Makefile
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +2 -1
#   Generic Hot Key support
# 
# drivers/acpi/Kconfig
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +9 -0
#   Generic Hot Key support
# 
# Documentation/acpi-hotkey.txt
#   2005/03/18 18:03:32-05:00 len.brown@intel.com +0 -0
#   BitKeeper file /home/lenb/src/26-latest-next/Documentation/acpi-hotkey.txt
# 
# ChangeSet
#   2005/03/18 16:43:54-05:00 len.brown@intel.com 
#   [ACPI] S3 Suspend to RAM: fix driver suspend/resume methods
#   
#   Drivers should do this:
#   
#   .suspend()
#   	pci_disable_device()
#   
#   .resume()
#   	pci_enable_device()
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3469
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/usb/core/hcd-pci.c
#   2005/03/18 16:41:51-05:00 len.brown@intel.com +1 -0
#   .suspend/.resume: pci_disable_device()/pci_enable_device()
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/03 00:34:31-05:00 len.brown@intel.com +3 -0
#   .suspend/.resume: pci_disable_device()/pci_enable_device()
# 
# drivers/net/ne2k-pci.c
#   2005/03/18 16:43:35-05:00 len.brown@intel.com +3 -0
#   .suspend/.resume: pci_disable_device()/pci_enable_device()
# 
# drivers/net/e1000/e1000_main.c
#   2005/03/03 00:33:08-05:00 len.brown@intel.com +1 -2
#   .suspend/.resume: pci_disable_device()/pci_enable_device()
# 
# drivers/net/b44.c
#   2005/03/03 00:33:59-05:00 len.brown@intel.com +3 -0
#   .suspend/.resume: pci_disable_device()/pci_enable_device()
# 
# ChangeSet
#   2005/03/18 16:30:29-05:00 len.brown@intel.com 
#   [ACPI] S3 Suspend to RAM: interrupt resume fix
#   
#   Delete PCI Interrupt Link Device .resume method --
#   it is the device driver's job to request interrupts,
#   not the Link's job to remember what the devices want.
#   
#   This addresses the issue of attempting to run
#   the ACPI interpreter too early in resume, when
#   interrupts are still disabled.
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3469
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/pci_link.c
#   2005/03/02 22:23:50-05:00 len.brown@intel.com +14 -22
#   Delete PCI Interrupt Link .resume method
# 
# ChangeSet
#   2005/03/18 16:27:13-05:00 len.brown@intel.com 
#   [ACPI] Suspend to RAM fix
#   
#   Free some RAM before entering S3 so that upon
#   resume we can be sure early allocations will succeed.
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3469
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# kernel/power/main.c
#   2005/03/02 22:23:28-05:00 len.brown@intel.com +14 -0
#   free RAM before entering S3
# 
# ChangeSet
#   2005/03/18 16:20:46-05:00 len.brown@intel.com 
#   [ACPI] ACPI poweroff fix
#   
#   Register an "acpi" system device to be notified of shutdown preparation.
#   This depends on CONFIG_PM
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=4041
#   
#   Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# kernel/power/main.c
#   2005/03/18 16:20:34-05:00 len.brown@intel.com +1 -1
#   ACPI poweroff fix
# 
# include/linux/pm.h
#   2005/03/18 16:20:34-05:00 len.brown@intel.com +1 -1
#   ACPI poweroff fix
# 
# drivers/base/sys.c
#   2005/03/18 16:20:34-05:00 len.brown@intel.com +0 -1
#   ACPI poweroff fix
# 
# drivers/acpi/sleep/poweroff.c
#   2005/03/18 16:20:34-05:00 len.brown@intel.com +73 -8
#   ACPI poweroff fix
# 
# drivers/acpi/sleep/main.c
#   2005/03/18 16:20:34-05:00 len.brown@intel.com +32 -42
#   ACPI poweroff fix
# 
# ChangeSet
#   2005/03/18 16:00:29-05:00 len.brown@intel.com 
#   [ACPI] CONFIG_ACPI now depends on CONFIG_PM
#   
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/Kconfig
#   2005/03/18 16:00:07-05:00 len.brown@intel.com +2 -1
#   CONFIG_ACPI now depends on CONFIG_PM
# 
# ChangeSet
#   2005/03/17 21:53:25-08:00 akpm@bix.(none) 
#   Merge bk://linux-acpi.bkbits.net/to-akpm
#   into bix.(none):/usr/src/bk-acpi
# 
# drivers/acpi/Kconfig
#   2005/03/17 21:53:19-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/03/17 21:53:19-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/18 00:04:06-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/26-latest-test
#   into intel.com:/home/lenb/bk/to-akpm
# 
# drivers/acpi/Kconfig
#   2005/03/18 00:04:01-05:00 len.brown@intel.com +0 -1
#   Auto merged
# 
# ChangeSet
#   2005/03/18 00:00:20-05:00 len.brown@intel.com 
#   merge
# 
# drivers/acpi/Kconfig
#   2005/03/18 00:00:12-05:00 len.brown@intel.com +1 -2
#   merge
# 
# ChangeSet
#   2005/03/17 23:47:07-05:00 len.brown@intel.com 
#   merge
# 
# drivers/acpi/Kconfig
#   2005/03/17 23:46:56-05:00 len.brown@intel.com +1 -2
#   merge
# 
# ChangeSet
#   2005/03/17 23:26:54-05:00 len.brown@intel.com 
#   [ACPI] build fix in acpi_pci_irq_disable()
#   
#   bk-acpi-acpi_pci_irq_disable-build-fix.patch
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/pci_irq.c
#   2005/03/12 04:57:08-05:00 len.brown@intel.com +2 -2
#   build fix in acpi_pci_irq_disable()
# 
# ChangeSet
#   2005/03/15 11:43:06-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/26-latest-ref
#   into intel.com:/home/lenb/src/26-latest-dev
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/03/15 11:43:00-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/13 18:10:24-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/03/13 18:10:16-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/13 14:08:50-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# drivers/acpi/Kconfig
#   2005/03/13 14:08:43-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/09 23:46:24-05:00 len.brown@intel.com 
#   [ACPI] ACPICA 20050309 from Bob Moore
#   
#   The string-to-buffer implicit conversion code has been
#   modified again after a change to the ACPI specification.
#   In order to match the behavior of the other major ACPI
#   implementation, the target buffer is no longer truncated
#   if the source string is smaller than an existing target
#   buffer. This change requires an update to the ACPI spec,
#   and should eliminate the recent AE_AML_BUFFER_LIMIT issues.
#   
#   The "implicit return" support was rewritten to a new
#   algorithm that solves the general case. Rather than
#   attempt to determine when a method is about to exit,
#   the result of every ASL operator is saved momentarily
#   until the very next ASL operator is executed. Therefore,
#   no matter how the method exits, there will always be a
#   saved implicit return value.  This feature is only enabled
#   with the acpi_gbl_enable_interpreter_slack flag which
#   Linux enables unless "acpi=strict".  This should
#   eliminate AE_AML_NO_RETURN_VALUE errors.
#   
#   Implemented implicit conversion support for the predicate
#   (operand) of the If, Else, and While operators. String and
#   Buffer arguments are automatically converted to Integers.
#   
#   Changed the string-to-integer conversion behavior to match
#   the new ACPI errata: "If no integer object exists, a new
#   integer is created. The ASCII string is interpreted as a
#   hexadecimal constant. Each string character is interpreted
#   as a hexadecimal value ('0'-'9', 'A'-'F', 'a', 'f'),
#   starting with the first character as the most significant
#   digit, and ending with the first non-hexadecimal character
#   or end-of-string."  This means that the first non-hex
#   character terminates the conversion and this is the code
#   that was changed.
#   
#   Fixed a problem where the ObjectType operator would fail
#   (fault) when used on an Index of a Package which pointed
#   to a null package element.  The operator now properly
#   returns zero (Uninitialized) in this case.
#   
#   Fixed a problem where the While operator used excessive
#   memory by not properly popping the result stack during
#   execution. There was no memory leak after execution,
#   however. (Code provided by Valery Podrezov.)
#   
#   Fixed a problem where references to control methods within
#   Package objects caused the method to be invoked, instead
#   of producing a reference object pointing to the method.
#   
#   Restructured and simplified the pswalk.c module
#   (acpi_ps_delete_parse_tree) to improve performance and reduce
#   code size. (Code provided by Alexey Starikovskiy.)
#   
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/acpi/acstruct.h
#   2005/03/09 23:41:38-05:00 len.brown@intel.com +1 -0
#   ACPICA 20050309
# 
# include/acpi/acinterp.h
#   2005/03/09 23:41:38-05:00 len.brown@intel.com +0 -1
#   ACPICA 20050309
# 
# include/acpi/acdispat.h
#   2005/03/09 23:41:38-05:00 len.brown@intel.com +10 -0
#   ACPICA 20050309
# 
# include/acpi/acconfig.h
#   2005/03/09 23:41:38-05:00 len.brown@intel.com +1 -1
#   ACPICA 20050309
# 
# drivers/acpi/utilities/utmisc.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +15 -9
#   ACPICA 20050309
# 
# drivers/acpi/utilities/utcopy.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +15 -4
#   ACPICA 20050309
# 
# drivers/acpi/parser/pswalk.c
#   2005/03/09 23:41:41-05:00 len.brown@intel.com +31 -223
#   ACPICA 20050309
# 
# drivers/acpi/parser/psparse.c
#   2005/03/09 23:41:41-05:00 len.brown@intel.com +34 -8
#   ACPICA 20050309
# 
# drivers/acpi/executer/exstorob.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +16 -11
#   ACPICA 20050309
# 
# drivers/acpi/executer/exstoren.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +2 -5
#   ACPICA 20050309
# 
# drivers/acpi/executer/exresolv.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +6 -0
#   ACPICA 20050309
# 
# drivers/acpi/executer/exmisc.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +3 -2
#   ACPICA 20050309
# 
# drivers/acpi/dispatcher/dswexec.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +46 -15
#   ACPICA 20050309
# 
# drivers/acpi/dispatcher/dsutils.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +132 -34
#   ACPICA 20050309
# 
# drivers/acpi/dispatcher/dsopcode.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +8 -0
#   ACPICA 20050309
# 
# drivers/acpi/dispatcher/dsmethod.c
#   2005/03/09 23:41:42-05:00 len.brown@intel.com +10 -1
#   ACPICA 20050309
# 
# ChangeSet
#   2005/03/09 01:38:15-05:00 len.brown@intel.com 
#   [ACPI] limit scope of various globals to static
#   
#   Signed-off-by: Adrian Bunk <bunk@stusta.de>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/linux/acpi.h
#   2005/01/26 16:09:44-05:00 len.brown@intel.com +0 -2
#   static
# 
# include/acpi/processor.h
#   2005/01/26 16:14:00-05:00 len.brown@intel.com +0 -2
#   static
# 
# include/acpi/acpi_bus.h
#   2005/01/26 16:15:37-05:00 len.brown@intel.com +0 -1
#   static
# 
# drivers/acpi/video.c
#   2005/01/26 16:35:07-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/toshiba_acpi.c
#   2005/01/26 16:23:18-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/thermal.c
#   2005/01/26 16:22:54-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/scan.c
#   2005/01/26 16:16:02-05:00 len.brown@intel.com +8 -4
#   static
# 
# drivers/acpi/processor_throttling.c
#   2005/01/26 16:14:19-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/processor_thermal.c
#   2005/01/26 16:13:47-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/processor_core.c
#   2005/01/26 16:48:14-05:00 len.brown@intel.com +3 -3
#   static
# 
# drivers/acpi/power.c
#   2005/01/26 16:11:21-05:00 len.brown@intel.com +5 -5
#   static
# 
# drivers/acpi/pci_irq.c
#   2005/01/26 16:10:10-05:00 len.brown@intel.com +2 -2
#   static
# 
# drivers/acpi/osl.c
#   2005/01/26 16:00:15-05:00 len.brown@intel.com +5 -5
#   static
# 
# drivers/acpi/ibm_acpi.c
#   2005/01/26 15:42:24-05:00 len.brown@intel.com +2 -2
#   static
# 
# drivers/acpi/fan.c
#   2005/01/26 15:40:22-05:00 len.brown@intel.com +7 -7
#   static
# 
# drivers/acpi/ec.c
#   2005/01/26 14:06:06-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/debug.c
#   2005/01/26 13:59:33-05:00 len.brown@intel.com +2 -2
#   static
# 
# drivers/acpi/container.c
#   2005/01/26 13:59:05-05:00 len.brown@intel.com +2 -2
#   static
# 
# drivers/acpi/button.c
#   2005/01/26 13:58:34-05:00 len.brown@intel.com +2 -2
#   static
# 
# drivers/acpi/battery.c
#   2005/01/26 13:58:07-05:00 len.brown@intel.com +1 -1
#   static
# 
# drivers/acpi/ac.c
#   2005/01/26 13:57:37-05:00 len.brown@intel.com +9 -9
#   static
# 
# ChangeSet
#   2005/03/09 01:31:00-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-stable-dev
#   into intel.com:/home/lenb/src/26-latest-dev
# 
# drivers/acpi/numa.c
#   2005/03/09 01:30:56-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/09 01:29:06-05:00 len.brown@intel.com 
#   [ACPI] fix acpi_numa_init() build warning
#   
#   Signed-off-by: Randy Dunlap <rdddunlap@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/numa.c
#   2005/03/09 01:09:45-05:00 len.brown@intel.com +1 -1
#   warning: non-ANSI function declaration
#   
# 
# ChangeSet
#   2005/03/09 00:32:09-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-stable-dev
#   into intel.com:/home/lenb/src/26-latest-dev
# 
# drivers/acpi/pci_irq.c
#   2005/03/09 00:32:02-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/09 00:02:51-05:00 len.brown@intel.com 
#   [ACPI] Allow 4 digits when printing PCI segments
#   to be consistent with the rest of the kernel.
#   
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/pci_root.c
#   2005/02/15 16:10:14-05:00 len.brown@intel.com +2 -2
#   Allow 4 digits when printing PCI segments
# 
# ChangeSet
#   2005/03/08 23:59:02-05:00 len.brown@intel.com 
#   [ACPI] Make PCI device -> interrupt link associations explicit,
#   
#   ACPI: PCI Interrupt 0000:00:0f.2[A] -> Link [IUSB] -> GSI 10 (level, low) -> IRQ 10
#   
#   Previously, you could sometimes infer an association based on the output
#   when an interrupt link is enabled, but when interrupt links are shared
#   among several PCI devices, you could only make the inference for the first
#   device to be enabled.
#   
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/acpi/acpi_drivers.h
#   2005/02/15 10:46:08-05:00 len.brown@intel.com +2 -1
#   Make PCI device -> interrupt link associations explicit
# 
# drivers/acpi/pci_link.c
#   2005/02/15 11:16:53-05:00 len.brown@intel.com +9 -5
#   Make PCI device -> interrupt link associations explicit
# 
# drivers/acpi/pci_irq.c
#   2005/02/15 11:37:51-05:00 len.brown@intel.com +20 -10
#   Make PCI device -> interrupt link associations explicit
# 
# ChangeSet
#   2005/03/08 23:56:24-05:00 len.brown@intel.com 
#   [ACPI] PNPACPI should ignore vendor-defined resources
#   
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pnp/pnpacpi/rsparser.c
#   2005/02/11 14:43:12-05:00 len.brown@intel.com +5 -4
#   Don't complain about vendor-defined resources, just ignore them.
#   And make warning messages a little more consistent.
# 
# ChangeSet
#   2005/03/03 23:21:29-05:00 len.brown@intel.com 
#   [ACPI] fix [ACPI_MTX_Hardware] AE_TIME warning
#   which resulted from enabling the wake-on-RTC feature
#   
#   http://bugme.osdl.org/show_bug.cgi?id=3967
#   
#   Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/events/evxface.c
#   2004/12/30 02:39:01-05:00 len.brown@intel.com +3 -1
#   fix [ACPI_MTX_Hardware] AE_TIME warnings resulting from wake-on-RTC fix
# 
# ChangeSet
#   2005/03/03 19:55:50-05:00 len.brown@intel.com 
#   [ACPI] ACPICA 20050303 from Bob Moore for AE_AML_BUFFER_LIMIT issue.
#   
#   It turns out that tightening up the interpreter to truncate buffers
#   per the ACPI spec was a bad idea -- BIOS' in the field depended
#   on old behaviour.  Instead, we'll endeavor to update the ACPI spec
#   to reflect industry practice in this area.
#   
#   http://bugme.osdl.org/show_bug.cgi?id=4263
#   
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/acpi/acconfig.h
#   2005/03/03 19:55:39-05:00 len.brown@intel.com +1 -1
#   ACPICA 20050303
# 
# drivers/acpi/executer/exstorob.c
#   2005/03/03 19:55:38-05:00 len.brown@intel.com +2 -0
#   ACPICA 20050303
# 
# ChangeSet
#   2005/03/02 20:54:36-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-stable-dev
#   into intel.com:/home/lenb/src/26-latest-dev
# 
# drivers/acpi/scan.c
#   2005/03/02 20:54:31-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/ia64/kernel/acpi.c
#   2005/03/02 20:54:31-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/02 14:13:39-05:00 len.brown@intel.com 
#   [ACPI] fix sysfs "eject" file
#   
#   This fixes a if-statement in setup_sys_fs_device_files().  It seems to
#   assume that 'struct acpi_device_flags.ejectable' indicates whether a device
#   has _EJ0 or not.  But this is not a right assumption.  It indicates whether
#   a device has _EJ0|_EJD (See acpi_bus_get_flags() function).
#   
#   setup_sys_fs_device_files() creates 'eject' file for devices that have _EJ0
#   control method under a corresponding directory in
#   /sys/firmware/acpi/namespace/ACPI/.  'eject' file is used to trigger
#   hot-removal function from userland.
#   
#   <Note that we expect this file location to change in the future.>
#   
#   Signed-off-by: Keiichiro Tokunaga <tokunaga.keiich@jp.fujitsu.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/scan.c
#   2005/02/23 04:48:12-05:00 len.brown@intel.com +9 -1
#   Import patch acpi-fix-a-if-statement-in-setup_sys_fs_device_files.patch
# 
# ChangeSet
#   2005/03/02 14:06:18-05:00 len.brown@intel.com 
#   [ACPI] fix ACPI container driver's notify handler.
#   
#   Previously, the handler tried to make a container device be offline if an
#   ACPI_NOTIFY_BUS/DEVICE_CHECK notification is performed on the device was
#   present and has its acpi_device.  But, the condition is weird.  Whenever
#   the notification is performed, there should be only the following two
#   conditions:
#   
#     1. the device is present, but does not have its acpi_device.
#     2. the device is not present, but has its acpi_device.
#   
#   #1 is a hot-addition case, which was handled properly also in previous
#   handler.  #2 is a surprising hot-removal case, which was not handled in
#   previous handler.
#   
#   Signed-off-by: Keiichiro Tokunaga <tokunaga.keiich@jp.fujitsu.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/container.c
#   2005/02/23 04:48:06-05:00 len.brown@intel.com +8 -3
#   Import patch acpi-fix-containers-notify-handler-to-handle-proper-cases-properly.patch
# 
# ChangeSet
#   2005/03/02 14:02:55-05:00 len.brown@intel.com 
#   [ACPI] fix kobject_hotplug() use by ACPI processor and container drivers
#   
#   A while ago, the drivers used their own function
#   'processor_run_sbin_hotplug() and container_run_sbin_hotplug()' to notify
#   the agent script using /sbin/hotplug mechanism.  But, they were changed to
#   use kobject_hotplug() instead and this has caused a side effect.
#   
#   The container driver was supposed to invoke a container.agent (user mode
#   agent script) using /sbin/hotplug mechanism, but after the changes, it is
#   not able to call the agent any more and kobject_hotplug() in the
#   container.c became to invoke a namespace.agent instead if exists.  So, I
#   would like to use the namespace.agent to handle container hotplug event (or
#   something else) and let the agent to call proper agent (e.g. 
#   container.agent).  But, there is an issue we need to solve.  When the
#   namespace.agent is called, a path name of associated kobject is passed as a
#   DEVPATH (e.g./sys/firmware/ acpi/namespace/ACPI/_SB/DEV0).  However, the
#   agent would not know what device is associated with the DEVPATH nor which
#   agents to call since the DEVPATH name depends on platform.  The attached
#   patch is to add .hotplug_ops member to acpi_namespace_kset structure and
#   let it to set a driver name attached to the target kobject into the envp[]
#   variable as a DRV_NAME element.  With this, the namespace.agent can call
#   proper agents (e.g.  container.agent) by refering the DRV_NAME.
#   
#   Signed-off-by: Keiichiro Tokunaga <tokunaga.keiich@jp.fujitsu.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/scan.c
#   2005/02/23 04:48:05-05:00 len.brown@intel.com +25 -0
#   Import patch fix-an-issue-in-acpi-processor-and-container-drivers-related-with-kobject_hotplug.patch
# 
# ChangeSet
#   2005/03/02 13:57:35-05:00 len.brown@intel.com 
#   [ACPI] flush TLB in init_low_mappings()
#   
#   From: Li Shaohua <shaohua.li@intel.com>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/02/23 04:48:04-05:00 len.brown@intel.com +2 -1
#   Import patch acpi-flush-tlb-when-pagetable-changed.patch
# 
# ChangeSet
#   2005/03/02 13:54:47-05:00 len.brown@intel.com 
#   [ACPI] enhance fan output in error path
#   
#   Currently, fan.c ignores errors from acpi_bus_get_power.  On compaq evo
#   notebook that leads to very confusing empty output.
#   
#   From: Pavel Machek <pavel@ucw.cz>
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/fan.c
#   2005/02/23 04:48:03-05:00 len.brown@intel.com +8 -11
#   Import patch acpi-report-errors-in-fanc.patch
# 
# ChangeSet
#   2005/03/02 13:36:53-05:00 len.brown@intel.com 
#   [ACPI] CONFIG_ACPI_NUMA build fix
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# arch/ia64/kernel/acpi.c
#   2005/02/23 04:47:50-05:00 len.brown@intel.com +1 -1
#   Import patch ia64-acpi-build-fix.patch
# 
# ChangeSet
#   2005/03/01 15:26:20-05:00 len.brown@intel.com 
#   [ACPI] ACPICA 20050228 from Bob Moore
#   
#   Fixed a problem where the result of an Index() operator
#   (an object reference) must increment the reference count
#   on the target object for the life of the object reference.
#   
#   Implemented AML Interpreter and Debugger support for
#   the new ACPI 3.0 Extended Address (IO, Memory, Space),
#   QwordSpace, DwordSpace, and WordSpace resource descriptors.
#   
#   Implemented support in the _OSI method for the ACPI 3.0
#   "Extended Address Space Descriptor" string, indicating
#   interpreter support for the descriptors above.
#   
#   Implemented header support for the new ACPI 3.0 FADT
#   flag bits.
#   
#   Implemented header support for the new ACPI 3.0 PCI Express
#   bits for the PM1 status/enable registers.
#   
#   Updated header support for the MADT processor local Apic
#   struct and MADT platform interrupt source struct for new
#   ACPI 3.0 fields.
#   
#   Implemented header support for the SRAT and SLIT ACPI
#   tables.
#   
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/acpi/platform/acenv.h
#   2005/03/01 15:20:35-05:00 len.brown@intel.com +2 -0
#   ACPICA 20050228
# 
# include/acpi/actypes.h
#   2005/03/01 15:14:22-05:00 len.brown@intel.com +18 -15
#   ACPICA 20050228
# 
# include/acpi/actbl2.h
#   2005/03/01 15:14:22-05:00 len.brown@intel.com +68 -11
#   ACPICA 20050228
# 
# include/acpi/actbl.h
#   2005/03/01 15:14:22-05:00 len.brown@intel.com +3 -1
#   ACPICA 20050228
# 
# include/acpi/aclocal.h
#   2005/03/01 15:14:23-05:00 len.brown@intel.com +4 -0
#   ACPICA 20050228
# 
# include/acpi/acdisasm.h
#   2005/03/01 15:14:23-05:00 len.brown@intel.com +5 -0
#   ACPICA 20050228
# 
# include/acpi/acconfig.h
#   2005/03/01 15:14:23-05:00 len.brown@intel.com +2 -2
#   ACPICA 20050228
# 
# drivers/acpi/utilities/utmisc.c
#   2005/03/01 15:14:26-05:00 len.brown@intel.com +12 -8
#   ACPICA 20050228
# 
# drivers/acpi/utilities/utglobal.c
#   2005/03/01 15:14:26-05:00 len.brown@intel.com +9 -1
#   ACPICA 20050228
# 
# drivers/acpi/utilities/utdelete.c
#   2005/03/01 15:14:26-05:00 len.brown@intel.com +17 -1
#   ACPICA 20050228
# 
# drivers/acpi/resources/rslist.c
#   2005/03/01 15:14:25-05:00 len.brown@intel.com +1 -0
#   ACPICA 20050228
# 
# drivers/acpi/resources/rsdump.c
#   2005/03/01 15:14:25-05:00 len.brown@intel.com +13 -10
#   ACPICA 20050228
# 
# drivers/acpi/resources/rscalc.c
#   2005/03/01 15:14:25-05:00 len.brown@intel.com +14 -0
#   ACPICA 20050228
# 
# drivers/acpi/resources/rsaddr.c
#   2005/03/01 15:14:25-05:00 len.brown@intel.com +82 -64
#   ACPICA 20050228
# 
# drivers/acpi/parser/psopcode.c
#   2005/03/01 15:14:25-05:00 len.brown@intel.com +1 -1
#   ACPICA 20050228
# 
# drivers/acpi/executer/exoparg2.c
#   2005/03/01 15:14:25-05:00 len.brown@intel.com +6 -0
#   ACPICA 20050228
# 
# ChangeSet
#   2005/02/17 01:50:15-05:00 len.brown@intel.com 
#   [ACPI] Add ACPI-based memory hot plug driver.
#   
#   The ACPI based memory hot plug driver patch supports physical hotplug
#   operations on memory. This driver fields notifications for memory add
#   and remove operations from firmware and notifies the VM of the affected
#   memory ranges. Accordingly, this driver also maintains and updates the
#   states of all the memory ranges. This driver is useful on hardware which
#   helps firmware generating ACPI events for every physical hotplug
#   operation of memory boards on the system during runtime.
#   
#   Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
#   Signed-off-by: Naveen B S <naveen.b.s@intel.com>
#   Signed-off-by: Matt Tolentino <matthew.e.tolentino@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/acpi_memhotplug.c
#   2005/01/17 08:37:54-05:00 len.brown@intel.com +542 -0
#   Import patch acpi_memhp_driver.patch
# 
# drivers/acpi/acpi_memhotplug.c
#   2005/01/17 08:37:54-05:00 len.brown@intel.com +0 -0
#   BitKeeper file /home/lenb/src/26-latest-hotplug/drivers/acpi/acpi_memhotplug.c
# 
# drivers/acpi/Makefile
#   2005/01/17 08:37:54-05:00 len.brown@intel.com +1 -0
#   Import patch acpi_memhp_driver.patch
# 
# drivers/acpi/Kconfig
#   2005/01/17 09:09:09-05:00 len.brown@intel.com +21 -0
#   Import patch acpi_memhp_driver.patch
# 
diff -Nru a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/Documentation/acpi-hotkey.txt	2005-03-30 17:02:46 -08:00
@@ -0,0 +1,35 @@
+driver/acpi/hotkey.c implement:
+1. /proc/acpi/hotkey/event_config 
+(event based hotkey or event config interface):
+a. add a  event based hotkey(event) : 
+echo "0:bus::action:method:num:num" > event_config
+
+b. delete a event based hotkey(event): 
+echo "1:::::num:num" > event_config
+
+c.  modify a event based hotkey(event):    
+echo "2:bus::action:method:num:num" > event_config
+
+2. /proc/acpi/hotkey/poll_config 
+(polling based hotkey or event config interface):
+a.add a polling based hotkey(event) : 	
+echo "0:bus:method:action:method:num" > poll_config
+this adding command will create a proc file 
+/proc/acpi/hotkey/method, which is used to get 
+result of polling.
+
+b.delete a polling based hotkey(event): 	
+echo "1:::::num" > event_config
+
+c.modify a polling based hotkey(event):    
+echo "2:bus:method:action:method:num" > poll_config
+
+3./proc/acpi/hotkey/action 
+(interface to call aml method associated with a 
+specific hotkey(event))
+echo "event_num:event_type:event_argument" > 
+	/proc/acpi/hotkey/action.
+The result of the execution of this aml method is 
+attached to /proc/acpi/hotkey/poll_method, which is dnyamically
+created.  Please use command "cat /proc/acpi/hotkey/polling_method" 
+to retrieve it.
diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
--- a/arch/i386/kernel/acpi/sleep.c	2005-03-30 17:02:46 -08:00
+++ b/arch/i386/kernel/acpi/sleep.c	2005-03-30 17:02:46 -08:00
@@ -8,7 +8,7 @@
 #include <linux/acpi.h>
 #include <linux/bootmem.h>
 #include <asm/smp.h>
-
+#include <asm/tlbflush.h>
 
 /* address in low memory of the wakeup routine. */
 unsigned long acpi_wakeup_address = 0;
@@ -27,6 +27,7 @@
 		set_pgd(pgd, *(pgd+USER_PTRS_PER_PGD));
 		pgd_ofs++, pgd++;
 	}
+	flush_tlb_all();
 }
 
 /**
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	2005-03-30 17:02:46 -08:00
+++ b/arch/ia64/kernel/acpi.c	2005-03-30 17:02:46 -08:00
@@ -771,7 +771,7 @@
 #endif /* CONFIG_ACPI_HOTPLUG_CPU */
  
 
-#ifdef CONFIG_NUMA
+#ifdef CONFIG_ACPI_NUMA
 acpi_status __init
 acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret)
 {
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/Kconfig	2005-03-30 17:02:46 -08:00
@@ -3,6 +3,7 @@
 #
 
 menu "ACPI (Advanced Configuration and Power Interface) Support"
+	depends on PM
 	depends on !X86_VISWS
 	depends on !IA64_HP_SIM
 	depends on IA64 || X86
@@ -57,7 +58,7 @@
 config ACPI_SLEEP
 	bool "Sleep States (EXPERIMENTAL)"
 	depends on X86
-	depends on EXPERIMENTAL && PM
+	depends on EXPERIMENTAL
 	default y
 	---help---
 	  This option adds support for ACPI suspend states. 
@@ -123,6 +124,15 @@
 	  Note that this is an ref. implementation only.  It may or may not work
 	  for your integrated video device.
 
+config ACPI_HOTKEY
+	tristate "Generic Hotkey"
+	depends on ACPI_INTERPRETER
+	depends on EXPERIMENTAL
+	depends on !IA64_SGI_SN
+	default m
+	help
+	ACPI generic hotkey
+
 config ACPI_FAN
 	tristate "Fan"
 	depends on !IA64_SGI_SN
@@ -331,6 +341,26 @@
 	 	This is the ACPI generic container driver which supports
 		ACPI0004, PNP0A05 and PNP0A06 devices
 
+config ACPI_HOTPLUG_MEMORY
+	tristate "Memory Hotplug"
+	depends on ACPI
+	depends on MEMORY_HOTPLUG
+	default n
+	help
+	  This driver adds supports for ACPI Memory Hotplug.  This driver
+	  provides support for fielding notifications on ACPI memory
+	  devices (PNP0C80) which represent memory ranges that may be
+	  onlined or offlined during runtime.  
+
+	  Enabling this driver assumes that your platform hardware
+	  and firmware have support for hot-plugging physical memory. If
+	  your system does not support physically adding or ripping out 
+	  memory DIMMs at some platfrom defined granularity (individually 
+	  or as a bank) at runtime, then you need not enable this driver.
+
+	  If one selects "m," this driver can be loaded using the following
+	  command: 
+		$>modprobe acpi_memhotplug 
 endif	# ACPI
 
 endmenu
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/Makefile	2005-03-30 17:02:46 -08:00
@@ -36,13 +36,14 @@
 endif
 
 obj-$(CONFIG_ACPI_BUS)		+= sleep/
-obj-$(CONFIG_ACPI_BUS)		+= bus.o
+obj-$(CONFIG_ACPI_BUS)		+= bus.o glue.o
 obj-$(CONFIG_ACPI_AC) 		+= ac.o
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_BUTTON)	+= button.o
 obj-$(CONFIG_ACPI_EC)		+= ec.o
 obj-$(CONFIG_ACPI_FAN)		+= fan.o
-obj-$(CONFIG_ACPI_VIDEO)	+= video.o
+obj-$(CONFIG_ACPI_VIDEO)	+= video.o 
+obj-$(CONFIG_ACPI_HOTKEY)	+= hotkey.o
 obj-$(CONFIG_ACPI_PCI)		+= pci_root.o pci_link.o pci_irq.o pci_bind.o
 obj-$(CONFIG_ACPI_POWER)	+= power.o
 obj-$(CONFIG_ACPI_PROCESSOR)	+= processor.o
@@ -55,3 +56,4 @@
 obj-$(CONFIG_ACPI_IBM)		+= ibm_acpi.o
 obj-$(CONFIG_ACPI_TOSHIBA)	+= toshiba_acpi.o
 obj-$(CONFIG_ACPI_BUS)		+= scan.o motherboard.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY)	+= acpi_memhotplug.o
diff -Nru a/drivers/acpi/ac.c b/drivers/acpi/ac.c
--- a/drivers/acpi/ac.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/ac.c	2005-03-30 17:02:46 -08:00
@@ -51,8 +51,8 @@
 MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
-int acpi_ac_add (struct acpi_device *device);
-int acpi_ac_remove (struct acpi_device *device, int type);
+static int acpi_ac_add (struct acpi_device *device);
+static int acpi_ac_remove (struct acpi_device *device, int type);
 static int acpi_ac_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_ac_driver = {
@@ -108,9 +108,9 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_ac_dir;
+static struct proc_dir_entry	*acpi_ac_dir;
 
-int acpi_ac_seq_show(struct seq_file *seq, void *offset)
+static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
 {
 	struct acpi_ac		*ac = (struct acpi_ac *) seq->private;
 
@@ -200,7 +200,7 @@
                                    Driver Model
    -------------------------------------------------------------------------- */
 
-void
+static void
 acpi_ac_notify (
 	acpi_handle		handle,
 	u32			event,
@@ -232,7 +232,7 @@
 }
 
 
-int
+static int
 acpi_ac_add (
 	struct acpi_device	*device)
 {
@@ -286,7 +286,7 @@
 }
 
 
-int
+static int
 acpi_ac_remove (
 	struct acpi_device	*device,
 	int			type)
@@ -315,7 +315,7 @@
 }
 
 
-int __init
+static int __init
 acpi_ac_init (void)
 {
 	int			result = 0;
@@ -337,7 +337,7 @@
 }
 
 
-void __exit
+static void __exit
 acpi_ac_exit (void)
 {
 	ACPI_FUNCTION_TRACE("acpi_ac_exit");
diff -Nru a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/acpi_memhotplug.c	2005-03-30 17:02:46 -08:00
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2004 Intel Corporation <naveen.b.s@intel.com>
+ *
+ * All rights reserved.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT.  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * ACPI based HotPlug driver that supports Memory Hotplug
+ * This driver fields notifications from firmare for memory add
+ * and remove operations and alerts the VM of the affected memory
+ * ranges.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/memory_hotplug.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define ACPI_MEMORY_DEVICE_COMPONENT		0x08000000UL
+#define ACPI_MEMORY_DEVICE_CLASS		"memory"
+#define ACPI_MEMORY_DEVICE_HID			"PNP0C80"
+#define ACPI_MEMORY_DEVICE_DRIVER_NAME		"Hotplug Mem Driver"
+#define ACPI_MEMORY_DEVICE_NAME			"Hotplug Mem Device"
+
+#define _COMPONENT		ACPI_MEMORY_DEVICE_COMPONENT
+
+ACPI_MODULE_NAME		("acpi_memory")
+MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
+MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME);
+MODULE_LICENSE("GPL");
+
+/* ACPI _STA method values */
+#define ACPI_MEMORY_STA_PRESENT		(0x00000001UL)
+#define ACPI_MEMORY_STA_ENABLED		(0x00000002UL)
+#define ACPI_MEMORY_STA_FUNCTIONAL	(0x00000008UL)
+
+/* Memory Device States */
+#define MEMORY_INVALID_STATE	0
+#define MEMORY_POWER_ON_STATE	1
+#define MEMORY_POWER_OFF_STATE	2
+
+static int acpi_memory_device_add (struct acpi_device *device);
+static int acpi_memory_device_remove (struct acpi_device *device, int type);
+
+static struct acpi_driver acpi_memory_device_driver = {
+	.name =		ACPI_MEMORY_DEVICE_DRIVER_NAME,
+	.class =	ACPI_MEMORY_DEVICE_CLASS,
+	.ids =		ACPI_MEMORY_DEVICE_HID,
+	.ops =		{
+				.add =		acpi_memory_device_add,
+				.remove =	acpi_memory_device_remove,
+			},
+};
+
+struct acpi_memory_device {
+	acpi_handle handle;
+	unsigned int state;		/* State of the memory device */
+	unsigned short cache_attribute;	/* memory cache attribute */
+	unsigned short read_write_attribute;/* memory read/write attribute */
+	u64 start_addr;	/* Memory Range start physical addr */
+	u64 end_addr;	/* Memory Range end physical addr */
+};
+
+
+static int
+acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_resource *resource = NULL;
+	struct acpi_resource_address64 address64;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources");
+
+	/* Get the range from the _CRS */
+	status = acpi_get_current_resources(mem_device->handle, &buffer);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-EINVAL);
+
+	resource = (struct acpi_resource *) buffer.pointer;
+	status = acpi_resource_to_address64(resource, &address64);
+	if (ACPI_SUCCESS(status)) {
+		if (address64.resource_type == ACPI_MEMORY_RANGE) {
+			/* Populate the structure */
+			mem_device->cache_attribute =
+				address64.attribute.memory.cache_attribute;
+			mem_device->read_write_attribute =
+			address64.attribute.memory.read_write_attribute;
+			mem_device->start_addr = address64.min_address_range;
+			mem_device->end_addr = address64.max_address_range;
+		}
+	}
+
+	acpi_os_free(buffer.pointer);
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_get_device(acpi_handle handle,
+	struct acpi_memory_device **mem_device)
+{
+	acpi_status status;
+	acpi_handle phandle;
+	struct acpi_device *device = NULL;
+	struct acpi_device *pdevice = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_get_device");
+
+	if (!acpi_bus_get_device(handle, &device) && device)
+		goto end;
+
+	status = acpi_get_parent(handle, &phandle);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error in acpi_get_parent\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	/* Get the parent device */
+	status = acpi_bus_get_device(phandle, &pdevice);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error in acpi_bus_get_device\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	/*
+	 * Now add the notified device.  This creates the acpi_device
+	 * and invokes .add function
+	 */
+	status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error in acpi_bus_add\n"));
+		return_VALUE(-EINVAL);
+	}
+
+end:
+	*mem_device = acpi_driver_data(device);
+	if (!(*mem_device)) {
+		printk(KERN_ERR "\n driver data not found" );
+		return_VALUE(-ENODEV);
+	}
+
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_check_device(struct acpi_memory_device *mem_device)
+{
+	unsigned long current_status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_check_device");
+
+	/* Get device present/absent information from the _STA */
+	if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->handle, "_STA",
+		NULL, &current_status)))
+		return_VALUE(-ENODEV);
+	/*
+	 * Check for device status. Device should be
+	 * present/enabled/functioning.
+	 */
+	if (!((current_status & ACPI_MEMORY_STA_PRESENT)
+		&& (current_status & ACPI_MEMORY_STA_ENABLED)
+		&& (current_status & ACPI_MEMORY_STA_FUNCTIONAL)))
+		return_VALUE(-ENODEV);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_enable_device(struct acpi_memory_device *mem_device)
+{
+	int result;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_enable_device");
+
+	/* Get the range from the _CRS */
+	result = acpi_memory_get_device_resources(mem_device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"\nget_device_resources failed\n"));
+		mem_device->state = MEMORY_INVALID_STATE;
+		return result;
+	}
+
+	/*
+	 * Tell the VM there is more memory here...
+	 * Note: Assume that this function returns zero on success
+	 */
+	result = add_memory(mem_device->start_addr,
+			(mem_device->end_addr - mem_device->start_addr) + 1,
+			mem_device->read_write_attribute);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"\nadd_memory failed\n"));
+		mem_device->state = MEMORY_INVALID_STATE;
+		return result;
+	}
+
+	return result;
+}
+
+static int
+acpi_memory_powerdown_device(struct acpi_memory_device *mem_device)
+{
+	acpi_status status;
+	struct acpi_object_list	arg_list;
+	union acpi_object arg;
+	unsigned long current_status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_powerdown_device");
+
+	/* Issue the _EJ0 command */
+	arg_list.count = 1;
+	arg_list.pointer = &arg;
+	arg.type = ACPI_TYPE_INTEGER;
+	arg.integer.value = 1;
+	status = acpi_evaluate_object(mem_device->handle,
+			"_EJ0", &arg_list, NULL);
+	/* Return on _EJ0 failure */
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"_EJ0 failed.\n"));
+		return_VALUE(-ENODEV);
+	}
+
+	/* Evalute _STA to check if the device is disabled */
+	status = acpi_evaluate_integer(mem_device->handle, "_STA",
+		NULL, &current_status);
+	if (ACPI_FAILURE(status))
+		return_VALUE(-ENODEV);
+
+	/* Check for device status.  Device should be disabled */
+	if (current_status & ACPI_MEMORY_STA_ENABLED)
+		return_VALUE(-EINVAL);
+
+	return_VALUE(0);
+}
+
+static int
+acpi_memory_disable_device(struct acpi_memory_device *mem_device)
+{
+	int result;
+	u64 start = mem_device->start_addr;
+	u64 len = mem_device->end_addr - start + 1;
+	unsigned long attr = mem_device->read_write_attribute;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_disable_device");
+
+	/*
+	 * Ask the VM to offline this memory range.
+	 * Note: Assume that this function returns zero on success
+	 */
+	result = remove_memory(start, len, attr);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n"));
+		return_VALUE(result);
+	}
+
+	/* Power-off and eject the device */
+	result = acpi_memory_powerdown_device(mem_device);
+	if (result) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Device Power Down failed.\n"));
+		/* Set the status of the device to invalid */
+		mem_device->state = MEMORY_INVALID_STATE;
+		return result;
+	}
+
+	mem_device->state = MEMORY_POWER_OFF_STATE;
+	return result;
+}
+
+static void
+acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
+{
+	struct acpi_memory_device *mem_device;
+	struct acpi_device *device;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_notify");
+
+	switch (event) {
+	case ACPI_NOTIFY_BUS_CHECK:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"\nReceived BUS CHECK notification for device\n"));
+		/* Fall Through */
+	case ACPI_NOTIFY_DEVICE_CHECK:
+		if (event == ACPI_NOTIFY_DEVICE_CHECK)
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"\nReceived DEVICE CHECK notification for device\n"));
+		if (acpi_memory_get_device(handle, &mem_device)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error in finding driver data\n"));
+			return_VOID;
+		}
+
+		if (!acpi_memory_check_device(mem_device)) {
+			if (acpi_memory_enable_device(mem_device))
+				ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error in acpi_memory_enable_device\n"));
+		}
+		break;
+	case ACPI_NOTIFY_EJECT_REQUEST:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"\nReceived EJECT REQUEST notification for device\n"));
+
+		if (acpi_bus_get_device(handle, &device)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Device doesn't exist\n"));
+			break;
+		}
+		mem_device = acpi_driver_data(device);
+		if (!mem_device) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+					"Driver Data is NULL\n"));
+			break;
+		}
+
+		/*
+		 * Currently disabling memory device from kernel mode
+		 * TBD: Can also be disabled from user mode scripts
+		 * TBD: Can also be disabled by Callback registration
+		 * 	with generic sysfs driver
+		 */
+		if (acpi_memory_disable_device(mem_device))
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error in acpi_memory_disable_device\n"));
+		/*
+		 * TBD: Invoke acpi_bus_remove to cleanup data structures
+		 */
+		break;
+	default:
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Unsupported event [0x%x]\n", event));
+		break;
+	}
+
+	return_VOID;
+}
+
+static int
+acpi_memory_device_add(struct acpi_device *device)
+{
+	int result;
+	struct acpi_memory_device *mem_device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_add");
+
+	if (!device)
+		return_VALUE(-EINVAL);
+
+	mem_device = kmalloc(sizeof(struct acpi_memory_device), GFP_KERNEL);
+	if (!mem_device)
+		return_VALUE(-ENOMEM);
+	memset(mem_device, 0, sizeof(struct acpi_memory_device));
+
+	mem_device->handle = device->handle;
+	sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME);
+	sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS);
+	acpi_driver_data(device) = mem_device;
+
+	/* Get the range from the _CRS */
+	result = acpi_memory_get_device_resources(mem_device);
+	if (result) {
+		kfree(mem_device);
+		return_VALUE(result);
+	}
+
+	/* Set the device state */
+	mem_device->state = MEMORY_POWER_ON_STATE;
+
+	printk(KERN_INFO "%s \n", acpi_device_name(device));
+
+	return_VALUE(result);
+}
+
+static int
+acpi_memory_device_remove (struct acpi_device *device, int type)
+{
+	struct acpi_memory_device *mem_device = NULL;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_remove");
+
+	if (!device || !acpi_driver_data(device))
+		return_VALUE(-EINVAL);
+
+	mem_device = (struct acpi_memory_device *) acpi_driver_data(device);
+	kfree(mem_device);
+
+	return_VALUE(0);
+}
+
+/*
+ * Helper function to check for memory device
+ */
+static acpi_status
+is_memory_device(acpi_handle handle)
+{
+	char *hardware_id;
+	acpi_status status;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	struct acpi_device_info *info;
+
+	ACPI_FUNCTION_TRACE("is_memory_device");
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_ERROR);
+
+	info = buffer.pointer;
+	if (!(info->valid & ACPI_VALID_HID)) {
+		acpi_os_free(buffer.pointer);
+		return_ACPI_STATUS(AE_ERROR);
+	}
+
+	hardware_id = info->hardware_id.value;
+	if ((hardware_id == NULL) ||
+		(strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
+		status = AE_ERROR;
+
+	acpi_os_free(buffer.pointer);
+	return_ACPI_STATUS(status);
+}
+
+static acpi_status
+acpi_memory_register_notify_handler (acpi_handle handle,
+	u32 level, void *ctxt, void **retv)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_register_notify_handler");
+
+	status = is_memory_device(handle);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_OK);	/* continue */
+
+	status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
+			acpi_memory_device_notify, NULL);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+			"Error installing notify handler\n"));
+		return_ACPI_STATUS(AE_OK);	/* continue */
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+static acpi_status
+acpi_memory_deregister_notify_handler (acpi_handle handle,
+			       u32 level, void *ctxt, void **retv)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_deregister_notify_handler");
+
+	status = is_memory_device(handle);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(AE_OK);	/* continue */
+
+	status = acpi_remove_notify_handler(handle,
+			ACPI_SYSTEM_NOTIFY, acpi_memory_device_notify);
+	if (ACPI_FAILURE(status)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				"Error removing notify handler\n"));
+		return_ACPI_STATUS(AE_OK);	/* continue */
+	}
+
+	return_ACPI_STATUS(status);
+}
+
+static int __init
+acpi_memory_device_init (void)
+{
+	int result;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_init");
+
+	result = acpi_bus_register_driver(&acpi_memory_device_driver);
+
+	if (result < 0)
+		return_VALUE(-ENODEV);
+
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+				ACPI_UINT32_MAX,
+				acpi_memory_register_notify_handler,
+				NULL, NULL);
+
+	if (ACPI_FAILURE (status)) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+		acpi_bus_unregister_driver(&acpi_memory_device_driver);
+		return_VALUE(-ENODEV);
+        }
+
+	return_VALUE(0);
+}
+
+static void __exit
+acpi_memory_device_exit (void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("acpi_memory_device_exit");
+
+	/*
+	 * Adding this to un-install notification handlers for all the device
+	 * handles.
+	 */
+	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+			ACPI_UINT32_MAX,
+			acpi_memory_deregister_notify_handler,
+			NULL, NULL);
+
+	if (ACPI_FAILURE (status))
+		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed\n"));
+
+	acpi_bus_unregister_driver(&acpi_memory_device_driver);
+
+	return_VOID;
+}
+
+module_init(acpi_memory_device_init);
+module_exit(acpi_memory_device_exit);
+
+
diff -Nru a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
--- a/drivers/acpi/asus_acpi.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/asus_acpi.c	2005-03-30 17:02:46 -08:00
@@ -1204,6 +1204,10 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
+	if (!acpi_specific_hotkey_enabled){
+		printk(KERN_ERR "Using generic hotkey driver\n");
+		return -ENODEV;	
+	}
 	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
 	if (!asus_proc_dir) {
 		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
diff -Nru a/drivers/acpi/battery.c b/drivers/acpi/battery.c
--- a/drivers/acpi/battery.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/battery.c	2005-03-30 17:02:46 -08:00
@@ -341,7 +341,7 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_battery_dir;
+static struct proc_dir_entry	*acpi_battery_dir;
 static int acpi_battery_read_info(struct seq_file *seq, void *offset)
 {
 	int			result = 0;
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/bus.c	2005-03-30 17:02:46 -08:00
@@ -212,6 +212,12 @@
 		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device is not power manageable\n"));
 		return_VALUE(-ENODEV);
 	}
+	/*
+	 * Get device's current power state if it's unknown
+	 * This means device power state isn't initialized or previous setting failed
+	 */
+	if (device->power.state == ACPI_STATE_UNKNOWN)
+		acpi_bus_get_power(device->handle, &device->power.state);
 	if (state == device->power.state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", state));
 		return_VALUE(0);
@@ -231,7 +237,7 @@
 	 * On transitions to a high-powered state we first apply power (via
 	 * power resources) then evalute _PSx.  Conversly for transitions to
 	 * a lower-powered state.
-	 */ 
+	 */
 	if (state < device->power.state) {
 		if (device->power.flags.power_resources) {
 			result = acpi_power_transition(device, state);
diff -Nru a/drivers/acpi/button.c b/drivers/acpi/button.c
--- a/drivers/acpi/button.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/button.c	2005-03-30 17:02:46 -08:00
@@ -275,7 +275,7 @@
                                 Driver Interface
    -------------------------------------------------------------------------- */
 
-void
+static void
 acpi_button_notify (
 	acpi_handle		handle,
 	u32			event,
@@ -302,7 +302,7 @@
 }
 
 
-acpi_status
+static acpi_status
 acpi_button_notify_fixed (
 	void			*data)
 {
diff -Nru a/drivers/acpi/container.c b/drivers/acpi/container.c
--- a/drivers/acpi/container.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/container.c	2005-03-30 17:02:46 -08:00
@@ -177,13 +177,18 @@
 		printk("Container driver received %s event\n",
 			(type == ACPI_NOTIFY_BUS_CHECK)?
 			"ACPI_NOTIFY_BUS_CHECK":"ACPI_NOTIFY_DEVICE_CHECK");
+		status = acpi_bus_get_device(handle, &device);
 		if (present) {
-			status = acpi_bus_get_device(handle, &device);
 			if (ACPI_FAILURE(status) || !device) {
 				result = container_device_add(&device, handle);
 				if (!result)
-					kobject_hotplug(&device->kobj, KOBJ_ONLINE);
-			} else {
+					kobject_hotplug(&device->kobj,
+							KOBJ_ONLINE);
+				else
+					printk("Failed to add container\n");
+			}
+		} else {
+			if (ACPI_SUCCESS(status)) {
 				/* device exist and this is a remove request */
 				kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
 			}
@@ -255,7 +260,7 @@
 }
 
 
-int __init
+static int __init
 acpi_container_init(void)
 {
 	int	result = 0;
@@ -276,7 +281,7 @@
 	return(0);
 }
 
-void __exit
+static void __exit
 acpi_container_exit(void)
 {
 	int			action = UNINSTALL_NOTIFY_HANDLER;
diff -Nru a/drivers/acpi/debug.c b/drivers/acpi/debug.c
--- a/drivers/acpi/debug.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/debug.c	2005-03-30 17:02:46 -08:00
@@ -35,7 +35,7 @@
 };
 #define ACPI_DEBUG_INIT(v)	{ .name = #v, .value = v }
 
-const struct acpi_dlayer acpi_debug_layers[] =
+static const struct acpi_dlayer acpi_debug_layers[] =
 {
 	ACPI_DEBUG_INIT(ACPI_UTILITIES),
 	ACPI_DEBUG_INIT(ACPI_HARDWARE),
@@ -53,7 +53,7 @@
 	ACPI_DEBUG_INIT(ACPI_TOOLS),
 };
 
-const struct acpi_dlevel acpi_debug_levels[] =
+static const struct acpi_dlevel acpi_debug_levels[] =
 {
 	ACPI_DEBUG_INIT(ACPI_LV_ERROR),
 	ACPI_DEBUG_INIT(ACPI_LV_WARN),
diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
--- a/drivers/acpi/dispatcher/dsmethod.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/dispatcher/dsmethod.c	2005-03-30 17:02:46 -08:00
@@ -448,7 +448,16 @@
 			 */
 			walk_state->return_desc = return_desc;
 		}
-		else {
+
+		/*
+		 * The following code is the
+		 * optional support for a so-called "implicit return". Some AML code
+		 * assumes that the last value of the method is "implicitly" returned
+		 * to the caller. Just save the last result as the return value.
+		 * NOTE: this is optional because the ASL language does not actually
+		 * support this behavior.
+		 */
+		else if (!acpi_ds_do_implicit_return (return_desc, walk_state, FALSE)) {
 			/*
 			 * Delete the return value if it will not be used by the
 			 * calling method
diff -Nru a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
--- a/drivers/acpi/dispatcher/dsopcode.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/dispatcher/dsopcode.c	2005-03-30 17:02:46 -08:00
@@ -1010,6 +1010,10 @@
 		 * has been bubbled up the tree
 		 */
 		if (op->common.value.arg) {
+			/* Since we have a real Return(), delete any implicit return */
+
+			acpi_ds_clear_implicit_return (walk_state);
+
 			/* Return statement has an immediate operand */
 
 			status = acpi_ds_create_operands (walk_state, op->common.value.arg);
@@ -1036,6 +1040,10 @@
 		}
 		else if ((walk_state->results) &&
 				 (walk_state->results->results.num_results > 0)) {
+			/* Since we have a real Return(), delete any implicit return */
+
+			acpi_ds_clear_implicit_return (walk_state);
+
 			/*
 			 * The return value has come from a previous calculation.
 			 *
diff -Nru a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
--- a/drivers/acpi/dispatcher/dsutils.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/dispatcher/dsutils.c	2005-03-30 17:02:46 -08:00
@@ -54,10 +54,120 @@
 	 ACPI_MODULE_NAME    ("dsutils")
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ds_clear_implicit_return
+ *
+ * PARAMETERS:  walk_state          - Current State
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Clear and remove a reference on an implicit return value.  Used
+ *              to delete "stale" return values (if enabled, the return value
+ *              from every operator is saved at least momentarily, in case the
+ *              parent method exits.)
+ *
+ ******************************************************************************/
+
+void
+acpi_ds_clear_implicit_return (
+	struct acpi_walk_state          *walk_state)
+{
+	ACPI_FUNCTION_NAME ("ds_clear_implicit_return");
+
+
+	/*
+	 * Slack must be enabled for this feature
+	 */
+	if (!acpi_gbl_enable_interpreter_slack) {
+		return;
+	}
+
+	if (walk_state->implicit_return_obj) {
+		/*
+		 * Delete any "stale" implicit return. However, in
+		 * complex statements, the implicit return value can be
+		 * bubbled up several levels.
+		 */
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"Removing reference on stale implicit return obj %p\n",
+			walk_state->implicit_return_obj));
+
+		acpi_ut_remove_reference (walk_state->implicit_return_obj);
+		walk_state->implicit_return_obj = NULL;
+	}
+}
+
+
 #ifndef ACPI_NO_METHOD_EXECUTION
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ds_do_implicit_return
+ *
+ * PARAMETERS:  return_desc         - The return value
+ *              walk_state          - Current State
+ *              add_reference       - True if a reference should be added to the
+ *                                    return object
+ *
+ * RETURN:      TRUE if implicit return enabled, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the optional "implicit return".  We save the result
+ *              of every ASL operator and control method invocation in case the
+ *              parent method exit.  Before storing a new return value, we
+ *              delete the previous return value.
+ *
+ ******************************************************************************/
+
+u8
+acpi_ds_do_implicit_return (
+	union acpi_operand_object       *return_desc,
+	struct acpi_walk_state          *walk_state,
+	u8                              add_reference)
+{
+	ACPI_FUNCTION_NAME ("ds_do_implicit_return");
+
+
+	/*
+	 * Slack must be enabled for this feature, and we must
+	 * have a valid return object
+	 */
+	if ((!acpi_gbl_enable_interpreter_slack) ||
+		(!return_desc)) {
+		return (FALSE);
+	}
+
+	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"Result %p will be implicitly returned; Prev=%p\n",
+			return_desc,
+			walk_state->implicit_return_obj));
+
+	/*
+	 * Delete any "stale" implicit return value first. However, in
+	 * complex statements, the implicit return value can be
+	 * bubbled up several levels, so we don't clear the value if it
+	 * is the same as the return_desc.
+	 */
+	if (walk_state->implicit_return_obj) {
+		if (walk_state->implicit_return_obj == return_desc) {
+			return (TRUE);
+		}
+		acpi_ds_clear_implicit_return (walk_state);
+	}
+
+	/* Save the implicit return value, add a reference if requested */
+
+	walk_state->implicit_return_obj = return_desc;
+	if (add_reference) {
+		acpi_ut_add_reference (return_desc);
+	}
+
+	return (TRUE);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ds_is_result_used
  *
  * PARAMETERS:  Op                  - Current Op
@@ -76,7 +186,6 @@
 {
 	const struct acpi_opcode_info   *parent_info;
 
-
 	ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
 
 
@@ -88,6 +197,19 @@
 	}
 
 	/*
+	 * We know that this operator is not a
+	 * Return() operator (would not come here.) The following code is the
+	 * optional support for a so-called "implicit return". Some AML code
+	 * assumes that the last value of the method is "implicitly" returned
+	 * to the caller. Just save the last result as the return value.
+	 * NOTE: this is optional because the ASL language does not actually
+	 * support this behavior.
+	 */
+	acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
+
+	/*
+	 * Now determine if the parent will use the result
+	 *
 	 * If there is no parent, or the parent is a scope_op, we are executing
 	 * at the method level. An executing method typically has no parent,
 	 * since each method is parsed separately.  A method invoked externally
@@ -95,29 +217,10 @@
 	 */
 	if ((!op->common.parent) ||
 		(op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
-		/*
-		 * If this is the last statement in the method, we know it is not a
-		 * Return() operator (would not come here.) The following code is the
-		 * optional support for a so-called "implicit return". Some AML code
-		 * assumes that the last value of the method is "implicitly" returned
-		 * to the caller. Just save the last result as the return value.
-		 * NOTE: this is optional because the ASL language does not actually
-		 * support this behavior.
-		 */
-		if ((acpi_gbl_enable_interpreter_slack) &&
-			(walk_state->parser_state.aml >= walk_state->parser_state.aml_end)) {
-			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
-					"Result of [%s] will be implicitly returned\n",
-					acpi_ps_get_opcode_name (op->common.aml_opcode)));
-
-			/* Use the top of the result stack as the implicit return value */
-
-			walk_state->return_desc = walk_state->results->results.obj_desc[0];
-			return_VALUE (TRUE);
-		}
-
 		/* No parent, the return value cannot possibly be used */
 
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "At Method level, result of [%s] not used\n",
+				acpi_ps_get_opcode_name (op->common.aml_opcode)));
 		return_VALUE (FALSE);
 	}
 
@@ -262,9 +365,8 @@
 	}
 
 	if (!acpi_ds_is_result_used (op, walk_state)) {
-		/*
-		 * Must pop the result stack (obj_desc should be equal to result_obj)
-		 */
+		/* Must pop the result stack (obj_desc should be equal to result_obj) */
+
 		status = acpi_ds_result_pop (&obj_desc, walk_state);
 		if (ACPI_SUCCESS (status)) {
 			acpi_ut_remove_reference (result_obj);
@@ -338,9 +440,8 @@
 	ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
 
 
-	/*
-	 * Remove a reference on each operand on the stack
-	 */
+	/* Remove a reference on each operand on the stack */
+
 	for (i = 0; i < walk_state->num_operands; i++) {
 		/*
 		 * Remove a reference to all operands, including both
@@ -407,11 +508,7 @@
 			return_ACPI_STATUS (status);
 		}
 
-		/*
-		 * All prefixes have been handled, and the name is
-		 * in name_string
-		 */
-
+		/* All prefixes have been handled, and the name is in name_string */
 
 		/*
 		 * Special handling for buffer_field declarations. This is a deferred
@@ -586,7 +683,8 @@
  *
  * FUNCTION:    acpi_ds_create_operands
  *
- * PARAMETERS:  first_arg           - First argument of a parser argument tree
+ * PARAMETERS:  walk_state          - Current state
+ *              first_arg           - First argument of a parser argument tree
  *
  * RETURN:      Status
  *
diff -Nru a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
--- a/drivers/acpi/dispatcher/dswexec.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/dispatcher/dswexec.c	2005-03-30 17:02:46 -08:00
@@ -91,6 +91,7 @@
 	union acpi_operand_object       *result_obj) {
 	acpi_status                     status = AE_OK;
 	union acpi_operand_object       *obj_desc;
+	union acpi_operand_object       *local_obj_desc = NULL;
 
 
 	ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state);
@@ -130,12 +131,17 @@
 	}
 
 	/*
-	 * Result of predicate evaluation currently must
-	 * be a number
+	 * Result of predicate evaluation must be an Integer
+	 * object. Implicitly convert the argument if necessary.
 	 */
-	if (ACPI_GET_OBJECT_TYPE (obj_desc) != ACPI_TYPE_INTEGER) {
+	status = acpi_ex_convert_to_integer (obj_desc, &local_obj_desc, 16);
+	if (ACPI_FAILURE (status)) {
+		goto cleanup;
+	}
+
+	if (ACPI_GET_OBJECT_TYPE (local_obj_desc) != ACPI_TYPE_INTEGER) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
-			"Bad predicate (not a number) obj_desc=%p State=%p Type=%X\n",
+			"Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
 			obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
 
 		status = AE_AML_OPERAND_TYPE;
@@ -144,13 +150,13 @@
 
 	/* Truncate the predicate to 32-bits if necessary */
 
-	acpi_ex_truncate_for32bit_table (obj_desc);
+	acpi_ex_truncate_for32bit_table (local_obj_desc);
 
 	/*
 	 * Save the result of the predicate evaluation on
 	 * the control stack
 	 */
-	if (obj_desc->integer.value) {
+	if (local_obj_desc->integer.value) {
 		walk_state->control_state->common.value = TRUE;
 	}
 	else {
@@ -170,12 +176,15 @@
 
 	 /* Break to debugger to display result */
 
-	ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state));
+	ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (local_obj_desc, walk_state));
 
 	/*
 	 * Delete the predicate result object (we know that
 	 * we don't need it anymore)
 	 */
+	if (local_obj_desc != obj_desc) {
+		acpi_ut_remove_reference (local_obj_desc);
+	}
 	acpi_ut_remove_reference (obj_desc);
 
 	walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
@@ -306,9 +315,10 @@
 	case AML_CLASS_EXECUTE:
 	case AML_CLASS_CREATE:
 
-		/* most operators with arguments */
-		/* Start a new result/operand state */
-
+		/*
+		 * Most operators with arguments.
+		 * Start a new result/operand state
+		 */
 		status = acpi_ds_result_stack_push (walk_state);
 		break;
 
@@ -471,20 +481,41 @@
 			/* 1 Operand, 0 external_result, 0 internal_result */
 
 			status = acpi_ds_exec_end_control_op (walk_state, op);
-			if (ACPI_FAILURE (status)) {
-				break;
-			}
 
-			status = acpi_ds_result_stack_pop (walk_state);
+			/* Make sure to properly pop the result stack */
+
+			if (ACPI_SUCCESS (status)) {
+				status = acpi_ds_result_stack_pop (walk_state);
+			}
+			else if (status == AE_CTRL_PENDING) {
+				status = acpi_ds_result_stack_pop (walk_state);
+				if (ACPI_SUCCESS (status)) {
+					status = AE_CTRL_PENDING;
+				}
+			}
 			break;
 
 
 		case AML_TYPE_METHOD_CALL:
 
+			/*
+			 * If the method is referenced from within a package
+			 * declaration, it is not a invocation of the method, just
+			 * a reference to it.
+			 */
+			if ((op->asl.parent) &&
+			   ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
+				(op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
+				ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method Reference in a Package, Op=%p\n", op));
+				op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
+				acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
+				return_ACPI_STATUS (AE_OK);
+			}
+
 			ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
 
 			/*
-			 * (AML_METHODCALL) Op->Value->Arg->Node contains
+			 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
 			 * the method Node pointer
 			 */
 			/* next_op points to the op that holds the method name */
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/ec.c	2005-03-30 17:02:46 -08:00
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/interrupt.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
@@ -49,17 +50,19 @@
 
 #define ACPI_EC_FLAG_OBF	0x01	/* Output buffer full */
 #define ACPI_EC_FLAG_IBF	0x02	/* Input buffer full */
+#define ACPI_EC_FLAG_BURST	0x10	/* burst mode */
 #define ACPI_EC_FLAG_SCI	0x20	/* EC-SCI occurred */
 
 #define ACPI_EC_EVENT_OBF	0x01	/* Output buffer full */
 #define ACPI_EC_EVENT_IBE	0x02	/* Input buffer empty */
 
-#define ACPI_EC_UDELAY		100	/* Poll @ 100us increments */
-#define ACPI_EC_UDELAY_COUNT	1000	/* Wait 10ms max. during EC ops */
+#define ACPI_EC_DELAY		50	/* Wait 50ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
 
 #define ACPI_EC_COMMAND_READ	0x80
 #define ACPI_EC_COMMAND_WRITE	0x81
+#define ACPI_EC_BURST_ENABLE	0x82
+#define ACPI_EC_BURST_DISABLE	0x83
 #define ACPI_EC_COMMAND_QUERY	0x84
 
 static int acpi_ec_add (struct acpi_device *device);
@@ -87,7 +90,11 @@
 	struct acpi_generic_address	command_addr;
 	struct acpi_generic_address	data_addr;
 	unsigned long			global_lock;
-	spinlock_t			lock;
+	unsigned int			expect_event;
+	atomic_t			leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/
+	atomic_t			pending_gpe;
+	struct semaphore		sem;
+	wait_queue_head_t		wait;
 };
 
 /* If we find an EC via the ECDT, we need to keep a ptr to its context */
@@ -100,42 +107,122 @@
                              Transaction Management
    -------------------------------------------------------------------------- */
 
-static int
-acpi_ec_wait (
-	struct acpi_ec		*ec,
-	u8			event)
+static inline u32 acpi_ec_read_status(struct acpi_ec *ec)
 {
-	u32			acpi_ec_status = 0;
-	u32			i = ACPI_EC_UDELAY_COUNT;
+	u32	status = 0;
 
-	if (!ec)
-		return -EINVAL;
+	acpi_hw_low_level_read(8, &status, &ec->status_addr);
+	return status;
+}
+
+static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event)
+{
+	int	result = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_wait");
 
-	/* Poll the EC status register waiting for the event to occur. */
+	ec->expect_event = event;
+	smp_mb();
+
+	result = wait_event_interruptible_timeout(ec->wait,
+					!ec->expect_event,
+					msecs_to_jiffies(ACPI_EC_DELAY));
+	
+	ec->expect_event = 0;
+	smp_mb();
+
+	if (result < 0){
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR," result  = %d ", result));
+		return_VALUE(result);
+	}
+
+	/*
+	 * Verify that the event in question has actually happened by
+	 * querying EC status. Do the check even if operation timed-out
+	 * to make sure that we did not miss interrupt.
+	 */
 	switch (event) {
 	case ACPI_EC_EVENT_OBF:
-		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
-			if (acpi_ec_status & ACPI_EC_FLAG_OBF)
-				return 0;
-			udelay(ACPI_EC_UDELAY);
-		} while (--i>0);
+		if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
+			return_VALUE(0);
 		break;
+
 	case ACPI_EC_EVENT_IBE:
-		do {
-			acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr);
-			if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
-				return 0;
-			udelay(ACPI_EC_UDELAY);
-		} while (--i>0);
+		if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
+			return_VALUE(0);
 		break;
-	default:
-		return -EINVAL;
 	}
 
-	return -ETIME;
+	return_VALUE(-ETIME);
+}
+
+
+
+static int
+acpi_ec_enter_burst_mode (
+	struct acpi_ec		*ec)
+{
+	u32			tmp = 0;
+	int			status = 0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_enter_burst_mode");
+
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL &&
+		!(status & ACPI_EC_FLAG_BURST)){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"entering burst mode \n"));
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
+		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+		if (status){
+			acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR," status = %d\n", status));
+			return_VALUE(-EINVAL);
+		}
+		acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+		if(tmp != 0x90 ) {/* Burst ACK byte*/
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"Ack failed \n"));
+			return_VALUE(-EINVAL);
+		}
+	} else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in burst mode \n"));
+	atomic_set(&ec->leaving_burst , 0);
+	return_VALUE(0);
 }
 
+static int
+acpi_ec_leave_burst_mode (
+	struct acpi_ec		*ec)
+{
+	int			status =0;
+
+	ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode");
+
+	atomic_set(&ec->leaving_burst , 1);
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL &&
+		(status & ACPI_EC_FLAG_BURST)){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n"));
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->command_addr);
+		status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF);
+		if (status){
+			acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n"));
+			return_VALUE(-EINVAL);
+		}
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+		status = acpi_ec_read_status(ec);
+		if (status != -EINVAL &&
+			(status & ACPI_EC_FLAG_BURST)) {
+			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->status fail\n"));
+			return_VALUE(-EINVAL);
+		}
+	}else
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"already be in Non-burst mode \n"));
+	ACPI_DEBUG_PRINT((ACPI_DB_INFO,"leaving burst mode\n"));
+
+	return_VALUE(0);
+}
 
 static int
 acpi_ec_read (
@@ -143,16 +230,15 @@
 	u8			address,
 	u32			*data)
 {
-	acpi_status		status = AE_OK;
-	int			result = 0;
-	unsigned long		flags = 0;
-	u32			glk = 0;
+	int			status = 0;
+	u32			glk;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_read");
 
 	if (!ec || !data)
 		return_VALUE(-EINVAL);
 
+retry:
 	*data = 0;
 
 	if (ec->global_lock) {
@@ -160,32 +246,50 @@
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 	}
-	
-	spin_lock_irqsave(&ec->lock, flags);
+
+	WARN_ON(in_interrupt());
+	down(&ec->sem);
+
+	if(acpi_ec_enter_burst_mode(ec))
+		goto end;
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr);
-	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	if (result)
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	if (status) {
 		goto end;
+	}
 
 	acpi_hw_low_level_write(8, address, &ec->data_addr);
-	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-	if (result)
+	status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+	if (status){
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 		goto end;
-
+	}
 
 	acpi_hw_low_level_read(8, data, &ec->data_addr);
+	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
 		*data, address));
-
+	
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	acpi_ec_leave_burst_mode(ec);
+	up(&ec->sem);
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
 
-	return_VALUE(result);
+	if(atomic_read(&ec->leaving_burst) == 2){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+		while(!atomic_read(&ec->pending_gpe)){
+			msleep(1);	
+		}
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+		goto retry;
+	}
+
+	return_VALUE(status);
 }
 
 
@@ -195,49 +299,80 @@
 	u8			address,
 	u8			data)
 {
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	unsigned long		flags = 0;
-	u32			glk = 0;
+	int			status = 0;
+	u32			glk;
+	u32			tmp;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_write");
 
 	if (!ec)
 		return_VALUE(-EINVAL);
-
+retry:
 	if (ec->global_lock) {
 		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
 		if (ACPI_FAILURE(status))
 			return_VALUE(-ENODEV);
 	}
 
-	spin_lock_irqsave(&ec->lock, flags);
+	WARN_ON(in_interrupt());
+	down(&ec->sem);
+
+	if(acpi_ec_enter_burst_mode(ec))
+		goto end;
+
+	status = acpi_ec_read_status(ec);
+	if (status != -EINVAL &&
+		!(status & ACPI_EC_FLAG_BURST)){
+		acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr);
+		status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+		if (status)
+			goto end;
+		acpi_hw_low_level_read(8, &tmp, &ec->data_addr);
+		if(tmp != 0x90 ) /* Burst ACK byte*/
+			goto end;
+	}
+	/*Now we are in burst mode*/
 
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr);
-	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	if (result)
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	if (status){
 		goto end;
+	}
 
 	acpi_hw_low_level_write(8, address, &ec->data_addr);
-	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	if (result)
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	if (status){
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 		goto end;
+	}
 
 	acpi_hw_low_level_write(8, data, &ec->data_addr);
-	result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
-	if (result)
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
+	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	if (status)
 		goto end;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n",
 		data, address));
 
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	acpi_ec_leave_burst_mode(ec);
+	up(&ec->sem);
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
 
-	return_VALUE(result);
+	if(atomic_read(&ec->leaving_burst) == 2){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+		while(!atomic_read(&ec->pending_gpe)){
+			msleep(1);	
+		}
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+		goto retry;
+	}
+
+	return_VALUE(status);
 }
 
 /*
@@ -289,16 +424,14 @@
 	struct acpi_ec		*ec,
 	u32			*data)
 {
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	unsigned long		flags = 0;
-	u32			glk = 0;
+	int			status = 0;
+	u32			glk;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_query");
 
 	if (!ec || !data)
 		return_VALUE(-EINVAL);
-
+retry:
 	*data = 0;
 
 	if (ec->global_lock) {
@@ -307,29 +440,43 @@
 			return_VALUE(-ENODEV);
 	}
 
+	down(&ec->sem);
+	if(acpi_ec_enter_burst_mode(ec))
+		goto end;
 	/*
 	 * Query the EC to find out which _Qxx method we need to evaluate.
 	 * Note that successful completion of the query causes the ACPI_EC_SCI
 	 * bit to be cleared (and thus clearing the interrupt source).
 	 */
-	spin_lock_irqsave(&ec->lock, flags);
-
 	acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr);
-	result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
-	if (result)
+	status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
+	if (status){
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 		goto end;
-	
+	}
+
 	acpi_hw_low_level_read(8, data, &ec->data_addr);
+	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
 	if (!*data)
-		result = -ENODATA;
+		status = -ENODATA;
 
 end:
-	spin_unlock_irqrestore(&ec->lock, flags);
+	acpi_ec_leave_burst_mode(ec);
+	up(&ec->sem);
 
 	if (ec->global_lock)
 		acpi_release_global_lock(glk);
 
-	return_VALUE(result);
+	if(atomic_read(&ec->leaving_burst) == 2){
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n"));
+		while(!atomic_read(&ec->pending_gpe)){
+			msleep(1);	
+		}
+		acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+		goto retry;
+	}
+
+	return_VALUE(status);
 }
 
 
@@ -347,42 +494,29 @@
 	void			*ec_cxt)
 {
 	struct acpi_ec		*ec = (struct acpi_ec *) ec_cxt;
-	u32			value = 0;
-	unsigned long		flags = 0;
+	u32			value;
+	int			result = -ENODATA;
 	static char		object_name[5] = {'_','Q','0','0','\0'};
 	const char		hex[] = {'0','1','2','3','4','5','6','7',
 				         '8','9','A','B','C','D','E','F'};
 
 	ACPI_FUNCTION_TRACE("acpi_ec_gpe_query");
 
-	if (!ec_cxt)
-		goto end;	
+	if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
+		result = acpi_ec_query(ec, &value);
 
-	spin_lock_irqsave(&ec->lock, flags);
-	acpi_hw_low_level_read(8, &value, &ec->command_addr);
-	spin_unlock_irqrestore(&ec->lock, flags);
-
-	/* TBD: Implement asynch events!
-	 * NOTE: All we care about are EC-SCI's.  Other EC events are
-	 * handled via polling (yuck!).  This is because some systems
-	 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
-	 *  a purely interrupt-driven approach (grumble, grumble).
-	 */
-	if (!(value & ACPI_EC_FLAG_SCI))
+	if (result)
 		goto end;
 
-	if (acpi_ec_query(ec, &value))
-		goto end;
-	
 	object_name[2] = hex[((value >> 4) & 0x0F)];
 	object_name[3] = hex[(value & 0x0F)];
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
 
 	acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
-
-end:
-	acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
+	atomic_dec(&ec->pending_gpe);
+end:	
+	return;
 }
 
 static u32
@@ -390,6 +524,7 @@
 	void			*data)
 {
 	acpi_status		status = AE_OK;
+	u32			value;
 	struct acpi_ec		*ec = (struct acpi_ec *) data;
 
 	if (!ec)
@@ -397,13 +532,39 @@
 
 	acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
 
-	status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
-		acpi_ec_gpe_query, ec);
+	value = acpi_ec_read_status(ec);
 
-	if (status == AE_OK)
-		return ACPI_INTERRUPT_HANDLED;
-	else
-		return ACPI_INTERRUPT_NOT_HANDLED;
+	if((value & ACPI_EC_FLAG_IBF) &&
+		!(value & ACPI_EC_FLAG_BURST) &&
+			(atomic_read(&ec->leaving_burst) == 0)) { 
+	/*
+	 * the embedded controller disables 
+	 * burst mode for any reason other 
+	 * than the burst disable command
+	 * to process critical event.
+	 */
+		atomic_set(&ec->leaving_burst , 2); /* block current pending transaction
+					and retry */
+		wake_up(&ec->wait);
+	}else {
+		if ((ec->expect_event == ACPI_EC_EVENT_OBF &&
+				(value & ACPI_EC_FLAG_OBF)) ||
+	    			(ec->expect_event == ACPI_EC_EVENT_IBE &&
+				!(value & ACPI_EC_FLAG_IBF))) {
+			ec->expect_event = 0;
+			wake_up(&ec->wait);
+			
+		}
+	}
+
+	if (value & ACPI_EC_FLAG_SCI){
+		atomic_add(1, &ec->pending_gpe) ;
+		status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
+						acpi_ec_gpe_query, ec);
+	} 
+
+	return status == AE_OK ?
+		ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
 
 /* --------------------------------------------------------------------------
@@ -421,10 +582,8 @@
 	 * The EC object is in the handler context and is needed
 	 * when calling the acpi_ec_space_handler.
 	 */
-	if(function == ACPI_REGION_DEACTIVATE) 
-		*return_context = NULL;
-	else 
-		*return_context = handler_context;
+	*return_context  = (function != ACPI_REGION_DEACTIVATE) ?
+						handler_context : NULL;
 
 	return AE_OK;
 }
@@ -441,7 +600,7 @@
 {
 	int			result = 0;
 	struct acpi_ec		*ec = NULL;
-	u32			temp = 0;
+	u64			temp = *value;
 	acpi_integer		f_v = 0;
 	int 			i = 0;
 
@@ -450,10 +609,9 @@
 	if ((address > 0xFF) || !value || !handler_context)
 		return_VALUE(AE_BAD_PARAMETER);
 
-	if(bit_width != 8) {
+	if (bit_width != 8 && acpi_strict) {
 		printk(KERN_WARNING PREFIX "acpi_ec_space_handler: bit_width should be 8\n");
-		if (acpi_strict)
-			return_VALUE(AE_BAD_PARAMETER);
+		return_VALUE(AE_BAD_PARAMETER);
 	}
 
 	ec = (struct acpi_ec *) handler_context;
@@ -461,11 +619,11 @@
 next_byte:
 	switch (function) {
 	case ACPI_READ:
-		result = acpi_ec_read(ec, (u8) address, &temp);
-		*value = (acpi_integer) temp;
+		temp = 0;
+		result = acpi_ec_read(ec, (u8) address, (u32 *)&temp);
 		break;
 	case ACPI_WRITE:
-		result = acpi_ec_write(ec, (u8) address, (u8) *value);
+		result = acpi_ec_write(ec, (u8) address, (u8) temp);
 		break;
 	default:
 		result = -EINVAL;
@@ -474,19 +632,18 @@
 	}
 
 	bit_width -= 8;
-	if(bit_width){
-
-		if(function == ACPI_READ)
-			f_v |= (acpi_integer) (*value) << 8*i;
-		if(function == ACPI_WRITE)
-			(*value) >>=8; 
+	if (bit_width) {
+		if (function == ACPI_READ)
+			f_v |= temp << 8 * i;
+		if (function == ACPI_WRITE)
+			temp >>= 8;
 		i++;
+		(u8)address ++;
 		goto next_byte;
 	}
 
-
-	if(function == ACPI_READ){
-		f_v |= (acpi_integer) (*value) << 8*i;
+	if (function == ACPI_READ) {
+		f_v |= temp << 8 * i;
 		*value = f_v;
 	}
 
@@ -505,8 +662,6 @@
 	default:
 		return_VALUE(AE_OK);
 	}
-	
-
 }
 
 
@@ -514,7 +669,7 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_ec_dir;
+static struct proc_dir_entry	*acpi_ec_dir;
 
 
 static int
@@ -555,7 +710,7 @@
 acpi_ec_add_fs (
 	struct acpi_device	*device)
 {
-	struct proc_dir_entry	*entry = NULL;
+	struct proc_dir_entry	*entry;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_add_fs");
 
@@ -606,9 +761,9 @@
 acpi_ec_add (
 	struct acpi_device	*device)
 {
-	int			result = 0;
-	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = NULL;
+	int			result;
+	acpi_status		status;
+	struct acpi_ec		*ec;
 	unsigned long		uid;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_add");
@@ -623,7 +778,10 @@
 
 	ec->handle = device->handle;
 	ec->uid = -1;
-	spin_lock_init(&ec->lock);
+ 	atomic_set(&ec->pending_gpe, 0);
+ 	atomic_set(&ec->leaving_burst , 1);
+ 	init_MUTEX(&ec->sem);
+ 	init_waitqueue_head(&ec->wait);
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 	acpi_driver_data(device) = ec;
@@ -637,7 +795,7 @@
 	if (ec_ecdt && ec_ecdt->uid == uid) {
 		acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
 			ACPI_ADR_SPACE_EC, &acpi_ec_space_handler);
-	
+
 		acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler);
 
 		kfree(ec_ecdt);
@@ -677,7 +835,7 @@
 	struct acpi_device	*device,
 	int			type)
 {
-	struct acpi_ec		*ec = NULL;
+	struct acpi_ec		*ec;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_remove");
 
@@ -732,8 +890,8 @@
 acpi_ec_start (
 	struct acpi_device	*device)
 {
-	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = NULL;
+	acpi_status		status;
+	struct acpi_ec		*ec;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_start");
 
@@ -789,8 +947,8 @@
 	struct acpi_device	*device,
 	int			type)
 {
-	acpi_status		status = AE_OK;
-	struct acpi_ec		*ec = NULL;
+	acpi_status		status;
+	struct acpi_ec		*ec;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_stop");
 
@@ -832,7 +990,6 @@
 	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit);
 	if (ACPI_FAILURE(status))
 		return status;
-	spin_lock_init(&ec_ecdt->lock);
 	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->handle = handle;
 
@@ -890,7 +1047,7 @@
 	acpi_status		status;
 	struct acpi_table_ecdt 	*ecdt_ptr;
 
-	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
+	status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
 		(struct acpi_table_header **) &ecdt_ptr);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
@@ -905,11 +1062,12 @@
 		return -ENOMEM;
 	memset(ec_ecdt, 0, sizeof(struct acpi_ec));
 
+ 	init_MUTEX(&ec_ecdt->sem);
+ 	init_waitqueue_head(&ec_ecdt->wait);
 	ec_ecdt->command_addr = ecdt_ptr->ec_control;
 	ec_ecdt->status_addr = ecdt_ptr->ec_control;
 	ec_ecdt->data_addr = ecdt_ptr->ec_data;
 	ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
-	spin_lock_init(&ec_ecdt->lock);
 	/* use the GL just to be safe */
 	ec_ecdt->global_lock = TRUE;
 	ec_ecdt->uid = ecdt_ptr->uid;
@@ -978,7 +1136,7 @@
 
 static int __init acpi_ec_init (void)
 {
-	int			result = 0;
+	int			result;
 
 	ACPI_FUNCTION_TRACE("acpi_ec_init");
 
diff -Nru a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
--- a/drivers/acpi/events/evxface.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/events/evxface.c	2005-03-30 17:02:46 -08:00
@@ -149,7 +149,9 @@
 	acpi_gbl_fixed_event_handlers[event].handler = handler;
 	acpi_gbl_fixed_event_handlers[event].context = context;
 
-	status = acpi_enable_event (event, 0);
+	status = acpi_clear_event (event);
+	if (ACPI_SUCCESS(status))
+		status = acpi_enable_event (event, 0);
 	if (ACPI_FAILURE (status)) {
 		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
 
diff -Nru a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
--- a/drivers/acpi/executer/exmisc.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/executer/exmisc.c	2005-03-30 17:02:46 -08:00
@@ -95,6 +95,7 @@
 		switch (obj_desc->reference.opcode) {
 		case AML_LOCAL_OP:
 		case AML_ARG_OP:
+		case AML_DEBUG_OP:
 
 			/* The referenced object is the pseudo-node for the local/arg */
 
@@ -103,7 +104,7 @@
 
 		default:
 
-			ACPI_REPORT_ERROR (("Unknown Reference subtype in get ref %X\n",
+			ACPI_REPORT_ERROR (("Unknown Reference opcode in get_reference %X\n",
 				obj_desc->reference.opcode));
 			return_ACPI_STATUS (AE_AML_INTERNAL);
 		}
@@ -121,7 +122,7 @@
 
 	default:
 
-		ACPI_REPORT_ERROR (("Invalid descriptor type in get ref: %X\n",
+		ACPI_REPORT_ERROR (("Invalid descriptor type in get_reference: %X\n",
 				ACPI_GET_DESCRIPTOR_TYPE (obj_desc)));
 		return_ACPI_STATUS (AE_TYPE);
 	}
diff -Nru a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
--- a/drivers/acpi/executer/exoparg2.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/executer/exoparg2.c	2005-03-30 17:02:46 -08:00
@@ -442,6 +442,12 @@
 			return_desc->reference.object    = operand[0];
 		}
 
+		/*
+		 * Add a reference to the target package/buffer/string for the life
+		 * of the index.
+		 */
+		acpi_ut_add_reference (operand[0]);
+
 		/* Complete the Index reference object */
 
 		return_desc->reference.opcode    = AML_INDEX_OP;
diff -Nru a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c
--- a/drivers/acpi/executer/exresolv.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/executer/exresolv.c	2005-03-30 17:02:46 -08:00
@@ -422,6 +422,12 @@
 			 * This could of course in turn be another reference object.
 			 */
 			obj_desc = *(obj_desc->reference.where);
+			if (!obj_desc) {
+				/* NULL package elements are allowed */
+
+				type = 0; /* Uninitialized */
+				goto exit;
+			}
 			break;
 
 
diff -Nru a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
--- a/drivers/acpi/executer/exstoren.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/executer/exstoren.c	2005-03-30 17:02:46 -08:00
@@ -206,7 +206,6 @@
 {
 	union acpi_operand_object       *actual_src_desc;
 	acpi_status                     status = AE_OK;
-	acpi_object_type                original_src_type;
 
 
 	ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
@@ -223,8 +222,7 @@
 		return_ACPI_STATUS (status);
 	}
 
-	original_src_type = ACPI_GET_OBJECT_TYPE (source_desc);
-	if (original_src_type != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+	if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
 		/*
 		 * The source type does not match the type of the destination.
 		 * Perform the "implicit conversion" of the source to the current type
@@ -275,8 +273,7 @@
 		 * Note: There is different store behavior depending on the original
 		 * source type
 		 */
-		status = acpi_ex_store_buffer_to_buffer (original_src_type, actual_src_desc,
-				 dest_desc);
+		status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
 		break;
 
 	case ACPI_TYPE_PACKAGE:
diff -Nru a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
--- a/drivers/acpi/executer/exstorob.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/executer/exstorob.c	2005-03-30 17:02:46 -08:00
@@ -66,7 +66,6 @@
 
 acpi_status
 acpi_ex_store_buffer_to_buffer (
-	acpi_object_type                original_src_type,
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *target_desc)
 {
@@ -77,9 +76,8 @@
 	ACPI_FUNCTION_TRACE_PTR ("ex_store_buffer_to_buffer", source_desc);
 
 
-	/*
-	 * We know that source_desc is a buffer by now
-	 */
+	/* We know that source_desc is a buffer by now */
+
 	buffer = (u8 *) source_desc->buffer.pointer;
 	length = source_desc->buffer.length;
 
@@ -105,7 +103,17 @@
 		ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
 		ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
 
+#ifdef ACPI_OBSOLETE_BEHAVIOR
+		/*
+		 * NOTE: ACPI versions up to 3.0 specified that the buffer must be
+		 * truncated if the string is smaller than the buffer.  However, "other"
+		 * implementations of ACPI never did this and thus became the defacto
+		 * standard. ACPi 3.0_a changes this behavior such that the buffer
+		 * is no longer truncated.
+		 */
+
 		/*
+		 * OBSOLETE BEHAVIOR:
 		 * If the original source was a string, we must truncate the buffer,
 		 * according to the ACPI spec.  Integer-to-Buffer and Buffer-to-Buffer
 		 * copy must not truncate the original buffer.
@@ -115,6 +123,7 @@
 
 			target_desc->buffer.length = length;
 		}
+#endif
 	}
 	else {
 		/* Truncate the source, copy only what will fit */
@@ -159,9 +168,8 @@
 	ACPI_FUNCTION_TRACE_PTR ("ex_store_string_to_string", source_desc);
 
 
-	/*
-	 * We know that source_desc is a string by now.
-	 */
+	/* We know that source_desc is a string by now */
+
 	buffer = (u8 *) source_desc->string.pointer;
 	length = source_desc->string.length;
 
@@ -185,9 +193,8 @@
 		 */
 		if (target_desc->string.pointer &&
 		   (!(target_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
-			/*
-			 * Only free if not a pointer into the DSDT
-			 */
+			/* Only free if not a pointer into the DSDT */
+
 			ACPI_MEM_FREE (target_desc->string.pointer);
 		}
 
diff -Nru a/drivers/acpi/fan.c b/drivers/acpi/fan.c
--- a/drivers/acpi/fan.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/fan.c	2005-03-30 17:02:46 -08:00
@@ -50,8 +50,8 @@
 MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
-int acpi_fan_add (struct acpi_device *device);
-int acpi_fan_remove (struct acpi_device *device, int type);
+static int acpi_fan_add (struct acpi_device *device);
+static int acpi_fan_remove (struct acpi_device *device, int type);
 
 static struct acpi_driver acpi_fan_driver = {
 	.name =		ACPI_FAN_DRIVER_NAME,
@@ -72,27 +72,24 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_fan_dir;
+static struct proc_dir_entry	*acpi_fan_dir;
 
 
 static int
 acpi_fan_read_state (struct seq_file *seq, void *offset)
 {
-	struct acpi_fan		*fan = (struct acpi_fan *) seq->private;
+	struct acpi_fan		*fan = seq->private;
 	int			state = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_fan_read_state");
 
-	if (!fan)
-		goto end;
-
-	if (acpi_bus_get_power(fan->handle, &state))
-		goto end;
-
-	seq_printf(seq, "status:                  %s\n",
-		!state?"on":"off");
-
-end:
+	if (fan) {
+		if (acpi_bus_get_power(fan->handle, &state))
+			seq_printf(seq, "status:                  ERROR\n");
+		else
+			seq_printf(seq, "status:                  %s\n",
+				     !state?"on":"off");
+	}
 	return_VALUE(0);
 }
 
@@ -197,7 +194,7 @@
                                  Driver Interface
    -------------------------------------------------------------------------- */
 
-int
+static int
 acpi_fan_add (
 	struct acpi_device	*device)
 {
@@ -243,7 +240,7 @@
 }
 
 
-int
+static int
 acpi_fan_remove (
 	struct acpi_device	*device,
 	int			type)
@@ -265,7 +262,7 @@
 }
 
 
-int __init
+static int __init
 acpi_fan_init (void)
 {
 	int			result = 0;
@@ -287,7 +284,7 @@
 }
 
 
-void __exit
+static void __exit
 acpi_fan_exit (void)
 {
 	ACPI_FUNCTION_TRACE("acpi_fan_exit");
diff -Nru a/drivers/acpi/glue.c b/drivers/acpi/glue.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/glue.c	2005-03-30 17:02:46 -08:00
@@ -0,0 +1,362 @@
+/*
+ * Link physical devices with ACPI devices support
+ *
+ * Copyright (c) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (c) 2005 Intel Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/rwsem.h>
+#include <linux/acpi.h>
+
+#define ACPI_GLUE_DEBUG	0
+#if ACPI_GLUE_DEBUG
+#define DBG(x...) printk(PREFIX x)
+#else
+#define DBG(x...)
+#endif
+static LIST_HEAD(bus_type_list);
+static DECLARE_RWSEM(bus_type_sem);
+
+int register_acpi_bus_type(struct acpi_bus_type *type)
+{
+	if (acpi_disabled)
+		return -ENODEV;
+	if (type && type->bus && type->find_device) {
+		down_write(&bus_type_sem);
+		list_add_tail(&type->list, &bus_type_list);
+		up_write(&bus_type_sem);
+		DBG("ACPI bus type %s registered\n", type->bus->name);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+EXPORT_SYMBOL(register_acpi_bus_type);
+
+int unregister_acpi_bus_type(struct acpi_bus_type *type)
+{
+	if (acpi_disabled)
+		return 0;
+	if (type) {
+		down_write(&bus_type_sem);
+		list_del_init(&type->list);
+		up_write(&bus_type_sem);
+		DBG("ACPI bus type %s unregistered\n", type->bus->name);
+		return 0;
+	}
+	return -ENODEV;
+}
+
+EXPORT_SYMBOL(unregister_acpi_bus_type);
+
+static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type)
+{
+	struct acpi_bus_type *tmp, *ret = NULL;
+
+	down_read(&bus_type_sem);
+	list_for_each_entry(tmp, &bus_type_list, list) {
+		if (tmp->bus == type) {
+			ret = tmp;
+			break;
+		}
+	}
+	up_read(&bus_type_sem);
+	return ret;
+}
+
+static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle)
+{
+	struct acpi_bus_type *tmp;
+	int ret = -ENODEV;
+
+	down_read(&bus_type_sem);
+	list_for_each_entry(tmp, &bus_type_list, list) {
+		if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) {
+			ret = 0;
+			break;
+		}
+	}
+	up_read(&bus_type_sem);
+	return ret;
+}
+
+/* Get PCI root bridge's handle from its segment and bus number */
+struct acpi_find_pci_root {
+	unsigned int seg;
+	unsigned int bus;
+	acpi_handle handle;
+};
+
+static acpi_status
+do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
+{
+	int *busnr = (int *)data;
+	struct acpi_resource_address64 address;
+
+	if (resource->id != ACPI_RSTYPE_ADDRESS16 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS32 &&
+	    resource->id != ACPI_RSTYPE_ADDRESS64)
+		return AE_OK;
+
+	acpi_resource_to_address64(resource, &address);
+	if ((address.address_length > 0) &&
+	    (address.resource_type == ACPI_BUS_NUMBER_RANGE))
+		*busnr = address.min_address_range;
+
+	return AE_OK;
+}
+
+static int get_root_bridge_busnr(acpi_handle handle)
+{
+	acpi_status status;
+	int bus, bbn;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL,
+				       (unsigned long *)&bbn);
+	if (status == AE_NOT_FOUND) {
+		/* Assume bus = 0 */
+		printk(KERN_INFO PREFIX
+		       "Assume root bridge [%s] bus is 0\n",
+		       (char *)buffer.pointer);
+		status = AE_OK;
+		bbn = 0;
+	}
+	if (ACPI_FAILURE(status)) {
+		bbn = -ENODEV;
+		goto exit;
+	}
+	if (bbn > 0)
+		goto exit;
+
+	/* _BBN in some systems return 0 for all root bridges */
+	bus = -1;
+	status = acpi_walk_resources(handle, METHOD_NAME__CRS,
+				     do_root_bridge_busnr_callback, &bus);
+	/* If _CRS failed, we just use _BBN */
+	if (ACPI_FAILURE(status) || (bus == -1))
+		goto exit;
+	/* We select _CRS */
+	if (bbn != bus) {
+		printk(KERN_INFO PREFIX
+		       "_BBN and _CRS returns different value for %s. Select _CRS\n",
+		       (char *)buffer.pointer);
+		bbn = bus;
+	}
+      exit:
+	acpi_os_free(buffer.pointer);
+	return bbn;
+}
+
+static acpi_status
+find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	struct acpi_find_pci_root *find = (struct acpi_find_pci_root *)context;
+	unsigned long seg, bus;
+	acpi_status status;
+	int tmp;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+
+	status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &seg);
+	if (status == AE_NOT_FOUND) {
+		/* Assume seg = 0 */
+		printk(KERN_INFO PREFIX
+		       "Assume root bridge [%s] segment is 0\n",
+		       (char *)buffer.pointer);
+		status = AE_OK;
+		seg = 0;
+	}
+	if (ACPI_FAILURE(status)) {
+		status = AE_CTRL_DEPTH;
+		goto exit;
+	}
+
+	tmp = get_root_bridge_busnr(handle);
+	if (tmp < 0) {
+		printk(KERN_ERR PREFIX
+		       "Find root bridge failed for %s\n",
+		       (char *)buffer.pointer);
+		status = AE_CTRL_DEPTH;
+		goto exit;
+	}
+	bus = tmp;
+
+	if (seg == find->seg && bus == find->bus)
+		find->handle = handle;
+	status = AE_OK;
+      exit:
+	acpi_os_free(buffer.pointer);
+	return status;
+}
+
+acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
+{
+	struct acpi_find_pci_root find = { seg, bus, NULL };
+
+	acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
+	return find.handle;
+}
+
+/* Get device's handler per its address under its parent */
+struct acpi_find_child {
+	acpi_handle handle;
+	acpi_integer address;
+};
+
+static acpi_status
+do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+	acpi_status status;
+	struct acpi_device_info *info;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_find_child *find = (struct acpi_find_child *)context;
+
+	status = acpi_get_object_info(handle, &buffer);
+	if (ACPI_SUCCESS(status)) {
+		info = buffer.pointer;
+		if (info->address == find->address)
+			find->handle = handle;
+		acpi_os_free(buffer.pointer);
+	}
+	return AE_OK;
+}
+
+acpi_handle acpi_get_child(acpi_handle parent, acpi_integer address)
+{
+	struct acpi_find_child find = { NULL, address };
+
+	if (!parent)
+		return NULL;
+	acpi_walk_namespace(ACPI_TYPE_DEVICE, parent,
+			    1, do_acpi_find_child, &find, NULL);
+	return find.handle;
+}
+
+EXPORT_SYMBOL(acpi_get_child);
+
+/* Link ACPI devices with physical devices */
+static void acpi_glue_data_handler(acpi_handle handle,
+				   u32 function, void *context)
+{
+	/* we provide an empty handler */
+}
+
+/* Note: a success call will increase reference count by one */
+struct device *acpi_get_physical_device(acpi_handle handle)
+{
+	acpi_status status;
+	struct device *dev;
+
+	status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
+	if (ACPI_SUCCESS(status))
+		return get_device(dev);
+	return NULL;
+}
+
+EXPORT_SYMBOL(acpi_get_physical_device);
+
+static int acpi_bind_one(struct device *dev, acpi_handle handle)
+{
+	acpi_status status;
+
+	if (dev->firmware_data) {
+		printk(KERN_WARNING PREFIX
+		       "Drivers changed 'firmware_data' for %s\n", dev->bus_id);
+		return -EINVAL;
+	}
+	get_device(dev);
+	status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
+	if (ACPI_FAILURE(status)) {
+		put_device(dev);
+		return -EINVAL;
+	}
+	dev->firmware_data = handle;
+
+	return 0;
+}
+
+static int acpi_unbind_one(struct device *dev)
+{
+	if (!dev->firmware_data)
+		return 0;
+	if (dev == acpi_get_physical_device(dev->firmware_data)) {
+		/* acpi_get_physical_device increase refcnt by one */
+		put_device(dev);
+		acpi_detach_data(dev->firmware_data, acpi_glue_data_handler);
+		dev->firmware_data = NULL;
+		/* acpi_bind_one increase refcnt by one */
+		put_device(dev);
+	} else {
+		printk(KERN_ERR PREFIX
+		       "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id);
+	}
+	return 0;
+}
+
+static int acpi_platform_notify(struct device *dev)
+{
+	struct acpi_bus_type *type;
+	acpi_handle handle;
+	int ret = -EINVAL;
+
+	if (!dev->bus || !dev->parent) {
+		/* bridge devices genernally haven't bus or parent */
+		ret = acpi_find_bridge_device(dev, &handle);
+		goto end;
+	}
+	type = acpi_get_bus_type(dev->bus);
+	if (!type) {
+		printk(KERN_INFO PREFIX "No ACPI bus support for %s\n",
+		       dev->bus_id);
+		ret = -EINVAL;
+		goto end;
+	}
+	if ((ret = type->find_device(dev, &handle)) != 0)
+		printk(KERN_INFO PREFIX "Can't get handler for %s\n",
+		       dev->bus_id);
+      end:
+	if (!ret)
+		acpi_bind_one(dev, handle);
+
+#if ACPI_GLUE_DEBUG
+	if (!ret) {
+		struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+
+		acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer);
+		DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer);
+		acpi_os_free(buffer.pointer);
+	} else
+		DBG("Device %s -> No ACPI support\n", dev->bus_id);
+#endif
+
+	return ret;
+}
+
+static int acpi_platform_notify_remove(struct device *dev)
+{
+	acpi_unbind_one(dev);
+	return 0;
+}
+
+static int __init init_acpi_device_notify(void)
+{
+	if (acpi_disabled)
+		return 0;
+	if (platform_notify || platform_notify_remove) {
+		printk(KERN_ERR PREFIX "Can't use platform_notify\n");
+		return 0;
+	}
+	platform_notify = acpi_platform_notify;
+	platform_notify_remove = acpi_platform_notify_remove;
+	return 0;
+}
+
+arch_initcall(init_acpi_device_notify);
diff -Nru a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/hotkey.c	2005-03-30 17:02:46 -08:00
@@ -0,0 +1,1018 @@
+/* 
+ *  hotkey.c - ACPI Hotkey Driver ($Revision:$)
+ *
+ *  Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  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/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/sched.h>
+#include <linux/kmod.h>
+#include <linux/seq_file.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define HOTKEY_ACPI_VERSION "0.1"
+
+#define HOTKEY_PROC "hotkey"
+#define HOTKEY_EV_CONFIG    "event_config"
+#define HOTKEY_PL_CONFIG    "poll_config"
+#define HOTKEY_ACTION   "action"
+#define HOTKEY_INFO "info"
+
+#define ACPI_HOTK_NAME          "Generic Hotkey Driver"
+#define ACPI_HOTK_CLASS         "Hotkey"
+#define ACPI_HOTK_DEVICE_NAME   "Hotkey"
+#define ACPI_HOTK_HID           "Unknown?"
+#define ACPI_HOTKEY_COMPONENT   0x20000000
+
+#define ACPI_HOTKEY_EVENT   0x1
+#define ACPI_HOTKEY_POLLING 0x2
+#define ACPI_UNDEFINED_EVENT    0xf
+
+#define MAX_CONFIG_RECORD_LEN   80
+#define MAX_NAME_PATH_LEN   80
+#define MAX_CALL_PARM       80
+
+#define IS_EVENT(e)       0xff	/* ((e) & 0x40000000)  */
+#define IS_POLL(e)      0xff	/* (~((e) & 0x40000000))  */
+
+#define _COMPONENT              ACPI_HOTKEY_COMPONENT
+ACPI_MODULE_NAME("acpi_hotkey")
+
+    MODULE_AUTHOR("luming.yu@intel.com");
+MODULE_DESCRIPTION(ACPI_HOTK_NAME);
+MODULE_LICENSE("GPL");
+
+/*  standardized internal hotkey number/event  */
+enum {
+	/* Video Extension event */
+	HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
+	HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
+	HK_EVENT_CYCLE_DISPLAY_OUTPUT,
+	HK_EVENT_NEXT_DISPLAY_OUTPUT,
+	HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
+	HK_EVENT_CYCLE_BRIGHTNESS,
+	HK_EVENT_INCREASE_BRIGHTNESS,
+	HK_EVENT_DECREASE_BRIGHTNESS,
+	HK_EVENT_ZERO_BRIGHTNESS,
+	HK_EVENT_DISPLAY_DEVICE_OFF,
+
+	/* Snd Card event */
+	HK_EVENT_VOLUME_MUTE,
+	HK_EVENT_VOLUME_INCLREASE,
+	HK_EVENT_VOLUME_DECREASE,
+
+	/* running state control */
+	HK_EVENT_ENTERRING_S3,
+	HK_EVENT_ENTERRING_S4,
+	HK_EVENT_ENTERRING_S5,
+};
+
+/*  procdir we use */
+static struct proc_dir_entry *hotkey_proc_dir;
+static struct proc_dir_entry *hotkey_config;
+static struct proc_dir_entry *hotkey_poll_config;
+static struct proc_dir_entry *hotkey_action;
+static struct proc_dir_entry *hotkey_info;
+
+/* linkage for all type of hotkey */
+struct acpi_hotkey_link {
+	struct list_head entries;
+	int hotkey_type;	/* event or polling based hotkey  */
+	int hotkey_standard_num;	/* standardized hotkey(event) number */
+};
+
+/* event based hotkey */
+struct acpi_event_hotkey {
+	struct acpi_hotkey_link hotkey_link;
+	int flag;
+	acpi_handle bus_handle;	/* bus to install notify handler */
+	int external_hotkey_num;	/* external hotkey/event number */
+	acpi_handle action_handle;	/* acpi handle attached aml action method */
+	char *action_method;	/* action method */
+};
+
+/* 
+ * There are two ways to poll status
+ * 1. directy call read_xxx method, without any arguments passed in
+ * 2. call write_xxx method, with arguments passed in, you need
+ * the result is saved in acpi_polling_hotkey.poll_result.
+ * anthoer read command through polling interface.
+ *
+ */
+
+/* polling based hotkey */
+struct acpi_polling_hotkey {
+	struct acpi_hotkey_link hotkey_link;
+	int flag;
+	acpi_handle poll_handle;	/* acpi handle attached polling method */
+	char *poll_method;	/* poll method */
+	acpi_handle action_handle;	/* acpi handle attached action method */
+	char *action_method;	/* action method */
+	void *poll_result;	/* polling_result */
+	struct proc_dir_entry *proc;
+};
+
+/* hotkey object union */
+union acpi_hotkey {
+	struct list_head entries;
+	struct acpi_hotkey_link link;
+	struct acpi_event_hotkey event_hotkey;
+	struct acpi_polling_hotkey poll_hotkey;
+};
+
+/* hotkey object list */
+struct acpi_hotkey_list {
+	struct list_head *entries;
+	int count;
+};
+
+static int auto_hotkey_add(struct acpi_device *device);
+static int auto_hotkey_remove(struct acpi_device *device, int type);
+
+static struct acpi_driver hotkey_driver = {
+	.name = ACPI_HOTK_NAME,
+	.class = ACPI_HOTK_CLASS,
+	.ids = ACPI_HOTK_HID,
+	.ops = {
+		.add = auto_hotkey_add,
+		.remove = auto_hotkey_remove,
+		},
+};
+
+static int hotkey_open_config(struct inode *inode, struct file *file);
+static ssize_t hotkey_write_config(struct file *file,
+				   const char __user * buffer,
+				   size_t count, loff_t * data);
+static ssize_t hotkey_write_poll_config(struct file *file,
+					const char __user * buffer,
+					size_t count, loff_t * data);
+static int hotkey_info_open_fs(struct inode *inode, struct file *file);
+static int hotkey_action_open_fs(struct inode *inode, struct file *file);
+static ssize_t hotkey_execute_aml_method(struct file *file,
+					 const char __user * buffer,
+					 size_t count, loff_t * data);
+static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
+static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
+
+/* event based config */
+static struct file_operations hotkey_config_fops = {
+	.open = hotkey_open_config,
+	.read = seq_read,
+	.write = hotkey_write_config,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* polling based config */
+static struct file_operations hotkey_poll_config_fops = {
+	.open = hotkey_open_config,
+	.read = seq_read,
+	.write = hotkey_write_poll_config,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* hotkey driver info */
+static struct file_operations hotkey_info_fops = {
+	.open = hotkey_info_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* action */
+static struct file_operations hotkey_action_fops = {
+	.open = hotkey_action_open_fs,
+	.read = seq_read,
+	.write = hotkey_execute_aml_method,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+/* polling results */
+static struct file_operations hotkey_polling_fops = {
+	.open = hotkey_polling_open_fs,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+struct acpi_hotkey_list global_hotkey_list;	/* link all ev or pl hotkey  */
+struct list_head hotkey_entries;	/* head of the list of hotkey_list */
+
+static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
+{
+	ACPI_FUNCTION_TRACE("hotkey_info_seq_show");
+
+	seq_printf(seq, "Hotkey generic driver ver: %s", HOTKEY_ACPI_VERSION);
+
+	return_VALUE(0);
+}
+
+static int hotkey_info_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
+}
+
+static char *format_result(union acpi_object *object)
+{
+	char *buf = (char *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+
+	memset(buf, 0, sizeof(union acpi_object));
+
+	/* Now, just support integer type */
+	if (object->type == ACPI_TYPE_INTEGER)
+		sprintf(buf, "%d", (u32) object->integer.value);
+
+	return buf;
+}
+
+static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_polling_hotkey *poll_hotkey =
+	    (struct acpi_polling_hotkey *)seq->private;
+
+	ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");
+
+	if (poll_hotkey->poll_result)
+		seq_printf(seq, "%s", format_result(poll_hotkey->poll_result));
+
+	return_VALUE(0);
+}
+
+static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
+}
+
+static int hotkey_action_open_fs(struct inode *inode, struct file *file)
+{
+	return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
+}
+
+/* Mapping external hotkey number to standardized hotkey event num */
+static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
+{
+	struct list_head *entries, *next;
+	int val = 0;
+
+	ACPI_FUNCTION_TRACE("hotkey_get_internal_event");
+
+	list_for_each_safe(entries, next, list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
+		    && key->event_hotkey.external_hotkey_num == event)
+			val = key->link.hotkey_standard_num;
+		else
+			val = -1;
+	}
+
+	return_VALUE(val);
+}
+
+static void
+acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
+{
+	struct acpi_device *device = NULL;
+	u32 internal_event;
+
+	ACPI_FUNCTION_TRACE("acpi_hotkey_notify_handler");
+
+	if (acpi_bus_get_device(handle, &device))
+		return_VOID;
+
+	internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
+	acpi_bus_generate_event(device, event, 0);
+
+	return_VOID;
+}
+
+/* Need to invent automatically hotkey add method */
+static int auto_hotkey_add(struct acpi_device *device)
+{
+	/* Implement me */
+	return 0;
+}
+
+/* Need to invent automatically hotkey remove method */
+static int auto_hotkey_remove(struct acpi_device *device, int type)
+{
+	/* Implement me */
+	return 0;
+}
+
+/* Create a proc file for each polling method */
+static int create_polling_proc(union acpi_hotkey *device)
+{
+	struct proc_dir_entry *proc;
+
+	ACPI_FUNCTION_TRACE("create_polling_proc");
+	mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
+
+	proc = create_proc_entry(device->poll_hotkey.action_method,
+				 mode, hotkey_proc_dir);
+
+	if (!proc) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  device->poll_hotkey.poll_method));
+		return_VALUE(-ENODEV);
+	} else {
+		proc->proc_fops = &hotkey_polling_fops;
+		proc->owner = THIS_MODULE;
+		proc->data = device;
+		proc->uid = 0;
+		proc->gid = 0;
+		device->poll_hotkey.proc = proc;
+	}
+	return_VALUE(0);
+}
+
+static int is_valid_acpi_path(const char *pathname)
+{
+	acpi_handle handle;
+	acpi_status status;
+	ACPI_FUNCTION_TRACE("is_valid_acpi_path");
+
+	status = acpi_get_handle(NULL, (char *)pathname, &handle);
+	return_VALUE(!ACPI_FAILURE(status));
+}
+
+static int is_valid_hotkey(union acpi_hotkey *device)
+{
+	ACPI_FUNCTION_TRACE("is_valid_hotkey");
+	/* Implement valid check */
+	return_VALUE(1);
+}
+
+static int hotkey_add(union acpi_hotkey *device)
+{
+	int status = 0;
+	struct acpi_device *dev = NULL;
+
+	ACPI_FUNCTION_TRACE("hotkey_add");
+
+	if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+		status =
+		    acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
+		if (status)
+			return_VALUE(status);
+
+		status = acpi_install_notify_handler(dev->handle,
+						     ACPI_SYSTEM_NOTIFY,
+						     acpi_hotkey_notify_handler,
+						     device);
+	} else			/* Add polling hotkey */
+		create_polling_proc(device);
+
+	global_hotkey_list.count++;
+
+	list_add_tail(&device->link.entries, global_hotkey_list.entries);
+
+	return_VALUE(status);
+}
+
+static int hotkey_remove(union acpi_hotkey *device)
+{
+	struct list_head *entries, *next;
+
+	ACPI_FUNCTION_TRACE("hotkey_remove");
+
+	list_for_each_safe(entries, next, global_hotkey_list.entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_standard_num ==
+		    device->link.hotkey_standard_num) {
+			list_del(&key->link.entries);
+			remove_proc_entry(key->poll_hotkey.action_method,
+					  hotkey_proc_dir);
+			global_hotkey_list.count--;
+			break;
+		}
+	}
+	return_VALUE(0);
+}
+
+static void hotkey_update(union acpi_hotkey *key)
+{
+	struct list_head *entries, *next;
+
+	ACPI_FUNCTION_TRACE("hotkey_update");
+
+	list_for_each_safe(entries, next, global_hotkey_list.entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_standard_num ==
+		    key->link.hotkey_standard_num) {
+			key->event_hotkey.bus_handle =
+			    key->event_hotkey.bus_handle;
+			key->event_hotkey.external_hotkey_num =
+			    key->event_hotkey.external_hotkey_num;
+			key->event_hotkey.action_handle =
+			    key->event_hotkey.action_handle;
+			key->event_hotkey.action_method =
+			    key->event_hotkey.action_method;
+			break;
+		}
+	}
+
+	return_VOID;
+}
+
+static void free_hotkey_device(union acpi_hotkey *key)
+{
+	struct acpi_device *dev;
+	int status;
+
+	ACPI_FUNCTION_TRACE("free_hotkey_device");
+
+	if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+		status =
+		    acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
+		if (dev->handle)
+			acpi_remove_notify_handler(dev->handle,
+						   ACPI_SYSTEM_NOTIFY,
+						   acpi_hotkey_notify_handler);
+	} else
+		remove_proc_entry(key->poll_hotkey.action_method,
+				  hotkey_proc_dir);
+	kfree(key);
+	return_VOID;
+}
+
+static int
+init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str,
+		   char *method, int std_num, int external_num)
+{
+	ACPI_FUNCTION_TRACE("init_hotkey_device");
+
+	key->link.hotkey_type = ACPI_HOTKEY_EVENT;
+	key->link.hotkey_standard_num = std_num;
+	key->event_hotkey.flag = 0;
+	if (is_valid_acpi_path(bus_str))
+		acpi_get_handle((acpi_handle) 0,
+				bus_str, &(key->event_hotkey.bus_handle));
+	else
+		return_VALUE(-ENODEV);
+	key->event_hotkey.external_hotkey_num = external_num;
+	if (is_valid_acpi_path(action_str))
+		acpi_get_handle((acpi_handle) 0,
+				action_str, &(key->event_hotkey.action_handle));
+	key->event_hotkey.action_method = kmalloc(sizeof(method), GFP_KERNEL);
+	strcpy(key->event_hotkey.action_method, method);
+
+	return_VALUE(!is_valid_hotkey(key));
+}
+
+static int
+init_poll_hotkey_device(union acpi_hotkey *key,
+			char *poll_str,
+			char *poll_method,
+			char *action_str, char *action_method, int std_num)
+{
+	ACPI_FUNCTION_TRACE("init_poll_hotkey_device");
+
+	key->link.hotkey_type = ACPI_HOTKEY_POLLING;
+	key->link.hotkey_standard_num = std_num;
+	key->poll_hotkey.flag = 0;
+	if (is_valid_acpi_path(poll_str))
+		acpi_get_handle((acpi_handle) 0,
+				poll_str, &(key->poll_hotkey.poll_handle));
+	else
+		return_VALUE(-ENODEV);
+	key->poll_hotkey.poll_method = poll_method;
+	if (is_valid_acpi_path(action_str))
+		acpi_get_handle((acpi_handle) 0,
+				action_str, &(key->poll_hotkey.action_handle));
+	key->poll_hotkey.action_method =
+	    kmalloc(sizeof(action_method), GFP_KERNEL);
+	strcpy(key->poll_hotkey.action_method, action_method);
+	key->poll_hotkey.poll_result =
+	    (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
+	return_VALUE(is_valid_hotkey(key));
+}
+
+static int check_hotkey_valid(union acpi_hotkey *key,
+			      struct acpi_hotkey_list *list)
+{
+	ACPI_FUNCTION_TRACE("check_hotkey_valid");
+	return_VALUE(0);
+}
+
+static int hotkey_open_config(struct inode *inode, struct file *file)
+{
+	ACPI_FUNCTION_TRACE("hotkey_open_config");
+	return_VALUE(single_open
+		     (file, hotkey_config_seq_show, PDE(inode)->data));
+}
+
+static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
+{
+	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+	struct list_head *entries, *next;
+	char bus_name[ACPI_PATHNAME_MAX] = { 0 };
+	char action_name[ACPI_PATHNAME_MAX] = { 0 };
+	struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
+	struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
+
+	ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
+
+	if (!hotkey_list)
+		goto end;
+
+	list_for_each_safe(entries, next, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
+			acpi_get_name(key->event_hotkey.bus_handle,
+				      ACPI_NAME_TYPE_MAX, &bus);
+			acpi_get_name(key->event_hotkey.action_handle,
+				      ACPI_NAME_TYPE_MAX, &act);
+			seq_printf(seq, "%s:%s:%s:%d:%d", bus_name,
+				   action_name,
+				   key->event_hotkey.action_method,
+				   key->link.hotkey_standard_num,
+				   key->event_hotkey.external_hotkey_num);
+		} /* ACPI_HOTKEY_POLLING */
+		else {
+			acpi_get_name(key->poll_hotkey.poll_handle,
+				      ACPI_NAME_TYPE_MAX, &bus);
+			acpi_get_name(key->poll_hotkey.action_handle,
+				      ACPI_NAME_TYPE_MAX, &act);
+			seq_printf(seq, "%s:%s:%s:%s:%d", bus_name,
+				   key->poll_hotkey.poll_method,
+				   action_name,
+				   key->poll_hotkey.action_method,
+				   key->link.hotkey_standard_num);
+		}
+	}
+	seq_puts(seq, "\n");
+      end:
+	return_VALUE(0);
+}
+
+static int
+get_parms(char *config_record,
+	  int *cmd,
+	  char *bus_handle,
+	  char *bus_method,
+	  char *action_handle,
+	  char *method, int *internal_event_num, int *external_event_num)
+{
+	char *tmp, *tmp1;
+	ACPI_FUNCTION_TRACE(("get_parms"));
+
+	sscanf(config_record, "%d", cmd);
+
+	tmp = strchr(config_record, ':');
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	strncpy(bus_handle, tmp, tmp1 - tmp);
+	bus_handle[tmp1 - tmp] = 0;
+
+	tmp = tmp1;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	strncpy(bus_method, tmp, tmp1 - tmp);
+	bus_method[tmp1 - tmp] = 0;
+
+	tmp = tmp1;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	strncpy(action_handle, tmp, tmp1 - tmp);
+	action_handle[tmp1 - tmp] = 0;
+
+	tmp = tmp1;
+	tmp++;
+	tmp1 = strchr(tmp, ':');
+	strncpy(method, tmp, tmp1 - tmp);
+	method[tmp1 - tmp] = 0;
+
+	sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num);
+	return_VALUE(6);
+}
+
+/*  count is length for one input record */
+static ssize_t hotkey_write_config(struct file *file,
+				   const char __user * buffer,
+				   size_t count, loff_t * data)
+{
+	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+	char config_record[MAX_CONFIG_RECORD_LEN];
+	char bus_handle[MAX_NAME_PATH_LEN];
+	char bus_method[MAX_NAME_PATH_LEN];
+	char action_handle[MAX_NAME_PATH_LEN];
+	char method[20];
+	int cmd, internal_event_num, external_event_num;
+	int ret = 0;
+	union acpi_hotkey *key = NULL;
+
+	ACPI_FUNCTION_TRACE(("hotkey_write_config"));
+
+	if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (copy_from_user(config_record, buffer, count)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
+		return_VALUE(-EINVAL);
+	}
+	config_record[count] = '\0';
+
+	ret = get_parms(config_record,
+			&cmd,
+			bus_handle,
+			bus_method,
+			action_handle,
+			method, &internal_event_num, &external_event_num);
+	if (ret != 6) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Invalid data format ret=%d\n", ret));
+		return_VALUE(-EINVAL);
+	}
+
+	key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
+	ret = init_hotkey_device(key, bus_handle, action_handle, method,
+				 internal_event_num, external_event_num);
+
+	if (ret || check_hotkey_valid(key, hotkey_list)) {
+		kfree(key);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
+		return_VALUE(-EINVAL);
+	}
+	switch (cmd) {
+	case 0:
+		hotkey_add(key);
+		break;
+	case 1:
+		hotkey_remove(key);
+		free_hotkey_device(key);
+		break;
+	case 2:
+		hotkey_update(key);
+		break;
+	default:
+		break;
+	}
+	return_VALUE(count);
+}
+
+/*  count is length for one input record */
+static ssize_t hotkey_write_poll_config(struct file *file,
+					const char __user * buffer,
+					size_t count, loff_t * data)
+{
+	struct seq_file *m = (struct seq_file *)file->private_data;
+	struct acpi_hotkey_list *hotkey_list =
+	    (struct acpi_hotkey_list *)m->private;
+
+	char config_record[MAX_CONFIG_RECORD_LEN];
+	char polling_handle[MAX_NAME_PATH_LEN];
+	char action_handle[MAX_NAME_PATH_LEN];
+	char poll_method[20], action_method[20];
+	int ret, internal_event_num, cmd, external_event_num;
+	union acpi_hotkey *key = NULL;
+
+	ACPI_FUNCTION_TRACE("hotkey_write_poll_config");
+
+	if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (copy_from_user(config_record, buffer, count)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n"));
+		return_VALUE(-EINVAL);
+	}
+	config_record[count] = '\0';
+
+	ret = get_parms(config_record,
+			&cmd,
+			polling_handle,
+			poll_method,
+			action_handle,
+			action_method,
+			&internal_event_num, &external_event_num);
+
+	if (ret != 6) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
+		return_VALUE(-EINVAL);
+	}
+
+	key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
+	ret = init_poll_hotkey_device(key, polling_handle, poll_method,
+				      action_handle, action_method,
+				      internal_event_num);
+	if (ret || check_hotkey_valid(key, hotkey_list)) {
+		kfree(key);
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
+		return_VALUE(-EINVAL);
+	}
+	switch (cmd) {
+	case 0:
+		hotkey_add(key);
+		break;
+	case 1:
+		hotkey_remove(key);
+		break;
+	case 2:
+		hotkey_update(key);
+		break;
+	default:
+		break;
+	}
+	return_VALUE(count);
+}
+
+/*  
+ * This function evaluates an ACPI method, given an int as parameter, the
+ * method is searched within the scope of the handle, can be NULL. The output
+ * of the method is written is output, which can also be NULL
+ *
+ * returns 1 if write is successful, 0 else.
+ */
+static int write_acpi_int(acpi_handle handle, const char *method, int val,
+			  struct acpi_buffer *output)
+{
+	struct acpi_object_list params;	/* list of input parameters (an int here) */
+	union acpi_object in_obj;	/* the only param we use */
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("write_acpi_int");
+	params.count = 1;
+	params.pointer = &in_obj;
+	in_obj.type = ACPI_TYPE_INTEGER;
+	in_obj.integer.value = val;
+
+	status = acpi_evaluate_object(handle, (char *)method, &params, output);
+
+	return_VALUE(status == AE_OK);
+}
+
+static int read_acpi_int(acpi_handle handle, const char *method, int *val)
+{
+	struct acpi_buffer output;
+	union acpi_object out_obj;
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE("read_acpi_int");
+	output.length = sizeof(out_obj);
+	output.pointer = &out_obj;
+
+	status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
+	*val = out_obj.integer.value;
+	return_VALUE((status == AE_OK)
+		     && (out_obj.type == ACPI_TYPE_INTEGER));
+}
+
+static acpi_handle
+get_handle_from_hotkeylist(struct acpi_hotkey_list *hotkey_list, int event_num)
+{
+	struct list_head *entries, *next;
+
+	list_for_each_safe(entries, next, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
+		    && key->link.hotkey_standard_num == event_num) {
+			return (key->event_hotkey.action_handle);
+		}
+	}
+	return (NULL);
+}
+
+static
+char *get_method_from_hotkeylist(struct acpi_hotkey_list *hotkey_list,
+				 int event_num)
+{
+	struct list_head *entries, *next;
+
+	list_for_each_safe(entries, next, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+
+		if (key->link.hotkey_type == ACPI_HOTKEY_EVENT &&
+		    key->link.hotkey_standard_num == event_num)
+			return (key->event_hotkey.action_method);
+	}
+	return (NULL);
+}
+
+static struct acpi_polling_hotkey *get_hotkey_by_event(struct
+						       acpi_hotkey_list
+						       *hotkey_list, int event)
+{
+	struct list_head *entries, *next;
+
+	list_for_each_safe(entries, next, hotkey_list->entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+		if (key->link.hotkey_type == ACPI_HOTKEY_POLLING
+		    && key->link.hotkey_standard_num == event) {
+			return (&key->poll_hotkey);
+		}
+	}
+	return (NULL);
+}
+
+/*  
+ * user call AML method interface:
+ * Call convention:
+ * echo "event_num: arg type : value"
+ * example: echo "1:1:30" > /proc/acpi/action
+ * Just support 1 integer arg passing to AML method
+ */
+
+static ssize_t hotkey_execute_aml_method(struct file *file,
+					 const char __user * buffer,
+					 size_t count, loff_t * data)
+{
+	struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
+	char arg[MAX_CALL_PARM];
+	int event, type, value;
+
+	char *method;
+	acpi_handle handle;
+
+	ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");
+
+	if (!hotkey_list || count > MAX_CALL_PARM) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 1"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (copy_from_user(arg, buffer, count)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2"));
+		return_VALUE(-EINVAL);
+	}
+
+	arg[count] = '\0';
+
+	if (sscanf(arg, "%d:%d:%d", &event, &type, &value) != 3) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3"));
+		return_VALUE(-EINVAL);
+	}
+
+	if (type == ACPI_TYPE_INTEGER) {
+		handle = get_handle_from_hotkeylist(hotkey_list, event);
+		method = (char *)get_method_from_hotkeylist(hotkey_list, event);
+		if (IS_EVENT(event))
+			write_acpi_int(handle, method, value, NULL);
+		else if (IS_POLL(event)) {
+			struct acpi_polling_hotkey *key;
+			key = (struct acpi_polling_hotkey *)
+			    get_hotkey_by_event(hotkey_list, event);
+			read_acpi_int(handle, method, key->poll_result);
+		}
+	} else {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported"));
+		return_VALUE(-EINVAL);
+	}
+
+	return_VALUE(count);
+}
+
+static int __init hotkey_init(void)
+{
+	int result;
+	mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
+
+	ACPI_FUNCTION_TRACE("hotkey_init");
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	if (acpi_specific_hotkey_enabled) {
+		printk("Using specific hotkey driver\n");
+		return -ENODEV;
+	}
+
+	hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
+	if (!hotkey_proc_dir) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_PROC));
+		return (-ENODEV);
+	}
+	hotkey_proc_dir->owner = THIS_MODULE;
+
+	hotkey_config =
+	    create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
+	if (!hotkey_config) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_EV_CONFIG));
+		return (-ENODEV);
+	} else {
+		hotkey_config->proc_fops = &hotkey_config_fops;
+		hotkey_config->data = &global_hotkey_list;
+		hotkey_config->owner = THIS_MODULE;
+		hotkey_config->uid = 0;
+		hotkey_config->gid = 0;
+	}
+
+	hotkey_poll_config =
+	    create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
+	if (!hotkey_poll_config) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_EV_CONFIG));
+		return (-ENODEV);
+	} else {
+		hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
+		hotkey_poll_config->data = &global_hotkey_list;
+		hotkey_poll_config->owner = THIS_MODULE;
+		hotkey_poll_config->uid = 0;
+		hotkey_poll_config->gid = 0;
+	}
+
+	hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
+	if (!hotkey_action) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_ACTION));
+		return (-ENODEV);
+	} else {
+		hotkey_action->proc_fops = &hotkey_action_fops;
+		hotkey_action->owner = THIS_MODULE;
+		hotkey_action->uid = 0;
+		hotkey_action->gid = 0;
+	}
+
+	hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
+	if (!hotkey_info) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+				  "Hotkey: Unable to create %s entry\n",
+				  HOTKEY_INFO));
+		return (-ENODEV);
+	} else {
+		hotkey_info->proc_fops = &hotkey_info_fops;
+		hotkey_info->owner = THIS_MODULE;
+		hotkey_info->uid = 0;
+		hotkey_info->gid = 0;
+	}
+
+	result = acpi_bus_register_driver(&hotkey_driver);
+	if (result < 0) {
+		remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+		return (-ENODEV);
+	}
+	global_hotkey_list.count = 0;
+	global_hotkey_list.entries = &hotkey_entries;
+
+	INIT_LIST_HEAD(&hotkey_entries);
+
+	return (0);
+}
+
+static void __exit hotkey_exit(void)
+{
+	struct list_head *entries, *next;
+
+	ACPI_FUNCTION_TRACE("hotkey_remove");
+
+	list_for_each_safe(entries, next, global_hotkey_list.entries) {
+		union acpi_hotkey *key =
+		    container_of(entries, union acpi_hotkey, entries);
+
+		acpi_os_wait_events_complete(NULL);
+		list_del(&key->link.entries);
+		global_hotkey_list.count--;
+		free_hotkey_device(key);
+	}
+	acpi_bus_unregister_driver(&hotkey_driver);
+	remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
+	remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
+	return;
+}
+
+module_init(hotkey_init);
+module_exit(hotkey_exit);
diff -Nru a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
--- a/drivers/acpi/ibm_acpi.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/ibm_acpi.c	2005-03-30 17:02:46 -08:00
@@ -155,7 +155,7 @@
 	int experimental;
 };
 
-struct proc_dir_entry *proc_dir = NULL;
+static struct proc_dir_entry *proc_dir = NULL;
 
 #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
 #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -856,7 +856,7 @@
 	return 0;
 }	
 		
-struct ibm_struct ibms[] = {
+static struct ibm_struct ibms[] = {
 	{
 		.name	= "driver",
 		.init	= driver_init,
@@ -1025,7 +1025,7 @@
 	return 0;
 }
 
-static int device_add(struct acpi_device *device)
+static int ibmacpi_device_add(struct acpi_device *device)
 {
 	return 0;
 }
@@ -1043,7 +1043,7 @@
 	memset(ibm->driver, 0, sizeof(struct acpi_driver));
 	sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name);
 	ibm->driver->ids = ibm->hid;
-	ibm->driver->ops.add = &device_add;
+	ibm->driver->ops.add = &ibmacpi_device_add;
 
 	ret = acpi_bus_register_driver(ibm->driver);
 	if (ret < 0) {
@@ -1185,6 +1185,10 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
+	if (!acpi_specific_hotkey_enabled){
+		printk(IBM_ERR "Using generic hotkey driver\n");
+		return -ENODEV;	
+	}
 	/* these handles are required */
 	if (IBM_HANDLE_INIT(ec,	  1) < 0 ||
 	    IBM_HANDLE_INIT(hkey, 1) < 0 ||
diff -Nru a/drivers/acpi/numa.c b/drivers/acpi/numa.c
--- a/drivers/acpi/numa.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/numa.c	2005-03-30 17:02:46 -08:00
@@ -170,7 +170,7 @@
 
 
 int __init
-acpi_numa_init()
+acpi_numa_init(void)
 {
 	int			result;
 
diff -Nru a/drivers/acpi/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/osl.c	2005-03-30 17:02:46 -08:00
@@ -71,6 +71,9 @@
 extern char line_buf[80];
 #endif /*ENABLE_DEBUGGER*/
 
+int acpi_specific_hotkey_enabled;
+EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
+
 static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
@@ -563,7 +566,7 @@
 }
 
 /* TODO: Change code to take advantage of driver model more */
-void
+static void
 acpi_os_derive_pci_id_2 (
 	acpi_handle		rhandle,        /* upper bound  */
 	acpi_handle		chandle,        /* current node */
@@ -1071,7 +1074,7 @@
 }
 EXPORT_SYMBOL(acpi_os_signal);
 
-int __init
+static int __init
 acpi_os_name_setup(char *str)
 {
 	char *p = acpi_os_name;
@@ -1101,7 +1104,7 @@
  * empty string disables _OSI
  * TBD additional string adds to _OSI
  */
-int __init
+static int __init
 acpi_osi_setup(char *str)
 {
 	if (str == NULL || *str == '\0') {
@@ -1119,7 +1122,7 @@
 __setup("acpi_osi=", acpi_osi_setup);
 
 /* enable serialization to combat AE_ALREADY_EXISTS errors */
-int __init
+static int __init
 acpi_serialize_setup(char *str)
 {
 	printk(KERN_INFO PREFIX "serialize enabled\n");
@@ -1140,7 +1143,7 @@
  * Run-time events on the same GPE this flag is available
  * to tell Linux to keep the wake-time GPEs enabled at run-time.
  */
-int __init
+static int __init
 acpi_wake_gpes_always_on_setup(char *str)
 {
 	printk(KERN_INFO PREFIX "wake GPEs not disabled\n");
@@ -1151,6 +1154,15 @@
 }
 
 __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
+
+int __init
+acpi_hotkey_setup(char *str)
+{
+	acpi_specific_hotkey_enabled = TRUE;
+	return 1;
+}
+
+__setup("acpi_specific_hotkey", acpi_hotkey_setup);
 
 /*
  * max_cstate is defined in the base kernel so modules can
diff -Nru a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
--- a/drivers/acpi/parser/psopcode.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/parser/psopcode.c	2005-03-30 17:02:46 -08:00
@@ -522,7 +522,7 @@
 /* 2E */ ACPI_OP ("DerefOf",            ARGP_DEREF_OF_OP,          ARGI_DEREF_OF_OP,           ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R),
 /* 2F */ ACPI_OP ("Notify",             ARGP_NOTIFY_OP,            ARGI_NOTIFY_OP,             ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_0T_0R,   AML_FLAGS_EXEC_2A_0T_0R),
 /* 30 */ ACPI_OP ("SizeOf",             ARGP_SIZE_OF_OP,           ARGI_SIZE_OF_OP,            ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_1A_0T_1R,   AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE),
-/* 31 */ ACPI_OP ("Index",              ARGP_INDEX_OP,             ARGI_INDEX_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R | AML_CONSTANT),
+/* 31 */ ACPI_OP ("Index",              ARGP_INDEX_OP,             ARGI_INDEX_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_2A_1T_1R,   AML_FLAGS_EXEC_2A_1T_1R),
 /* 32 */ ACPI_OP ("Match",              ARGP_MATCH_OP,             ARGI_MATCH_OP,              ACPI_TYPE_ANY,               AML_CLASS_EXECUTE,         AML_TYPE_EXEC_6A_0T_1R,   AML_FLAGS_EXEC_6A_0T_1R | AML_CONSTANT),
 /* 33 */ ACPI_OP ("CreateDWordField",   ARGP_CREATE_DWORD_FIELD_OP,ARGI_CREATE_DWORD_FIELD_OP, ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
 /* 34 */ ACPI_OP ("CreateWordField",    ARGP_CREATE_WORD_FIELD_OP, ARGI_CREATE_WORD_FIELD_OP,  ACPI_TYPE_BUFFER_FIELD,      AML_CLASS_CREATE,          AML_TYPE_CREATE_FIELD,    AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/parser/psparse.c	2005-03-30 17:02:46 -08:00
@@ -1187,8 +1187,8 @@
 
 		previous_walk_state = walk_state;
 
-		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, State=%p\n",
-			walk_state->return_desc, walk_state));
+		ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "return_value=%p, implicit_value=%p State=%p\n",
+			walk_state->return_desc, walk_state->implicit_return_obj, walk_state));
 
 		/* Check if we have restarted a preempted walk */
 
@@ -1200,8 +1200,20 @@
 				 * If the method return value is not used by the parent,
 				 * The object is deleted
 				 */
-				status = acpi_ds_restart_control_method (walk_state,
-						 previous_walk_state->return_desc);
+				if (!previous_walk_state->return_desc) {
+					status = acpi_ds_restart_control_method (walk_state,
+							 previous_walk_state->implicit_return_obj);
+				}
+				else {
+					/*
+					 * We have a valid return value, delete any implicit
+					 * return value.
+					 */
+					acpi_ds_clear_implicit_return (previous_walk_state);
+
+					status = acpi_ds_restart_control_method (walk_state,
+							 previous_walk_state->return_desc);
+				}
 				if (ACPI_SUCCESS (status)) {
 					walk_state->walk_type |= ACPI_WALK_METHOD_RESTART;
 				}
@@ -1218,12 +1230,26 @@
 		 * value (if any)
 		 */
 		else if (previous_walk_state->caller_return_desc) {
-			*(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; /* NULL if no return value */
+			if (previous_walk_state->implicit_return_obj) {
+				*(previous_walk_state->caller_return_desc) = previous_walk_state->implicit_return_obj;
+			}
+			else {
+				 /* NULL if no return value */
+
+				*(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc;
+			}
 		}
-		else if (previous_walk_state->return_desc) {
-			/* Caller doesn't want it, must delete it */
+		else {
+			if (previous_walk_state->return_desc) {
+				/* Caller doesn't want it, must delete it */
 
-			acpi_ut_remove_reference (previous_walk_state->return_desc);
+				acpi_ut_remove_reference (previous_walk_state->return_desc);
+			}
+			if (previous_walk_state->implicit_return_obj) {
+				/* Caller doesn't want it, must delete it */
+
+				acpi_ut_remove_reference (previous_walk_state->implicit_return_obj);
+			}
 		}
 
 		acpi_ds_delete_walk_state (previous_walk_state);
diff -Nru a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c
--- a/drivers/acpi/parser/pswalk.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/parser/pswalk.c	2005-03-30 17:02:46 -08:00
@@ -44,7 +44,6 @@
 
 #include <acpi/acpi.h>
 #include <acpi/acparser.h>
-#include <acpi/acdispat.h>
 
 #define _COMPONENT          ACPI_PARSER
 	 ACPI_MODULE_NAME    ("pswalk")
@@ -52,256 +51,65 @@
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ps_get_next_walk_op
+ * FUNCTION:    acpi_ps_delete_parse_tree
  *
- * PARAMETERS:  walk_state          - Current state of the walk
- *              Op                  - Current Op to be walked
- *              ascending_callback  - Procedure called when Op is complete
+ * PARAMETERS:  subtree_root        - Root of tree (or subtree) to delete
  *
- * RETURN:      Status
+ * RETURN:      None
  *
- * DESCRIPTION: Get the next Op in a walk of the parse tree.
+ * DESCRIPTION: Delete a portion of or an entire parse tree.
  *
  ******************************************************************************/
 
-acpi_status
-acpi_ps_get_next_walk_op (
-	struct acpi_walk_state          *walk_state,
-	union acpi_parse_object         *op,
-	acpi_parse_upwards              ascending_callback)
+void
+acpi_ps_delete_parse_tree (
+	union acpi_parse_object         *subtree_root)
 {
-	union acpi_parse_object         *next;
-	union acpi_parse_object         *parent;
-	union acpi_parse_object         *grand_parent;
-	acpi_status                     status;
+	union acpi_parse_object         *op = subtree_root;
+	union acpi_parse_object         *next = NULL;
+	union acpi_parse_object         *parent = NULL;
 
 
-	ACPI_FUNCTION_TRACE_PTR ("ps_get_next_walk_op", op);
+	ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
 
 
-	/* Check for a argument only if we are descending in the tree */
+	/* Visit all nodes in the subtree */
 
-	if (walk_state->next_op_info != ACPI_NEXT_OP_UPWARD) {
-		/* Look for an argument or child of the current op */
+	while (op) {
+		/* Check if we are not ascending */
 
-		next = acpi_ps_get_arg (op, 0);
-		if (next) {
-			/* Still going downward in tree (Op is not completed yet) */
+		if (op != parent) {
+			/* Look for an argument or child of the current op */
 
-			walk_state->prev_op     = op;
-			walk_state->next_op     = next;
-			walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
+			next = acpi_ps_get_arg (op, 0);
+			if (next) {
+				/* Still going downward in tree (Op is not completed yet) */
 
-			return_ACPI_STATUS (AE_OK);
+				op = next;
+				continue;
+			}
 		}
 
 		/*
-		 * No more children, this Op is complete.  Save Next and Parent
-		 * in case the Op object gets deleted by the callback routine
+		 * No more children, this Op is complete.
 		 */
-		next    = op->common.next;
-		parent  = op->common.parent;
+		next = op->common.next;
+		parent = op->common.parent;
 
-		walk_state->op    = op;
-		walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
-		walk_state->opcode = op->common.aml_opcode;
-
-		status = ascending_callback (walk_state);
+		acpi_ps_free_op (op);
 
 		/*
 		 * If we are back to the starting point, the walk is complete.
 		 */
-		if (op == walk_state->origin) {
-			/* Reached the point of origin, the walk is complete */
-
-			walk_state->prev_op     = op;
-			walk_state->next_op     = NULL;
-
-			return_ACPI_STATUS (status);
+		if (op == subtree_root) {
+			return_VOID;
 		}
-
-		/*
-		 * Check for a sibling to the current op.  A sibling means
-		 * we are still going "downward" in the tree.
-		 */
 		if (next) {
-			/* There is a sibling, it will be next */
-
-			walk_state->prev_op     = op;
-			walk_state->next_op     = next;
-			walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
-
-			/* Continue downward */
-
-			return_ACPI_STATUS (status);
-		}
-
-		/*
-		 * Drop into the loop below because we are moving upwards in
-		 * the tree
-		 */
-	}
-	else {
-		/*
-		 * We are resuming a walk, and we were (are) going upward in the tree.
-		 * So, we want to drop into the parent loop below.
-		 */
-		parent = op;
-	}
-
-	/*
-	 * Look for a sibling of the current Op's parent
-	 * Continue moving up the tree until we find a node that has not been
-	 * visited, or we get back to where we started.
-	 */
-	while (parent) {
-		/* We are moving up the tree, therefore this parent Op is complete */
-
-		grand_parent = parent->common.parent;
-		next        = parent->common.next;
-
-		walk_state->op    = parent;
-		walk_state->op_info = acpi_ps_get_opcode_info (parent->common.aml_opcode);
-		walk_state->opcode = parent->common.aml_opcode;
-
-		status = ascending_callback (walk_state);
-
-		/*
-		 * If we are back to the starting point, the walk is complete.
-		 */
-		if (parent == walk_state->origin) {
-			/* Reached the point of origin, the walk is complete */
-
-			walk_state->prev_op     = parent;
-			walk_state->next_op     = NULL;
-
-			return_ACPI_STATUS (status);
+			op = next;
 		}
-
-		/*
-		 * If there is a sibling to this parent (it is not the starting point
-		 * Op), then we will visit it.
-		 */
-		if (next) {
-			/* found sibling of parent */
-
-			walk_state->prev_op     = parent;
-			walk_state->next_op     = next;
-			walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
-
-			return_ACPI_STATUS (status);
+		else {
+			op = parent;
 		}
-
-		/* No siblings, no errors, just move up one more level in the tree */
-
-		op                  = parent;
-		parent              = grand_parent;
-		walk_state->prev_op = op;
 	}
-
-
-	/*
-	 * Got all the way to the top of the tree, we must be done!
-	 * However, the code should have terminated in the loop above
-	 */
-	walk_state->next_op     = NULL;
-
-	return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_delete_completed_op
- *
- * PARAMETERS:  State           - Walk state
- *              Op              - Completed op
- *
- * RETURN:      AE_OK
- *
- * DESCRIPTION: Callback function for acpi_ps_get_next_walk_op(). Used during
- *              acpi_ps_delete_parse tree to delete Op objects when all sub-objects
- *              have been visited (and deleted.)
- *
- ******************************************************************************/
-
-acpi_status
-acpi_ps_delete_completed_op (
-	struct acpi_walk_state          *walk_state)
-{
-
-	acpi_ps_free_op (walk_state->op);
-	return (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ps_delete_parse_tree
- *
- * PARAMETERS:  subtree_root        - Root of tree (or subtree) to delete
- *
- * RETURN:      None
- *
- * DESCRIPTION: Delete a portion of or an entire parse tree.
- *
- ******************************************************************************/
-
-void
-acpi_ps_delete_parse_tree (
-	union acpi_parse_object         *subtree_root)
-{
-	struct acpi_walk_state          *walk_state;
-	struct acpi_thread_state        *thread;
-	acpi_status                     status;
-
-
-	ACPI_FUNCTION_TRACE_PTR ("ps_delete_parse_tree", subtree_root);
-
-
-	if (!subtree_root) {
-		return_VOID;
-	}
-
-	/* Create and initialize a new walk list */
-
-	thread = acpi_ut_create_thread_state ();
-	if (!thread) {
-		return_VOID;
-	}
-
-	walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread);
-	if (!walk_state) {
-		return_VOID;
-	}
-
-	walk_state->parse_flags         = 0;
-	walk_state->descending_callback = NULL;
-	walk_state->ascending_callback  = NULL;
-
-	walk_state->origin = subtree_root;
-	walk_state->next_op = subtree_root;
-
-	/* Head downward in the tree */
-
-	walk_state->next_op_info = ACPI_NEXT_OP_DOWNWARD;
-
-	/* Visit all nodes in the subtree */
-
-	while (walk_state->next_op) {
-		status = acpi_ps_get_next_walk_op (walk_state, walk_state->next_op,
-				 acpi_ps_delete_completed_op);
-		if (ACPI_FAILURE (status)) {
-			break;
-		}
-	}
-
-	/* We are done with this walk */
-
-	acpi_ut_delete_generic_state (ACPI_CAST_PTR (union acpi_generic_state, thread));
-	acpi_ds_delete_walk_state (walk_state);
-
 	return_VOID;
 }
-
-
diff -Nru a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/pci_irq.c	2005-03-30 17:02:46 -08:00
@@ -42,8 +42,8 @@
 #define _COMPONENT		ACPI_PCI_COMPONENT
 ACPI_MODULE_NAME		("pci_irq")
 
-struct acpi_prt_list		acpi_prt;
-DEFINE_SPINLOCK(acpi_prt_lock);
+static struct acpi_prt_list	acpi_prt;
+static DEFINE_SPINLOCK(acpi_prt_lock);
 
 /* --------------------------------------------------------------------------
                          PCI IRQ Routing Table (PRT) Support
@@ -281,7 +281,8 @@
 	int			device,
 	int			pin,
 	int			*edge_level,
-	int			*active_high_low)
+	int			*active_high_low,
+	char			**link)
 {
 	struct acpi_prt_entry	*entry = NULL;
 	int segment = pci_domain_nr(bus);
@@ -301,7 +302,8 @@
 	}
 	
 	if (entry->link.handle) {
-		irq = acpi_pci_link_get_irq(entry->link.handle, entry->link.index, edge_level, active_high_low);
+		irq = acpi_pci_link_get_irq(entry->link.handle,
+			entry->link.index, edge_level, active_high_low, link);
 		if (irq < 0) {
 			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n"));
 			return_VALUE(-1);
@@ -327,7 +329,8 @@
 	struct pci_dev		*dev,
 	int			pin,
 	int			*edge_level,
-	int			*active_high_low)
+	int			*active_high_low,
+	char			**link)
 {
 	struct pci_dev		*bridge = dev;
 	int			irq = -1;
@@ -360,7 +363,7 @@
 		}
 
 		irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn),
-			pin, edge_level, active_high_low);
+			pin, edge_level, active_high_low, link);
 	}
 
 	if (irq < 0) {
@@ -389,6 +392,7 @@
 	int			edge_level = ACPI_LEVEL_SENSITIVE;
 	int			active_high_low = ACPI_ACTIVE_LOW;
 	extern int		via_interrupt_line_quirk;
+	char			*link = NULL;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_irq_enable");
 
@@ -411,21 +415,23 @@
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.  PRT
 	 * values override any BIOS-assigned IRQs set during boot.
 	 */
- 	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, &edge_level, &active_high_low);
+ 	irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
+		&edge_level, &active_high_low, &link);
 
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 */
 	if (irq < 0)
- 		irq = acpi_pci_irq_derive(dev, pin, &edge_level, &active_high_low);
+ 		irq = acpi_pci_irq_derive(dev, pin, &edge_level,
+			&active_high_low, &link);
  
 	/*
 	 * No IRQ known to the ACPI subsystem - maybe the BIOS / 
 	 * driver reported one, then use it. Exit in any case.
 	 */
 	if (irq < 0) {
-		printk(KERN_WARNING PREFIX "PCI interrupt %s[%c]: no GSI",
+		printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
 			pci_name(dev), ('A' + pin));
 		/* Interrupt Line values above 0xF are forbidden */
 		if (dev->irq >= 0 && (dev->irq <= 0xF)) {
@@ -443,9 +449,13 @@
 
 	dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
-	printk(KERN_INFO PREFIX "PCI interrupt %s[%c] -> GSI %u "
-		"(%s, %s) -> IRQ %d\n",
-		pci_name(dev), 'A' + pin, irq,
+	printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ",
+		pci_name(dev), 'A' + pin);
+
+	if (link)
+		printk("Link [%s] -> ", link);
+
+	printk("GSI %u (%s, %s) -> IRQ %d\n", irq,
 		(edge_level == ACPI_LEVEL_SENSITIVE) ? "level" : "edge",
 		(active_high_low == ACPI_ACTIVE_LOW) ? "low" : "high",
 		dev->irq);
@@ -482,14 +492,14 @@
 	 * First we check the PCI IRQ routing table (PRT) for an IRQ.
 	 */
  	gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin,
-				  &edge_level, &active_high_low);
+				  &edge_level, &active_high_low, NULL);
 	/*
 	 * If no PRT entry was found, we'll try to derive an IRQ from the
 	 * device's parent bridge.
 	 */
 	if (gsi < 0)
  		gsi = acpi_pci_irq_derive(dev, pin,
-					  &edge_level, &active_high_low);
+					  &edge_level, &active_high_low, NULL);
 	if (gsi < 0)
 		return_VOID;
 
diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/pci_link.c	2005-03-30 17:02:46 -08:00
@@ -72,10 +72,12 @@
 	u8			active;			/* Current IRQ */
 	u8			edge_level;		/* All IRQs */
 	u8			active_high_low;	/* All IRQs */
-	u8			initialized;
 	u8			resource_type;
 	u8			possible_count;
 	u8			possible[ACPI_PCI_LINK_MAX_POSSIBLE];
+	u8			initialized:1;
+	u8			suspend_resume:1;
+	u8			reserved:6;
 };
 
 struct acpi_pci_link {
@@ -522,12 +524,18 @@
 
 static int acpi_irq_balance;	/* 0: static, 1: balance */
 
-static int acpi_pci_link_allocate(struct acpi_pci_link* link) {
-	int irq;
-	int i;
+static int acpi_pci_link_allocate(
+	struct acpi_pci_link	*link)
+{
+	int			irq;
+	int			i;
 
 	ACPI_FUNCTION_TRACE("acpi_pci_link_allocate");
 
+	if (link->irq.suspend_resume) {
+		acpi_pci_link_set(link, link->irq.active);
+		link->irq.suspend_resume = 0;
+	}
 	if (link->irq.initialized)
 		return_VALUE(0);
 
@@ -597,8 +605,9 @@
 acpi_pci_link_get_irq (
 	acpi_handle		handle,
 	int			index,
-	int*			edge_level,
-	int*			active_high_low)
+	int			*edge_level,
+	int			*active_high_low,
+	char			**name)
 {
 	int                     result = 0;
 	struct acpi_device	*device = NULL;
@@ -634,6 +643,7 @@
 
 	if (edge_level) *edge_level = link->irq.edge_level;
 	if (active_high_low) *active_high_low = link->irq.active_high_low;
+	if (name) *name = acpi_device_bid(link->device);
 	return_VALUE(link->irq.active);
 }
 
@@ -709,38 +719,24 @@
 	return_VALUE(result);
 }
 
-
 static int
-acpi_pci_link_resume (
-	struct acpi_pci_link	*link)
-{
-	ACPI_FUNCTION_TRACE("acpi_pci_link_resume");
-	
-	if (link->irq.active && link->irq.initialized)
-		return_VALUE(acpi_pci_link_set(link, link->irq.active));
-	else
-		return_VALUE(0);
-}
-
-
-static int
-irqrouter_resume(
-	struct sys_device *dev)
+irqrouter_suspend(
+	struct sys_device *dev,
+	u32	state)
 {
 	struct list_head        *node = NULL;
 	struct acpi_pci_link    *link = NULL;
 
-	ACPI_FUNCTION_TRACE("irqrouter_resume");
+	ACPI_FUNCTION_TRACE("irqrouter_suspend");
 
 	list_for_each(node, &acpi_link.entries) {
-
 		link = list_entry(node, struct acpi_pci_link, node);
 		if (!link) {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n"));
 			continue;
 		}
-
-		acpi_pci_link_resume(link);
+		if (link->irq.active && link->irq.initialized)
+			link->irq.suspend_resume = 1;
 	}
 	return_VALUE(0);
 }
@@ -852,7 +848,7 @@
 
 static struct sysdev_class irqrouter_sysdev_class = {
         set_kset_name("irqrouter"),
-        .resume = irqrouter_resume,
+        .suspend = irqrouter_suspend,
 };
 
 
diff -Nru a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
--- a/drivers/acpi/pci_root.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/pci_root.c	2005-03-30 17:02:46 -08:00
@@ -258,7 +258,7 @@
  	/* TBD: Locking */
  	list_add_tail(&root->node, &acpi_pci_roots);
 
-	printk(KERN_INFO PREFIX "%s [%s] (%02x:%02x)\n", 
+	printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", 
 		acpi_device_name(device), acpi_device_bid(device),
 		root->id.segment, root->id.bus);
 
@@ -272,7 +272,7 @@
 	root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus);
 	if (!root->bus) {
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 
-			"Bus %02x:%02x not present in PCI namespace\n", 
+			"Bus %04x:%02x not present in PCI namespace\n", 
 			root->id.segment, root->id.bus));
 		result = -ENODEV;
 		goto end;
diff -Nru a/drivers/acpi/power.c b/drivers/acpi/power.c
--- a/drivers/acpi/power.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/power.c	2005-03-30 17:02:46 -08:00
@@ -58,8 +58,8 @@
 #define ACPI_POWER_RESOURCE_STATE_ON	0x01
 #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
 
-int acpi_power_add (struct acpi_device *device);
-int acpi_power_remove (struct acpi_device *device, int type);
+static int acpi_power_add (struct acpi_device *device);
+static int acpi_power_remove (struct acpi_device *device, int type);
 static int acpi_power_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_power_driver = {
@@ -479,7 +479,7 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_power_dir;
+static struct proc_dir_entry	*acpi_power_dir;
 
 static int acpi_power_seq_show(struct seq_file *seq, void *offset)
 {
@@ -576,7 +576,7 @@
                                 Driver Interface
    -------------------------------------------------------------------------- */
 
-int
+static int
 acpi_power_add (
 	struct acpi_device	*device)
 {
@@ -642,7 +642,7 @@
 }
 
 
-int
+static int
 acpi_power_remove (
 	struct acpi_device	*device,
 	int			type)
diff -Nru a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
--- a/drivers/acpi/processor_core.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/processor_core.c	2005-03-30 17:02:46 -08:00
@@ -105,7 +105,7 @@
 #define UNINSTALL_NOTIFY_HANDLER	2
 
 
-struct file_operations acpi_processor_info_fops = {
+static struct file_operations acpi_processor_info_fops = {
 	.open 		= acpi_processor_info_open_fs,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
@@ -121,7 +121,7 @@
                                 Errata Handling
    -------------------------------------------------------------------------- */
 
-int
+static int
 acpi_processor_errata_piix4 (
 	struct pci_dev		*dev)
 {
@@ -259,7 +259,7 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_processor_dir = NULL;
+static struct proc_dir_entry	*acpi_processor_dir = NULL;
 
 static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
 {
diff -Nru a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
--- a/drivers/acpi/processor_thermal.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/processor_thermal.c	2005-03-30 17:02:46 -08:00
@@ -345,7 +345,7 @@
 	return_VALUE(0);
 }
 
-int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
+static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file)
 {
 	return single_open(file, acpi_processor_limit_seq_show,
 						PDE(inode)->data);
diff -Nru a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
--- a/drivers/acpi/processor_throttling.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/processor_throttling.c	2005-03-30 17:02:46 -08:00
@@ -308,7 +308,7 @@
 	return_VALUE(0);
 }
 
-int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
+static int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file)
 {
 	return single_open(file, acpi_processor_throttling_seq_show,
 						PDE(inode)->data);
diff -Nru a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c
--- a/drivers/acpi/resources/rsaddr.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/resources/rsaddr.c	2005-03-30 17:02:46 -08:00
@@ -110,13 +110,13 @@
 	buffer += 2;
 	temp8 = *buffer;
 
-	/* Values 0-2 are valid */
+	/* Values 0-2 and 0xC0-0xFF are valid */
 
-	if (temp8 > 2) {
+	if ((temp8 > 2) && (temp8 < 0xC0)) {
 		return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
 	}
 
-	output_struct->data.address16.resource_type = temp8 & 0x03;
+	output_struct->data.address16.resource_type = temp8;
 
 	/*
 	 * Get the General Flags (Byte4)
@@ -496,12 +496,13 @@
 	buffer += 2;
 	temp8 = *buffer;
 
-	/* Values 0-2 are valid */
-	if(temp8 > 2) {
+	/* Values 0-2 and 0xC0-0xFF are valid */
+
+	if ((temp8 > 2) && (temp8 < 0xC0)) {
 		return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
 	}
 
-	output_struct->data.address32.resource_type = temp8 & 0x03;
+	output_struct->data.address32.resource_type = temp8;
 
 	/*
 	 * Get the General Flags (Byte4)
@@ -850,6 +851,7 @@
 	struct acpi_resource            *output_struct = (void *) *output_buffer;
 	u16                             temp16;
 	u8                              temp8;
+	u8                              resource_type;
 	u8                              *temp_ptr;
 	acpi_size                       struct_size;
 	u32                             index;
@@ -860,6 +862,7 @@
 
 	buffer = byte_stream_buffer;
 	struct_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+	resource_type = *buffer;
 
 	/*
 	 * Point past the Descriptor to get the number of bytes consumed
@@ -882,13 +885,13 @@
 	buffer += 2;
 	temp8 = *buffer;
 
-	/* Values 0-2 are valid */
+	/* Values 0-2 and 0xC0-0xFF are valid */
 
-	if(temp8 > 2) {
+	if ((temp8 > 2) && (temp8 < 0xC0)) {
 		return_ACPI_STATUS (AE_AML_INVALID_RESOURCE_TYPE);
 	}
 
-	output_struct->data.address64.resource_type = temp8 & 0x03;
+	output_struct->data.address64.resource_type = temp8;
 
 	/*
 	 * Get the General Flags (Byte4)
@@ -942,98 +945,113 @@
 		}
 	}
 
+	if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
+		/* Move past revision_id and Reserved byte */
+
+		buffer += 2;
+	}
+
 	/*
-	 * Get Granularity (Bytes 6-13)
+	 * Get Granularity (Bytes 6-13) or (Bytes 8-15)
 	 */
 	buffer += 1;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.granularity, buffer);
 
 	/*
-	 * Get min_address_range (Bytes 14-21)
+	 * Get min_address_range (Bytes 14-21) or (Bytes 16-23)
 	 */
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.min_address_range, buffer);
 
 	/*
-	 * Get max_address_range (Bytes 22-29)
+	 * Get max_address_range (Bytes 22-29) or (Bytes 24-31)
 	 */
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.max_address_range, buffer);
 
 	/*
-	 * Get address_translation_offset (Bytes 30-37)
+	 * Get address_translation_offset (Bytes 30-37) or (Bytes 32-39)
 	 */
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_translation_offset, buffer);
 
 	/*
-	 * Get address_length (Bytes 38-45)
+	 * Get address_length (Bytes 38-45) or (Bytes 40-47)
 	 */
 	buffer += 8;
 	ACPI_MOVE_64_TO_64 (&output_struct->data.address64.address_length, buffer);
 
-	/*
-	 * Resource Source Index (if present)
-	 */
-	buffer += 8;
+	output_struct->data.address64.resource_source.index = 0x00;
+	output_struct->data.address64.resource_source.string_length = 0;
+	output_struct->data.address64.resource_source.string_ptr = NULL;
 
-	/*
-	 * This will leave us pointing to the Resource Source Index
-	 * If it is present, then save it off and calculate the
-	 * pointer to where the null terminated string goes:
-	 * Each Interrupt takes 32-bits + the 5 bytes of the
-	 * stream that are default.
-	 *
-	 * Note: Some resource descriptors will have an additional null, so
-	 * we add 1 to the length.
-	 */
-	if (*bytes_consumed > (46 + 1)) {
-		/* Dereference the Index */
+	if (resource_type == ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE) {
+		/* Get type_specific_attribute (Bytes 48-55) */
 
-		temp8 = *buffer;
-		output_struct->data.address64.resource_source.index =
-				(u32) temp8;
+		buffer += 8;
+		ACPI_MOVE_64_TO_64 (&output_struct->data.address64.type_specific_attributes, buffer);
+	}
+	else {
+		output_struct->data.address64.type_specific_attributes = 0;
 
-		/* Point to the String */
+		/*
+		 * Resource Source Index (if present)
+		 */
+		buffer += 8;
 
-		buffer += 1;
+		/*
+		 * This will leave us pointing to the Resource Source Index
+		 * If it is present, then save it off and calculate the
+		 * pointer to where the null terminated string goes:
+		 * Each Interrupt takes 32-bits + the 5 bytes of the
+		 * stream that are default.
+		 *
+		 * Note: Some resource descriptors will have an additional null, so
+		 * we add 1 to the length.
+		 */
+		if (*bytes_consumed > (46 + 1)) {
+			/* Dereference the Index */
 
-		/* Point the String pointer to the end of this structure */
+			temp8 = *buffer;
+			output_struct->data.address64.resource_source.index =
+					(u32) temp8;
 
-		output_struct->data.address64.resource_source.string_ptr =
-				(char *)((u8 *)output_struct + struct_size);
+			/* Point to the String */
 
-		temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
+			buffer += 1;
 
-		/* Copy the string into the buffer */
+			/* Point the String pointer to the end of this structure */
 
-		index = 0;
-		while (0x00 != *buffer) {
-			*temp_ptr = *buffer;
+			output_struct->data.address64.resource_source.string_ptr =
+					(char *)((u8 *)output_struct + struct_size);
 
-			temp_ptr += 1;
-			buffer += 1;
-			index += 1;
-		}
+			temp_ptr = (u8 *) output_struct->data.address64.resource_source.string_ptr;
 
-		/*
-		 * Add the terminating null
-		 */
-		*temp_ptr = 0x00;
-		output_struct->data.address64.resource_source.string_length = index + 1;
+			/* Copy the string into the buffer */
 
-		/*
-		 * In order for the struct_size to fall on a 32-bit boundary,
-		 * calculate the length of the string and expand the
-		 * struct_size to the next 32-bit boundary.
-		 */
-		temp8 = (u8) (index + 1);
-		struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
-	}
-	else {
-		output_struct->data.address64.resource_source.index = 0x00;
-		output_struct->data.address64.resource_source.string_length = 0;
-		output_struct->data.address64.resource_source.string_ptr = NULL;
+			index = 0;
+			while (0x00 != *buffer) {
+				*temp_ptr = *buffer;
+
+				temp_ptr += 1;
+				buffer += 1;
+				index += 1;
+			}
+
+			/*
+			 * Add the terminating null
+			 */
+			*temp_ptr = 0x00;
+			output_struct->data.address64.resource_source.string_length = index + 1;
+
+			/*
+			 * In order for the struct_size to fall on a 32-bit boundary,
+			 * calculate the length of the string and expand the
+			 * struct_size to the next 32-bit boundary.
+			 */
+			temp8 = (u8) (index + 1);
+			struct_size += ACPI_ROUND_UP_to_32_bITS (temp8);
+		}
 	}
 
 	/*
diff -Nru a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
--- a/drivers/acpi/resources/rscalc.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/resources/rscalc.c	2005-03-30 17:02:46 -08:00
@@ -376,6 +376,20 @@
 			break;
 
 
+		case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
+			/*
+			 * 64-Bit Address Resource
+			 */
+			buffer = byte_stream_buffer;
+
+			++buffer;
+			ACPI_MOVE_16_TO_16 (&temp16, buffer);
+
+			bytes_consumed = temp16 + 3;
+			structure_size = ACPI_SIZEOF_RESOURCE (struct acpi_resource_address64);
+			break;
+
+
 		case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
 			/*
 			 * 64-Bit Address Resource
diff -Nru a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
--- a/drivers/acpi/resources/rsdump.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/resources/rsdump.c	2005-03-30 17:02:46 -08:00
@@ -571,7 +571,7 @@
 			break;
 		}
 
-		acpi_os_printf (" Type Specific: %s Translation\n",
+		acpi_os_printf ("  Type Specific: %s Translation\n",
 			ACPI_SPARSE_TRANSLATION ==
 			address16_data->attribute.io.translation_attribute ?
 			"Sparse" : "Dense");
@@ -584,8 +584,8 @@
 
 	default:
 
-		acpi_os_printf ("Invalid resource type. Exiting.\n");
-		return;
+		acpi_os_printf ("0x%2.2X\n", address16_data->resource_type);
+		break;
 	}
 
 	acpi_os_printf ("  Resource %s\n",
@@ -718,7 +718,7 @@
 			break;
 		}
 
-		acpi_os_printf (" Type Specific: %s Translation\n",
+		acpi_os_printf ("  Type Specific: %s Translation\n",
 			ACPI_SPARSE_TRANSLATION ==
 			address32_data->attribute.io.translation_attribute ?
 			"Sparse" : "Dense");
@@ -731,8 +731,8 @@
 
 	default:
 
-		acpi_os_printf ("  Invalid Resource Type..exiting.\n");
-		return;
+		acpi_os_printf ("  Resource Type: 0x%2.2X\n", address32_data->resource_type);
+		break;
 	}
 
 	acpi_os_printf ("  Resource %s\n",
@@ -865,7 +865,7 @@
 			break;
 		}
 
-		acpi_os_printf (" Type Specific: %s Translation\n",
+		acpi_os_printf ("  Type Specific: %s Translation\n",
 			ACPI_SPARSE_TRANSLATION ==
 			address64_data->attribute.io.translation_attribute ?
 			"Sparse" : "Dense");
@@ -878,8 +878,8 @@
 
 	default:
 
-		acpi_os_printf ("  Invalid Resource Type..exiting.\n");
-		return;
+		acpi_os_printf ("  Resource Type: 0x%2.2X\n", address64_data->resource_type);
+		break;
 	}
 
 	acpi_os_printf ("  Resource %s\n",
@@ -913,7 +913,10 @@
 	acpi_os_printf ("  Address Length: %8.8X%8.8X\n",
 			 ACPI_FORMAT_UINT64 (address64_data->address_length));
 
-	if(0xFF != address64_data->resource_source.index) {
+	acpi_os_printf ("  Type Specific Attributes: %8.8X%8.8X\n",
+			 ACPI_FORMAT_UINT64 (address64_data->type_specific_attributes));
+
+	if (0xFF != address64_data->resource_source.index) {
 		acpi_os_printf ("  Resource Source Index: %X\n",
 				 address64_data->resource_source.index);
 		acpi_os_printf ("  Resource Source: %s\n",
diff -Nru a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
--- a/drivers/acpi/resources/rslist.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/resources/rslist.c	2005-03-30 17:02:46 -08:00
@@ -178,6 +178,7 @@
 
 
 		case ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE:
+		case ACPI_RDESC_TYPE_EXTENDED_ADDRESS_SPACE:
 			/*
 			 * 64-Bit Address Resource
 			 */
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/scan.c	2005-03-30 17:02:46 -08:00
@@ -27,6 +27,10 @@
 DEFINE_SPINLOCK(acpi_device_lock);
 LIST_HEAD(acpi_wakeup_device_list);
 
+static int
+acpi_bus_trim(struct acpi_device	*start,
+		int rmdevice);
+
 static void acpi_device_release(struct kobject * kobj)
 {
 	struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj);
@@ -81,12 +85,37 @@
 	.release	= acpi_device_release,
 };
 
+static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
+			     char **envp, int num_envp, char *buffer,
+			     int buffer_size)
+{
+	struct acpi_device *dev = to_acpi_device(kobj);
+	int i = 0;
+	int len = 0;
+
+	if (!dev->driver)
+		return 0;
+
+	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
+				"PHYSDEVDRIVER=%s", dev->driver->name))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+static struct kset_hotplug_ops namespace_hotplug_ops = {
+	.hotplug = &namespace_hotplug,
+};
+
 static struct kset acpi_namespace_kset = {
 	.kobj		= { 
 		.name = "namespace",
 	},
 	.subsys = &acpi_subsys,
 	.ktype	= &ktype_acpi_ns,
+	.hotplug_ops = &namespace_hotplug_ops,
 };
 
 
@@ -358,7 +387,15 @@
 	struct acpi_device *dev,
 	acpi_device_sysfs_files *func)
 {
-	if (dev->flags.ejectable == 1)
+	acpi_status		status;
+	acpi_handle		temp = NULL;
+
+	/*
+	 * If device has _EJ0, 'eject' file is created that is used to trigger
+	 * hot-removal function from userland.
+	 */
+	status = acpi_get_handle(dev->handle, "_EJ0", &temp);
+	if (ACPI_SUCCESS(status))
 		(*(func))(&dev->kobj,&acpi_device_attr_eject.attr);
 }
 
@@ -857,7 +894,7 @@
 	acpi_os_free(buffer.pointer);
 }
 
-int acpi_device_set_context(struct acpi_device * device, int type)
+static int acpi_device_set_context(struct acpi_device * device, int type)
 {
 	acpi_status status = AE_OK;
 	int result = 0;
@@ -882,7 +919,7 @@
 	return result;
 }
 
-void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
+static void acpi_device_get_debug_info(struct acpi_device * device, acpi_handle handle, int type)
 {
 #ifdef CONFIG_ACPI_DEBUG_OUTPUT
 	char		*type_string = NULL;
@@ -925,7 +962,7 @@
 }
 
 
-int
+static int
 acpi_bus_remove (
 	struct acpi_device *dev,
 	int rmdevice)
@@ -1223,7 +1260,7 @@
 EXPORT_SYMBOL(acpi_bus_scan);
 
 
-int
+static int
 acpi_bus_trim(struct acpi_device	*start,
 		int rmdevice)
 {
diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/sleep/main.c	2005-03-30 17:02:46 -08:00
@@ -1,6 +1,7 @@
 /*
  * sleep.c - ACPI sleep support.
  *
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
  * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
  * Copyright (c) 2000-2003 Patrick Mochel
  * Copyright (c) 2003 Open Source Development Lab
@@ -14,7 +15,6 @@
 #include <linux/dmi.h>
 #include <linux/device.h>
 #include <linux/suspend.h>
-#include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 #include "sleep.h"
@@ -27,10 +27,11 @@
 extern void do_suspend_lowlevel(void);
 
 static u32 acpi_suspend_states[] = {
-	[PM_SUSPEND_ON]		= ACPI_STATE_S0,
-	[PM_SUSPEND_STANDBY]	= ACPI_STATE_S1,
-	[PM_SUSPEND_MEM]	= ACPI_STATE_S3,
-	[PM_SUSPEND_DISK]	= ACPI_STATE_S4,
+	[PM_SUSPEND_ON] = ACPI_STATE_S0,
+	[PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
+	[PM_SUSPEND_MEM] = ACPI_STATE_S3,
+	[PM_SUSPEND_DISK] = ACPI_STATE_S4,
+	[PM_SUSPEND_MAX] = ACPI_STATE_S5
 };
 
 static int init_8259A_after_S1;
@@ -44,30 +45,20 @@
  *	wakeup code to the waking vector. 
  */
 
+extern int acpi_sleep_prepare(u32 acpi_state);
+extern void acpi_power_off(void);
+
 static int acpi_pm_prepare(suspend_state_t pm_state)
 {
 	u32 acpi_state = acpi_suspend_states[pm_state];
 
-	if (!sleep_states[acpi_state])
+	if (!sleep_states[acpi_state]) {
+		printk("acpi_pm_prepare does not support %d \n", pm_state);
 		return -EPERM;
-
-	/* 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 (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) {
-		if (!acpi_wakeup_address)
-			return -EFAULT;
-		acpi_set_firmware_waking_vector(
-			(acpi_physical_address) virt_to_phys(
-				(void *)acpi_wakeup_address));
 	}
-	ACPI_FLUSH_CPU_CACHE();
-	acpi_enable_wakeup_device_prep(acpi_state);
-	acpi_enter_sleep_state_prep(acpi_state);
-	return 0;
+	return acpi_sleep_prepare(acpi_state);
 }
 
-
 /**
  *	acpi_pm_enter - Actually enter a sleep state.
  *	@pm_state:		State we're entering.
@@ -92,11 +83,9 @@
 			return error;
 	}
 
-
 	local_irq_save(flags);
 	acpi_enable_wakeup_device(acpi_state);
-	switch (pm_state)
-	{
+	switch (pm_state) {
 	case PM_SUSPEND_STANDBY:
 		barrier();
 		status = acpi_enter_sleep_state(acpi_state);
@@ -112,6 +101,10 @@
 		else
 			do_suspend_lowlevel_s4bios();
 		break;
+	case PM_SUSPEND_MAX:
+		acpi_power_off();
+		break;
+
 	default:
 		return -EINVAL;
 	}
@@ -126,11 +119,9 @@
 	if (pm_state > PM_SUSPEND_STANDBY)
 		acpi_restore_state_mem();
 
-
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
 
-
 /**
  *	acpi_pm_finish - Finish up suspend sequence.
  *	@pm_state:		State we're coming out of.
@@ -156,27 +147,26 @@
 	return 0;
 }
 
-
 int acpi_suspend(u32 acpi_state)
 {
 	suspend_state_t states[] = {
-		[1]	= PM_SUSPEND_STANDBY,
-		[3]	= PM_SUSPEND_MEM,
-		[4]	= PM_SUSPEND_DISK,
+		[1] = PM_SUSPEND_STANDBY,
+		[3] = PM_SUSPEND_MEM,
+		[4] = PM_SUSPEND_DISK,
+		[5] = PM_SUSPEND_MAX
 	};
 
-	if (acpi_state <= 4 && states[acpi_state])
+	if (acpi_state < 6 && states[acpi_state])
 		return pm_suspend(states[acpi_state]);
 	return -EINVAL;
 }
 
 static struct pm_ops acpi_pm_ops = {
-	.prepare	= acpi_pm_prepare,
-	.enter		= acpi_pm_enter,
-	.finish		= acpi_pm_finish,
+	.prepare = acpi_pm_prepare,
+	.enter = acpi_pm_enter,
+	.finish = acpi_pm_finish,
 };
 
-
 /*
  * Toshiba fails to preserve interrupts over S1, reinitialization
  * of 8259 is needed after S1 resume.
@@ -190,16 +180,16 @@
 
 static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 	{
-		.callback = init_ints_after_s1,
-		.ident = "Toshiba Satellite 4030cdt",
-		.matches = { DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), },
-	},
-	{ },
+	 .callback = init_ints_after_s1,
+	 .ident = "Toshiba Satellite 4030cdt",
+	 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
+	 },
+	{},
 };
 
 static int __init acpi_sleep_init(void)
 {
-	int			i = 0;
+	int i = 0;
 
 	dmi_check_system(acpisleep_dmi_table);
 
@@ -207,7 +197,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/poweroff.c b/drivers/acpi/sleep/poweroff.c
--- a/drivers/acpi/sleep/poweroff.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/sleep/poweroff.c	2005-03-30 17:02:46 -08:00
@@ -3,35 +3,100 @@
  *
  * AKA S5, but it is independent of whether or not the kernel supports
  * any other sleep support in the system.
+ *
+ * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
+ *
+ * This file is released under the GPLv2.
  */
 
 #include <linux/pm.h>
 #include <linux/init.h>
 #include <acpi/acpi_bus.h>
 #include <linux/sched.h>
+#include <linux/sysdev.h>
+#include <asm/io.h>
 #include "sleep.h"
 
-static void
-acpi_power_off (void)
+int acpi_sleep_prepare(u32 acpi_state)
 {
-	printk("%s called\n",__FUNCTION__);
+	/* Flag to do not allow second time invocation for S5 state */
+	static int shutdown_prepared = 0;
+#ifdef CONFIG_ACPI_SLEEP
+	/* 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 (acpi_state == ACPI_STATE_S3 || acpi_state == ACPI_STATE_S4) {
+		if (!acpi_wakeup_address) {
+			return -EFAULT;
+		}
+		acpi_set_firmware_waking_vector((acpi_physical_address)
+						virt_to_phys((void *)
+							     acpi_wakeup_address));
+
+	}
+	ACPI_FLUSH_CPU_CACHE();
+	acpi_enable_wakeup_device_prep(acpi_state);
+#endif
+	if (acpi_state == ACPI_STATE_S5) {
+		/* Check if we were already called */
+		if (shutdown_prepared)
+			return 0;
+		acpi_wakeup_gpe_poweroff_prepare();
+		shutdown_prepared = 1;
+	}
+	acpi_enter_sleep_state_prep(acpi_state);
+	return 0;
+}
+
+void acpi_power_off(void)
+{
+	printk("%s called\n", __FUNCTION__);
+	acpi_sleep_prepare(ACPI_STATE_S5);
+	local_irq_disable();
 	/* Some SMP machines only can poweroff in boot CPU */
 	set_cpus_allowed(current, cpumask_of_cpu(0));
-	acpi_wakeup_gpe_poweroff_prepare();
-	acpi_enter_sleep_state_prep(ACPI_STATE_S5);
-	ACPI_DISABLE_IRQS();
 	acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
+#ifdef CONFIG_PM
+
+static int acpi_shutdown(struct sys_device *x)
+{
+	return acpi_sleep_prepare(ACPI_STATE_S5);
+}
+
+static struct sysdev_class acpi_sysclass = {
+	set_kset_name("acpi"),
+	.shutdown = acpi_shutdown
+};
+
+static struct sys_device device_acpi = {
+	.id = 0,
+	.cls = &acpi_sysclass,
+};
+
+#endif
+
 static int acpi_poweroff_init(void)
 {
 	if (!acpi_disabled) {
 		u8 type_a, type_b;
 		acpi_status status;
 
-		status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
-		if (ACPI_SUCCESS(status))
+		status =
+		    acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
+		if (ACPI_SUCCESS(status)) {
 			pm_power_off = acpi_power_off;
+#ifdef CONFIG_PM
+			{
+				int error;
+				error = sysdev_class_register(&acpi_sysclass);
+				if (!error)
+					error = sysdev_register(&device_acpi);
+				return error;
+			}
+#endif
+		}
 	}
 	return 0;
 }
diff -Nru a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
--- a/drivers/acpi/thermal.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/thermal.c	2005-03-30 17:02:46 -08:00
@@ -774,7 +774,7 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_thermal_dir;
+static struct proc_dir_entry	*acpi_thermal_dir;
 
 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
 {
diff -Nru a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/toshiba_acpi.c	2005-03-30 17:02:46 -08:00
@@ -481,7 +481,7 @@
 
 #define PROC_TOSHIBA		"toshiba"
 
-ProcItem proc_items[] =
+static ProcItem proc_items[] =
 {
 	{ "lcd"		, read_lcd	, write_lcd	},
 	{ "video"	, read_video	, write_video	},
@@ -529,6 +529,11 @@
 
 	if (acpi_disabled)
 		return -ENODEV;
+
+	if (!acpi_specific_hotkey_enabled){
+		printk(MY_INFO "Using generic hotkey driver\n");
+		return -ENODEV;	
+	}
 	/* simple device detection: look for HCI method */
 	if (is_valid_acpi_path(METHOD_HCI_1))
 		method_hci = METHOD_HCI_1;
diff -Nru a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c
--- a/drivers/acpi/utilities/utcopy.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/utilities/utcopy.c	2005-03-30 17:02:46 -08:00
@@ -659,15 +659,17 @@
 			/* Create an actual buffer only if length > 0 */
 
 			if (source_desc->buffer.length) {
-				dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length);
+				dest_desc->buffer.pointer =
+					ACPI_MEM_ALLOCATE (source_desc->buffer.length);
 				if (!dest_desc->buffer.pointer) {
 					return (AE_NO_MEMORY);
 				}
 
 				/* Copy the actual buffer data */
 
-				ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer,
-						  source_desc->buffer.length);
+				ACPI_MEMCPY (dest_desc->buffer.pointer,
+						source_desc->buffer.pointer,
+						source_desc->buffer.length);
 			}
 		}
 		break;
@@ -682,7 +684,8 @@
 		 */
 		if ((source_desc->string.pointer) &&
 			(!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) {
-			dest_desc->string.pointer = ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
+			dest_desc->string.pointer =
+				ACPI_MEM_ALLOCATE ((acpi_size) source_desc->string.length + 1);
 			if (!dest_desc->string.pointer) {
 				return (AE_NO_MEMORY);
 			}
@@ -690,6 +693,14 @@
 			ACPI_MEMCPY (dest_desc->string.pointer, source_desc->string.pointer,
 					  (acpi_size) source_desc->string.length + 1);
 		}
+		break;
+
+	case ACPI_TYPE_LOCAL_REFERENCE:
+		/*
+		 * We copied the reference object, so we now must add a reference
+		 * to the object pointed to by the reference
+		 */
+		acpi_ut_add_reference (source_desc->reference.object);
 		break;
 
 	default:
diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
--- a/drivers/acpi/utilities/utdelete.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/utilities/utdelete.c	2005-03-30 17:02:46 -08:00
@@ -46,6 +46,7 @@
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
 #include <acpi/acevents.h>
+#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_UTILITIES
 	 ACPI_MODULE_NAME    ("utdelete")
@@ -562,8 +563,23 @@
 			break;
 
 
-		case ACPI_TYPE_REGION:
 		case ACPI_TYPE_LOCAL_REFERENCE:
+
+			/*
+			 * The target of an Index (a package, string, or buffer) must track
+			 * changes to the ref count of the index.
+			 */
+			if (object->reference.opcode == AML_INDEX_OP) {
+				status = acpi_ut_create_update_state_and_push (
+						 object->reference.object, action, &state_list);
+				if (ACPI_FAILURE (status)) {
+					goto error_exit;
+				}
+			}
+			break;
+
+
+		case ACPI_TYPE_REGION:
 		default:
 
 			/* No subobjects */
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/utilities/utglobal.c	2005-03-30 17:02:46 -08:00
@@ -194,6 +194,8 @@
  */
 const char                          *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] =
 {
+	/* Operating System Vendor Strings */
+
 	"Linux",
 	"Windows 2000",
 	"Windows 2001",
@@ -202,7 +204,11 @@
 	"Windows 2001 SP1",
 	"Windows 2001 SP2",
 	"Windows 2001 SP3",
-	"Windows 2001 SP4"
+	"Windows 2001 SP4",
+
+	/* Feature Group Strings */
+
+	"Extended Address Space Descriptor"
 };
 
 
@@ -355,6 +361,7 @@
 	/* ACPI_BITREG_SLEEP_BUTTON_STATUS  */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_SLEEP_BUTTON_STATUS,   ACPI_BITMASK_SLEEP_BUTTON_STATUS},
 	/* ACPI_BITREG_RT_CLOCK_STATUS      */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_RT_CLOCK_STATUS,       ACPI_BITMASK_RT_CLOCK_STATUS},
 	/* ACPI_BITREG_WAKE_STATUS          */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_WAKE_STATUS,           ACPI_BITMASK_WAKE_STATUS},
+	/* ACPI_BITREG_PCIEXP_WAKE_STATUS   */   {ACPI_REGISTER_PM1_STATUS,   ACPI_BITPOSITION_PCIEXP_WAKE_STATUS,    ACPI_BITMASK_PCIEXP_WAKE_STATUS},
 
 	/* ACPI_BITREG_TIMER_ENABLE         */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_TIMER_ENABLE,          ACPI_BITMASK_TIMER_ENABLE},
 	/* ACPI_BITREG_GLOBAL_LOCK_ENABLE   */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_GLOBAL_LOCK_ENABLE,    ACPI_BITMASK_GLOBAL_LOCK_ENABLE},
@@ -362,6 +369,7 @@
 	/* ACPI_BITREG_SLEEP_BUTTON_ENABLE  */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE,   ACPI_BITMASK_SLEEP_BUTTON_ENABLE},
 	/* ACPI_BITREG_RT_CLOCK_ENABLE      */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_RT_CLOCK_ENABLE,       ACPI_BITMASK_RT_CLOCK_ENABLE},
 	/* ACPI_BITREG_WAKE_ENABLE          */   {ACPI_REGISTER_PM1_ENABLE,   0,                                      0},
+	/* ACPI_BITREG_PCIEXP_WAKE_DISABLE  */   {ACPI_REGISTER_PM1_ENABLE,   ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE,   ACPI_BITMASK_PCIEXP_WAKE_DISABLE},
 
 	/* ACPI_BITREG_SCI_ENABLE           */   {ACPI_REGISTER_PM1_CONTROL,  ACPI_BITPOSITION_SCI_ENABLE,            ACPI_BITMASK_SCI_ENABLE},
 	/* ACPI_BITREG_BUS_MASTER_RLD       */   {ACPI_REGISTER_PM1_CONTROL,  ACPI_BITPOSITION_BUS_MASTER_RLD,        ACPI_BITMASK_BUS_MASTER_RLD},
diff -Nru a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
--- a/drivers/acpi/utilities/utmisc.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/utilities/utmisc.c	2005-03-30 17:02:46 -08:00
@@ -372,7 +372,7 @@
 	u32                             base,
 	acpi_integer                    *ret_integer)
 {
-	u32                             this_digit;
+	u32                             this_digit = 0;
 	acpi_integer                    return_value = 0;
 	acpi_integer                    quotient;
 
@@ -380,6 +380,10 @@
 	ACPI_FUNCTION_TRACE ("ut_stroul64");
 
 
+	if ((!string) || !(*string)) {
+		goto error_exit;
+	}
+
 	switch (base) {
 	case ACPI_ANY_BASE:
 	case 10:
@@ -394,7 +398,7 @@
 	/* Skip over any white space in the buffer */
 
 	while (ACPI_IS_SPACE (*string) || *string == '\t') {
-		++string;
+		string++;
 	}
 
 	/*
@@ -403,9 +407,9 @@
 	 */
 	if (base == 0) {
 		if ((*string == '0') &&
-			(ACPI_TOLOWER (*(++string)) == 'x')) {
+			(ACPI_TOLOWER (*(string + 1)) == 'x')) {
 			base = 16;
-			++string;
+			string += 2;
 		}
 		else {
 			base = 10;
@@ -416,10 +420,10 @@
 	 * For hexadecimal base, skip over the leading
 	 * 0 or 0x, if they are present.
 	 */
-	if (base == 16 &&
-		*string == '0' &&
-		ACPI_TOLOWER (*(++string)) == 'x') {
-		string++;
+	if ((base == 16) &&
+		(*string == '0') &&
+		(ACPI_TOLOWER (*(string + 1)) == 'x')) {
+		string += 2;
 	}
 
 	/* Any string left? */
@@ -437,23 +441,27 @@
 			this_digit = ((u8) *string) - '0';
 		}
 		else {
+			if (base == 10) {
+				/* Digit is out of range */
+
+				goto error_exit;
+			}
+
 			this_digit = (u8) ACPI_TOUPPER (*string);
-			if (ACPI_IS_UPPER ((char) this_digit)) {
+			if (ACPI_IS_XDIGIT ((char) this_digit)) {
 				/* Convert ASCII Hex char to value */
 
 				this_digit = this_digit - 'A' + 10;
 			}
 			else {
-				goto error_exit;
+				/*
+				 * We allow non-hex chars, just stop now, same as end-of-string.
+				 * See ACPI spec, string-to-integer conversion.
+				 */
+				break;
 			}
 		}
 
-		/* Check to see if digit is out of range */
-
-		if (this_digit >= base) {
-			goto error_exit;
-		}
-
 		/* Divide the digit into the correct position */
 
 		(void) acpi_ut_short_divide ((ACPI_INTEGER_MAX - (acpi_integer) this_digit),
@@ -464,8 +472,10 @@
 
 		return_value *= base;
 		return_value += this_digit;
-		++string;
+		string++;
 	}
+
+	/* All done, normal exit */
 
 	*ret_integer = return_value;
 	return_ACPI_STATUS (AE_OK);
diff -Nru a/drivers/acpi/video.c b/drivers/acpi/video.c
--- a/drivers/acpi/video.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/acpi/video.c	2005-03-30 17:02:46 -08:00
@@ -683,7 +683,7 @@
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
 
-struct proc_dir_entry		*acpi_video_dir;
+static struct proc_dir_entry	*acpi_video_dir;
 
 /* video devices */
 
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/base/sys.c	2005-03-30 17:02:46 -08:00
@@ -21,7 +21,6 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 
-
 extern struct subsystem devices_subsys;
 
 #define to_sysdev(k) container_of(k, struct sys_device, kobj)
diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/net/b44.c	2005-03-30 17:02:46 -08:00
@@ -1921,6 +1921,7 @@
 	b44_free_rings(bp);
 
 	spin_unlock_irq(&bp->lock);
+	pci_disable_device(pdev);
 	return 0;
 }
 
@@ -1930,6 +1931,8 @@
 	struct b44 *bp = netdev_priv(dev);
 
 	pci_restore_state(pdev);
+	pci_enable_device(pdev);
+	pci_set_master(pdev);
 
 	if (!netif_running(dev))
 		return 0;
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/net/e1000/e1000_main.c	2005-03-30 17:02:46 -08:00
@@ -3103,8 +3103,7 @@
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 	ret = pci_enable_device(pdev);
-	if (pdev->is_busmaster)
-		pci_set_master(pdev);
+	pci_set_master(pdev);
 
 	pci_enable_wake(pdev, 3, 0);
 	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
--- a/drivers/net/ne2k-pci.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/net/ne2k-pci.c	2005-03-30 17:02:46 -08:00
@@ -660,6 +660,7 @@
 
 	netif_device_detach(dev);
 	pci_save_state(pdev);
+	pci_disable_device(pdev);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
@@ -671,6 +672,8 @@
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
+	pci_enable_device(pdev);
+	pci_set_master(pdev);
 	NS8390_init(dev, 1);
 	netif_device_attach(dev);
 
diff -Nru a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
--- a/drivers/pci/pci-acpi.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/pci/pci-acpi.c	2005-03-30 17:02:46 -08:00
@@ -1,9 +1,10 @@
 /*
  * File:	pci-acpi.c
- * Purpose:	Provide PCI supports in ACPI
+ * Purpose:	Provide PCI support in ACPI
  *
- * Copyright (C) 2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com>
+ * Copyright (C) 2004 Intel Corp.
  */
 
 #include <linux/delay.h>
@@ -16,6 +17,7 @@
 #include <acpi/acpi_bus.h>
 
 #include <linux/pci-acpi.h>
+#include "pci.h"
 
 static u32 ctrlset_buf[3] = {0, 0, 0};
 static u32 global_ctrlsets = 0;
@@ -207,3 +209,105 @@
 	return status;
 }
 EXPORT_SYMBOL(pci_osc_control_set);
+
+/*
+ * _SxD returns the D-state with the highest power
+ * (lowest D-state number) supported in the S-state "x".
+ *
+ * If the devices does not have a _PRW
+ * (Power Resources for Wake) supporting system wakeup from "x"
+ * then the OS is free to choose a lower power (higher number
+ * D-state) than the return value from _SxD.
+ *
+ * But if _PRW is enabled at S-state "x", the OS
+ * must not choose a power lower than _SxD --
+ * unless the device has an _SxW method specifying
+ * the lowest power (highest D-state number) the device
+ * may enter while still able to wake the system.
+ *
+ * ie. depending on global OS policy:
+ *
+ * if (_PRW at S-state x)
+ *	choose from highest power _SxD to lowest power _SxW
+ * else // no _PRW at S-state x
+ * 	choose highest power _SxD or any lower power
+ *
+ * currently we simply return _SxD, if present.
+ */
+
+static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state)
+{
+	/* TBD */
+
+	return -ENODEV;
+}
+
+static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
+{
+	acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
+	static int state_conv[] = {
+		[0] = 0,
+		[1] = 1,
+		[2] = 2,
+		[3] = 3,
+		[4] = 3
+	};
+	int acpi_state = state_conv[(int __force) state];
+
+	if (!handle)
+		return -ENODEV;
+	return acpi_bus_set_power(handle, acpi_state);
+}
+
+
+/* ACPI bus type */
+static int pci_acpi_find_device(struct device *dev, acpi_handle *handle)
+{
+	struct pci_dev * pci_dev;
+	acpi_integer	addr;
+
+	pci_dev = to_pci_dev(dev);
+	/* Please ref to ACPI spec for the syntax of _ADR */
+	addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+	*handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+	if (!*handle)
+		return -ENODEV;
+	return 0;
+}
+
+static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle)
+{
+	int num;
+	unsigned int seg, bus;
+
+	/*
+	 * The string should be the same as root bridge's name
+	 * Please look at 'pci_scan_bus_parented'
+	 */
+	num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus);
+	if (num != 2)
+		return -ENODEV;
+	*handle = acpi_get_pci_rootbridge_handle(seg, bus);
+	if (!*handle)
+		return -ENODEV;
+	return 0;
+}
+
+static struct acpi_bus_type pci_acpi_bus = {
+	.bus = &pci_bus_type,
+	.find_device = pci_acpi_find_device,
+	.find_bridge = pci_acpi_find_root_bridge,
+};
+
+static int __init pci_acpi_init(void)
+{
+	int ret;
+
+	ret = register_acpi_bus_type(&pci_acpi_bus);
+	if (ret)
+		return 0;
+	platform_pci_choose_state = acpi_pci_choose_state;
+	platform_pci_set_power_state = acpi_pci_set_power_state;
+	return 0;
+}
+arch_initcall(pci_acpi_init);
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/pci/pci.c	2005-03-30 17:02:46 -08:00
@@ -240,7 +240,7 @@
  * -EIO if device does not support PCI PM.
  * 0 if we can successfully change the power state.
  */
-
+int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t) = NULL;
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
@@ -304,8 +304,15 @@
 		msleep(10);
 	else if (state == PCI_D2 || dev->current_state == PCI_D2)
 		udelay(200);
-	dev->current_state = state;
 
+	/*
+	 * Give firmware a chance to be called, such as ACPI _PRx, _PSx
+	 * Firmware method after natice method ?
+	 */
+	if (platform_pci_set_power_state)
+		platform_pci_set_power_state(dev, state);
+
+	dev->current_state = state;
 	return 0;
 }
 
@@ -318,12 +325,19 @@
  * Returns PCI power state suitable for given device and given system
  * message.
  */
+int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state) = NULL;
 
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
 {
+	int	ret;
 	if (!pci_find_capability(dev, PCI_CAP_ID_PM))
 		return PCI_D0;
 
+	if (platform_pci_choose_state) {
+		ret = platform_pci_choose_state(dev, state);
+		if (ret >= 0)
+			state = ret;
+	}
 	switch (state) {
 	case 0: return PCI_D0;
 	case 3: return PCI_D3hot;
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h	2005-03-30 17:02:46 -08:00
+++ b/drivers/pci/pci.h	2005-03-30 17:02:46 -08:00
@@ -11,6 +11,10 @@
 				  void (*alignf)(void *, struct resource *,
 					  	 unsigned long, unsigned long),
 				  void *alignf_data);
+/* Firmware callbacks */
+extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
+extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state);
+
 /* PCI /proc functions */
 #ifdef CONFIG_PROC_FS
 extern int pci_proc_attach_device(struct pci_dev *dev);
diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- a/drivers/pcmcia/yenta_socket.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/pcmcia/yenta_socket.c	2005-03-30 17:02:46 -08:00
@@ -1032,6 +1032,7 @@
 		pci_save_state(dev);
 		pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
 		pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
+		pci_disable_device(dev);
 
 		/*
 		 * Some laptops (IBM T22) do not like us putting the Cardbus
@@ -1055,6 +1056,8 @@
 		pci_restore_state(dev);
 		pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
 		pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
+		pci_enable_device(dev);
+		pci_set_master(dev);
 
 		if (socket->type && socket->type->restore_state)
 			socket->type->restore_state(socket);
diff -Nru a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
--- a/drivers/pnp/pnpacpi/rsparser.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/pnp/pnpacpi/rsparser.c	2005-03-30 17:02:46 -08:00
@@ -219,9 +219,10 @@
 		res->data.address64.min_address_range, 
 		res->data.address64.address_length);
 		break;
+	case ACPI_RSTYPE_VENDOR:
+		break;
 	default:
-		pnp_warn("PnPACPI: Alloc type : %d not handle", 
-				res->id);
+		pnp_warn("PnPACPI: unknown resource type %d", res->id);
 		return AE_ERROR;
 	}
 			
@@ -508,7 +509,7 @@
 		case ACPI_RSTYPE_END_DPF:
 			return AE_CTRL_TERMINATE;
 		default:
-			pnp_warn("PnPACPI:Option type: %d not handle", res->id);
+			pnp_warn("PnPACPI: unknown resource type %d", res->id);
 			return AE_ERROR;
 	}
 			
@@ -810,7 +811,7 @@
 			mem ++;
 			break;
 		default: /* other type */
-			pnp_warn("Invalid type");
+			pnp_warn("unknown resource type %d", resource->id);
 			return -EINVAL;
 		}
 		resource ++;
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c	2005-03-30 17:02:46 -08:00
+++ b/drivers/usb/core/hcd-pci.c	2005-03-30 17:02:46 -08:00
@@ -349,6 +349,7 @@
 		usb_hc_died (hcd);
 	}
 
+	pci_enable_device(dev);
 	return retval;
 }
 EXPORT_SYMBOL (usb_hcd_pci_resume);
diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- a/include/acpi/acconfig.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acconfig.h	2005-03-30 17:02:46 -08:00
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20050211
+#define ACPI_CA_VERSION                 0x20050309
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
@@ -198,7 +198,7 @@
 
 /* Number of strings associated with the _OSI reserved method */
 
-#define ACPI_NUM_OSI_STRINGS            9
+#define ACPI_NUM_OSI_STRINGS            10
 
 
 /******************************************************************************
diff -Nru a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h
--- a/include/acpi/acdisasm.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acdisasm.h	2005-03-30 17:02:46 -08:00
@@ -75,6 +75,11 @@
 extern const char                       *acpi_gbl_TYPdecode[4];
 extern const char                       *acpi_gbl_BMdecode[2];
 extern const char                       *acpi_gbl_SIZdecode[4];
+extern const char                       *acpi_gbl_TTPdecode[2];
+extern const char                       *acpi_gbl_MTPdecode[4];
+extern const char                       *acpi_gbl_TRSdecode[2];
+
+
 extern const char                       *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES];
 extern const char                       *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES];
 extern const char                       *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES];
diff -Nru a/include/acpi/acdispat.h b/include/acpi/acdispat.h
--- a/include/acpi/acdispat.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acdispat.h	2005-03-30 17:02:46 -08:00
@@ -374,6 +374,16 @@
 
 /* dsutils - Parser/Interpreter interface utility routines */
 
+void
+acpi_ds_clear_implicit_return (
+	struct acpi_walk_state          *walk_state);
+
+u8
+acpi_ds_do_implicit_return (
+	union acpi_operand_object       *return_desc,
+	struct acpi_walk_state          *walk_state,
+	u8                              add_reference);
+
 u8
 acpi_ds_is_result_used (
 	union acpi_parse_object         *op,
diff -Nru a/include/acpi/acinterp.h b/include/acpi/acinterp.h
--- a/include/acpi/acinterp.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acinterp.h	2005-03-30 17:02:46 -08:00
@@ -617,7 +617,6 @@
 
 acpi_status
 acpi_ex_store_buffer_to_buffer (
-	acpi_object_type                original_src_type,
 	union acpi_operand_object       *source_desc,
 	union acpi_operand_object       *target_desc);
 
diff -Nru a/include/acpi/aclocal.h b/include/acpi/aclocal.h
--- a/include/acpi/aclocal.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/aclocal.h	2005-03-30 17:02:46 -08:00
@@ -774,6 +774,7 @@
 #define ACPI_BITMASK_POWER_BUTTON_STATUS        0x0100
 #define ACPI_BITMASK_SLEEP_BUTTON_STATUS        0x0200
 #define ACPI_BITMASK_RT_CLOCK_STATUS            0x0400
+#define ACPI_BITMASK_PCIEXP_WAKE_STATUS         0x4000    /* ACPI 3.0 */
 #define ACPI_BITMASK_WAKE_STATUS                0x8000
 
 #define ACPI_BITMASK_ALL_FIXED_STATUS           (ACPI_BITMASK_TIMER_STATUS          | \
@@ -789,6 +790,7 @@
 #define ACPI_BITMASK_POWER_BUTTON_ENABLE        0x0100
 #define ACPI_BITMASK_SLEEP_BUTTON_ENABLE        0x0200
 #define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
+#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE        0x4000    /* ACPI 3.0 */
 
 #define ACPI_BITMASK_SCI_ENABLE                 0x0001
 #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
@@ -807,6 +809,7 @@
 #define ACPI_BITPOSITION_POWER_BUTTON_STATUS    0x08
 #define ACPI_BITPOSITION_SLEEP_BUTTON_STATUS    0x09
 #define ACPI_BITPOSITION_RT_CLOCK_STATUS        0x0A
+#define ACPI_BITPOSITION_PCIEXP_WAKE_STATUS     0x0E    /* ACPI 3.0 */
 #define ACPI_BITPOSITION_WAKE_STATUS            0x0F
 
 #define ACPI_BITPOSITION_TIMER_ENABLE           0x00
@@ -814,6 +817,7 @@
 #define ACPI_BITPOSITION_POWER_BUTTON_ENABLE    0x08
 #define ACPI_BITPOSITION_SLEEP_BUTTON_ENABLE    0x09
 #define ACPI_BITPOSITION_RT_CLOCK_ENABLE        0x0A
+#define ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE    0x0E    /* ACPI 3.0 */
 
 #define ACPI_BITPOSITION_SCI_ENABLE             0x00
 #define ACPI_BITPOSITION_BUS_MASTER_RLD         0x01
diff -Nru a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
--- a/include/acpi/acpi_bus.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acpi_bus.h	2005-03-30 17:02:46 -08:00
@@ -328,7 +328,6 @@
 int acpi_bus_register_driver (struct acpi_driver *driver);
 int acpi_bus_unregister_driver (struct acpi_driver *driver);
 int acpi_bus_scan (struct acpi_device *start);
-int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
 		acpi_handle handle, int type);
 
@@ -336,6 +335,27 @@
 int acpi_match_ids (struct acpi_device	*device, char	*ids);
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
+
+
+/*
+ * Bind physical devices with ACPI devices
+ */
+#include <linux/device.h>
+struct acpi_bus_type {
+	struct list_head	list;
+	struct bus_type		*bus;
+	/* For general devices under the bus*/
+	int (*find_device)(struct device *, acpi_handle*);
+	/* For bridges, such as PCI root bridge, IDE controller */
+	int (*find_bridge)(struct device *, acpi_handle *);
+};
+int register_acpi_bus_type(struct acpi_bus_type *);
+int unregister_acpi_bus_type(struct acpi_bus_type *);
+struct device *acpi_get_physical_device(acpi_handle);
+/* helper */
+acpi_handle acpi_get_child(acpi_handle, acpi_integer);
+acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
+#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data))
 
 #endif /*CONFIG_ACPI_BUS*/
 
diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- a/include/acpi/acpi_drivers.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acpi_drivers.h	2005-03-30 17:02:46 -08:00
@@ -56,7 +56,8 @@
 /* ACPI PCI Interrupt Link (pci_link.c) */
 
 int acpi_irq_penalty_init (void);
-int acpi_pci_link_get_irq (acpi_handle handle, int index, int* edge_level, int* active_high_low);
+int acpi_pci_link_get_irq (acpi_handle handle, int index, int *edge_level,
+	int *active_high_low, char **name);
 
 /* ACPI PCI Interrupt Routing (pci_irq.c) */
 
@@ -107,5 +108,10 @@
 
 int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
 
+/* --------------------------------------------------------------------------
+                                    Hot Keys
+   -------------------------------------------------------------------------- */
+
+extern int acpi_specific_hotkey_enabled;
 
 #endif /*__ACPI_DRIVERS_H__*/
diff -Nru a/include/acpi/acstruct.h b/include/acpi/acstruct.h
--- a/include/acpi/acstruct.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/acstruct.h	2005-03-30 17:02:46 -08:00
@@ -94,6 +94,7 @@
 	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_gpe_event_info          *gpe_event_info;                    /* Info for GPE (_Lxx/_Exx methods only */
+	union acpi_operand_object           *implicit_return_obj;
 	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 */
diff -Nru a/include/acpi/actbl.h b/include/acpi/actbl.h
--- a/include/acpi/actbl.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/actbl.h	2005-03-30 17:02:46 -08:00
@@ -261,6 +261,8 @@
 	u8                              local_sapic_eid;        /* SAPIC EID */
 	u8                              reserved [3];           /* Reserved - must be zero */
 	LOCAL_APIC_FLAGS
+	u32                             processor_uID;          /* Numeric UID - ACPI 3.0 */
+	char                            processor_uIDstring[1]; /* String UID  - ACPI 3.0 */
 };
 
 struct madt_interrupt_source
@@ -272,7 +274,7 @@
 	u8                              processor_eid;          /* Processor EID */
 	u8                              io_sapic_vector;        /* Vector value for PMI interrupts */
 	u32                             interrupt;              /* Global system interrupt */
-	u32                             reserved;               /* Reserved - must be zero */
+	u32                             flags;                  /* Interrupt Source Flags */
 };
 
 
diff -Nru a/include/acpi/actbl2.h b/include/acpi/actbl2.h
--- a/include/acpi/actbl2.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/actbl2.h	2005-03-30 17:02:46 -08:00
@@ -108,7 +108,7 @@
 
 
 /*
- * ACPI 2.0 Generic Address Structure (GAS)
+ * ACPI 2.0+ Generic Address Structure (GAS)
  */
 struct acpi_generic_address
 {
@@ -159,7 +159,7 @@
 	u16                             iapc_boot_arch;     /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/
 
 /*
- * ACPI 2.0 Fixed ACPI Description Table (FADT)
+ * ACPI 2.0+ Fixed ACPI Description Table (FADT)
  */
 struct fadt_descriptor_rev2
 {
@@ -174,17 +174,25 @@
 	u32                             sleep_button : 1;   /* Sleep button is handled as a generic feature, or not present */
 	u32                             fixed_rTC   : 1;    /* RTC wakeup stat not in fixed register space */
 	u32                             rtcs4       : 1;    /* RTC wakeup stat not possible from S4 */
-	u32                             tmr_val_ext : 1;    /* Indicates tmr_val is 32 bits 0=24-bits*/
+	u32                             tmr_val_ext : 1;    /* Indicates tmr_val is 32 bits 0=24-bits */
 	u32                             dock_cap    : 1;    /* Supports Docking */
-	u32                             reset_reg_sup : 1;  /* Indicates system supports system reset via the FADT RESET_REG*/
-	u32                             sealed_case : 1;    /* Indicates system has no internal expansion capabilities and case is sealed. */
-	u32                             headless    : 1;    /* Indicates system does not have local video capabilities or local input devices.*/
+	u32                             reset_reg_sup : 1;  /* Indicates system supports system reset via the FADT RESET_REG */
+	u32                             sealed_case : 1;    /* Indicates system has no internal expansion capabilities and case is sealed */
+	u32                             headless    : 1;    /* Indicates system does not have local video capabilities or local input devices */
 	u32                             cpu_sw_sleep : 1;   /* Indicates to OSPM that a processor native instruction */
-			   /* Must be executed after writing the SLP_TYPx register. */
-	u32                             reserved6   : 18;   /* Reserved - must be zero */
+			   /* must be executed after writing the SLP_TYPx register */
+	/* ACPI 3.0 flag bits */
+
+	u32                             pci_exp_wak                         : 1; /* System supports PCIEXP_WAKE (STS/EN) bits */
+	u32                             use_platform_clock                  : 1; /* OSPM should use platform-provided timer */
+	u32                             S4rtc_sts_valid                     : 1; /* Contents of RTC_STS valid after S4 wake */
+	u32                             remote_power_on_capable             : 1; /* System is compatible with remote power on */
+	u32                             force_apic_cluster_model            : 1; /* All local APICs must use cluster model */
+	u32                             force_apic_physical_destination_mode : 1; /* all local x_aPICs must use physical dest mode */
+	u32                             reserved6                           : 12;/* Reserved - must be zero */
 
 	struct acpi_generic_address     reset_register;     /* Reset register address in GAS format */
-	u8                              reset_value;        /* Value to write to the reset_register port to reset the system. */
+	u8                              reset_value;        /* Value to write to the reset_register port to reset the system */
 	u8                              reserved7[3];       /* These three bytes must be zero */
 	u64                             xfirmware_ctrl;     /* 64-bit physical address of FACS */
 	u64                             Xdsdt;              /* 64-bit physical address of DSDT */
@@ -199,7 +207,7 @@
 };
 
 
-/* "Downrevved" ACPI 2.0 FADT descriptor */
+/* "Down-revved" ACPI 2.0 FADT descriptor */
 
 struct fadt_descriptor_rev2_minus
 {
@@ -213,7 +221,7 @@
 };
 
 
-/* Embedded Controller */
+/* ECDT - Embedded Controller Boot Resources Table */
 
 struct ec_boot_resources
 {
@@ -223,6 +231,55 @@
 	u32                             uid;                /* Unique ID - must be same as the EC _UID method */
 	u8                              gpe_bit;            /* The GPE for the EC */
 	u8                              ec_id[1];           /* Full namepath of the EC in the ACPI namespace */
+};
+
+
+/* SRAT - System Resource Affinity Table */
+
+struct static_resource_alloc
+{
+	u8                              type;
+	u8                              length;
+	u8                              proximity_domain_lo;
+	u8                              apic_id;
+	u32                             enabled         :1;
+	u32                             reserved3       :31;
+	u8                              local_sapic_eid;
+	u8                              proximity_domain_hi[3];
+	u32                             reserved4;
+};
+
+struct memory_affinity
+{
+	u8                              type;
+	u8                              length;
+	u32                             proximity_domain;
+	u16                             reserved3;
+	u64                             base_address;
+	u64                             address_length;
+	u32                             reserved4;
+	u32                             enabled         :1;
+	u32                             hot_pluggable   :1;
+	u32                             non_volatile    :1;
+	u32                             reserved5       :29;
+	u64                             reserved6;
+};
+
+struct system_resource_affinity
+{
+	ACPI_TABLE_HEADER_DEF
+	u32                             reserved1;          /* Must be value '1' */
+	u64                             reserved2;
+};
+
+
+/* SLIT - System Locality Distance Information Table */
+
+struct system_locality_info
+{
+	ACPI_TABLE_HEADER_DEF
+	u64                             locality_count;
+	u8                              entry[1][1];
 };
 
 
diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h
--- a/include/acpi/actypes.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/actypes.h	2005-03-30 17:02:46 -08:00
@@ -653,24 +653,26 @@
 #define ACPI_BITREG_SLEEP_BUTTON_STATUS         0x04
 #define ACPI_BITREG_RT_CLOCK_STATUS             0x05
 #define ACPI_BITREG_WAKE_STATUS                 0x06
+#define ACPI_BITREG_PCIEXP_WAKE_STATUS          0x07
 
-#define ACPI_BITREG_TIMER_ENABLE                0x07
-#define ACPI_BITREG_GLOBAL_LOCK_ENABLE          0x08
-#define ACPI_BITREG_POWER_BUTTON_ENABLE         0x09
-#define ACPI_BITREG_SLEEP_BUTTON_ENABLE         0x0A
-#define ACPI_BITREG_RT_CLOCK_ENABLE             0x0B
-#define ACPI_BITREG_WAKE_ENABLE                 0x0C
-
-#define ACPI_BITREG_SCI_ENABLE                  0x0D
-#define ACPI_BITREG_BUS_MASTER_RLD              0x0E
-#define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x0F
-#define ACPI_BITREG_SLEEP_TYPE_A                0x10
-#define ACPI_BITREG_SLEEP_TYPE_B                0x11
-#define ACPI_BITREG_SLEEP_ENABLE                0x12
+#define ACPI_BITREG_TIMER_ENABLE                0x08
+#define ACPI_BITREG_GLOBAL_LOCK_ENABLE          0x09
+#define ACPI_BITREG_POWER_BUTTON_ENABLE         0x0A
+#define ACPI_BITREG_SLEEP_BUTTON_ENABLE         0x0B
+#define ACPI_BITREG_RT_CLOCK_ENABLE             0x0C
+#define ACPI_BITREG_WAKE_ENABLE                 0x0D
+#define ACPI_BITREG_PCIEXP_WAKE_DISABLE         0x0E
+
+#define ACPI_BITREG_SCI_ENABLE                  0x0F
+#define ACPI_BITREG_BUS_MASTER_RLD              0x10
+#define ACPI_BITREG_GLOBAL_LOCK_RELEASE         0x11
+#define ACPI_BITREG_SLEEP_TYPE_A                0x12
+#define ACPI_BITREG_SLEEP_TYPE_B                0x13
+#define ACPI_BITREG_SLEEP_ENABLE                0x14
 
-#define ACPI_BITREG_ARB_DISABLE                 0x13
+#define ACPI_BITREG_ARB_DISABLE                 0x15
 
-#define ACPI_BITREG_MAX                         0x13
+#define ACPI_BITREG_MAX                         0x15
 #define ACPI_NUM_BITREG                         ACPI_BITREG_MAX + 1
 
 
@@ -1206,6 +1208,7 @@
 	u64                                 max_address_range;
 	u64                                 address_translation_offset;
 	u64                                 address_length;
+	u64                                 type_specific_attributes;
 	struct acpi_resource_source         resource_source;
 };
 
diff -Nru a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
--- a/include/acpi/platform/acenv.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/platform/acenv.h	2005-03-30 17:02:46 -08:00
@@ -226,6 +226,7 @@
  */
 
 #define ACPI_STRSTR(s1,s2)      strstr((s1), (s2))
+#define ACPI_STRCHR(s1,c)       strchr((s1), (c))
 
 #ifdef ACPI_FUTURE_USAGE
 #define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
@@ -294,6 +295,7 @@
 
 
 #define ACPI_STRSTR(s1,s2)      acpi_ut_strstr ((s1), (s2))
+#define ACPI_STRCHR(s1,c)       acpi_ut_strchr ((s1), (c))
 
 #ifdef ACPI_FUTURE_USAGE
 #define ACPI_STRUPR(s)          (void) acpi_ut_strupr ((s))
diff -Nru a/include/acpi/processor.h b/include/acpi/processor.h
--- a/include/acpi/processor.h	2005-03-30 17:02:46 -08:00
+++ b/include/acpi/processor.h	2005-03-30 17:02:46 -08:00
@@ -201,7 +201,6 @@
 /* in processor_throttling.c */
 int acpi_processor_get_throttling_info (struct acpi_processor *pr);
 int acpi_processor_set_throttling (struct acpi_processor *pr, int state);
-int acpi_processor_throttling_open_fs(struct inode *inode, struct file *file);
 ssize_t acpi_processor_write_throttling (
         struct file		*file,
         const char		__user *buffer,
@@ -217,7 +216,6 @@
 
 /* in processor_thermal.c */
 int acpi_processor_get_limit_info (struct acpi_processor *pr);
-int acpi_processor_limit_open_fs(struct inode *inode, struct file *file);
 ssize_t acpi_processor_write_limit (
 	struct file		*file,
 	const char		__user *buffer,
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	2005-03-30 17:02:46 -08:00
+++ b/include/linux/acpi.h	2005-03-30 17:02:46 -08:00
@@ -455,8 +455,6 @@
 	struct list_head	entries;
 };
 
-extern struct acpi_prt_list	acpi_prt;
-
 struct pci_dev;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	2005-03-30 17:02:46 -08:00
+++ b/include/linux/device.h	2005-03-30 17:02:46 -08:00
@@ -269,8 +269,10 @@
 	struct device_driver *driver;	/* which driver has allocated this
 					   device */
 	void		*driver_data;	/* data private to the driver */
-	void		*platform_data;	/* Platform specific data (e.g. ACPI,
-					   BIOS data relevant to device) */
+	void		*platform_data;	/* Platform specific data, device
+					   core doesn't touch it */
+	void		*firmware_data; /* Firmware specific data (e.g. ACPI,
+					   BIOS data),reserved for device core*/
 	struct dev_pm_info	power;
 
 	u32		detach_state;	/* State to enter when device is
diff -Nru a/include/linux/pm.h b/include/linux/pm.h
--- a/include/linux/pm.h	2005-03-30 17:02:46 -08:00
+++ b/include/linux/pm.h	2005-03-30 17:02:46 -08:00
@@ -175,7 +175,7 @@
 };
 
 extern void pm_set_ops(struct pm_ops *);
-
+extern struct pm_ops *pm_ops;
 extern int pm_suspend(suspend_state_t state);
 
 
diff -Nru a/kernel/power/main.c b/kernel/power/main.c
--- a/kernel/power/main.c	2005-03-30 17:02:46 -08:00
+++ b/kernel/power/main.c	2005-03-30 17:02:46 -08:00
@@ -19,6 +19,9 @@
 
 #include "power.h"
 
+/*This is just an arbitrary number */
+#define FREE_PAGE_NUMBER (100)
+
 DECLARE_MUTEX(pm_sem);
 
 struct pm_ops * pm_ops = NULL;
@@ -49,6 +52,7 @@
 static int suspend_prepare(suspend_state_t state)
 {
 	int error = 0;
+	unsigned int free_pages;
 
 	if (!pm_ops || !pm_ops->enter)
 		return -EPERM;
@@ -60,6 +64,16 @@
 		goto Thaw;
 	}
 
+	if ((free_pages = nr_free_pages()) < FREE_PAGE_NUMBER) {
+		pr_debug("PM: free some memory\n");
+		shrink_all_memory(FREE_PAGE_NUMBER - free_pages);
+		if (nr_free_pages() < FREE_PAGE_NUMBER) {
+			error = -ENOMEM;
+			printk(KERN_ERR "PM: No enough memory\n");
+			goto Thaw;
+		}
+	}
+
 	if (pm_ops->prepare) {
 		if ((error = pm_ops->prepare(state)))
 			goto Thaw;
@@ -190,7 +204,7 @@
 
 int pm_suspend(suspend_state_t state)
 {
-	if (state > PM_SUSPEND_ON && state < PM_SUSPEND_MAX)
+	if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX)
 		return enter_state(state);
 	return -EINVAL;
 }