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

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/04/04 00:42:58-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# drivers/pci/quirks.c
#   2005/04/04 00:42:51-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pci/pci.c
#   2005/04/04 00:42:51-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/04/01 11:14:11-08:00 akpm@bix.(none) 
#   Merge bk://linux-acpi.bkbits.net/to-akpm
#   into bix.(none):/usr/src/bk-acpi
# 
# kernel/power/main.c
#   2005/04/01 11:14:06-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/04/01 11:14:06-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pci/pci.c
#   2005/04/01 11:14:06-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/net/e1000/e1000_main.c
#   2005/04/01 11:14:06-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/net/b44.c
#   2005/04/01 11:14:06-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/04/01 00:59:46-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-latest-hotplug
#   into intel.com:/home/lenb/bk/to-akpm
# 
# include/linux/acpi.h
#   2005/04/01 00:59:41-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/net/e1000/e1000_main.c
#   2005/04/01 00:59:41-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/net/b44.c
#   2005/04/01 00:59:41-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/04/01 00:56:27-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-latest-next
#   into intel.com:/home/lenb/bk/to-akpm
# 
# kernel/power/main.c
#   2005/04/01 00:56:22-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pnp/pnpacpi/rsparser.c
#   2005/04/01 00:56:22-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/04/01 00:56:22-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pci/pci.c
#   2005/04/01 00:56:22-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/pci/irq.c
#   2005/04/01 00:56:22-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/04/01 00:07:31-05:00 len.brown@intel.com 
#   [ACPI] PNPACPI vs sound IRQ
#   
#   http://bugme.osdl.org/show_bug.cgi?id=4016
#   
#   Written-by: David Shaohua Li <shaohua.li@intel.com>
#   Acked-by: Adam Belay <abelay@novell.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/linux/acpi.h
#   2005/01/11 21:12:55-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-x86_64/pci.h
#   2005/01/11 21:03:54-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-sparc64/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-sparc/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-sh64/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-sh/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-ppc64/pci.h
#   2005/01/11 21:03:54-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-ppc/pci.h
#   2005/01/11 21:08:28-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-mips/pci.h
#   2005/01/11 21:03:54-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-m68k/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-ia64/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-i386/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-h8300/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-arm/pci.h
#   2005/01/11 21:06:45-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# include/asm-alpha/pci.h
#   2005/01/11 21:04:00-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# drivers/pnp/resource.c
#   2005/01/11 21:09:53-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# drivers/pnp/pnpbios/rsparser.c
#   2005/01/11 21:10:55-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# drivers/pnp/pnpacpi/rsparser.c
#   2005/01/11 21:11:40-05:00 len.brown@intel.com +2 -2
#   PNPACPI vs sound IRQ
# 
# drivers/acpi/pci_link.c
#   2005/01/11 21:15:10-05:00 len.brown@intel.com +5 -2
#   PNPACPI vs sound IRQ
# 
# arch/i386/pci/visws.c
#   2005/01/11 21:03:54-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# arch/i386/pci/irq.c
#   2005/01/11 21:15:49-05:00 len.brown@intel.com +10 -6
#   PNPACPI vs sound IRQ
# 
# arch/frv/mb93090-mb00/pci-irq.c
#   2005/04/01 00:07:22-05:00 len.brown@intel.com +1 -1
#   PNPACPI vs sound IRQ
# 
# ChangeSet
#   2005/03/31 23:23:15-05:00 len.brown@intel.com 
#   [ACPI] update /proc/acpi/processor/*/power even if only C1 support
#   
#   Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/processor_idle.c
#   2005/03/25 21:41:52-05:00 len.brown@intel.com +26 -7
#   C1 stats
# 
# ChangeSet
#   2005/03/31 22:51:10-05:00 len.brown@intel.com 
#   [ACPI] Evaluate CPEI Processor Override flag
#   
#   ACPI 3.0 added a Correctable Platform Error Interrupt (CPEI)
#   Processor Overide flag to MADT.Platform_Interrupt_Source.
#   Record the processor that was provided as hint from ACPI.
#   
#   Signed-off-by: Ashok Raj <ashok.raj@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# include/linux/acpi.h
#   2005/03/21 17:51:34-05:00 len.brown@intel.com +4 -1
#   CPEI Processor Override support
# 
# include/asm-ia64/acpi.h
#   2005/03/21 17:51:34-05:00 len.brown@intel.com +9 -0
#   CPEI Processor Override support
# 
# arch/ia64/kernel/topology.c
#   2005/03/21 17:51:34-05:00 len.brown@intel.com +7 -0
#   CPEI Processor Override support
# 
# arch/ia64/kernel/mca.c
#   2005/03/21 18:22:57-05:00 len.brown@intel.com +1 -1
#   CPEI Processor override support
# 
# arch/ia64/kernel/acpi.c
#   2005/03/22 16:21:07-05:00 len.brown@intel.com +54 -0
#   CPEI Processor Override support
# 
# ChangeSet
#   2005/03/31 12:31:39-08:00 akpm@bix.(none) 
#   Merge bk://linux-acpi.bkbits.net/to-akpm
#   into bix.(none):/usr/src/bk-acpi
# 
# kernel/power/main.c
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# include/linux/device.h
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/hcd-pci.c
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/pci/pci.c
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/acpi/Kconfig
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/03/31 12:31:35-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/31 12:30:20-08:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-acpi
# 
# drivers/net/e1000/e1000_main.c
#   2005/03/31 12:30:16-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/net/b44.c
#   2005/03/31 12:30:16-08:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/31 13:12:38-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/26-latest-test
#   into intel.com:/home/lenb/bk/to-akpm
# 
# include/linux/device.h
#   2005/03/31 13:12:34-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/usb/core/hcd-pci.c
#   2005/03/31 13:12:34-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/31 13:12:34-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pci/pci.c
#   2005/03/31 13:12:33-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/31 13:08:00-05:00 len.brown@intel.com 
#   [ACPI] fix build error resulting from merge
#   
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/button.c
#   2005/03/31 13:07:46-05:00 len.brown@intel.com +0 -1
#   fix merge
# 
# ChangeSet
#   2005/03/30 23:24:18-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/26-latest-ref
#   into intel.com:/home/lenb/src/26-latest-next
# 
# kernel/power/main.c
#   2005/03/30 23:24:13-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/30 23:24:13-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/30 23:23:21-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-latest-hotplug
#   into intel.com:/home/lenb/bk/to-akpm
# 
# drivers/acpi/Kconfig
#   2005/03/30 23:23:14-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/30 23:15:47-05:00 len.brown@intel.com 
#   [ACPI] hotplug Processor consideration in acpi_bus_add()
#   
#   Signed-off-by: Keiichiro Tokunaga <tokunaga.keiich@jp.fujitsu.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/scan.c
#   2005/03/27 01:51:44-05:00 len.brown@intel.com +7 -5
#   This is to add CPU hotplug consideration to acpi_bus_add()
#   that now assumes processor objects are always present,
#   functioning, etc. at least when parent object is present.
#   But, CPU hotplug is supported today, so we need to change
#   the assumption.  If a processor object has _STA method, we
#   should respect it.
# 
# ChangeSet
#   2005/03/30 22:53:30-05:00 len.brown@intel.com 
#   [ACPI] fix debug-mode build warning in acpi/hotkey.c
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/hotkey.c
#   2005/03/30 08:16:09-05:00 len.brown@intel.com +2 -1
#   fix debug-mode build warning in acpi/hotkey.c
#   
#   drivers/acpi/hotkey.c: In function `create_polling_proc':
#   drivers/acpi/hotkey.c:334: warning: ISO C90 forbids mixed declarations and code
# 
# ChangeSet
#   2005/03/30 22:12:13-05:00 len.brown@intel.com 
#   [ACPI] fix build warning
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/ec.c
#   2005/03/30 08:15:58-05:00 len.brown@intel.com +1 -1
#   drivers/acpi/ec.c: In function `acpi_ec_space_handler':
#   drivers/acpi/ec.c:641: warning: value computed is not used
# 
# ChangeSet
#   2005/03/30 22:04:17-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/Kconfig
#   2005/03/30 22:04:12-05:00 len.brown@intel.com +7 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/30 21:56:37-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-stable-acpica
#   into intel.com:/home/lenb/src/26-stable-dev
# 
# drivers/acpi/Kconfig
#   2005/03/30 21:56:33-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/30 21:23:19-05:00 len.brown@intel.com 
#   cleanup: remove unnecessary initializer on static pointers
#   
#   Suggested-by: Greg KH <greg@kroah.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pci/pci.c
#   2005/03/30 21:23:10-05:00 len.brown@intel.com +2 -2
#   remove unnecessary initializers on static pointers
# 
# ChangeSet
#   2005/03/30 20:50:40-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/26-latest-test
#   into intel.com:/home/lenb/bk/to-akpm
# 
# kernel/power/main.c
#   2005/03/30 20:50:35-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/pcmcia/yenta_socket.c
#   2005/03/30 20:50:35-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# 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/30 11:40:44-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/26-latest-ref
#   into intel.com:/home/lenb/src/26-latest-dev
# 
# drivers/pci/quirks.c
#   2005/03/30 11:40:29-05:00 len.brown@intel.com +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/25 14:10:11-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/pci/quirks.c
#   2005/03/25 14:10:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/acpi/pci_irq.c
#   2005/03/25 14:10:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/pci/irq.c
#   2005/03/25 14:10:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/03/25 14:10:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/25 14:02:20-05:00 len.brown@intel.com 
#   VIA Interrupt quirk
#   
#   Delete quirk_via_bridge()
#   Restore quirk_via_irqpic()
#   But now improved to be invoked upon device ENABLE,
#   only for VIA devices -- not all devices behind VIA bridges
#   and only in PIC mode.
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3319
#   
#   Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pci/quirks.c
#   2005/03/25 14:02:12-05:00 len.brown@intel.com +24 -16
#   VIA quirk
# 
# drivers/acpi/pci_irq.c
#   2005/03/25 14:02:12-05:00 len.brown@intel.com +0 -4
#   VIA quirk
# 
# arch/i386/pci/irq.c
#   2005/03/25 14:02:12-05:00 len.brown@intel.com +0 -5
#   VIA quirk
# 
# ChangeSet
#   2005/03/25 13:32:40-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/src/26-stable-dev
#   into intel.com:/lenb/src/26-stable-dev
# 
# arch/i386/kernel/acpi/wakeup.S
#   2005/03/25 13:32:35-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/i386/kernel/acpi/sleep.c
#   2005/03/25 13:32:35-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/25 12:42:31-05:00 len.brown@intel.com 
#   merge
# 
# drivers/acpi/button.c
#   2005/03/25 12:42:23-05:00 len.brown@intel.com +1 -3
#   merge
# 
# ChangeSet
#   2005/03/25 12:03:15-05:00 len.brown@intel.com 
#   [ACPI] PNPACPI parse error
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3912
#   
#   Written-by: matthieu castet <castet.matthieu@free.fr>
#   Acked-by: Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/pnp/pnpacpi/rsparser.c
#   2005/03/25 11:20:41-05:00 len.brown@intel.com +10 -1
#   [ACPI] PNPACPI parse error
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=3912
#   
#   Written-by: matthieu castet <castet.matthieu@free.fr>
#   Acked-by: Shaohua Li <shaohua.li@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/scan.c
#   2005/03/23 20:39:09-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/acpi/pci_irq.c
#   2005/03/23 20:39:09-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/acpi/numa.c
#   2005/03/23 20:39:09-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/ia64/kernel/acpi.c
#   2005/03/23 20:39:08-05:00 len.brown@intel.com +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/18 15:51:24-05:00 len.brown@intel.com 
#   Merge intel.com:/home/lenb/bk/linux-2.6.11
#   into intel.com:/home/lenb/src/26-stable-dev
# 
# drivers/acpi/scan.c
#   2005/03/18 15:51:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/acpi/pci_irq.c
#   2005/03/18 15:51:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# drivers/acpi/numa.c
#   2005/03/18 15:51:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# arch/ia64/kernel/acpi.c
#   2005/03/18 15:51:07-05:00 len.brown@intel.com +0 -0
#   Auto merged
# 
# ChangeSet
#   2005/03/18 15:35:22-05:00 len.brown@intel.com 
#   [ACPI] Allow simultaneous Fixed Feature and Control Method buttons
#   delete /proc/acpi/button
#   
#   http://bugzilla.kernel.org/show_bug.cgi?id=1920
#   
#   Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# drivers/acpi/button.c
#   2005/03/18 15:35:11-05:00 len.brown@intel.com +3 -249
#   Allow simultaneous Fixed Feature and Control Method buttons
#   delete /proc/acpi/button
# 
# 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/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/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/02 13:40:30-05:00 len.brown@intel.com 
#   [ACPI] update CONFIG_ACPI_CONTAINER Kconfig help
#   
#   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/Kconfig
#   2005/02/17 12:13:31-05:00 len.brown@intel.com +7 -2
#   Import patch fix-help-for-acpi_container.patch
# 
# ChangeSet
#   2005/02/08 09:29:08-05:00 len.brown@intel.com 
#   [ACPI] GDT wakeup vector fix
#   
#   Written-by:  Hiroshi Itoh <hiroit@jp.ibm.com>
#   Signed-off-by: Len Brown <len.brown@intel.com>
# 
# arch/i386/kernel/acpi/wakeup.S
#   2005/02/08 09:28:53-05:00 len.brown@intel.com +15 -0
#   Import patch wakeup_gdt2.patch
# 
# arch/i386/kernel/acpi/sleep.c
#   2004/10/18 11:59:32-04:00 len.brown@intel.com +3 -2
#   Import patch wakeup_gdt2.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-04-07 17:51:34 -07: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/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
--- a/arch/frv/mb93090-mb00/pci-irq.c	2005-04-07 17:51:34 -07:00
+++ b/arch/frv/mb93090-mb00/pci-irq.c	2005-04-07 17:51:34 -07:00
@@ -60,7 +60,7 @@
 	}
 }
 
