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