-void __init pcibios_penalize_isa_irq(int irq)
+void __init pcibios_penalize_isa_irq(int irq, int active)
 {
 }
 
diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
--- a/arch/i386/kernel/acpi/sleep.c	2005-04-07 17:51:33 -07:00
+++ b/arch/i386/kernel/acpi/sleep.c	2005-04-07 17:51:33 -07:00
@@ -17,7 +17,7 @@
 
 extern void zap_low_mappings(void);
 
-extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
+extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long,unsigned long));
 
 static void init_low_mapping(pgd_t *pgd, int pgd_limit)
 {
@@ -42,7 +42,8 @@
 		return 1;
 	init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
 	memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
-	acpi_copy_wakeup_routine(acpi_wakeup_address);
+	acpi_copy_wakeup_routine(acpi_wakeup_address,
+				 virt_to_phys((void *)acpi_wakeup_address));
 
 	return 0;
 }
diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- a/arch/i386/kernel/acpi/wakeup.S	2005-04-07 17:51:33 -07:00
+++ b/arch/i386/kernel/acpi/wakeup.S	2005-04-07 17:51:33 -07:00
@@ -97,6 +97,7 @@
 real_magic:	.long 0
 video_mode:	.long 0
 video_flags:	.long 0
+real_gdt_table: .fill GDT_ENTRIES, 8, 0
 real_efer_save_restore:	.long 0
 real_save_efer_edx: 	.long 0
 real_save_efer_eax: 	.long 0
@@ -224,6 +225,7 @@
 #
 # Parameters:
 # %eax:	place to copy wakeup routine to
+# %edx: the second argument (physical address)
 #
 # Returned address is location of code in low memory (past data and stack)
 #
@@ -248,6 +250,9 @@
 	popl	%eax
 2:
 
+	# save wakeup_start physical address in ecx
+	movl	%edx, %ecx
+
 	movl    %cr3, %edx
 	movl    %edx, real_save_cr3 - wakeup_start (%eax)
 	movl    %cr4, %edx
@@ -255,6 +260,16 @@
 	movl	%cr0, %edx
 	movl	%edx, real_save_cr0 - wakeup_start (%eax)
 	sgdt    real_save_gdt - wakeup_start (%eax)
+
+	# gdt body must be addressable from real mode by
+	# copying it to the lower mem
+	lea     real_gdt_table - wakeup_start (%ecx), %ecx
+	movl    %ecx, real_save_gdt + 2 - wakeup_start (%eax)
+	xor     %ecx, %ecx
+	movw    saved_gdt, %cx
+	movl    saved_gdt + 2, %esi
+	lea     real_gdt_table - wakeup_start (%eax), %edi
+	rep movsb
 
 	movl	saved_videomode, %edx
 	movl	%edx, video_mode - wakeup_start (%eax)
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c	2005-04-07 17:51:34 -07:00
+++ b/arch/i386/pci/irq.c	2005-04-07 17:51:34 -07:00
@@ -1003,30 +1003,33 @@
 subsys_initcall(pcibios_irq_init);
 
 
-static void pirq_penalize_isa_irq(int irq)
+static void pirq_penalize_isa_irq(int irq, int active)
 {
 	/*
 	 *  If any ISAPnP device reports an IRQ in its list of possible
 	 *  IRQ's, we try to avoid assigning it to PCI devices.
 	 */
-	if (irq < 16)
-		pirq_penalty[irq] += 100;
+	if (irq < 16) {
+		if (active)
+			pirq_penalty[irq] += 1000;
+		else
+			pirq_penalty[irq] += 100;
+	}
 }
 
-void pcibios_penalize_isa_irq(int irq)
+void pcibios_penalize_isa_irq(int irq, int active)
 {
 #ifdef CONFIG_ACPI_PCI
 	if (!acpi_noirq)
-		acpi_penalize_isa_irq(irq);
+		acpi_penalize_isa_irq(irq, active);
 	else
 #endif
-		pirq_penalize_isa_irq(irq);
+		pirq_penalize_isa_irq(irq, active);
 }
 
 static int pirq_enable_irq(struct pci_dev *dev)
 {
 	u8 pin;
-	extern int via_interrupt_line_quirk;
 	struct pci_dev *temp_dev;
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1081,10 +1084,6 @@
 		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
 		       'A' + pin, pci_name(dev), msg);
 	}
-	/* VIA bridges use interrupt line for apic/pci steering across
-	   the V-Link */
-	else if (via_interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
 	return 0;
 }
 
diff -Nru a/arch/i386/pci/visws.c b/arch/i386/pci/visws.c
--- a/arch/i386/pci/visws.c	2005-04-07 17:51:34 -07:00
+++ b/arch/i386/pci/visws.c	2005-04-07 17:51:34 -07:00
@@ -21,7 +21,7 @@
 
 int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq;
 
-void __init pcibios_penalize_isa_irq(int irq) {}
+void __init pcibios_penalize_isa_irq(int irq, int active) {}
 
 
 unsigned int pci_bus0, pci_bus1;
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	2005-04-07 17:51:34 -07:00
+++ b/arch/ia64/kernel/acpi.c	2005-04-07 17:51:34 -07:00
@@ -11,6 +11,7 @@
  *  Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com>
  *  Copyright (C) 2001 Takayoshi Kochi <t-kochi@bq.jp.nec.com>
  *  Copyright (C) 2002 Erich Focht <efocht@ess.nec.de>
+ *  Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
@@ -67,6 +68,11 @@
 unsigned char acpi_kbd_controller_present = 1;
 unsigned char acpi_legacy_devices;
 
+static unsigned int __initdata acpi_madt_rev;
+
+unsigned int acpi_cpei_override;
+unsigned int acpi_cpei_phys_cpuid;
+
 #define MAX_SAPICS 256
 u16 ia64_acpiid_to_sapicid[MAX_SAPICS] =
 	{ [0 ... MAX_SAPICS - 1] = -1 };
@@ -267,10 +273,56 @@
 						(plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
 
 	platform_intr_list[plintsrc->type] = vector;
+	if (acpi_madt_rev > 1) {
+		acpi_cpei_override = plintsrc->plint_flags.cpei_override_flag;
+	}
+
+	/*
+	 * Save the physical id, so we can check when its being removed
+	 */
+	acpi_cpei_phys_cpuid = ((plintsrc->id << 8) | (plintsrc->eid)) & 0xffff;
+
 	return 0;
 }
 
 
+unsigned int can_cpei_retarget(void)
+{
+	extern int cpe_vector;
+
+	/*
+	 * Only if CPEI is supported and the override flag
+	 * is present, otherwise return that its re-targettable
+	 * if we are in polling mode.
+	 */
+	if (cpe_vector > 0 && !acpi_cpei_override)
+		return 0;
+	else
+		return 1;
+}
+
+unsigned int is_cpu_cpei_target(unsigned int cpu)
+{
+	unsigned int logical_id;
+
+	logical_id = cpu_logical_id(acpi_cpei_phys_cpuid);
+
+	if (logical_id == cpu)
+		return 1;
+	else
+		return 0;
+}
+
+void set_cpei_target_cpu(unsigned int cpu)
+{
+	acpi_cpei_phys_cpuid = cpu_physical_id(cpu);
+}
+
+unsigned int get_cpei_target_cpu(void)
+{
+	return acpi_cpei_phys_cpuid;
+}
+
 static int __init
 acpi_parse_int_src_ovr (
 	acpi_table_entry_header *header, const unsigned long end)
@@ -327,6 +379,8 @@
 		return -EINVAL;
 
 	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
+
+	acpi_madt_rev = acpi_madt->header.revision;
 
 	/* remember the value for reference after free_initmem() */
 #ifdef CONFIG_ITANIUM
diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c	2005-04-07 17:51:34 -07:00
+++ b/arch/ia64/kernel/mca.c	2005-04-07 17:51:34 -07:00
@@ -271,7 +271,7 @@
 
 #ifdef CONFIG_ACPI
 
-static int cpe_vector = -1;
+int cpe_vector = -1;
 
 static irqreturn_t
 ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
diff -Nru a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
--- a/arch/ia64/kernel/topology.c	2005-04-07 17:51:34 -07:00
+++ b/arch/ia64/kernel/topology.c	2005-04-07 17:51:34 -07:00
@@ -36,6 +36,13 @@
 	parent = &sysfs_nodes[cpu_to_node(num)];
 #endif /* CONFIG_NUMA */
 
+	/*
+	 * If CPEI cannot be re-targetted, and this is
+	 * CPEI target, then dont create the control file
+	 */
+	if (!can_cpei_retarget() && is_cpu_cpei_target(num))
+		sysfs_cpus[num].cpu.no_control = 1;
+
 	return register_cpu(&sysfs_cpus[num].cpu, num, parent);
 }
 
diff -Nru a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig	2005-04-07 17:51:34 -07:00
+++ b/drivers/acpi/Kconfig	2005-04-07 17:51:34 -07: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
@@ -328,8 +338,13 @@
 	depends on EXPERIMENTAL
 	default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
 	 ---help---
-	 	This is the ACPI generic container driver which supports
-		ACPI0004, PNP0A05 and PNP0A06 devices
+	  This allows _physical_ insertion and removal of CPUs and memory.
+	  This can be useful, for example, on NUMA machines that support
+	  ACPI based physical hotplug of nodes, or non-NUMA machines that
+	  support physical cpu/memory hot-plug.
+
+	  If one selects "m", this driver can be loaded with
+	  "modprobe acpi_container".
 
 config ACPI_HOTPLUG_MEMORY
 	tristate "Memory Hotplug"
diff -Nru a/drivers/acpi/Makefile b/drivers/acpi/Makefile
--- a/drivers/acpi/Makefile	2005-04-07 17:51:34 -07:00
+++ b/drivers/acpi/Makefile	2005-04-07 17:51:34 -07: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
diff -Nru a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
--- a/drivers/acpi/asus_acpi.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/acpi/asus_acpi.c	2005-04-07 17:51:33 -07: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/bus.c b/drivers/acpi/bus.c
--- a/drivers/acpi/bus.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/acpi/bus.c	2005-04-07 17:51:34 -07: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-04-07 17:51:33 -07:00
+++ b/drivers/acpi/button.c	2005-04-07 17:51:33 -07:00
@@ -26,9 +26,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/types.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
 
@@ -36,9 +33,6 @@
 #define ACPI_BUTTON_COMPONENT		0x00080000
 #define ACPI_BUTTON_DRIVER_NAME		"ACPI Button Driver"
 #define ACPI_BUTTON_CLASS		"button"
-#define ACPI_BUTTON_FILE_INFO		"info"
-#define ACPI_BUTTON_FILE_STATE		"state"
-#define ACPI_BUTTON_TYPE_UNKNOWN	0x00
 #define ACPI_BUTTON_NOTIFY_STATUS	0x80
 
 #define ACPI_BUTTON_SUBCLASS_POWER	"power"
@@ -70,8 +64,6 @@
 
 static int acpi_button_add (struct acpi_device *device);
 static int acpi_button_remove (struct acpi_device *device, int type);
-static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
-static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
 static struct acpi_driver acpi_button_driver = {
 	.name =		ACPI_BUTTON_DRIVER_NAME,
@@ -90,191 +82,6 @@
 	unsigned long		pushed;
 };
 
-static struct file_operations acpi_button_info_fops = {
-	.open		= acpi_button_info_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-static struct file_operations acpi_button_state_fops = {
-	.open		= acpi_button_state_open_fs,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-/* --------------------------------------------------------------------------
-                              FS Interface (/proc)
-   -------------------------------------------------------------------------- */
-
-static struct proc_dir_entry	*acpi_button_dir;
-
-static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_button	*button = (struct acpi_button *) seq->private;
-
-	ACPI_FUNCTION_TRACE("acpi_button_info_seq_show");
-
-	if (!button || !button->device)
-		return_VALUE(0);
-
-	seq_printf(seq, "type:                    %s\n", 
-		acpi_device_name(button->device));
-
-	return_VALUE(0);
-}
-
-static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
-}
-	
-static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
-{
-	struct acpi_button	*button = (struct acpi_button *) seq->private;
-	acpi_status		status;
-	unsigned long		state;
-
-	ACPI_FUNCTION_TRACE("acpi_button_state_seq_show");
-
-	if (!button || !button->device)
-		return_VALUE(0);
-
-	status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state);
-	if (ACPI_FAILURE(status)) {
-		seq_printf(seq, "state:      unsupported\n");
-	}
-	else{
-		seq_printf(seq, "state:      %s\n", (state ? "open" : "closed")); 
-	}
-
-	return_VALUE(0);
-}
-
-static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
-{
-	return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
-}
-
-static int
-acpi_button_add_fs (
-	struct acpi_device	*device)
-{
-	struct proc_dir_entry	*entry = NULL;
-	struct acpi_button	*button = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_button_add_fs");
-
-	if (!device || !acpi_driver_data(device))
-		return_VALUE(-EINVAL);
-
-	button = acpi_driver_data(device);
-
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
-			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 
-				acpi_button_dir);
-		break;
-	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
-			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, 
-				acpi_button_dir);
-		break;
-	case ACPI_BUTTON_TYPE_LID:
-			entry = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, 
-				acpi_button_dir);
-		break;
-	}
-
-	if (!entry)
-		return_VALUE(-ENODEV);
-	entry->owner = THIS_MODULE;
-
-	acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
-	if (!acpi_device_dir(device))
-		return_VALUE(-ENODEV);
-	acpi_device_dir(device)->owner = THIS_MODULE;
-
-	/* 'info' [R] */
-	entry = create_proc_entry(ACPI_BUTTON_FILE_INFO,
-		S_IRUGO, acpi_device_dir(device));
-	if (!entry)
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-			"Unable to create '%s' fs entry\n",
-			ACPI_BUTTON_FILE_INFO));
-	else {
-		entry->proc_fops = &acpi_button_info_fops;
-		entry->data = acpi_driver_data(device);
-		entry->owner = THIS_MODULE;
-	}
-
-	/* show lid state [R] */
-	if (button->type == ACPI_BUTTON_TYPE_LID) {
-		entry = create_proc_entry(ACPI_BUTTON_FILE_STATE,
-			S_IRUGO, acpi_device_dir(device));
-		if (!entry)
-			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				"Unable to create '%s' fs entry\n",
-				ACPI_BUTTON_FILE_INFO));
-		else {
-			entry->proc_fops = &acpi_button_state_fops;
-			entry->data = acpi_driver_data(device);
-			entry->owner = THIS_MODULE;
-		}
-	}
-
-	return_VALUE(0);
-}
-
-
-static int
-acpi_button_remove_fs (
-	struct acpi_device	*device)
-{
-	struct acpi_button	*button = NULL;
-
-	ACPI_FUNCTION_TRACE("acpi_button_remove_fs");
-
-	button = acpi_driver_data(device);
-	if (acpi_device_dir(device)) {
-		if (button->type == ACPI_BUTTON_TYPE_LID)
-			remove_proc_entry(ACPI_BUTTON_FILE_STATE,
-					     acpi_device_dir(device));
-		remove_proc_entry(ACPI_BUTTON_FILE_INFO,
-				     acpi_device_dir(device));
-
-		remove_proc_entry(acpi_device_bid(device),
-				     acpi_device_dir(device)->parent);
-
-
-		switch (button->type) {
-			case ACPI_BUTTON_TYPE_POWER:
-			case ACPI_BUTTON_TYPE_POWERF:
-				remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, 
-					acpi_button_dir);
-				break;
-			case ACPI_BUTTON_TYPE_SLEEP:
-			case ACPI_BUTTON_TYPE_SLEEPF:
-				remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, 
-					acpi_button_dir);
-				break;
-			case ACPI_BUTTON_TYPE_LID:
-				remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, 
-					acpi_button_dir);
-				break;
-		}
-		acpi_device_dir(device) = NULL;
-	}
-
-	return_VALUE(0);
-}
-
-
-/* --------------------------------------------------------------------------
-                                Driver Interface
-   -------------------------------------------------------------------------- */
-
 static void
 acpi_button_notify (
 	acpi_handle		handle,
@@ -310,8 +117,7 @@
 	
 	ACPI_FUNCTION_TRACE("acpi_button_notify_fixed");
 
-	if (!button)
-		return_ACPI_STATUS(AE_BAD_PARAMETER);
+	BUG_ON(!button);
 
 	acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
 
@@ -327,10 +133,6 @@
 	acpi_status		status = AE_OK;
 	struct acpi_button	*button = NULL;
 
-	static struct acpi_device *power_button;
-	static struct acpi_device *sleep_button;
-	static struct acpi_device *lid_button;
-
 	ACPI_FUNCTION_TRACE("acpi_button_add");
 
 	if (!device)
@@ -391,42 +193,6 @@
 		goto end;
 	}
 
-	/*
-	 * Ensure only one button of each type is used.
-	 */
-	switch (button->type) {
-	case ACPI_BUTTON_TYPE_POWER:
-	case ACPI_BUTTON_TYPE_POWERF:
-		if (!power_button)
-			power_button = device;
-		else {
-			kfree(button);
-			return_VALUE(-ENODEV);
-		}
-		break;
-	case ACPI_BUTTON_TYPE_SLEEP:
-	case ACPI_BUTTON_TYPE_SLEEPF:
-		if (!sleep_button)
-			sleep_button = device;
-		else {
-			kfree(button);
-			return_VALUE(-ENODEV);
-		}
-		break;
-	case ACPI_BUTTON_TYPE_LID:
-		if (!lid_button)
-			lid_button = device;
-		else {
-			kfree(button);
-			return_VALUE(-ENODEV);
-		}
-		break;
-	}
-
-	result = acpi_button_add_fs(device);
-	if (result)
-		goto end;
-
 	switch (button->type) {
 	case ACPI_BUTTON_TYPE_POWERF:
 		status = acpi_install_fixed_event_handler (
@@ -470,7 +236,6 @@
 
 end:
 	if (result) {
-		acpi_button_remove_fs(device);
 		kfree(button);
 	}
 
@@ -511,8 +276,6 @@
 		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 			"Error removing notify handler\n"));
 
-	acpi_button_remove_fs(device);	
-
 	kfree(button);
 
 	return_VALUE(0);
@@ -526,21 +289,14 @@
 
 	ACPI_FUNCTION_TRACE("acpi_button_init");
 
-	acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
-	if (!acpi_button_dir)
-		return_VALUE(-ENODEV);
-	acpi_button_dir->owner = THIS_MODULE;
-
 	result = acpi_bus_register_driver(&acpi_button_driver);
 	if (result < 0) {
-		remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
 		return_VALUE(-ENODEV);
 	}
 
 	return_VALUE(0);
 }
 
-
 static void __exit
 acpi_button_exit (void)
 {
@@ -548,11 +304,8 @@
 
 	acpi_bus_unregister_driver(&acpi_button_driver);
 
-	remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
-
 	return_VOID;
 }
-
 
 module_init(acpi_button_init);
 module_exit(acpi_button_exit);
diff -Nru a/drivers/acpi/ec.c b/drivers/acpi/ec.c
--- a/drivers/acpi/ec.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/acpi/ec.c	2005-04-07 17:51:34 -07: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++;
+		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);
 	}
-	
-
 }
 
 
@@ -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/glue.c b/drivers/acpi/glue.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/acpi/glue.c	2005-04-07 17:51:34 -07: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-04-07 17:51:34 -07:00
@@ -0,0 +1,1019 @@
+/* 
+ *  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;
+	mode_t mode;
+
+	ACPI_FUNCTION_TRACE("create_polling_proc");
+	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-04-07 17:51:34 -07:00
+++ b/drivers/acpi/ibm_acpi.c	2005-04-07 17:51:34 -07:00
@@ -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/osl.c b/drivers/acpi/osl.c
--- a/drivers/acpi/osl.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/acpi/osl.c	2005-04-07 17:51:34 -07: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;
@@ -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/pci_irq.c b/drivers/acpi/pci_irq.c
--- a/drivers/acpi/pci_irq.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/acpi/pci_irq.c	2005-04-07 17:51:33 -07:00
@@ -391,7 +391,6 @@
 	u8			pin = 0;
 	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");
@@ -443,9 +442,6 @@
 			return_VALUE(0);
 		}
  	}
-
-	if (via_interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15);
 
 	dev->irq = acpi_register_gsi(irq, edge_level, active_high_low);
 
diff -Nru a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
--- a/drivers/acpi/pci_link.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/acpi/pci_link.c	2005-04-07 17:51:33 -07: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 {
@@ -530,6 +532,10 @@
 
 	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);
 
@@ -713,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);
 }
@@ -812,9 +804,12 @@
  * There is no ISA_POSSIBLE weight, so we simply use
  * the (small) PCI_USING penalty.
  */
-void acpi_penalize_isa_irq(int irq)
+void acpi_penalize_isa_irq(int irq, int active)
 {
-	acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
+	if (active)
+		acpi_irq_penalty[irq] += PIRQ_PENALTY_ISA_USED;
+	else
+		acpi_irq_penalty[irq] += PIRQ_PENALTY_PCI_USING;
 }
 
 /*
@@ -856,7 +851,7 @@
 
 static struct sysdev_class irqrouter_sysdev_class = {
         set_kset_name("irqrouter"),
-        .resume = irqrouter_resume,
+        .suspend = irqrouter_suspend,
 };
 
 
diff -Nru a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
--- a/drivers/acpi/processor_idle.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/acpi/processor_idle.c	2005-04-07 17:51:34 -07:00
@@ -519,6 +519,29 @@
 }
 
 
+static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr)
+{
+	int i;
+
+	ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1");
+
+	for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++)
+		memset(pr->power.states, 0, sizeof(struct acpi_processor_cx));
+
+	/* if info is obtained from pblk/fadt, type equals state */
+	pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
+	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
+	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
+
+	/* the C0 state only exists as a filler in our array,
+	 * and all processors need to support C1 */
+	pr->power.states[ACPI_STATE_C0].valid = 1;
+	pr->power.states[ACPI_STATE_C1].valid = 1;
+
+	return_VALUE(0);
+}
+
+
 static int acpi_processor_get_power_info_cst (struct acpi_processor *pr)
 {
 	acpi_status		status = 0;
@@ -787,10 +810,7 @@
 	if ((result) || (acpi_processor_power_verify(pr) < 2)) {
 		result = acpi_processor_get_power_info_fadt(pr);
 		if (result)
-			return_VALUE(result);
-
-		if (acpi_processor_power_verify(pr) < 2)
-			return_VALUE(-ENODEV);
+			result = acpi_processor_get_power_info_default_c1(pr);
 	}
 
 	/*
@@ -810,11 +830,10 @@
 	 * CPU as being "idle manageable"
 	 */
 	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
-		if (pr->power.states[i].valid)
+		if (pr->power.states[i].valid) {
 			pr->power.count = i;
-		if ((pr->power.states[i].valid) &&
-		    (pr->power.states[i].type >= ACPI_STATE_C2))
 			pr->flags.power = 1;
+		}
 	}
 
 	return_VALUE(0);
diff -Nru a/drivers/acpi/scan.c b/drivers/acpi/scan.c
--- a/drivers/acpi/scan.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/acpi/scan.c	2005-04-07 17:51:33 -07:00
@@ -1051,13 +1051,15 @@
 	/*
 	 * Status
 	 * ------
-	 * See if the device is present.  We always assume that non-Device()
-	 * objects (e.g. thermal zones, power resources, processors, etc.) are
-	 * present, functioning, etc. (at least when parent object is present).
-	 * Note that _STA has a different meaning for some objects (e.g.
-	 * power resources) so we need to be careful how we use it.
+	 * See if the device is present.  We always assume that non-Device
+	 * and non-Processor objects (e.g. thermal zones, power resources,
+	 * etc.) are present, functioning, etc. (at least when parent object
+	 * is present).  Note that _STA has a different meaning for some
+	 * objects (e.g. power resources) so we need to be careful how we use
+	 * it.
 	 */
 	switch (type) {
+	case ACPI_BUS_TYPE_PROCESSOR:
 	case ACPI_BUS_TYPE_DEVICE:
 		result = acpi_bus_get_status(device);
 		if (ACPI_FAILURE(result) || !device->status.present) {
diff -Nru a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
--- a/drivers/acpi/sleep/main.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/acpi/sleep/main.c	2005-04-07 17:51:33 -07: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-04-07 17:51:34 -07:00
+++ b/drivers/acpi/sleep/poweroff.c	2005-04-07 17:51:34 -07: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/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
--- a/drivers/acpi/toshiba_acpi.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/acpi/toshiba_acpi.c	2005-04-07 17:51:33 -07:00
@@ -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/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/base/sys.c	2005-04-07 17:51:33 -07: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-04-07 17:51:33 -07:00
+++ b/drivers/net/b44.c	2005-04-07 17:51:33 -07:00
@@ -1927,6 +1927,7 @@
 	b44_free_rings(bp);
 
 	spin_unlock_irq(&bp->lock);
+	pci_disable_device(pdev);
 	return 0;
 }
 
@@ -1936,6 +1937,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-04-07 17:51:34 -07:00
+++ b/drivers/net/e1000/e1000_main.c	2005-04-07 17:51:34 -07:00
@@ -3118,8 +3118,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-04-07 17:51:33 -07:00
+++ b/drivers/net/ne2k-pci.c	2005-04-07 17:51:33 -07: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-04-07 17:51:33 -07:00
+++ b/drivers/pci/pci-acpi.c	2005-04-07 17:51:33 -07: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-04-07 17:51:33 -07:00
+++ b/drivers/pci/pci.c	2005-04-07 17:51:33 -07:00
@@ -234,7 +234,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);
 int
 pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
@@ -298,8 +298,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;
 }
 
@@ -312,12 +319,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);
 
 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-04-07 17:51:34 -07:00
+++ b/drivers/pci/pci.h	2005-04-07 17:51:34 -07: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/pci/quirks.c b/drivers/pci/quirks.c
--- a/drivers/pci/quirks.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/pci/quirks.c	2005-04-07 17:51:33 -07:00
@@ -18,6 +18,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/acpi.h>
 
 /* Deal with broken BIOS'es that neglect to enable passive release,
    which can cause problems in combination with the 82441FX/PPro MTRRs */
@@ -465,9 +466,6 @@
  * non-x86 architectures (yes Via exists on PPC among other places),
  * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
  * interrupts delivered properly.
- *
- * TODO: When we have device-specific interrupt routers,
- * quirk_via_irqpic will go away from quirks.
  */
 
 /*
@@ -492,6 +490,29 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_via_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_via_acpi );
 
+static void __devinit quirk_via_irqpic(struct pci_dev *dev)
+{
+	u8 irq, new_irq;
+
+#ifdef CONFIG_X86_IO_APIC
+	if (nr_ioapics && !skip_ioapic_setup)
+		return;
+#endif
+#ifdef CONFIG_ACPI
+	if (acpi_irq_model != ACPI_IRQ_MODEL_PIC)
+		return;
+#endif
+	new_irq = dev->irq & 0xf;
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+	if (new_irq != irq) {
+		printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n",
+			pci_name(dev), irq, new_irq);
+		udelay(15);	/* unknown if delay really needed */
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
+	}
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic);
+
 /*
  * PIIX3 USB: We have to disable USB interrupts that are
  * hardwired to PIRQD# and may be shared with an
@@ -681,19 +702,6 @@
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82454NX,	quirk_disable_pxb );
 
-/*
- *	VIA northbridges care about PCI_INTERRUPT_LINE
- */
-int via_interrupt_line_quirk;
-
-static void __devinit quirk_via_bridge(struct pci_dev *pdev)
-{
-	if(pdev->devfn == 0) {
-		printk(KERN_INFO "PCI: Via IRQ fixup\n");
-		via_interrupt_line_quirk = 1;
-	}
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_ANY_ID,                     quirk_via_bridge );
 
 /*
  *	Serverworks CSB5 IDE does not fully support native mode
diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- a/drivers/pcmcia/yenta_socket.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/pcmcia/yenta_socket.c	2005-04-07 17:51:34 -07: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-04-07 17:51:34 -07:00
+++ b/drivers/pnp/pnpacpi/rsparser.c	2005-04-07 17:51:34 -07:00
@@ -160,7 +160,7 @@
 				acpi_register_gsi(res->data.irq.interrupts[0],
 					res->data.irq.edge_level,
 					res->data.irq.active_high_low));
-			pcibios_penalize_isa_irq(res->data.irq.interrupts[0]);
+			pcibios_penalize_isa_irq(res->data.irq.interrupts[0], 1);
 		}
 		break;
 
@@ -171,7 +171,7 @@
 				acpi_register_gsi(res->data.extended_irq.interrupts[0],
 					res->data.extended_irq.edge_level,
 					res->data.extended_irq.active_high_low));
-			pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0]);
+			pcibios_penalize_isa_irq(res->data.extended_irq.interrupts[0], 1);
 		}
 		break;
 	case ACPI_RSTYPE_DMA:
@@ -444,6 +444,7 @@
 
 struct acpipnp_parse_option_s {
 	struct pnp_option *option;
+	struct pnp_option *option_independent;
 	struct pnp_dev *dev;
 };
 
@@ -507,7 +508,14 @@
 			parse_data->option = option;	
 			break;
 		case ACPI_RSTYPE_END_DPF:
-			return AE_CTRL_TERMINATE;
+			/*only one EndDependentFn is allowed*/
+			if (!parse_data->option_independent) {
+				pnp_warn("PnPACPI: more than one EndDependentFn");
+				return AE_ERROR;
+			}
+			parse_data->option = parse_data->option_independent;
+			parse_data->option_independent = NULL;
+			break;
 		default:
 			pnp_warn("PnPACPI: unknown resource type %d", res->id);
 			return AE_ERROR;
@@ -525,6 +533,7 @@
 	parse_data.option = pnp_register_independent_option(dev);
 	if (!parse_data.option)
 		return AE_ERROR;
+	parse_data.option_independent = parse_data.option;
 	parse_data.dev = dev;
 	status = acpi_walk_resources(handle, METHOD_NAME__PRS, 
 		pnpacpi_option_resource, &parse_data);
diff -Nru a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
--- a/drivers/pnp/pnpbios/rsparser.c	2005-04-07 17:51:33 -07:00
+++ b/drivers/pnp/pnpbios/rsparser.c	2005-04-07 17:51:33 -07:00
@@ -64,7 +64,7 @@
 		}
 		res->irq_resource[i].start =
 		res->irq_resource[i].end = (unsigned long) irq;
-		pcibios_penalize_isa_irq(irq);
+		pcibios_penalize_isa_irq(irq, 1);
 	}
 }
 
diff -Nru a/drivers/pnp/resource.c b/drivers/pnp/resource.c
--- a/drivers/pnp/resource.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/pnp/resource.c	2005-04-07 17:51:34 -07:00
@@ -102,7 +102,7 @@
 
 		for (i = 0; i < 16; i++)
 			if (test_bit(i, data->map))
-				pcibios_penalize_isa_irq(i);
+				pcibios_penalize_isa_irq(i, 0);
 	}
 #endif
 	return 0;
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c	2005-04-07 17:51:34 -07:00
+++ b/drivers/usb/core/hcd-pci.c	2005-04-07 17:51:34 -07: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/acpi_bus.h b/include/acpi/acpi_bus.h
--- a/include/acpi/acpi_bus.h	2005-04-07 17:51:34 -07:00
+++ b/include/acpi/acpi_bus.h	2005-04-07 17:51:34 -07:00
@@ -336,6 +336,27 @@
 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*/
 
 #endif /*__ACPI_BUS_H__*/
diff -Nru a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
--- a/include/acpi/acpi_drivers.h	2005-04-07 17:51:34 -07:00
+++ b/include/acpi/acpi_drivers.h	2005-04-07 17:51:34 -07:00
@@ -108,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/asm-alpha/pci.h b/include/asm-alpha/pci.h
--- a/include/asm-alpha/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-alpha/pci.h	2005-04-07 17:51:34 -07:00
@@ -58,7 +58,7 @@
 
 extern void pcibios_set_master(struct pci_dev *dev);
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-arm/pci.h b/include/asm-arm/pci.h
--- a/include/asm-arm/pci.h	2005-04-07 17:51:33 -07:00
+++ b/include/asm-arm/pci.h	2005-04-07 17:51:33 -07:00
@@ -14,7 +14,7 @@
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-h8300/pci.h b/include/asm-h8300/pci.h
--- a/include/asm-h8300/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-h8300/pci.h	2005-04-07 17:51:34 -07:00
@@ -15,7 +15,7 @@
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-i386/pci.h b/include/asm-i386/pci.h
--- a/include/asm-i386/pci.h	2005-04-07 17:51:33 -07:00
+++ b/include/asm-i386/pci.h	2005-04-07 17:51:33 -07:00
@@ -27,7 +27,7 @@
 struct pci_bus * pcibios_scan_root(int bus);
 
 void pcibios_set_master(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq);
+void pcibios_penalize_isa_irq(int irq, int active);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
diff -Nru a/include/asm-ia64/acpi.h b/include/asm-ia64/acpi.h
--- a/include/asm-ia64/acpi.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-ia64/acpi.h	2005-04-07 17:51:34 -07:00
@@ -98,6 +98,15 @@
 int acpi_request_vector (u32 int_type);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
+/*
+ * Record the cpei override flag and current logical cpu. This is
+ * useful for CPU removal.
+ */
+extern unsigned int can_cpei_retarget(void);
+extern unsigned int is_cpu_cpei_target(unsigned int cpu);
+extern void set_cpei_target_cpu(unsigned int cpu);
+extern unsigned int get_cpei_target_cpu(void);
+
 #ifdef CONFIG_ACPI_NUMA
 /* Proximity bitmap length; _PXM is at most 255 (8 bit)*/
 #define MAX_PXM_DOMAINS (256)
diff -Nru a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
--- a/include/asm-ia64/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-ia64/pci.h	2005-04-07 17:51:34 -07:00
@@ -47,7 +47,7 @@
 }
 
 static inline void
-pcibios_penalize_isa_irq (int irq)
+pcibios_penalize_isa_irq (int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h
--- a/include/asm-m68k/pci.h	2005-04-07 17:51:33 -07:00
+++ b/include/asm-m68k/pci.h	2005-04-07 17:51:33 -07:00
@@ -43,7 +43,7 @@
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-mips/pci.h b/include/asm-mips/pci.h
--- a/include/asm-mips/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-mips/pci.h	2005-04-07 17:51:34 -07:00
@@ -69,7 +69,7 @@
 
 extern void pcibios_set_master(struct pci_dev *dev);
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h
--- a/include/asm-ppc/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-ppc/pci.h	2005-04-07 17:51:34 -07:00
@@ -37,7 +37,7 @@
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h
--- a/include/asm-ppc64/pci.h	2005-04-07 17:51:33 -07:00
+++ b/include/asm-ppc64/pci.h	2005-04-07 17:51:33 -07:00
@@ -37,7 +37,7 @@
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-sh/pci.h b/include/asm-sh/pci.h
--- a/include/asm-sh/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-sh/pci.h	2005-04-07 17:51:34 -07:00
@@ -36,7 +36,7 @@
 
 extern void pcibios_set_master(struct pci_dev *dev);
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h
--- a/include/asm-sh64/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-sh64/pci.h	2005-04-07 17:51:34 -07:00
@@ -26,7 +26,7 @@
 /*
  * Set penalize isa irq function
  */
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h
--- a/include/asm-sparc/pci.h	2005-04-07 17:51:34 -07:00
+++ b/include/asm-sparc/pci.h	2005-04-07 17:51:34 -07:00
@@ -20,7 +20,7 @@
 	/* No special bus mastering setup handling */
 }
 
-extern inline void pcibios_penalize_isa_irq(int irq)
+extern inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h
--- a/include/asm-sparc64/pci.h	2005-04-07 17:51:33 -07:00
+++ b/include/asm-sparc64/pci.h	2005-04-07 17:51:33 -07:00
@@ -23,7 +23,7 @@
 	/* No special bus mastering setup handling */
 }
 
-static inline void pcibios_penalize_isa_irq(int irq)
+static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't do dynamic PCI IRQ allocation */
 }
diff -Nru a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h
--- a/include/asm-x86_64/pci.h	2005-04-07 17:51:33 -07:00
+++ b/include/asm-x86_64/pci.h	2005-04-07 17:51:33 -07:00
@@ -33,7 +33,7 @@
 extern int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
 
 void pcibios_set_master(struct pci_dev *dev);
-void pcibios_penalize_isa_irq(int irq);
+void pcibios_penalize_isa_irq(int irq, int active);
 struct irq_routing_table *pcibios_get_irq_routing_table(void);
 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq);
 
diff -Nru a/include/linux/acpi.h b/include/linux/acpi.h
--- a/include/linux/acpi.h	2005-04-07 17:51:34 -07:00
+++ b/include/linux/acpi.h	2005-04-07 17:51:34 -07:00
@@ -202,7 +202,10 @@
 	u8			eid;
 	u8			iosapic_vector;
 	u32			global_irq;
-	u32			reserved;
+	struct {
+		u32			cpei_override_flag:1;
+		u32			reserved:31;
+	}			plint_flags;
 } __attribute__ ((packed));
 
 enum acpi_interrupt_id {
@@ -458,7 +461,7 @@
 struct pci_dev;
 
 int acpi_pci_irq_enable (struct pci_dev *dev);
-void acpi_penalize_isa_irq(int irq);
+void acpi_penalize_isa_irq(int irq, int active);
 
 #ifdef CONFIG_ACPI_DEALLOCATE_IRQ
 void acpi_pci_irq_disable (struct pci_dev *dev);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	2005-04-07 17:51:34 -07:00
+++ b/include/linux/device.h	2005-04-07 17:51:34 -07: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-04-07 17:51:34 -07:00
+++ b/include/linux/pm.h	2005-04-07 17:51:34 -07: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-04-07 17:51:33 -07:00
+++ b/kernel/power/main.c	2005-04-07 17:51:33 -07: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;
 }