aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/acpi
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig60
-rw-r--r--drivers/acpi/Makefile5
-rw-r--r--drivers/acpi/ac.c63
-rw-r--r--drivers/acpi/acpi_ipmi.c525
-rw-r--r--drivers/acpi/acpi_pad.c20
-rw-r--r--drivers/acpi/acpica/Makefile9
-rw-r--r--drivers/acpi/acpica/accommon.h2
-rw-r--r--drivers/acpi/acpica/acconfig.h3
-rw-r--r--drivers/acpi/acpica/acdebug.h4
-rw-r--r--drivers/acpi/acpica/acdispat.h40
-rw-r--r--drivers/acpi/acpica/acevents.h43
-rw-r--r--drivers/acpi/acpica/acglobal.h31
-rw-r--r--drivers/acpi/acpica/achware.h11
-rw-r--r--drivers/acpi/acpica/acinterp.h2
-rw-r--r--drivers/acpi/acpica/aclocal.h50
-rw-r--r--drivers/acpi/acpica/acmacros.h6
-rw-r--r--drivers/acpi/acpica/acnamesp.h14
-rw-r--r--drivers/acpi/acpica/acobject.h20
-rw-r--r--drivers/acpi/acpica/acopcode.h2
-rw-r--r--drivers/acpi/acpica/acparser.h2
-rw-r--r--drivers/acpi/acpica/acpredef.h2
-rw-r--r--drivers/acpi/acpica/acresrc.h2
-rw-r--r--drivers/acpi/acpica/acstruct.h2
-rw-r--r--drivers/acpi/acpica/actables.h2
-rw-r--r--drivers/acpi/acpica/acutils.h58
-rw-r--r--drivers/acpi/acpica/amlcode.h25
-rw-r--r--drivers/acpi/acpica/amlresrc.h2
-rw-r--r--drivers/acpi/acpica/dsargs.c391
-rw-r--r--drivers/acpi/acpica/dscontrol.c410
-rw-r--r--drivers/acpi/acpica/dsfield.c2
-rw-r--r--drivers/acpi/acpica/dsinit.c2
-rw-r--r--drivers/acpi/acpica/dsmethod.c66
-rw-r--r--drivers/acpi/acpica/dsmthdat.c2
-rw-r--r--drivers/acpi/acpica/dsobject.c2
-rw-r--r--drivers/acpi/acpica/dsopcode.c727
-rw-r--r--drivers/acpi/acpica/dsutils.c2
-rw-r--r--drivers/acpi/acpica/dswexec.c21
-rw-r--r--drivers/acpi/acpica/dswload.c674
-rw-r--r--drivers/acpi/acpica/dswload2.c720
-rw-r--r--drivers/acpi/acpica/dswscope.c2
-rw-r--r--drivers/acpi/acpica/dswstate.c2
-rw-r--r--drivers/acpi/acpica/evevent.c55
-rw-r--r--drivers/acpi/acpica/evglock.c335
-rw-r--r--drivers/acpi/acpica/evgpe.c287
-rw-r--r--drivers/acpi/acpica/evgpeblk.c66
-rw-r--r--drivers/acpi/acpica/evgpeinit.c61
-rw-r--r--drivers/acpi/acpica/evgpeutil.c41
-rw-r--r--drivers/acpi/acpica/evmisc.c291
-rw-r--r--drivers/acpi/acpica/evregion.c125
-rw-r--r--drivers/acpi/acpica/evrgnini.c22
-rw-r--r--drivers/acpi/acpica/evsci.c2
-rw-r--r--drivers/acpi/acpica/evxface.c94
-rw-r--r--drivers/acpi/acpica/evxfevnt.c575
-rw-r--r--drivers/acpi/acpica/evxfgpe.c696
-rw-r--r--drivers/acpi/acpica/evxfregn.c39
-rw-r--r--drivers/acpi/acpica/exconfig.c2
-rw-r--r--drivers/acpi/acpica/exconvrt.c2
-rw-r--r--drivers/acpi/acpica/excreate.c13
-rw-r--r--drivers/acpi/acpica/exdebug.c2
-rw-r--r--drivers/acpi/acpica/exdump.c4
-rw-r--r--drivers/acpi/acpica/exfield.c2
-rw-r--r--drivers/acpi/acpica/exfldio.c81
-rw-r--r--drivers/acpi/acpica/exmisc.c2
-rw-r--r--drivers/acpi/acpica/exmutex.c12
-rw-r--r--drivers/acpi/acpica/exnames.c2
-rw-r--r--drivers/acpi/acpica/exoparg1.c2
-rw-r--r--drivers/acpi/acpica/exoparg2.c2
-rw-r--r--drivers/acpi/acpica/exoparg3.c2
-rw-r--r--drivers/acpi/acpica/exoparg6.c2
-rw-r--r--drivers/acpi/acpica/exprep.c47
-rw-r--r--drivers/acpi/acpica/exregion.c6
-rw-r--r--drivers/acpi/acpica/exresnte.c2
-rw-r--r--drivers/acpi/acpica/exresolv.c2
-rw-r--r--drivers/acpi/acpica/exresop.c2
-rw-r--r--drivers/acpi/acpica/exstore.c2
-rw-r--r--drivers/acpi/acpica/exstoren.c2
-rw-r--r--drivers/acpi/acpica/exstorob.c2
-rw-r--r--drivers/acpi/acpica/exsystem.c2
-rw-r--r--drivers/acpi/acpica/exutils.c2
-rw-r--r--drivers/acpi/acpica/hwacpi.c2
-rw-r--r--drivers/acpi/acpica/hwgpe.c34
-rw-r--r--drivers/acpi/acpica/hwpci.c412
-rw-r--r--drivers/acpi/acpica/hwregs.c2
-rw-r--r--drivers/acpi/acpica/hwsleep.c2
-rw-r--r--drivers/acpi/acpica/hwtimer.c2
-rw-r--r--drivers/acpi/acpica/hwvalid.c2
-rw-r--r--drivers/acpi/acpica/hwxface.c12
-rw-r--r--drivers/acpi/acpica/nsaccess.c8
-rw-r--r--drivers/acpi/acpica/nsalloc.c15
-rw-r--r--drivers/acpi/acpica/nsdump.c17
-rw-r--r--drivers/acpi/acpica/nsdumpdv.c2
-rw-r--r--drivers/acpi/acpica/nseval.c4
-rw-r--r--drivers/acpi/acpica/nsinit.c4
-rw-r--r--drivers/acpi/acpica/nsload.c2
-rw-r--r--drivers/acpi/acpica/nsnames.c2
-rw-r--r--drivers/acpi/acpica/nsobject.c2
-rw-r--r--drivers/acpi/acpica/nsparse.c2
-rw-r--r--drivers/acpi/acpica/nspredef.c2
-rw-r--r--drivers/acpi/acpica/nsrepair.c15
-rw-r--r--drivers/acpi/acpica/nsrepair2.c165
-rw-r--r--drivers/acpi/acpica/nssearch.c2
-rw-r--r--drivers/acpi/acpica/nsutils.c100
-rw-r--r--drivers/acpi/acpica/nswalk.c2
-rw-r--r--drivers/acpi/acpica/nsxfeval.c2
-rw-r--r--drivers/acpi/acpica/nsxfname.c7
-rw-r--r--drivers/acpi/acpica/nsxfobj.c2
-rw-r--r--drivers/acpi/acpica/psargs.c2
-rw-r--r--drivers/acpi/acpica/psloop.c4
-rw-r--r--drivers/acpi/acpica/psopcode.c2
-rw-r--r--drivers/acpi/acpica/psparse.c27
-rw-r--r--drivers/acpi/acpica/psscope.c2
-rw-r--r--drivers/acpi/acpica/pstree.c2
-rw-r--r--drivers/acpi/acpica/psutils.c2
-rw-r--r--drivers/acpi/acpica/pswalk.c2
-rw-r--r--drivers/acpi/acpica/psxface.c9
-rw-r--r--drivers/acpi/acpica/rsaddr.c2
-rw-r--r--drivers/acpi/acpica/rscalc.c2
-rw-r--r--drivers/acpi/acpica/rscreate.c2
-rw-r--r--drivers/acpi/acpica/rsdump.c2
-rw-r--r--drivers/acpi/acpica/rsinfo.c2
-rw-r--r--drivers/acpi/acpica/rsio.c2
-rw-r--r--drivers/acpi/acpica/rsirq.c2
-rw-r--r--drivers/acpi/acpica/rslist.c2
-rw-r--r--drivers/acpi/acpica/rsmemory.c2
-rw-r--r--drivers/acpi/acpica/rsmisc.c2
-rw-r--r--drivers/acpi/acpica/rsutils.c2
-rw-r--r--drivers/acpi/acpica/rsxface.c2
-rw-r--r--drivers/acpi/acpica/tbfadt.c11
-rw-r--r--drivers/acpi/acpica/tbfind.c2
-rw-r--r--drivers/acpi/acpica/tbinstal.c2
-rw-r--r--drivers/acpi/acpica/tbutils.c2
-rw-r--r--drivers/acpi/acpica/tbxface.c2
-rw-r--r--drivers/acpi/acpica/tbxfroot.c2
-rw-r--r--drivers/acpi/acpica/utalloc.c2
-rw-r--r--drivers/acpi/acpica/utcopy.c2
-rw-r--r--drivers/acpi/acpica/utdebug.c9
-rw-r--r--drivers/acpi/acpica/utdecode.c549
-rw-r--r--drivers/acpi/acpica/utdelete.c2
-rw-r--r--drivers/acpi/acpica/uteval.c149
-rw-r--r--drivers/acpi/acpica/utglobal.c496
-rw-r--r--drivers/acpi/acpica/utids.c47
-rw-r--r--drivers/acpi/acpica/utinit.c6
-rw-r--r--drivers/acpi/acpica/utlock.c2
-rw-r--r--drivers/acpi/acpica/utmath.c25
-rw-r--r--drivers/acpi/acpica/utmisc.c164
-rw-r--r--drivers/acpi/acpica/utmutex.c50
-rw-r--r--drivers/acpi/acpica/utobject.c2
-rw-r--r--drivers/acpi/acpica/utosi.c380
-rw-r--r--drivers/acpi/acpica/utresrc.c4
-rw-r--r--drivers/acpi/acpica/utstate.c2
-rw-r--r--drivers/acpi/acpica/utxface.c140
-rw-r--r--drivers/acpi/acpica/utxferror.c415
-rw-r--r--drivers/acpi/apei/Kconfig9
-rw-r--r--drivers/acpi/apei/apei-internal.h2
-rw-r--r--drivers/acpi/apei/cper.c321
-rw-r--r--drivers/acpi/apei/einj.c10
-rw-r--r--drivers/acpi/apei/erst-dbg.c25
-rw-r--r--drivers/acpi/apei/erst.c424
-rw-r--r--drivers/acpi/apei/ghes.c433
-rw-r--r--drivers/acpi/apei/hest.c48
-rw-r--r--drivers/acpi/atomicio.c4
-rw-r--r--drivers/acpi/battery.c131
-rw-r--r--drivers/acpi/bus.c183
-rw-r--r--drivers/acpi/button.c183
-rw-r--r--drivers/acpi/custom_method.c100
-rw-r--r--drivers/acpi/debugfs.c83
-rw-r--r--drivers/acpi/dock.c7
-rw-r--r--drivers/acpi/ec.c36
-rw-r--r--drivers/acpi/ec_sys.c5
-rw-r--r--drivers/acpi/event.c1
-rw-r--r--drivers/acpi/fan.c166
-rw-r--r--drivers/acpi/glue.c5
-rw-r--r--drivers/acpi/internal.h19
-rw-r--r--drivers/acpi/numa.c19
-rw-r--r--drivers/acpi/nvs.c161
-rw-r--r--drivers/acpi/osl.c621
-rw-r--r--drivers/acpi/pci_irq.c1
-rw-r--r--drivers/acpi/pci_link.c31
-rw-r--r--drivers/acpi/pci_root.c49
-rw-r--r--drivers/acpi/power.c299
-rw-r--r--drivers/acpi/power_meter.c1023
-rw-r--r--drivers/acpi/proc.c41
-rw-r--r--drivers/acpi/processor_core.c33
-rw-r--r--drivers/acpi/processor_driver.c68
-rw-r--r--drivers/acpi/processor_idle.c38
-rw-r--r--drivers/acpi/processor_perflib.c6
-rw-r--r--drivers/acpi/processor_thermal.c187
-rw-r--r--drivers/acpi/processor_throttling.c220
-rw-r--r--drivers/acpi/reboot.c14
-rw-r--r--drivers/acpi/sbs.c27
-rw-r--r--drivers/acpi/scan.c206
-rw-r--r--drivers/acpi/sleep.c84
-rw-r--r--drivers/acpi/sleep.h1
-rw-r--r--drivers/acpi/sysfs.c27
-rw-r--r--drivers/acpi/thermal.c441
-rw-r--r--drivers/acpi/video.c905
-rw-r--r--drivers/acpi/video_detect.c52
-rw-r--r--drivers/acpi/wakeup.c26
198 files changed, 9060 insertions, 7997 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 88681aca88c5..de0e3df76776 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -7,9 +7,7 @@ menuconfig ACPI
7 depends on !IA64_HP_SIM 7 depends on !IA64_HP_SIM
8 depends on IA64 || X86 8 depends on IA64 || X86
9 depends on PCI 9 depends on PCI
10 depends on PM
11 select PNP 10 select PNP
12 select CPU_IDLE
13 default y 11 default y
14 help 12 help
15 Advanced Configuration and Power Interface (ACPI) support for 13 Advanced Configuration and Power Interface (ACPI) support for
@@ -52,12 +50,7 @@ config ACPI_PROCFS
52 For backwards compatibility, this option allows 50 For backwards compatibility, this option allows
53 deprecated /proc/acpi/ files to exist, even when 51 deprecated /proc/acpi/ files to exist, even when
54 they have been replaced by functions in /sys. 52 they have been replaced by functions in /sys.
55 The deprecated files (and their replacements) include:
56 53
57 /proc/acpi/processor/*/throttling (/sys/class/thermal/
58 cooling_device*/*)
59 /proc/acpi/video/*/brightness (/sys/class/backlight/)
60 /proc/acpi/thermal_zone/*/* (/sys/class/thermal/)
61 This option has no effect on /proc/acpi/ files 54 This option has no effect on /proc/acpi/ files
62 and functions which do not yet exist in /sys. 55 and functions which do not yet exist in /sys.
63 56
@@ -66,7 +59,6 @@ config ACPI_PROCFS
66config ACPI_PROCFS_POWER 59config ACPI_PROCFS_POWER
67 bool "Deprecated power /proc/acpi directories" 60 bool "Deprecated power /proc/acpi directories"
68 depends on PROC_FS 61 depends on PROC_FS
69 default y
70 help 62 help
71 For backwards compatibility, this option allows 63 For backwards compatibility, this option allows
72 deprecated power /proc/acpi/ directories to exist, even when 64 deprecated power /proc/acpi/ directories to exist, even when
@@ -76,27 +68,11 @@ config ACPI_PROCFS_POWER
76 /proc/acpi/ac_adapter/* (sys/class/power_supply/*) 68 /proc/acpi/ac_adapter/* (sys/class/power_supply/*)
77 This option has no effect on /proc/acpi/ directories 69 This option has no effect on /proc/acpi/ directories
78 and functions, which do not yet exist in /sys 70 and functions, which do not yet exist in /sys
71 This option, together with the proc directories, will be
72 deleted in 2.6.39.
79 73
80 Say N to delete power /proc/acpi/ directories that have moved to /sys/ 74 Say N to delete power /proc/acpi/ directories that have moved to /sys/
81 75
82config ACPI_POWER_METER
83 tristate "ACPI 4.0 power meter"
84 depends on HWMON
85 help
86 This driver exposes ACPI 4.0 power meters as hardware monitoring
87 devices. Say Y (or M) if you have a computer with ACPI 4.0 firmware
88 and a power meter.
89
90 To compile this driver as a module, choose M here:
91 the module will be called power-meter.
92
93config ACPI_SYSFS_POWER
94 bool "Future power /sys interface"
95 select POWER_SUPPLY
96 default y
97 help
98 Say N to disable power /sys interface
99
100config ACPI_EC_DEBUGFS 76config ACPI_EC_DEBUGFS
101 tristate "EC read/write access through /sys/kernel/debug/ec" 77 tristate "EC read/write access through /sys/kernel/debug/ec"
102 default n 78 default n
@@ -136,6 +112,7 @@ config ACPI_PROC_EVENT
136config ACPI_AC 112config ACPI_AC
137 tristate "AC Adapter" 113 tristate "AC Adapter"
138 depends on X86 114 depends on X86
115 select POWER_SUPPLY
139 default y 116 default y
140 help 117 help
141 This driver supports the AC Adapter object, which indicates 118 This driver supports the AC Adapter object, which indicates
@@ -148,6 +125,7 @@ config ACPI_AC
148config ACPI_BATTERY 125config ACPI_BATTERY
149 tristate "Battery" 126 tristate "Battery"
150 depends on X86 127 depends on X86
128 select POWER_SUPPLY
151 default y 129 default y
152 help 130 help
153 This driver adds support for battery information through 131 This driver adds support for battery information through
@@ -206,6 +184,7 @@ config ACPI_DOCK
206config ACPI_PROCESSOR 184config ACPI_PROCESSOR
207 tristate "Processor" 185 tristate "Processor"
208 select THERMAL 186 select THERMAL
187 select CPU_IDLE
209 default y 188 default y
210 help 189 help
211 This driver installs ACPI as the idle handler for Linux and uses 190 This driver installs ACPI as the idle handler for Linux and uses
@@ -215,6 +194,17 @@ config ACPI_PROCESSOR
215 194
216 To compile this driver as a module, choose M here: 195 To compile this driver as a module, choose M here:
217 the module will be called processor. 196 the module will be called processor.
197config ACPI_IPMI
198 tristate "IPMI"
199 depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER
200 default n
201 help
202 This driver enables the ACPI to access the BMC controller. And it
203 uses the IPMI request/response message to communicate with BMC
204 controller, which can be found on on the server.
205
206 To compile this driver as a module, choose M here:
207 the module will be called as acpi_ipmi.
218 208
219config ACPI_HOTPLUG_CPU 209config ACPI_HOTPLUG_CPU
220 bool 210 bool
@@ -316,7 +306,7 @@ config ACPI_PCI_SLOT
316 the module will be called pci_slot. 306 the module will be called pci_slot.
317 307
318config X86_PM_TIMER 308config X86_PM_TIMER
319 bool "Power Management Timer Support" if EMBEDDED 309 bool "Power Management Timer Support" if EXPERT
320 depends on X86 310 depends on X86
321 default y 311 default y
322 help 312 help
@@ -364,6 +354,7 @@ config ACPI_HOTPLUG_MEMORY
364config ACPI_SBS 354config ACPI_SBS
365 tristate "Smart Battery System" 355 tristate "Smart Battery System"
366 depends on X86 356 depends on X86
357 select POWER_SUPPLY
367 help 358 help
368 This driver supports the Smart Battery System, another 359 This driver supports the Smart Battery System, another
369 type of access to battery information, found on some laptops. 360 type of access to battery information, found on some laptops.
@@ -378,6 +369,21 @@ config ACPI_HED
378 which is used to report some hardware errors notified via 369 which is used to report some hardware errors notified via
379 SCI, mainly the corrected errors. 370 SCI, mainly the corrected errors.
380 371
372config ACPI_CUSTOM_METHOD
373 tristate "Allow ACPI methods to be inserted/replaced at run time"
374 depends on DEBUG_FS
375 default n
376 help
377 This debug facility allows ACPI AML methods to me inserted and/or
378 replaced without rebooting the system. For details refer to:
379 Documentation/acpi/method-customizing.txt.
380
381 NOTE: This option is security sensitive, because it allows arbitrary
382 kernel memory to be written to by root (uid=0) users, allowing them
383 to bypass certain security measures (e.g. if root is not allowed to
384 load additional kernel modules after boot, this feature may be used
385 to override that restriction).
386
381source "drivers/acpi/apei/Kconfig" 387source "drivers/acpi/apei/Kconfig"
382 388
383endif # ACPI 389endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 3d031d02e54b..ecb26b4f29a0 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -24,7 +24,7 @@ acpi-y += atomicio.o
24# sleep related files 24# sleep related files
25acpi-y += wakeup.o 25acpi-y += wakeup.o
26acpi-y += sleep.o 26acpi-y += sleep.o
27acpi-$(CONFIG_ACPI_SLEEP) += proc.o 27acpi-$(CONFIG_ACPI_SLEEP) += proc.o nvs.o
28 28
29 29
30# 30#
@@ -59,9 +59,9 @@ obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
59obj-$(CONFIG_ACPI_BATTERY) += battery.o 59obj-$(CONFIG_ACPI_BATTERY) += battery.o
60obj-$(CONFIG_ACPI_SBS) += sbshc.o 60obj-$(CONFIG_ACPI_SBS) += sbshc.o
61obj-$(CONFIG_ACPI_SBS) += sbs.o 61obj-$(CONFIG_ACPI_SBS) += sbs.o
62obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
63obj-$(CONFIG_ACPI_HED) += hed.o 62obj-$(CONFIG_ACPI_HED) += hed.o
64obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o 63obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
64obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
65 65
66# processor has its own "processor." module_param namespace 66# processor has its own "processor." module_param namespace
67processor-y := processor_driver.o processor_throttling.o 67processor-y := processor_driver.o processor_throttling.o
@@ -69,5 +69,6 @@ processor-y += processor_idle.o processor_thermal.o
69processor-$(CONFIG_CPU_FREQ) += processor_perflib.o 69processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
70 70
71obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o 71obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
72obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o
72 73
73obj-$(CONFIG_ACPI_APEI) += apei/ 74obj-$(CONFIG_ACPI_APEI) += apei/
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 56205a0b85df..58c3f74bd84c 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -32,9 +32,7 @@
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#endif 34#endif
35#ifdef CONFIG_ACPI_SYSFS_POWER
36#include <linux/power_supply.h> 35#include <linux/power_supply.h>
37#endif
38#include <acpi/acpi_bus.h> 36#include <acpi/acpi_bus.h>
39#include <acpi/acpi_drivers.h> 37#include <acpi/acpi_drivers.h>
40 38
@@ -86,9 +84,7 @@ static struct acpi_driver acpi_ac_driver = {
86}; 84};
87 85
88struct acpi_ac { 86struct acpi_ac {
89#ifdef CONFIG_ACPI_SYSFS_POWER
90 struct power_supply charger; 87 struct power_supply charger;
91#endif
92 struct acpi_device * device; 88 struct acpi_device * device;
93 unsigned long long state; 89 unsigned long long state;
94}; 90};
@@ -104,26 +100,7 @@ static const struct file_operations acpi_ac_fops = {
104 .release = single_release, 100 .release = single_release,
105}; 101};
106#endif 102#endif
107#ifdef CONFIG_ACPI_SYSFS_POWER
108static int get_ac_property(struct power_supply *psy,
109 enum power_supply_property psp,
110 union power_supply_propval *val)
111{
112 struct acpi_ac *ac = to_acpi_ac(psy);
113 switch (psp) {
114 case POWER_SUPPLY_PROP_ONLINE:
115 val->intval = ac->state;
116 break;
117 default:
118 return -EINVAL;
119 }
120 return 0;
121}
122 103
123static enum power_supply_property ac_props[] = {
124 POWER_SUPPLY_PROP_ONLINE,
125};
126#endif
127/* -------------------------------------------------------------------------- 104/* --------------------------------------------------------------------------
128 AC Adapter Management 105 AC Adapter Management
129 -------------------------------------------------------------------------- */ 106 -------------------------------------------------------------------------- */
@@ -146,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac)
146 return 0; 123 return 0;
147} 124}
148 125
126/* --------------------------------------------------------------------------
127 sysfs I/F
128 -------------------------------------------------------------------------- */
129static int get_ac_property(struct power_supply *psy,
130 enum power_supply_property psp,
131 union power_supply_propval *val)
132{
133 struct acpi_ac *ac = to_acpi_ac(psy);
134
135 if (!ac)
136 return -ENODEV;
137
138 if (acpi_ac_get_state(ac))
139 return -ENODEV;
140
141 switch (psp) {
142 case POWER_SUPPLY_PROP_ONLINE:
143 val->intval = ac->state;
144 break;
145 default:
146 return -EINVAL;
147 }
148 return 0;
149}
150
151static enum power_supply_property ac_props[] = {
152 POWER_SUPPLY_PROP_ONLINE,
153};
154
149#ifdef CONFIG_ACPI_PROCFS_POWER 155#ifdef CONFIG_ACPI_PROCFS_POWER
150/* -------------------------------------------------------------------------- 156/* --------------------------------------------------------------------------
151 FS Interface (/proc) 157 FS Interface (/proc)
@@ -191,7 +197,8 @@ static int acpi_ac_add_fs(struct acpi_device *device)
191{ 197{
192 struct proc_dir_entry *entry = NULL; 198 struct proc_dir_entry *entry = NULL;
193 199
194 200 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded,"
201 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
195 if (!acpi_device_dir(device)) { 202 if (!acpi_device_dir(device)) {
196 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 203 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
197 acpi_ac_dir); 204 acpi_ac_dir);
@@ -247,9 +254,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
247 dev_name(&device->dev), event, 254 dev_name(&device->dev), event,
248 (u32) ac->state); 255 (u32) ac->state);
249 acpi_notifier_call_chain(device, event, (u32) ac->state); 256 acpi_notifier_call_chain(device, event, (u32) ac->state);
250#ifdef CONFIG_ACPI_SYSFS_POWER
251 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 257 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
252#endif
253 } 258 }
254 259
255 return; 260 return;
@@ -282,14 +287,12 @@ static int acpi_ac_add(struct acpi_device *device)
282#endif 287#endif
283 if (result) 288 if (result)
284 goto end; 289 goto end;
285#ifdef CONFIG_ACPI_SYSFS_POWER
286 ac->charger.name = acpi_device_bid(device); 290 ac->charger.name = acpi_device_bid(device);
287 ac->charger.type = POWER_SUPPLY_TYPE_MAINS; 291 ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
288 ac->charger.properties = ac_props; 292 ac->charger.properties = ac_props;
289 ac->charger.num_properties = ARRAY_SIZE(ac_props); 293 ac->charger.num_properties = ARRAY_SIZE(ac_props);
290 ac->charger.get_property = get_ac_property; 294 ac->charger.get_property = get_ac_property;
291 power_supply_register(&ac->device->dev, &ac->charger); 295 power_supply_register(&ac->device->dev, &ac->charger);
292#endif
293 296
294 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 297 printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
295 acpi_device_name(device), acpi_device_bid(device), 298 acpi_device_name(device), acpi_device_bid(device),
@@ -316,10 +319,8 @@ static int acpi_ac_resume(struct acpi_device *device)
316 old_state = ac->state; 319 old_state = ac->state;
317 if (acpi_ac_get_state(ac)) 320 if (acpi_ac_get_state(ac))
318 return 0; 321 return 0;
319#ifdef CONFIG_ACPI_SYSFS_POWER
320 if (old_state != ac->state) 322 if (old_state != ac->state)
321 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 323 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
322#endif
323 return 0; 324 return 0;
324} 325}
325 326
@@ -333,10 +334,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
333 334
334 ac = acpi_driver_data(device); 335 ac = acpi_driver_data(device);
335 336
336#ifdef CONFIG_ACPI_SYSFS_POWER
337 if (ac->charger.dev) 337 if (ac->charger.dev)
338 power_supply_unregister(&ac->charger); 338 power_supply_unregister(&ac->charger);
339#endif
340#ifdef CONFIG_ACPI_PROCFS_POWER 339#ifdef CONFIG_ACPI_PROCFS_POWER
341 acpi_ac_remove_fs(device); 340 acpi_ac_remove_fs(device);
342#endif 341#endif
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c
new file mode 100644
index 000000000000..f40acef80269
--- /dev/null
+++ b/drivers/acpi/acpi_ipmi.c
@@ -0,0 +1,525 @@
1/*
2 * acpi_ipmi.c - ACPI IPMI opregion
3 *
4 * Copyright (C) 2010 Intel Corporation
5 * Copyright (C) 2010 Zhao Yakui <yakui.zhao@intel.com>
6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/types.h>
30#include <linux/delay.h>
31#include <linux/proc_fs.h>
32#include <linux/seq_file.h>
33#include <linux/interrupt.h>
34#include <linux/list.h>
35#include <linux/spinlock.h>
36#include <linux/io.h>
37#include <acpi/acpi_bus.h>
38#include <acpi/acpi_drivers.h>
39#include <linux/ipmi.h>
40#include <linux/device.h>
41#include <linux/pnp.h>
42
43MODULE_AUTHOR("Zhao Yakui");
44MODULE_DESCRIPTION("ACPI IPMI Opregion driver");
45MODULE_LICENSE("GPL");
46
47#define IPMI_FLAGS_HANDLER_INSTALL 0
48
49#define ACPI_IPMI_OK 0
50#define ACPI_IPMI_TIMEOUT 0x10
51#define ACPI_IPMI_UNKNOWN 0x07
52/* the IPMI timeout is 5s */
53#define IPMI_TIMEOUT (5 * HZ)
54
55struct acpi_ipmi_device {
56 /* the device list attached to driver_data.ipmi_devices */
57 struct list_head head;
58 /* the IPMI request message list */
59 struct list_head tx_msg_list;
60 struct mutex tx_msg_lock;
61 acpi_handle handle;
62 struct pnp_dev *pnp_dev;
63 ipmi_user_t user_interface;
64 int ipmi_ifnum; /* IPMI interface number */
65 long curr_msgid;
66 unsigned long flags;
67 struct ipmi_smi_info smi_data;
68};
69
70struct ipmi_driver_data {
71 struct list_head ipmi_devices;
72 struct ipmi_smi_watcher bmc_events;
73 struct ipmi_user_hndl ipmi_hndlrs;
74 struct mutex ipmi_lock;
75};
76
77struct acpi_ipmi_msg {
78 struct list_head head;
79 /*
80 * General speaking the addr type should be SI_ADDR_TYPE. And
81 * the addr channel should be BMC.
82 * In fact it can also be IPMB type. But we will have to
83 * parse it from the Netfn command buffer. It is so complex
84 * that it is skipped.
85 */
86 struct ipmi_addr addr;
87 long tx_msgid;
88 /* it is used to track whether the IPMI message is finished */
89 struct completion tx_complete;
90 struct kernel_ipmi_msg tx_message;
91 int msg_done;
92 /* tx data . And copy it from ACPI object buffer */
93 u8 tx_data[64];
94 int tx_len;
95 u8 rx_data[64];
96 int rx_len;
97 struct acpi_ipmi_device *device;
98};
99
100/* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */
101struct acpi_ipmi_buffer {
102 u8 status;
103 u8 length;
104 u8 data[64];
105};
106
107static void ipmi_register_bmc(int iface, struct device *dev);
108static void ipmi_bmc_gone(int iface);
109static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data);
110static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device);
111static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device);
112
113static struct ipmi_driver_data driver_data = {
114 .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices),
115 .bmc_events = {
116 .owner = THIS_MODULE,
117 .new_smi = ipmi_register_bmc,
118 .smi_gone = ipmi_bmc_gone,
119 },
120 .ipmi_hndlrs = {
121 .ipmi_recv_hndl = ipmi_msg_handler,
122 },
123};
124
125static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct acpi_ipmi_device *ipmi)
126{
127 struct acpi_ipmi_msg *ipmi_msg;
128 struct pnp_dev *pnp_dev = ipmi->pnp_dev;
129
130 ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL);
131 if (!ipmi_msg) {
132 dev_warn(&pnp_dev->dev, "Can't allocate memory for ipmi_msg\n");
133 return NULL;
134 }
135 init_completion(&ipmi_msg->tx_complete);
136 INIT_LIST_HEAD(&ipmi_msg->head);
137 ipmi_msg->device = ipmi;
138 return ipmi_msg;
139}
140
141#define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff)
142#define IPMI_OP_RGN_CMD(offset) (offset & 0xff)
143static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg,
144 acpi_physical_address address,
145 acpi_integer *value)
146{
147 struct kernel_ipmi_msg *msg;
148 struct acpi_ipmi_buffer *buffer;
149 struct acpi_ipmi_device *device;
150
151 msg = &tx_msg->tx_message;
152 /*
153 * IPMI network function and command are encoded in the address
154 * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3.
155 */
156 msg->netfn = IPMI_OP_RGN_NETFN(address);
157 msg->cmd = IPMI_OP_RGN_CMD(address);
158 msg->data = tx_msg->tx_data;
159 /*
160 * value is the parameter passed by the IPMI opregion space handler.
161 * It points to the IPMI request message buffer
162 */
163 buffer = (struct acpi_ipmi_buffer *)value;
164 /* copy the tx message data */
165 msg->data_len = buffer->length;
166 memcpy(tx_msg->tx_data, buffer->data, msg->data_len);
167 /*
168 * now the default type is SYSTEM_INTERFACE and channel type is BMC.
169 * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE,
170 * the addr type should be changed to IPMB. Then we will have to parse
171 * the IPMI request message buffer to get the IPMB address.
172 * If so, please fix me.
173 */
174 tx_msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
175 tx_msg->addr.channel = IPMI_BMC_CHANNEL;
176 tx_msg->addr.data[0] = 0;
177
178 /* Get the msgid */
179 device = tx_msg->device;
180 mutex_lock(&device->tx_msg_lock);
181 device->curr_msgid++;
182 tx_msg->tx_msgid = device->curr_msgid;
183 mutex_unlock(&device->tx_msg_lock);
184}
185
186static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg,
187 acpi_integer *value, int rem_time)
188{
189 struct acpi_ipmi_buffer *buffer;
190
191 /*
192 * value is also used as output parameter. It represents the response
193 * IPMI message returned by IPMI command.
194 */
195 buffer = (struct acpi_ipmi_buffer *)value;
196 if (!rem_time && !msg->msg_done) {
197 buffer->status = ACPI_IPMI_TIMEOUT;
198 return;
199 }
200 /*
201 * If the flag of msg_done is not set or the recv length is zero, it
202 * means that the IPMI command is not executed correctly.
203 * The status code will be ACPI_IPMI_UNKNOWN.
204 */
205 if (!msg->msg_done || !msg->rx_len) {
206 buffer->status = ACPI_IPMI_UNKNOWN;
207 return;
208 }
209 /*
210 * If the IPMI response message is obtained correctly, the status code
211 * will be ACPI_IPMI_OK
212 */
213 buffer->status = ACPI_IPMI_OK;
214 buffer->length = msg->rx_len;
215 memcpy(buffer->data, msg->rx_data, msg->rx_len);
216}
217
218static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi)
219{
220 struct acpi_ipmi_msg *tx_msg, *temp;
221 int count = HZ / 10;
222 struct pnp_dev *pnp_dev = ipmi->pnp_dev;
223
224 list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) {
225 /* wake up the sleep thread on the Tx msg */
226 complete(&tx_msg->tx_complete);
227 }
228
229 /* wait for about 100ms to flush the tx message list */
230 while (count--) {
231 if (list_empty(&ipmi->tx_msg_list))
232 break;
233 schedule_timeout(1);
234 }
235 if (!list_empty(&ipmi->tx_msg_list))
236 dev_warn(&pnp_dev->dev, "tx msg list is not NULL\n");
237}
238
239static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
240{
241 struct acpi_ipmi_device *ipmi_device = user_msg_data;
242 int msg_found = 0;
243 struct acpi_ipmi_msg *tx_msg;
244 struct pnp_dev *pnp_dev = ipmi_device->pnp_dev;
245
246 if (msg->user != ipmi_device->user_interface) {
247 dev_warn(&pnp_dev->dev, "Unexpected response is returned. "
248 "returned user %p, expected user %p\n",
249 msg->user, ipmi_device->user_interface);
250 ipmi_free_recv_msg(msg);
251 return;
252 }
253 mutex_lock(&ipmi_device->tx_msg_lock);
254 list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) {
255 if (msg->msgid == tx_msg->tx_msgid) {
256 msg_found = 1;
257 break;
258 }
259 }
260
261 mutex_unlock(&ipmi_device->tx_msg_lock);
262 if (!msg_found) {
263 dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is "
264 "returned.\n", msg->msgid);
265 ipmi_free_recv_msg(msg);
266 return;
267 }
268
269 if (msg->msg.data_len) {
270 /* copy the response data to Rx_data buffer */
271 memcpy(tx_msg->rx_data, msg->msg_data, msg->msg.data_len);
272 tx_msg->rx_len = msg->msg.data_len;
273 tx_msg->msg_done = 1;
274 }
275 complete(&tx_msg->tx_complete);
276 ipmi_free_recv_msg(msg);
277};
278
279static void ipmi_register_bmc(int iface, struct device *dev)
280{
281 struct acpi_ipmi_device *ipmi_device, *temp;
282 struct pnp_dev *pnp_dev;
283 ipmi_user_t user;
284 int err;
285 struct ipmi_smi_info smi_data;
286 acpi_handle handle;
287
288 err = ipmi_get_smi_info(iface, &smi_data);
289
290 if (err)
291 return;
292
293 if (smi_data.addr_src != SI_ACPI) {
294 put_device(smi_data.dev);
295 return;
296 }
297
298 handle = smi_data.addr_info.acpi_info.acpi_handle;
299
300 mutex_lock(&driver_data.ipmi_lock);
301 list_for_each_entry(temp, &driver_data.ipmi_devices, head) {
302 /*
303 * if the corresponding ACPI handle is already added
304 * to the device list, don't add it again.
305 */
306 if (temp->handle == handle)
307 goto out;
308 }
309
310 ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL);
311
312 if (!ipmi_device)
313 goto out;
314
315 pnp_dev = to_pnp_dev(smi_data.dev);
316 ipmi_device->handle = handle;
317 ipmi_device->pnp_dev = pnp_dev;
318
319 err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs,
320 ipmi_device, &user);
321 if (err) {
322 dev_warn(&pnp_dev->dev, "Can't create IPMI user interface\n");
323 kfree(ipmi_device);
324 goto out;
325 }
326 acpi_add_ipmi_device(ipmi_device);
327 ipmi_device->user_interface = user;
328 ipmi_device->ipmi_ifnum = iface;
329 mutex_unlock(&driver_data.ipmi_lock);
330 memcpy(&ipmi_device->smi_data, &smi_data, sizeof(struct ipmi_smi_info));
331 return;
332
333out:
334 mutex_unlock(&driver_data.ipmi_lock);
335 put_device(smi_data.dev);
336 return;
337}
338
339static void ipmi_bmc_gone(int iface)
340{
341 struct acpi_ipmi_device *ipmi_device, *temp;
342
343 mutex_lock(&driver_data.ipmi_lock);
344 list_for_each_entry_safe(ipmi_device, temp,
345 &driver_data.ipmi_devices, head) {
346 if (ipmi_device->ipmi_ifnum != iface)
347 continue;
348
349 acpi_remove_ipmi_device(ipmi_device);
350 put_device(ipmi_device->smi_data.dev);
351 kfree(ipmi_device);
352 break;
353 }
354 mutex_unlock(&driver_data.ipmi_lock);
355}
356/* --------------------------------------------------------------------------
357 * Address Space Management
358 * -------------------------------------------------------------------------- */
359/*
360 * This is the IPMI opregion space handler.
361 * @function: indicates the read/write. In fact as the IPMI message is driven
362 * by command, only write is meaningful.
363 * @address: This contains the netfn/command of IPMI request message.
364 * @bits : not used.
365 * @value : it is an in/out parameter. It points to the IPMI message buffer.
366 * Before the IPMI message is sent, it represents the actual request
367 * IPMI message. After the IPMI message is finished, it represents
368 * the response IPMI message returned by IPMI command.
369 * @handler_context: IPMI device context.
370 */
371
372static acpi_status
373acpi_ipmi_space_handler(u32 function, acpi_physical_address address,
374 u32 bits, acpi_integer *value,
375 void *handler_context, void *region_context)
376{
377 struct acpi_ipmi_msg *tx_msg;
378 struct acpi_ipmi_device *ipmi_device = handler_context;
379 int err, rem_time;
380 acpi_status status;
381 /*
382 * IPMI opregion message.
383 * IPMI message is firstly written to the BMC and system software
384 * can get the respsonse. So it is unmeaningful for the read access
385 * of IPMI opregion.
386 */
387 if ((function & ACPI_IO_MASK) == ACPI_READ)
388 return AE_TYPE;
389
390 if (!ipmi_device->user_interface)
391 return AE_NOT_EXIST;
392
393 tx_msg = acpi_alloc_ipmi_msg(ipmi_device);
394 if (!tx_msg)
395 return AE_NO_MEMORY;
396
397 acpi_format_ipmi_msg(tx_msg, address, value);
398 mutex_lock(&ipmi_device->tx_msg_lock);
399 list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list);
400 mutex_unlock(&ipmi_device->tx_msg_lock);
401 err = ipmi_request_settime(ipmi_device->user_interface,
402 &tx_msg->addr,
403 tx_msg->tx_msgid,
404 &tx_msg->tx_message,
405 NULL, 0, 0, 0);
406 if (err) {
407 status = AE_ERROR;
408 goto end_label;
409 }
410 rem_time = wait_for_completion_timeout(&tx_msg->tx_complete,
411 IPMI_TIMEOUT);
412 acpi_format_ipmi_response(tx_msg, value, rem_time);
413 status = AE_OK;
414
415end_label:
416 mutex_lock(&ipmi_device->tx_msg_lock);
417 list_del(&tx_msg->head);
418 mutex_unlock(&ipmi_device->tx_msg_lock);
419 kfree(tx_msg);
420 return status;
421}
422
423static void ipmi_remove_space_handler(struct acpi_ipmi_device *ipmi)
424{
425 if (!test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags))
426 return;
427
428 acpi_remove_address_space_handler(ipmi->handle,
429 ACPI_ADR_SPACE_IPMI, &acpi_ipmi_space_handler);
430
431 clear_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags);
432}
433
434static int ipmi_install_space_handler(struct acpi_ipmi_device *ipmi)
435{
436 acpi_status status;
437
438 if (test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags))
439 return 0;
440
441 status = acpi_install_address_space_handler(ipmi->handle,
442 ACPI_ADR_SPACE_IPMI,
443 &acpi_ipmi_space_handler,
444 NULL, ipmi);
445 if (ACPI_FAILURE(status)) {
446 struct pnp_dev *pnp_dev = ipmi->pnp_dev;
447 dev_warn(&pnp_dev->dev, "Can't register IPMI opregion space "
448 "handle\n");
449 return -EINVAL;
450 }
451 set_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags);
452 return 0;
453}
454
455static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device)
456{
457
458 INIT_LIST_HEAD(&ipmi_device->head);
459
460 mutex_init(&ipmi_device->tx_msg_lock);
461 INIT_LIST_HEAD(&ipmi_device->tx_msg_list);
462 ipmi_install_space_handler(ipmi_device);
463
464 list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices);
465}
466
467static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device)
468{
469 /*
470 * If the IPMI user interface is created, it should be
471 * destroyed.
472 */
473 if (ipmi_device->user_interface) {
474 ipmi_destroy_user(ipmi_device->user_interface);
475 ipmi_device->user_interface = NULL;
476 }
477 /* flush the Tx_msg list */
478 if (!list_empty(&ipmi_device->tx_msg_list))
479 ipmi_flush_tx_msg(ipmi_device);
480
481 list_del(&ipmi_device->head);
482 ipmi_remove_space_handler(ipmi_device);
483}
484
485static int __init acpi_ipmi_init(void)
486{
487 int result = 0;
488
489 if (acpi_disabled)
490 return result;
491
492 mutex_init(&driver_data.ipmi_lock);
493
494 result = ipmi_smi_watcher_register(&driver_data.bmc_events);
495
496 return result;
497}
498
499static void __exit acpi_ipmi_exit(void)
500{
501 struct acpi_ipmi_device *ipmi_device, *temp;
502
503 if (acpi_disabled)
504 return;
505
506 ipmi_smi_watcher_unregister(&driver_data.bmc_events);
507
508 /*
509 * When one smi_watcher is unregistered, it is only deleted
510 * from the smi_watcher list. But the smi_gone callback function
511 * is not called. So explicitly uninstall the ACPI IPMI oregion
512 * handler and free it.
513 */
514 mutex_lock(&driver_data.ipmi_lock);
515 list_for_each_entry_safe(ipmi_device, temp,
516 &driver_data.ipmi_devices, head) {
517 acpi_remove_ipmi_device(ipmi_device);
518 put_device(ipmi_device->smi_data.dev);
519 kfree(ipmi_device);
520 }
521 mutex_unlock(&driver_data.ipmi_lock);
522}
523
524module_init(acpi_ipmi_init);
525module_exit(acpi_ipmi_exit);
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 6b115f6c4313..a43fa1a57d57 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -30,18 +30,13 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <acpi/acpi_bus.h> 31#include <acpi/acpi_bus.h>
32#include <acpi/acpi_drivers.h> 32#include <acpi/acpi_drivers.h>
33#include <asm/mwait.h>
33 34
34#define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" 35#define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad"
35#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" 36#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
36#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 37#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
37static DEFINE_MUTEX(isolated_cpus_lock); 38static DEFINE_MUTEX(isolated_cpus_lock);
38 39
39#define MWAIT_SUBSTATE_MASK (0xf)
40#define MWAIT_CSTATE_MASK (0xf)
41#define MWAIT_SUBSTATE_SIZE (4)
42#define CPUID_MWAIT_LEAF (5)
43#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
44#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
45static unsigned long power_saving_mwait_eax; 40static unsigned long power_saving_mwait_eax;
46 41
47static unsigned char tsc_detected_unstable; 42static unsigned char tsc_detected_unstable;
@@ -303,7 +298,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev,
303static ssize_t acpi_pad_rrtime_show(struct device *dev, 298static ssize_t acpi_pad_rrtime_show(struct device *dev,
304 struct device_attribute *attr, char *buf) 299 struct device_attribute *attr, char *buf)
305{ 300{
306 return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time); 301 return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time);
307} 302}
308static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, 303static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR,
309 acpi_pad_rrtime_show, 304 acpi_pad_rrtime_show,
@@ -326,7 +321,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev,
326static ssize_t acpi_pad_idlepct_show(struct device *dev, 321static ssize_t acpi_pad_idlepct_show(struct device *dev,
327 struct device_attribute *attr, char *buf) 322 struct device_attribute *attr, char *buf)
328{ 323{
329 return scnprintf(buf, PAGE_SIZE, "%d", idle_pct); 324 return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct);
330} 325}
331static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, 326static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR,
332 acpi_pad_idlepct_show, 327 acpi_pad_idlepct_show,
@@ -347,8 +342,11 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev,
347static ssize_t acpi_pad_idlecpus_show(struct device *dev, 342static ssize_t acpi_pad_idlecpus_show(struct device *dev,
348 struct device_attribute *attr, char *buf) 343 struct device_attribute *attr, char *buf)
349{ 344{
350 return cpumask_scnprintf(buf, PAGE_SIZE, 345 int n = 0;
351 to_cpumask(pad_busy_cpus_bits)); 346 n = cpumask_scnprintf(buf, PAGE_SIZE-2, to_cpumask(pad_busy_cpus_bits));
347 buf[n++] = '\n';
348 buf[n] = '\0';
349 return n;
352} 350}
353static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, 351static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR,
354 acpi_pad_idlecpus_show, 352 acpi_pad_idlecpus_show,
@@ -458,7 +456,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event,
458 dev_name(&device->dev), event, 0); 456 dev_name(&device->dev), event, 0);
459 break; 457 break;
460 default: 458 default:
461 printk(KERN_WARNING"Unsupported event [0x%x]\n", event); 459 printk(KERN_WARNING "Unsupported event [0x%x]\n", event);
462 break; 460 break;
463 } 461 }
464} 462}
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index d93cc06f4bf8..301bd2d388ad 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -10,18 +10,18 @@ obj-y += acpi.o
10 10
11acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ 11acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
12 dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ 12 dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \
13 dsinit.o 13 dsinit.o dsargs.o dscontrol.o dswload2.o
14 14
15acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ 15acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \
16 evmisc.o evrgnini.o evxface.o evxfregn.o \ 16 evmisc.o evrgnini.o evxface.o evxfregn.o \
17 evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o 17 evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o evglock.o
18 18
19acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ 19acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
20 exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ 20 exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\
21 excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ 21 excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
22 exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o 22 exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o exdebug.o
23 23
24acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o 24acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o hwpci.o
25 25
26acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o 26acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
27 27
@@ -44,4 +44,5 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
44 44
45acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ 45acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
46 utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ 46 utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
47 utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o 47 utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o \
48 utosi.o utxferror.o utdecode.o
diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h
index 3e50c74ed4a1..e0ba17f0a7c8 100644
--- a/drivers/acpi/acpica/accommon.h
+++ b/drivers/acpi/acpica/accommon.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h
index b17d8de9f6ff..bc533dde16c4 100644
--- a/drivers/acpi/acpica/acconfig.h
+++ b/drivers/acpi/acpica/acconfig.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -187,7 +187,6 @@
187 187
188/* Operation regions */ 188/* Operation regions */
189 189
190#define ACPI_NUM_PREDEFINED_REGIONS 9
191#define ACPI_USER_REGION_BEGIN 0x80 190#define ACPI_USER_REGION_BEGIN 0x80
192 191
193/* Maximum space_ids for Operation Regions */ 192/* Maximum space_ids for Operation Regions */
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h
index 48faf3eba9fb..eb0b1f8dee6d 100644
--- a/drivers/acpi/acpica/acdebug.h
+++ b/drivers/acpi/acpica/acdebug.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -105,6 +105,8 @@ void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg);
105acpi_status 105acpi_status
106acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); 106acpi_db_display_objects(char *obj_type_arg, char *display_count_arg);
107 107
108void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg);
109
108acpi_status acpi_db_find_name_in_namespace(char *name_arg); 110acpi_status acpi_db_find_name_in_namespace(char *name_arg);
109 111
110void acpi_db_set_scope(char *name); 112void acpi_db_set_scope(char *name);
diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h
index 894a0ff2a946..2d1b7ffa377a 100644
--- a/drivers/acpi/acpica/acdispat.h
+++ b/drivers/acpi/acpica/acdispat.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,7 @@
48#define NAMEOF_ARG_NTE "__A0" 48#define NAMEOF_ARG_NTE "__A0"
49 49
50/* 50/*
51 * dsopcode - support for late evaluation 51 * dsargs - execution of dynamic arguments for static objects
52 */ 52 */
53acpi_status 53acpi_status
54acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc); 54acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc);
@@ -62,6 +62,20 @@ acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc);
62 62
63acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc); 63acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc);
64 64
65/*
66 * dscontrol - support for execution control opcodes
67 */
68acpi_status
69acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
70 union acpi_parse_object *op);
71
72acpi_status
73acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
74 union acpi_parse_object *op);
75
76/*
77 * dsopcode - support for late operand evaluation
78 */
65acpi_status 79acpi_status
66acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, 80acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
67 union acpi_parse_object *op); 81 union acpi_parse_object *op);
@@ -86,17 +100,6 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
86acpi_status acpi_ds_initialize_region(acpi_handle obj_handle); 100acpi_status acpi_ds_initialize_region(acpi_handle obj_handle);
87 101
88/* 102/*
89 * dsctrl - Parser/Interpreter interface, control stack routines
90 */
91acpi_status
92acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
93 union acpi_parse_object *op);
94
95acpi_status
96acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
97 union acpi_parse_object *op);
98
99/*
100 * dsexec - Parser/Interpreter interface, method execution callbacks 103 * dsexec - Parser/Interpreter interface, method execution callbacks
101 */ 104 */
102acpi_status 105acpi_status
@@ -136,23 +139,26 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
136 struct acpi_walk_state *walk_state); 139 struct acpi_walk_state *walk_state);
137 140
138/* 141/*
139 * dsload - Parser/Interpreter interface, namespace load callbacks 142 * dsload - Parser/Interpreter interface, pass 1 namespace load callbacks
140 */ 143 */
141acpi_status 144acpi_status
145acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
146
147acpi_status
142acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state, 148acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
143 union acpi_parse_object **out_op); 149 union acpi_parse_object **out_op);
144 150
145acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state); 151acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state);
146 152
153/*
154 * dsload - Parser/Interpreter interface, pass 2 namespace load callbacks
155 */
147acpi_status 156acpi_status
148acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, 157acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
149 union acpi_parse_object **out_op); 158 union acpi_parse_object **out_op);
150 159
151acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state); 160acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state);
152 161
153acpi_status
154acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number);
155
156/* 162/*
157 * dsmthdat - method data (locals/args) 163 * dsmthdat - method data (locals/args)
158 */ 164 */
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index 36867cd70eac..bea3b4899183 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -51,8 +51,6 @@ acpi_status acpi_ev_initialize_events(void);
51 51
52acpi_status acpi_ev_install_xrupt_handlers(void); 52acpi_status acpi_ev_install_xrupt_handlers(void);
53 53
54acpi_status acpi_ev_install_fadt_gpes(void);
55
56u32 acpi_ev_fixed_event_detect(void); 54u32 acpi_ev_fixed_event_detect(void);
57 55
58/* 56/*
@@ -60,12 +58,6 @@ u32 acpi_ev_fixed_event_detect(void);
60 */ 58 */
61u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node); 59u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node);
62 60
63acpi_status acpi_ev_acquire_global_lock(u16 timeout);
64
65acpi_status acpi_ev_release_global_lock(void);
66
67acpi_status acpi_ev_init_global_lock_handler(void);
68
69u32 acpi_ev_get_gpe_number_index(u32 gpe_number); 61u32 acpi_ev_get_gpe_number_index(u32 gpe_number);
70 62
71acpi_status 63acpi_status
@@ -73,6 +65,17 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node *node,
73 u32 notify_value); 65 u32 notify_value);
74 66
75/* 67/*
68 * evglock - Global Lock support
69 */
70acpi_status acpi_ev_init_global_lock_handler(void);
71
72acpi_status acpi_ev_acquire_global_lock(u16 timeout);
73
74acpi_status acpi_ev_release_global_lock(void);
75
76acpi_status acpi_ev_remove_global_lock_handler(void);
77
78/*
76 * evgpe - Low-level GPE support 79 * evgpe - Low-level GPE support
77 */ 80 */
78u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); 81u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
@@ -82,9 +85,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);
82 85
83acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); 86acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);
84 87
85acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); 88acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
86 89
87acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); 90acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info);
88 91
89struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, 92struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
90 u32 gpe_number); 93 u32 gpe_number);
@@ -93,6 +96,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number,
93 struct acpi_gpe_block_info 96 struct acpi_gpe_block_info
94 *gpe_block); 97 *gpe_block);
95 98
99acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info);
100
96/* 101/*
97 * evgpeblk - Upper-level GPE block support 102 * evgpeblk - Upper-level GPE block support
98 */ 103 */
@@ -105,13 +110,15 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
105 struct acpi_gpe_block_info **return_gpe_block); 110 struct acpi_gpe_block_info **return_gpe_block);
106 111
107acpi_status 112acpi_status
108acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 113acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
109 struct acpi_gpe_block_info *gpe_block); 114 struct acpi_gpe_block_info *gpe_block,
115 void *context);
110 116
111acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); 117acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block);
112 118
113u32 119u32
114acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, 120acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
121 struct acpi_gpe_event_info *gpe_event_info,
115 u32 gpe_number); 122 u32 gpe_number);
116 123
117/* 124/*
@@ -125,10 +132,6 @@ acpi_status
125acpi_ev_match_gpe_method(acpi_handle obj_handle, 132acpi_ev_match_gpe_method(acpi_handle obj_handle,
126 u32 level, void *context, void **return_value); 133 u32 level, void *context, void **return_value);
127 134
128acpi_status
129acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
130 u32 level, void *context, void **return_value);
131
132/* 135/*
133 * evgpeutil - GPE utilities 136 * evgpeutil - GPE utilities
134 */ 137 */
@@ -137,6 +140,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context);
137 140
138u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); 141u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
139 142
143acpi_status
144acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
145 struct acpi_gpe_block_info *gpe_block, void *context);
146
140struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); 147struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number);
141 148
142acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); 149acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt);
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 1d192142c691..73863d86f022 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -132,6 +132,7 @@ struct acpi_table_fadt acpi_gbl_FADT;
132u32 acpi_current_gpe_count; 132u32 acpi_current_gpe_count;
133u32 acpi_gbl_trace_flags; 133u32 acpi_gbl_trace_flags;
134acpi_name acpi_gbl_trace_method_name; 134acpi_name acpi_gbl_trace_method_name;
135u8 acpi_gbl_system_awake_and_running;
135 136
136#endif 137#endif
137 138
@@ -145,6 +146,9 @@ acpi_name acpi_gbl_trace_method_name;
145 146
146extern u32 acpi_gbl_nesting_level; 147extern u32 acpi_gbl_nesting_level;
147 148
149ACPI_EXTERN u32 acpi_gpe_count;
150ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS];
151
148/* Support for dynamic control method tracing mechanism */ 152/* Support for dynamic control method tracing mechanism */
149 153
150ACPI_EXTERN u32 acpi_gbl_original_dbg_level; 154ACPI_EXTERN u32 acpi_gbl_original_dbg_level;
@@ -187,6 +191,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
187ACPI_EXTERN u8 acpi_gbl_integer_byte_width; 191ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
188ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; 192ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
189 193
194/* Mutex for _OSI support */
195
196ACPI_EXTERN acpi_mutex acpi_gbl_osi_mutex;
197
190/* Reader/Writer lock is used for namespace walk and dynamic table unload */ 198/* Reader/Writer lock is used for namespace walk and dynamic table unload */
191 199
192ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; 200ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
@@ -206,22 +214,23 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[ACPI_NUM_MUTEX];
206 214
207/* 215/*
208 * Global lock mutex is an actual AML mutex object 216 * Global lock mutex is an actual AML mutex object
209 * Global lock semaphore works in conjunction with the HW global lock 217 * Global lock semaphore works in conjunction with the actual global lock
218 * Global lock spinlock is used for "pending" handshake
210 */ 219 */
211ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex; 220ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
212ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore; 221ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
222ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock;
213ACPI_EXTERN u16 acpi_gbl_global_lock_handle; 223ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
214ACPI_EXTERN u8 acpi_gbl_global_lock_acquired; 224ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
215ACPI_EXTERN u8 acpi_gbl_global_lock_present; 225ACPI_EXTERN u8 acpi_gbl_global_lock_present;
226ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
216 227
217/* 228/*
218 * Spinlocks are used for interfaces that can be possibly called at 229 * Spinlocks are used for interfaces that can be possibly called at
219 * interrupt level 230 * interrupt level
220 */ 231 */
221ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock; /* For GPE data structs and registers */ 232ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
222ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */ 233ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
223#define acpi_gbl_gpe_lock &_acpi_gbl_gpe_lock
224#define acpi_gbl_hardware_lock &_acpi_gbl_hardware_lock
225 234
226/***************************************************************************** 235/*****************************************************************************
227 * 236 *
@@ -255,6 +264,7 @@ ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
255ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler; 264ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
256ACPI_EXTERN void *acpi_gbl_table_handler_context; 265ACPI_EXTERN void *acpi_gbl_table_handler_context;
257ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; 266ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
267ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler;
258 268
259/* Owner ID support */ 269/* Owner ID support */
260 270
@@ -262,6 +272,10 @@ ACPI_EXTERN u32 acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS];
262ACPI_EXTERN u8 acpi_gbl_last_owner_id_index; 272ACPI_EXTERN u8 acpi_gbl_last_owner_id_index;
263ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset; 273ACPI_EXTERN u8 acpi_gbl_next_owner_id_offset;
264 274
275/* Initialization sequencing */
276
277ACPI_EXTERN u8 acpi_gbl_reg_methods_executed;
278
265/* Misc */ 279/* Misc */
266 280
267ACPI_EXTERN u32 acpi_gbl_original_mode; 281ACPI_EXTERN u32 acpi_gbl_original_mode;
@@ -273,8 +287,8 @@ ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
273ACPI_EXTERN u8 acpi_gbl_step_to_next_call; 287ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
274ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; 288ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
275ACPI_EXTERN u8 acpi_gbl_events_initialized; 289ACPI_EXTERN u8 acpi_gbl_events_initialized;
276ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
277ACPI_EXTERN u8 acpi_gbl_osi_data; 290ACPI_EXTERN u8 acpi_gbl_osi_data;
291ACPI_EXTERN struct acpi_interface_info *acpi_gbl_supported_interfaces;
278 292
279#ifndef DEFINE_ACPI_GLOBALS 293#ifndef DEFINE_ACPI_GLOBALS
280 294
@@ -364,6 +378,9 @@ ACPI_EXTERN struct acpi_fixed_event_handler
364ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; 378ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
365ACPI_EXTERN struct acpi_gpe_block_info 379ACPI_EXTERN struct acpi_gpe_block_info
366*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; 380*acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
381ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized;
382ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler;
383ACPI_EXTERN void *acpi_gbl_global_event_handler_context;
367 384
368/***************************************************************************** 385/*****************************************************************************
369 * 386 *
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 120b3af56596..e7213beaafc7 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -94,7 +94,7 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
94 struct acpi_gpe_register_info *gpe_register_info); 94 struct acpi_gpe_register_info *gpe_register_info);
95 95
96acpi_status 96acpi_status
97acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); 97acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
98 98
99acpi_status 99acpi_status
100acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 100acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
@@ -121,6 +121,13 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
121 struct acpi_gpe_block_info *gpe_block, 121 struct acpi_gpe_block_info *gpe_block,
122 void *context); 122 void *context);
123 123
124/*
125 * hwpci - PCI configuration support
126 */
127acpi_status
128acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id,
129 acpi_handle root_pci_device, acpi_handle pci_region);
130
124#ifdef ACPI_FUTURE_USAGE 131#ifdef ACPI_FUTURE_USAGE
125/* 132/*
126 * hwtimer - ACPI Timer prototypes 133 * hwtimer - ACPI Timer prototypes
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h
index 049e203bd621..3731e1c34b83 100644
--- a/drivers/acpi/acpica/acinterp.h
+++ b/drivers/acpi/acpica/acinterp.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 7dad9160f209..c7f743ca395b 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -89,25 +89,6 @@ union acpi_parse_object;
89#define ACPI_MAX_MUTEX 7 89#define ACPI_MAX_MUTEX 7
90#define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1 90#define ACPI_NUM_MUTEX ACPI_MAX_MUTEX+1
91 91
92#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
93#ifdef DEFINE_ACPI_GLOBALS
94
95/* Debug names for the mutexes above */
96
97static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
98 "ACPI_MTX_Interpreter",
99 "ACPI_MTX_Namespace",
100 "ACPI_MTX_Tables",
101 "ACPI_MTX_Events",
102 "ACPI_MTX_Caches",
103 "ACPI_MTX_Memory",
104 "ACPI_MTX_CommandComplete",
105 "ACPI_MTX_CommandReady"
106};
107
108#endif
109#endif
110
111/* Lock structure for reader/writer interfaces */ 92/* Lock structure for reader/writer interfaces */
112 93
113struct acpi_rw_lock { 94struct acpi_rw_lock {
@@ -408,16 +389,23 @@ struct acpi_predefined_data {
408 389
409/* Dispatch info for each GPE -- either a method or handler, cannot be both */ 390/* Dispatch info for each GPE -- either a method or handler, cannot be both */
410 391
411struct acpi_handler_info { 392struct acpi_gpe_handler_info {
412 acpi_event_handler address; /* Address of handler, if any */ 393 acpi_gpe_handler address; /* Address of handler, if any */
413 void *context; /* Context to be passed to handler */ 394 void *context; /* Context to be passed to handler */
414 struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ 395 struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */
415 u8 orig_flags; /* Original misc info about this GPE */ 396 u8 original_flags; /* Original (pre-handler) GPE info */
397 u8 originally_enabled; /* True if GPE was originally enabled */
398};
399
400struct acpi_gpe_notify_object {
401 struct acpi_namespace_node *node;
402 struct acpi_gpe_notify_object *next;
416}; 403};
417 404
418union acpi_gpe_dispatch_info { 405union acpi_gpe_dispatch_info {
419 struct acpi_namespace_node *method_node; /* Method node for this GPE level */ 406 struct acpi_namespace_node *method_node; /* Method node for this GPE level */
420 struct acpi_handler_info *handler; 407 struct acpi_gpe_handler_info *handler; /* Installed GPE handler */
408 struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */
421}; 409};
422 410
423/* 411/*
@@ -457,6 +445,7 @@ struct acpi_gpe_block_info {
457 u32 register_count; /* Number of register pairs in block */ 445 u32 register_count; /* Number of register pairs in block */
458 u16 gpe_count; /* Number of individual GPEs in block */ 446 u16 gpe_count; /* Number of individual GPEs in block */
459 u8 block_base_number; /* Base GPE number for this block */ 447 u8 block_base_number; /* Base GPE number for this block */
448 u8 initialized; /* TRUE if this block is initialized */
460}; 449};
461 450
462/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ 451/* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */
@@ -473,7 +462,6 @@ struct acpi_gpe_walk_info {
473 struct acpi_gpe_block_info *gpe_block; 462 struct acpi_gpe_block_info *gpe_block;
474 u16 count; 463 u16 count;
475 acpi_owner_id owner_id; 464 acpi_owner_id owner_id;
476 u8 enable_this_gpe;
477 u8 execute_by_owner_id; 465 u8 execute_by_owner_id;
478}; 466};
479 467
@@ -854,7 +842,7 @@ struct acpi_bit_register_info {
854 ACPI_BITMASK_POWER_BUTTON_STATUS | \ 842 ACPI_BITMASK_POWER_BUTTON_STATUS | \
855 ACPI_BITMASK_SLEEP_BUTTON_STATUS | \ 843 ACPI_BITMASK_SLEEP_BUTTON_STATUS | \
856 ACPI_BITMASK_RT_CLOCK_STATUS | \ 844 ACPI_BITMASK_RT_CLOCK_STATUS | \
857 ACPI_BITMASK_PCIEXP_WAKE_DISABLE | \ 845 ACPI_BITMASK_PCIEXP_WAKE_STATUS | \
858 ACPI_BITMASK_WAKE_STATUS) 846 ACPI_BITMASK_WAKE_STATUS)
859 847
860#define ACPI_BITMASK_TIMER_ENABLE 0x0001 848#define ACPI_BITMASK_TIMER_ENABLE 0x0001
@@ -909,15 +897,21 @@ struct acpi_bit_register_info {
909#define ACPI_OSI_WIN_VISTA 0x07 897#define ACPI_OSI_WIN_VISTA 0x07
910#define ACPI_OSI_WINSRV_2008 0x08 898#define ACPI_OSI_WINSRV_2008 0x08
911#define ACPI_OSI_WIN_VISTA_SP1 0x09 899#define ACPI_OSI_WIN_VISTA_SP1 0x09
912#define ACPI_OSI_WIN_7 0x0A 900#define ACPI_OSI_WIN_VISTA_SP2 0x0A
901#define ACPI_OSI_WIN_7 0x0B
913 902
914#define ACPI_ALWAYS_ILLEGAL 0x00 903#define ACPI_ALWAYS_ILLEGAL 0x00
915 904
916struct acpi_interface_info { 905struct acpi_interface_info {
917 char *name; 906 char *name;
907 struct acpi_interface_info *next;
908 u8 flags;
918 u8 value; 909 u8 value;
919}; 910};
920 911
912#define ACPI_OSI_INVALID 0x01
913#define ACPI_OSI_DYNAMIC 0x02
914
921struct acpi_port_info { 915struct acpi_port_info {
922 char *name; 916 char *name;
923 u16 start; 917 u16 start;
@@ -997,7 +991,7 @@ struct acpi_port_info {
997struct acpi_db_method_info { 991struct acpi_db_method_info {
998 acpi_handle main_thread_gate; 992 acpi_handle main_thread_gate;
999 acpi_handle thread_complete_gate; 993 acpi_handle thread_complete_gate;
1000 u32 *threads; 994 acpi_thread_id *threads;
1001 u32 num_threads; 995 u32 num_threads;
1002 u32 num_created; 996 u32 num_created;
1003 u32 num_completed; 997 u32 num_completed;
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 9894929a2abb..b7491ee1fba6 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -338,8 +338,8 @@
338 * the plist contains a set of parens to allow variable-length lists. 338 * the plist contains a set of parens to allow variable-length lists.
339 * These macros are used for both the debug and non-debug versions of the code. 339 * These macros are used for both the debug and non-debug versions of the code.
340 */ 340 */
341#define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); 341#define ACPI_ERROR_NAMESPACE(s, e) acpi_ut_namespace_error (AE_INFO, s, e);
342#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); 342#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e);
343#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist 343#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist
344#define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist 344#define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist
345 345
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 9f60ff002203..79a598c67fe3 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -339,18 +339,6 @@ acpi_object_type acpi_ns_get_type(struct acpi_namespace_node *node);
339u32 acpi_ns_local(acpi_object_type type); 339u32 acpi_ns_local(acpi_object_type type);
340 340
341void 341void
342acpi_ns_report_error(const char *module_name,
343 u32 line_number,
344 const char *internal_name, acpi_status lookup_status);
345
346void
347acpi_ns_report_method_error(const char *module_name,
348 u32 line_number,
349 const char *message,
350 struct acpi_namespace_node *node,
351 const char *path, acpi_status lookup_status);
352
353void
354acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg); 342acpi_ns_print_node_pathname(struct acpi_namespace_node *node, const char *msg);
355 343
356acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info); 344acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info);
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index 54857fa87aaf..1055769f2f01 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -93,12 +93,10 @@
93 93
94#define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ 94#define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */
95#define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ 95#define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */
96#define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */ 96#define AOPOBJ_DATA_VALID 0x04 /* Object is initialized and data is valid */
97#define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ 97#define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */
98#define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ 98#define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */
99#define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ 99#define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */
100#define AOPOBJ_MODULE_LEVEL 0x40 /* Method is actually module-level code */
101#define AOPOBJ_MODIFIED_NAMESPACE 0x80 /* Method modified the namespace */
102 100
103/****************************************************************************** 101/******************************************************************************
104 * 102 *
@@ -175,7 +173,7 @@ struct acpi_object_region {
175}; 173};
176 174
177struct acpi_object_method { 175struct acpi_object_method {
178 ACPI_OBJECT_COMMON_HEADER u8 method_flags; 176 ACPI_OBJECT_COMMON_HEADER u8 info_flags;
179 u8 param_count; 177 u8 param_count;
180 u8 sync_level; 178 u8 sync_level;
181 union acpi_operand_object *mutex; 179 union acpi_operand_object *mutex;
@@ -183,13 +181,21 @@ struct acpi_object_method {
183 union { 181 union {
184 ACPI_INTERNAL_METHOD implementation; 182 ACPI_INTERNAL_METHOD implementation;
185 union acpi_operand_object *handler; 183 union acpi_operand_object *handler;
186 } extra; 184 } dispatch;
187 185
188 u32 aml_length; 186 u32 aml_length;
189 u8 thread_count; 187 u8 thread_count;
190 acpi_owner_id owner_id; 188 acpi_owner_id owner_id;
191}; 189};
192 190
191/* Flags for info_flags field above */
192
193#define ACPI_METHOD_MODULE_LEVEL 0x01 /* Method is actually module-level code */
194#define ACPI_METHOD_INTERNAL_ONLY 0x02 /* Method is implemented internally (_OSI) */
195#define ACPI_METHOD_SERIALIZED 0x04 /* Method is serialized */
196#define ACPI_METHOD_SERIALIZED_PENDING 0x08 /* Method is to be marked serialized */
197#define ACPI_METHOD_MODIFIED_NAMESPACE 0x10 /* Method modified the namespace */
198
193/****************************************************************************** 199/******************************************************************************
194 * 200 *
195 * Objects that can be notified. All share a common notify_info area. 201 * Objects that can be notified. All share a common notify_info area.
@@ -248,7 +254,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
248 u32 base_byte_offset; /* Byte offset within containing object */\ 254 u32 base_byte_offset; /* Byte offset within containing object */\
249 u32 value; /* Value to store into the Bank or Index register */\ 255 u32 value; /* Value to store into the Bank or Index register */\
250 u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ 256 u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
251 u8 access_bit_width; /* Read/Write size in bits (8-64) */ 257
252 258
253struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ 259struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
254 ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */ 260 ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Parent Operation Region object (REGION/BANK fields only) */
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h
index 8c15ff43f42b..bb2ccfad7376 100644
--- a/drivers/acpi/acpica/acopcode.h
+++ b/drivers/acpi/acpica/acopcode.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h
index d0bb0fd3e57a..5ea1e06afa20 100644
--- a/drivers/acpi/acpica/acparser.h
+++ b/drivers/acpi/acpica/acparser.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 10998d369ad0..94e73c97cf85 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h
index 528bcbaf4ce7..f08b55b7f3a0 100644
--- a/drivers/acpi/acpica/acresrc.h
+++ b/drivers/acpi/acpica/acresrc.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h
index 6e5dd97949fe..1623b245dde2 100644
--- a/drivers/acpi/acpica/acstruct.h
+++ b/drivers/acpi/acpica/acstruct.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 62a576e34361..967f08124eba 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 35df755251ce..99c140d8e348 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -312,8 +312,6 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list);
312/* 312/*
313 * uteval - object evaluation 313 * uteval - object evaluation
314 */ 314 */
315acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
316
317acpi_status 315acpi_status
318acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, 316acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
319 char *path, 317 char *path,
@@ -395,6 +393,21 @@ acpi_status
395acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length); 393acpi_ut_get_object_size(union acpi_operand_object *obj, acpi_size * obj_length);
396 394
397/* 395/*
396 * utosi - Support for the _OSI predefined control method
397 */
398acpi_status acpi_ut_initialize_interfaces(void);
399
400void acpi_ut_interface_terminate(void);
401
402acpi_status acpi_ut_install_interface(acpi_string interface_name);
403
404acpi_status acpi_ut_remove_interface(acpi_string interface_name);
405
406struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name);
407
408acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state);
409
410/*
398 * utstate - Generic state creation/cache routines 411 * utstate - Generic state creation/cache routines
399 */ 412 */
400void 413void
@@ -473,17 +486,6 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position);
473 486
474acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); 487acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer);
475 488
476void ACPI_INTERNAL_VAR_XFACE
477acpi_ut_predefined_warning(const char *module_name,
478 u32 line_number,
479 char *pathname,
480 u8 node_flags, const char *format, ...);
481
482void ACPI_INTERNAL_VAR_XFACE
483acpi_ut_predefined_info(const char *module_name,
484 u32 line_number,
485 char *pathname, u8 node_flags, const char *format, ...);
486
487/* Values for Base above (16=Hex, 10=Decimal) */ 489/* Values for Base above (16=Hex, 10=Decimal) */
488 490
489#define ACPI_ANY_BASE 0 491#define ACPI_ANY_BASE 0
@@ -574,6 +576,32 @@ acpi_status
574acpi_ut_create_list(char *list_name, 576acpi_ut_create_list(char *list_name,
575 u16 object_size, struct acpi_memory_list **return_cache); 577 u16 object_size, struct acpi_memory_list **return_cache);
576 578
577#endif 579#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
580
581/*
582 * utxferror - various error/warning output functions
583 */
584void ACPI_INTERNAL_VAR_XFACE
585acpi_ut_predefined_warning(const char *module_name,
586 u32 line_number,
587 char *pathname,
588 u8 node_flags, const char *format, ...);
589
590void ACPI_INTERNAL_VAR_XFACE
591acpi_ut_predefined_info(const char *module_name,
592 u32 line_number,
593 char *pathname, u8 node_flags, const char *format, ...);
594
595void
596acpi_ut_namespace_error(const char *module_name,
597 u32 line_number,
598 const char *internal_name, acpi_status lookup_status);
599
600void
601acpi_ut_method_error(const char *module_name,
602 u32 line_number,
603 const char *message,
604 struct acpi_namespace_node *node,
605 const char *path, acpi_status lookup_status);
578 606
579#endif /* _ACUTILS_H */ 607#endif /* _ACUTILS_H */
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h
index 1f484ba228fc..1077f17859ed 100644
--- a/drivers/acpi/acpica/amlcode.h
+++ b/drivers/acpi/acpica/amlcode.h
@@ -7,7 +7,7 @@
7 *****************************************************************************/ 7 *****************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2010, Intel Corp. 10 * Copyright (C) 2000 - 2011, Intel Corp.
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
@@ -394,21 +394,6 @@
394#define AML_CLASS_METHOD_CALL 0x09 394#define AML_CLASS_METHOD_CALL 0x09
395#define AML_CLASS_UNKNOWN 0x0A 395#define AML_CLASS_UNKNOWN 0x0A
396 396
397/* Predefined Operation Region space_iDs */
398
399typedef enum {
400 REGION_MEMORY = 0,
401 REGION_IO,
402 REGION_PCI_CONFIG,
403 REGION_EC,
404 REGION_SMBUS,
405 REGION_CMOS,
406 REGION_PCI_BAR,
407 REGION_IPMI,
408 REGION_DATA_TABLE, /* Internal use only */
409 REGION_FIXED_HW = 0x7F
410} AML_REGION_TYPES;
411
412/* Comparison operation codes for match_op operator */ 397/* Comparison operation codes for match_op operator */
413 398
414typedef enum { 399typedef enum {
@@ -480,16 +465,10 @@ typedef enum {
480 AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D 465 AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D
481} AML_ACCESS_ATTRIBUTE; 466} AML_ACCESS_ATTRIBUTE;
482 467
483/* Bit fields in method_flags byte */ 468/* Bit fields in the AML method_flags byte */
484 469
485#define AML_METHOD_ARG_COUNT 0x07 470#define AML_METHOD_ARG_COUNT 0x07
486#define AML_METHOD_SERIALIZED 0x08 471#define AML_METHOD_SERIALIZED 0x08
487#define AML_METHOD_SYNC_LEVEL 0xF0 472#define AML_METHOD_SYNC_LEVEL 0xF0
488 473
489/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */
490
491#define AML_METHOD_INTERNAL_ONLY 0x01
492#define AML_METHOD_RESERVED1 0x02
493#define AML_METHOD_RESERVED2 0x04
494
495#endif /* __AMLCODE_H__ */ 474#endif /* __AMLCODE_H__ */
diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h
index 0e5798fcbb19..59122cde247c 100644
--- a/drivers/acpi/acpica/amlresrc.h
+++ b/drivers/acpi/acpica/amlresrc.h
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c
new file mode 100644
index 000000000000..8c7b99728aa2
--- /dev/null
+++ b/drivers/acpi/acpica/dsargs.c
@@ -0,0 +1,391 @@
1/******************************************************************************
2 *
3 * Module Name: dsargs - Support for execution of dynamic arguments for static
4 * objects (regions, fields, buffer fields, etc.)
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include "accommon.h"
47#include "acparser.h"
48#include "amlcode.h"
49#include "acdispat.h"
50#include "acnamesp.h"
51
52#define _COMPONENT ACPI_DISPATCHER
53ACPI_MODULE_NAME("dsargs")
54
55/* Local prototypes */
56static acpi_status
57acpi_ds_execute_arguments(struct acpi_namespace_node *node,
58 struct acpi_namespace_node *scope_node,
59 u32 aml_length, u8 *aml_start);
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ds_execute_arguments
64 *
65 * PARAMETERS: Node - Object NS node
66 * scope_node - Parent NS node
67 * aml_length - Length of executable AML
68 * aml_start - Pointer to the AML
69 *
70 * RETURN: Status.
71 *
72 * DESCRIPTION: Late (deferred) execution of region or field arguments
73 *
74 ******************************************************************************/
75
76static acpi_status
77acpi_ds_execute_arguments(struct acpi_namespace_node *node,
78 struct acpi_namespace_node *scope_node,
79 u32 aml_length, u8 *aml_start)
80{
81 acpi_status status;
82 union acpi_parse_object *op;
83 struct acpi_walk_state *walk_state;
84
85 ACPI_FUNCTION_TRACE(ds_execute_arguments);
86
87 /* Allocate a new parser op to be the root of the parsed tree */
88
89 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
90 if (!op) {
91 return_ACPI_STATUS(AE_NO_MEMORY);
92 }
93
94 /* Save the Node for use in acpi_ps_parse_aml */
95
96 op->common.node = scope_node;
97
98 /* Create and initialize a new parser state */
99
100 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
101 if (!walk_state) {
102 status = AE_NO_MEMORY;
103 goto cleanup;
104 }
105
106 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
107 aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
108 if (ACPI_FAILURE(status)) {
109 acpi_ds_delete_walk_state(walk_state);
110 goto cleanup;
111 }
112
113 /* Mark this parse as a deferred opcode */
114
115 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
116 walk_state->deferred_node = node;
117
118 /* Pass1: Parse the entire declaration */
119
120 status = acpi_ps_parse_aml(walk_state);
121 if (ACPI_FAILURE(status)) {
122 goto cleanup;
123 }
124
125 /* Get and init the Op created above */
126
127 op->common.node = node;
128 acpi_ps_delete_parse_tree(op);
129
130 /* Evaluate the deferred arguments */
131
132 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
133 if (!op) {
134 return_ACPI_STATUS(AE_NO_MEMORY);
135 }
136
137 op->common.node = scope_node;
138
139 /* Create and initialize a new parser state */
140
141 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
142 if (!walk_state) {
143 status = AE_NO_MEMORY;
144 goto cleanup;
145 }
146
147 /* Execute the opcode and arguments */
148
149 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
150 aml_length, NULL, ACPI_IMODE_EXECUTE);
151 if (ACPI_FAILURE(status)) {
152 acpi_ds_delete_walk_state(walk_state);
153 goto cleanup;
154 }
155
156 /* Mark this execution as a deferred opcode */
157
158 walk_state->deferred_node = node;
159 status = acpi_ps_parse_aml(walk_state);
160
161 cleanup:
162 acpi_ps_delete_parse_tree(op);
163 return_ACPI_STATUS(status);
164}
165
166/*******************************************************************************
167 *
168 * FUNCTION: acpi_ds_get_buffer_field_arguments
169 *
170 * PARAMETERS: obj_desc - A valid buffer_field object
171 *
172 * RETURN: Status.
173 *
174 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
175 * evaluation of these field attributes.
176 *
177 ******************************************************************************/
178
179acpi_status
180acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
181{
182 union acpi_operand_object *extra_desc;
183 struct acpi_namespace_node *node;
184 acpi_status status;
185
186 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
187
188 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
189 return_ACPI_STATUS(AE_OK);
190 }
191
192 /* Get the AML pointer (method object) and buffer_field node */
193
194 extra_desc = acpi_ns_get_secondary_object(obj_desc);
195 node = obj_desc->buffer_field.node;
196
197 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD,
198 node, NULL));
199
200 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
201 acpi_ut_get_node_name(node)));
202
203 /* Execute the AML code for the term_arg arguments */
204
205 status = acpi_ds_execute_arguments(node, node->parent,
206 extra_desc->extra.aml_length,
207 extra_desc->extra.aml_start);
208 return_ACPI_STATUS(status);
209}
210
211/*******************************************************************************
212 *
213 * FUNCTION: acpi_ds_get_bank_field_arguments
214 *
215 * PARAMETERS: obj_desc - A valid bank_field object
216 *
217 * RETURN: Status.
218 *
219 * DESCRIPTION: Get bank_field bank_value. This implements the late
220 * evaluation of these field attributes.
221 *
222 ******************************************************************************/
223
224acpi_status
225acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
226{
227 union acpi_operand_object *extra_desc;
228 struct acpi_namespace_node *node;
229 acpi_status status;
230
231 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
232
233 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
234 return_ACPI_STATUS(AE_OK);
235 }
236
237 /* Get the AML pointer (method object) and bank_field node */
238
239 extra_desc = acpi_ns_get_secondary_object(obj_desc);
240 node = obj_desc->bank_field.node;
241
242 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
243 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
244
245 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
246 acpi_ut_get_node_name(node)));
247
248 /* Execute the AML code for the term_arg arguments */
249
250 status = acpi_ds_execute_arguments(node, node->parent,
251 extra_desc->extra.aml_length,
252 extra_desc->extra.aml_start);
253 return_ACPI_STATUS(status);
254}
255
256/*******************************************************************************
257 *
258 * FUNCTION: acpi_ds_get_buffer_arguments
259 *
260 * PARAMETERS: obj_desc - A valid Buffer object
261 *
262 * RETURN: Status.
263 *
264 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
265 * the late evaluation of these attributes.
266 *
267 ******************************************************************************/
268
269acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
270{
271 struct acpi_namespace_node *node;
272 acpi_status status;
273
274 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
275
276 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
277 return_ACPI_STATUS(AE_OK);
278 }
279
280 /* Get the Buffer node */
281
282 node = obj_desc->buffer.node;
283 if (!node) {
284 ACPI_ERROR((AE_INFO,
285 "No pointer back to namespace node in buffer object %p",
286 obj_desc));
287 return_ACPI_STATUS(AE_AML_INTERNAL);
288 }
289
290 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
291
292 /* Execute the AML code for the term_arg arguments */
293
294 status = acpi_ds_execute_arguments(node, node,
295 obj_desc->buffer.aml_length,
296 obj_desc->buffer.aml_start);
297 return_ACPI_STATUS(status);
298}
299
300/*******************************************************************************
301 *
302 * FUNCTION: acpi_ds_get_package_arguments
303 *
304 * PARAMETERS: obj_desc - A valid Package object
305 *
306 * RETURN: Status.
307 *
308 * DESCRIPTION: Get Package length and initializer byte list. This implements
309 * the late evaluation of these attributes.
310 *
311 ******************************************************************************/
312
313acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
314{
315 struct acpi_namespace_node *node;
316 acpi_status status;
317
318 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
319
320 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
321 return_ACPI_STATUS(AE_OK);
322 }
323
324 /* Get the Package node */
325
326 node = obj_desc->package.node;
327 if (!node) {
328 ACPI_ERROR((AE_INFO,
329 "No pointer back to namespace node in package %p",
330 obj_desc));
331 return_ACPI_STATUS(AE_AML_INTERNAL);
332 }
333
334 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
335
336 /* Execute the AML code for the term_arg arguments */
337
338 status = acpi_ds_execute_arguments(node, node,
339 obj_desc->package.aml_length,
340 obj_desc->package.aml_start);
341 return_ACPI_STATUS(status);
342}
343
344/*******************************************************************************
345 *
346 * FUNCTION: acpi_ds_get_region_arguments
347 *
348 * PARAMETERS: obj_desc - A valid region object
349 *
350 * RETURN: Status.
351 *
352 * DESCRIPTION: Get region address and length. This implements the late
353 * evaluation of these region attributes.
354 *
355 ******************************************************************************/
356
357acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
358{
359 struct acpi_namespace_node *node;
360 acpi_status status;
361 union acpi_operand_object *extra_desc;
362
363 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
364
365 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
366 return_ACPI_STATUS(AE_OK);
367 }
368
369 extra_desc = acpi_ns_get_secondary_object(obj_desc);
370 if (!extra_desc) {
371 return_ACPI_STATUS(AE_NOT_EXIST);
372 }
373
374 /* Get the Region node */
375
376 node = obj_desc->region.node;
377
378 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
379 (ACPI_TYPE_REGION, node, NULL));
380
381 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
382 acpi_ut_get_node_name(node),
383 extra_desc->extra.aml_start));
384
385 /* Execute the argument AML */
386
387 status = acpi_ds_execute_arguments(node, node->parent,
388 extra_desc->extra.aml_length,
389 extra_desc->extra.aml_start);
390 return_ACPI_STATUS(status);
391}
diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c
new file mode 100644
index 000000000000..26c49fff58da
--- /dev/null
+++ b/drivers/acpi/acpica/dscontrol.c
@@ -0,0 +1,410 @@
1/******************************************************************************
2 *
3 * Module Name: dscontrol - Support for execution control opcodes -
4 * if/else/while/return
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include <acpi/acpi.h>
46#include "accommon.h"
47#include "amlcode.h"
48#include "acdispat.h"
49#include "acinterp.h"
50
51#define _COMPONENT ACPI_DISPATCHER
52ACPI_MODULE_NAME("dscontrol")
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ds_exec_begin_control_op
57 *
58 * PARAMETERS: walk_list - The list that owns the walk stack
59 * Op - The control Op
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Handles all control ops encountered during control method
64 * execution.
65 *
66 ******************************************************************************/
67acpi_status
68acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
69 union acpi_parse_object *op)
70{
71 acpi_status status = AE_OK;
72 union acpi_generic_state *control_state;
73
74 ACPI_FUNCTION_NAME(ds_exec_begin_control_op);
75
76 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n",
77 op, op->common.aml_opcode, walk_state));
78
79 switch (op->common.aml_opcode) {
80 case AML_WHILE_OP:
81
82 /*
83 * If this is an additional iteration of a while loop, continue.
84 * There is no need to allocate a new control state.
85 */
86 if (walk_state->control_state) {
87 if (walk_state->control_state->control.
88 aml_predicate_start ==
89 (walk_state->parser_state.aml - 1)) {
90
91 /* Reset the state to start-of-loop */
92
93 walk_state->control_state->common.state =
94 ACPI_CONTROL_CONDITIONAL_EXECUTING;
95 break;
96 }
97 }
98
99 /*lint -fallthrough */
100
101 case AML_IF_OP:
102
103 /*
104 * IF/WHILE: Create a new control state to manage these
105 * constructs. We need to manage these as a stack, in order
106 * to handle nesting.
107 */
108 control_state = acpi_ut_create_control_state();
109 if (!control_state) {
110 status = AE_NO_MEMORY;
111 break;
112 }
113 /*
114 * Save a pointer to the predicate for multiple executions
115 * of a loop
116 */
117 control_state->control.aml_predicate_start =
118 walk_state->parser_state.aml - 1;
119 control_state->control.package_end =
120 walk_state->parser_state.pkg_end;
121 control_state->control.opcode = op->common.aml_opcode;
122
123 /* Push the control state on this walk's control stack */
124
125 acpi_ut_push_generic_state(&walk_state->control_state,
126 control_state);
127 break;
128
129 case AML_ELSE_OP:
130
131 /* Predicate is in the state object */
132 /* If predicate is true, the IF was executed, ignore ELSE part */
133
134 if (walk_state->last_predicate) {
135 status = AE_CTRL_TRUE;
136 }
137
138 break;
139
140 case AML_RETURN_OP:
141
142 break;
143
144 default:
145 break;
146 }
147
148 return (status);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_ds_exec_end_control_op
154 *
155 * PARAMETERS: walk_list - The list that owns the walk stack
156 * Op - The control Op
157 *
158 * RETURN: Status
159 *
160 * DESCRIPTION: Handles all control ops encountered during control method
161 * execution.
162 *
163 ******************************************************************************/
164
165acpi_status
166acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
167 union acpi_parse_object * op)
168{
169 acpi_status status = AE_OK;
170 union acpi_generic_state *control_state;
171
172 ACPI_FUNCTION_NAME(ds_exec_end_control_op);
173
174 switch (op->common.aml_opcode) {
175 case AML_IF_OP:
176
177 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
178
179 /*
180 * Save the result of the predicate in case there is an
181 * ELSE to come
182 */
183 walk_state->last_predicate =
184 (u8)walk_state->control_state->common.value;
185
186 /*
187 * Pop the control state that was created at the start
188 * of the IF and free it
189 */
190 control_state =
191 acpi_ut_pop_generic_state(&walk_state->control_state);
192 acpi_ut_delete_generic_state(control_state);
193 break;
194
195 case AML_ELSE_OP:
196
197 break;
198
199 case AML_WHILE_OP:
200
201 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
202
203 control_state = walk_state->control_state;
204 if (control_state->common.value) {
205
206 /* Predicate was true, the body of the loop was just executed */
207
208 /*
209 * This loop counter mechanism allows the interpreter to escape
210 * possibly infinite loops. This can occur in poorly written AML
211 * when the hardware does not respond within a while loop and the
212 * loop does not implement a timeout.
213 */
214 control_state->control.loop_count++;
215 if (control_state->control.loop_count >
216 ACPI_MAX_LOOP_ITERATIONS) {
217 status = AE_AML_INFINITE_LOOP;
218 break;
219 }
220
221 /*
222 * Go back and evaluate the predicate and maybe execute the loop
223 * another time
224 */
225 status = AE_CTRL_PENDING;
226 walk_state->aml_last_while =
227 control_state->control.aml_predicate_start;
228 break;
229 }
230
231 /* Predicate was false, terminate this while loop */
232
233 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
234 "[WHILE_OP] termination! Op=%p\n", op));
235
236 /* Pop this control state and free it */
237
238 control_state =
239 acpi_ut_pop_generic_state(&walk_state->control_state);
240 acpi_ut_delete_generic_state(control_state);
241 break;
242
243 case AML_RETURN_OP:
244
245 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
246 "[RETURN_OP] Op=%p Arg=%p\n", op,
247 op->common.value.arg));
248
249 /*
250 * One optional operand -- the return value
251 * It can be either an immediate operand or a result that
252 * has been bubbled up the tree
253 */
254 if (op->common.value.arg) {
255
256 /* Since we have a real Return(), delete any implicit return */
257
258 acpi_ds_clear_implicit_return(walk_state);
259
260 /* Return statement has an immediate operand */
261
262 status =
263 acpi_ds_create_operands(walk_state,
264 op->common.value.arg);
265 if (ACPI_FAILURE(status)) {
266 return (status);
267 }
268
269 /*
270 * If value being returned is a Reference (such as
271 * an arg or local), resolve it now because it may
272 * cease to exist at the end of the method.
273 */
274 status =
275 acpi_ex_resolve_to_value(&walk_state->operands[0],
276 walk_state);
277 if (ACPI_FAILURE(status)) {
278 return (status);
279 }
280
281 /*
282 * Get the return value and save as the last result
283 * value. This is the only place where walk_state->return_desc
284 * is set to anything other than zero!
285 */
286 walk_state->return_desc = walk_state->operands[0];
287 } else if (walk_state->result_count) {
288
289 /* Since we have a real Return(), delete any implicit return */
290
291 acpi_ds_clear_implicit_return(walk_state);
292
293 /*
294 * The return value has come from a previous calculation.
295 *
296 * If value being returned is a Reference (such as
297 * an arg or local), resolve it now because it may
298 * cease to exist at the end of the method.
299 *
300 * Allow references created by the Index operator to return
301 * unchanged.
302 */
303 if ((ACPI_GET_DESCRIPTOR_TYPE
304 (walk_state->results->results.obj_desc[0]) ==
305 ACPI_DESC_TYPE_OPERAND)
306 && ((walk_state->results->results.obj_desc[0])->
307 common.type == ACPI_TYPE_LOCAL_REFERENCE)
308 && ((walk_state->results->results.obj_desc[0])->
309 reference.class != ACPI_REFCLASS_INDEX)) {
310 status =
311 acpi_ex_resolve_to_value(&walk_state->
312 results->results.
313 obj_desc[0],
314 walk_state);
315 if (ACPI_FAILURE(status)) {
316 return (status);
317 }
318 }
319
320 walk_state->return_desc =
321 walk_state->results->results.obj_desc[0];
322 } else {
323 /* No return operand */
324
325 if (walk_state->num_operands) {
326 acpi_ut_remove_reference(walk_state->
327 operands[0]);
328 }
329
330 walk_state->operands[0] = NULL;
331 walk_state->num_operands = 0;
332 walk_state->return_desc = NULL;
333 }
334
335 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
336 "Completed RETURN_OP State=%p, RetVal=%p\n",
337 walk_state, walk_state->return_desc));
338
339 /* End the control method execution right now */
340
341 status = AE_CTRL_TERMINATE;
342 break;
343
344 case AML_NOOP_OP:
345
346 /* Just do nothing! */
347 break;
348
349 case AML_BREAK_POINT_OP:
350
351 /*
352 * Set the single-step flag. This will cause the debugger (if present)
353 * to break to the console within the AML debugger at the start of the
354 * next AML instruction.
355 */
356 ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
357 ACPI_DEBUGGER_EXEC(acpi_os_printf
358 ("**break** Executed AML BreakPoint opcode\n"));
359
360 /* Call to the OSL in case OS wants a piece of the action */
361
362 status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
363 "Executed AML Breakpoint opcode");
364 break;
365
366 case AML_BREAK_OP:
367 case AML_CONTINUE_OP: /* ACPI 2.0 */
368
369 /* Pop and delete control states until we find a while */
370
371 while (walk_state->control_state &&
372 (walk_state->control_state->control.opcode !=
373 AML_WHILE_OP)) {
374 control_state =
375 acpi_ut_pop_generic_state(&walk_state->
376 control_state);
377 acpi_ut_delete_generic_state(control_state);
378 }
379
380 /* No while found? */
381
382 if (!walk_state->control_state) {
383 return (AE_AML_NO_WHILE);
384 }
385
386 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
387
388 walk_state->aml_last_while =
389 walk_state->control_state->control.package_end;
390
391 /* Return status depending on opcode */
392
393 if (op->common.aml_opcode == AML_BREAK_OP) {
394 status = AE_CTRL_BREAK;
395 } else {
396 status = AE_CTRL_CONTINUE;
397 }
398 break;
399
400 default:
401
402 ACPI_ERROR((AE_INFO, "Unknown control opcode=0x%X Op=%p",
403 op->common.aml_opcode, op));
404
405 status = AE_AML_BAD_OPCODE;
406 break;
407 }
408
409 return (status);
410}
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index 347bee1726f1..34be60c0e448 100644
--- a/drivers/acpi/acpica/dsfield.c
+++ b/drivers/acpi/acpica/dsfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index cc4a38c57558..a7718bf2b9a1 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c
index 64750ee96e20..5d797751e205 100644
--- a/drivers/acpi/acpica/dsmethod.c
+++ b/drivers/acpi/acpica/dsmethod.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -43,7 +43,6 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include "accommon.h" 45#include "accommon.h"
46#include "amlcode.h"
47#include "acdispat.h" 46#include "acdispat.h"
48#include "acinterp.h" 47#include "acinterp.h"
49#include "acnamesp.h" 48#include "acnamesp.h"
@@ -201,7 +200,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
201 /* 200 /*
202 * If this method is serialized, we need to acquire the method mutex. 201 * If this method is serialized, we need to acquire the method mutex.
203 */ 202 */
204 if (obj_desc->method.method_flags & AML_METHOD_SERIALIZED) { 203 if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) {
205 /* 204 /*
206 * Create a mutex for the method if it is defined to be Serialized 205 * Create a mutex for the method if it is defined to be Serialized
207 * and a mutex has not already been created. We defer the mutex creation 206 * and a mutex has not already been created. We defer the mutex creation
@@ -413,8 +412,9 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
413 412
414 /* Invoke an internal method if necessary */ 413 /* Invoke an internal method if necessary */
415 414
416 if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { 415 if (obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
417 status = obj_desc->method.extra.implementation(next_walk_state); 416 status =
417 obj_desc->method.dispatch.implementation(next_walk_state);
418 if (status == AE_OK) { 418 if (status == AE_OK) {
419 status = AE_CTRL_TERMINATE; 419 status = AE_CTRL_TERMINATE;
420 } 420 }
@@ -573,17 +573,20 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
573 573
574 acpi_os_release_mutex(method_desc->method. 574 acpi_os_release_mutex(method_desc->method.
575 mutex->mutex.os_mutex); 575 mutex->mutex.os_mutex);
576 method_desc->method.mutex->mutex.thread_id = NULL; 576 method_desc->method.mutex->mutex.thread_id = 0;
577 } 577 }
578 } 578 }
579 579
580 /* 580 /*
581 * Delete any namespace objects created anywhere within the 581 * Delete any namespace objects created anywhere within the
582 * namespace by the execution of this method. Unless this method 582 * namespace by the execution of this method. Unless:
583 * is a module-level executable code method, in which case we 583 * 1) This method is a module-level executable code method, in which
584 * want make the objects permanent. 584 * case we want make the objects permanent.
585 * 2) There are other threads executing the method, in which case we
586 * will wait until the last thread has completed.
585 */ 587 */
586 if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { 588 if (!(method_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL)
589 && (method_desc->method.thread_count == 1)) {
587 590
588 /* Delete any direct children of (created by) this method */ 591 /* Delete any direct children of (created by) this method */
589 592
@@ -593,12 +596,17 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
593 /* 596 /*
594 * Delete any objects that were created by this method 597 * Delete any objects that were created by this method
595 * elsewhere in the namespace (if any were created). 598 * elsewhere in the namespace (if any were created).
599 * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the
600 * deletion such that we don't have to perform an entire
601 * namespace walk for every control method execution.
596 */ 602 */
597 if (method_desc->method. 603 if (method_desc->method.
598 flags & AOPOBJ_MODIFIED_NAMESPACE) { 604 info_flags & ACPI_METHOD_MODIFIED_NAMESPACE) {
599 acpi_ns_delete_namespace_by_owner(method_desc-> 605 acpi_ns_delete_namespace_by_owner(method_desc->
600 method. 606 method.
601 owner_id); 607 owner_id);
608 method_desc->method.info_flags &=
609 ~ACPI_METHOD_MODIFIED_NAMESPACE;
602 } 610 }
603 } 611 }
604 } 612 }
@@ -629,19 +637,43 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
629 * Serialized if it appears that the method is incorrectly written and 637 * Serialized if it appears that the method is incorrectly written and
630 * does not support multiple thread execution. The best example of this 638 * does not support multiple thread execution. The best example of this
631 * is if such a method creates namespace objects and blocks. A second 639 * is if such a method creates namespace objects and blocks. A second
632 * thread will fail with an AE_ALREADY_EXISTS exception 640 * thread will fail with an AE_ALREADY_EXISTS exception.
633 * 641 *
634 * This code is here because we must wait until the last thread exits 642 * This code is here because we must wait until the last thread exits
635 * before creating the synchronization semaphore. 643 * before marking the method as serialized.
636 */ 644 */
637 if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) 645 if (method_desc->method.
638 && (!method_desc->method.mutex)) { 646 info_flags & ACPI_METHOD_SERIALIZED_PENDING) {
639 (void)acpi_ds_create_method_mutex(method_desc); 647 if (walk_state) {
648 ACPI_INFO((AE_INFO,
649 "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
650 walk_state->method_node->name.
651 ascii));
652 }
653
654 /*
655 * Method tried to create an object twice and was marked as
656 * "pending serialized". The probable cause is that the method
657 * cannot handle reentrancy.
658 *
659 * The method was created as not_serialized, but it tried to create
660 * a named object and then blocked, causing the second thread
661 * entrance to begin and then fail. Workaround this problem by
662 * marking the method permanently as Serialized when the last
663 * thread exits here.
664 */
665 method_desc->method.info_flags &=
666 ~ACPI_METHOD_SERIALIZED_PENDING;
667 method_desc->method.info_flags |=
668 ACPI_METHOD_SERIALIZED;
669 method_desc->method.sync_level = 0;
640 } 670 }
641 671
642 /* No more threads, we can free the owner_id */ 672 /* No more threads, we can free the owner_id */
643 673
644 if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { 674 if (!
675 (method_desc->method.
676 info_flags & ACPI_METHOD_MODULE_LEVEL)) {
645 acpi_ut_release_owner_id(&method_desc->method.owner_id); 677 acpi_ut_release_owner_id(&method_desc->method.owner_id);
646 } 678 }
647 } 679 }
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index 8095306fcd8c..905ce29a92e1 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 8e85f54a8e0e..f42e17e5c252 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 7c0e74227171..c627a288e027 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -1,12 +1,11 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Module Name: dsopcode - Dispatcher Op Region support and handling of 3 * Module Name: dsopcode - Dispatcher suport for regions and fields
4 * "control" opcodes
5 * 4 *
6 *****************************************************************************/ 5 *****************************************************************************/
7 6
8/* 7/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 9 * All rights reserved.
11 * 10 *
12 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -57,11 +56,6 @@ ACPI_MODULE_NAME("dsopcode")
57 56
58/* Local prototypes */ 57/* Local prototypes */
59static acpi_status 58static acpi_status
60acpi_ds_execute_arguments(struct acpi_namespace_node *node,
61 struct acpi_namespace_node *scope_node,
62 u32 aml_length, u8 * aml_start);
63
64static acpi_status
65acpi_ds_init_buffer_field(u16 aml_opcode, 59acpi_ds_init_buffer_field(u16 aml_opcode,
66 union acpi_operand_object *obj_desc, 60 union acpi_operand_object *obj_desc,
67 union acpi_operand_object *buffer_desc, 61 union acpi_operand_object *buffer_desc,
@@ -71,361 +65,6 @@ acpi_ds_init_buffer_field(u16 aml_opcode,
71 65
72/******************************************************************************* 66/*******************************************************************************
73 * 67 *
74 * FUNCTION: acpi_ds_execute_arguments
75 *
76 * PARAMETERS: Node - Object NS node
77 * scope_node - Parent NS node
78 * aml_length - Length of executable AML
79 * aml_start - Pointer to the AML
80 *
81 * RETURN: Status.
82 *
83 * DESCRIPTION: Late (deferred) execution of region or field arguments
84 *
85 ******************************************************************************/
86
87static acpi_status
88acpi_ds_execute_arguments(struct acpi_namespace_node *node,
89 struct acpi_namespace_node *scope_node,
90 u32 aml_length, u8 * aml_start)
91{
92 acpi_status status;
93 union acpi_parse_object *op;
94 struct acpi_walk_state *walk_state;
95
96 ACPI_FUNCTION_TRACE(ds_execute_arguments);
97
98 /*
99 * Allocate a new parser op to be the root of the parsed tree
100 */
101 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
102 if (!op) {
103 return_ACPI_STATUS(AE_NO_MEMORY);
104 }
105
106 /* Save the Node for use in acpi_ps_parse_aml */
107
108 op->common.node = scope_node;
109
110 /* Create and initialize a new parser state */
111
112 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
113 if (!walk_state) {
114 status = AE_NO_MEMORY;
115 goto cleanup;
116 }
117
118 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
119 aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
120 if (ACPI_FAILURE(status)) {
121 acpi_ds_delete_walk_state(walk_state);
122 goto cleanup;
123 }
124
125 /* Mark this parse as a deferred opcode */
126
127 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
128 walk_state->deferred_node = node;
129
130 /* Pass1: Parse the entire declaration */
131
132 status = acpi_ps_parse_aml(walk_state);
133 if (ACPI_FAILURE(status)) {
134 goto cleanup;
135 }
136
137 /* Get and init the Op created above */
138
139 op->common.node = node;
140 acpi_ps_delete_parse_tree(op);
141
142 /* Evaluate the deferred arguments */
143
144 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP);
145 if (!op) {
146 return_ACPI_STATUS(AE_NO_MEMORY);
147 }
148
149 op->common.node = scope_node;
150
151 /* Create and initialize a new parser state */
152
153 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
154 if (!walk_state) {
155 status = AE_NO_MEMORY;
156 goto cleanup;
157 }
158
159 /* Execute the opcode and arguments */
160
161 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
162 aml_length, NULL, ACPI_IMODE_EXECUTE);
163 if (ACPI_FAILURE(status)) {
164 acpi_ds_delete_walk_state(walk_state);
165 goto cleanup;
166 }
167
168 /* Mark this execution as a deferred opcode */
169
170 walk_state->deferred_node = node;
171 status = acpi_ps_parse_aml(walk_state);
172
173 cleanup:
174 acpi_ps_delete_parse_tree(op);
175 return_ACPI_STATUS(status);
176}
177
178/*******************************************************************************
179 *
180 * FUNCTION: acpi_ds_get_buffer_field_arguments
181 *
182 * PARAMETERS: obj_desc - A valid buffer_field object
183 *
184 * RETURN: Status.
185 *
186 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
187 * evaluation of these field attributes.
188 *
189 ******************************************************************************/
190
191acpi_status
192acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
193{
194 union acpi_operand_object *extra_desc;
195 struct acpi_namespace_node *node;
196 acpi_status status;
197
198 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
199
200 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
201 return_ACPI_STATUS(AE_OK);
202 }
203
204 /* Get the AML pointer (method object) and buffer_field node */
205
206 extra_desc = acpi_ns_get_secondary_object(obj_desc);
207 node = obj_desc->buffer_field.node;
208
209 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
210 (ACPI_TYPE_BUFFER_FIELD, node, NULL));
211 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
212 acpi_ut_get_node_name(node)));
213
214 /* Execute the AML code for the term_arg arguments */
215
216 status = acpi_ds_execute_arguments(node, node->parent,
217 extra_desc->extra.aml_length,
218 extra_desc->extra.aml_start);
219 return_ACPI_STATUS(status);
220}
221
222/*******************************************************************************
223 *
224 * FUNCTION: acpi_ds_get_bank_field_arguments
225 *
226 * PARAMETERS: obj_desc - A valid bank_field object
227 *
228 * RETURN: Status.
229 *
230 * DESCRIPTION: Get bank_field bank_value. This implements the late
231 * evaluation of these field attributes.
232 *
233 ******************************************************************************/
234
235acpi_status
236acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
237{
238 union acpi_operand_object *extra_desc;
239 struct acpi_namespace_node *node;
240 acpi_status status;
241
242 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
243
244 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
245 return_ACPI_STATUS(AE_OK);
246 }
247
248 /* Get the AML pointer (method object) and bank_field node */
249
250 extra_desc = acpi_ns_get_secondary_object(obj_desc);
251 node = obj_desc->bank_field.node;
252
253 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
254 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
255 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
256 acpi_ut_get_node_name(node)));
257
258 /* Execute the AML code for the term_arg arguments */
259
260 status = acpi_ds_execute_arguments(node, node->parent,
261 extra_desc->extra.aml_length,
262 extra_desc->extra.aml_start);
263 return_ACPI_STATUS(status);
264}
265
266/*******************************************************************************
267 *
268 * FUNCTION: acpi_ds_get_buffer_arguments
269 *
270 * PARAMETERS: obj_desc - A valid Buffer object
271 *
272 * RETURN: Status.
273 *
274 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
275 * the late evaluation of these attributes.
276 *
277 ******************************************************************************/
278
279acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
280{
281 struct acpi_namespace_node *node;
282 acpi_status status;
283
284 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
285
286 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
287 return_ACPI_STATUS(AE_OK);
288 }
289
290 /* Get the Buffer node */
291
292 node = obj_desc->buffer.node;
293 if (!node) {
294 ACPI_ERROR((AE_INFO,
295 "No pointer back to namespace node in buffer object %p",
296 obj_desc));
297 return_ACPI_STATUS(AE_AML_INTERNAL);
298 }
299
300 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
301
302 /* Execute the AML code for the term_arg arguments */
303
304 status = acpi_ds_execute_arguments(node, node,
305 obj_desc->buffer.aml_length,
306 obj_desc->buffer.aml_start);
307 return_ACPI_STATUS(status);
308}
309
310/*******************************************************************************
311 *
312 * FUNCTION: acpi_ds_get_package_arguments
313 *
314 * PARAMETERS: obj_desc - A valid Package object
315 *
316 * RETURN: Status.
317 *
318 * DESCRIPTION: Get Package length and initializer byte list. This implements
319 * the late evaluation of these attributes.
320 *
321 ******************************************************************************/
322
323acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
324{
325 struct acpi_namespace_node *node;
326 acpi_status status;
327
328 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
329
330 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
331 return_ACPI_STATUS(AE_OK);
332 }
333
334 /* Get the Package node */
335
336 node = obj_desc->package.node;
337 if (!node) {
338 ACPI_ERROR((AE_INFO,
339 "No pointer back to namespace node in package %p",
340 obj_desc));
341 return_ACPI_STATUS(AE_AML_INTERNAL);
342 }
343
344 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
345
346 /* Execute the AML code for the term_arg arguments */
347
348 status = acpi_ds_execute_arguments(node, node,
349 obj_desc->package.aml_length,
350 obj_desc->package.aml_start);
351 return_ACPI_STATUS(status);
352}
353
354/*****************************************************************************
355 *
356 * FUNCTION: acpi_ds_get_region_arguments
357 *
358 * PARAMETERS: obj_desc - A valid region object
359 *
360 * RETURN: Status.
361 *
362 * DESCRIPTION: Get region address and length. This implements the late
363 * evaluation of these region attributes.
364 *
365 ****************************************************************************/
366
367acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
368{
369 struct acpi_namespace_node *node;
370 acpi_status status;
371 union acpi_operand_object *extra_desc;
372
373 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
374
375 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
376 return_ACPI_STATUS(AE_OK);
377 }
378
379 extra_desc = acpi_ns_get_secondary_object(obj_desc);
380 if (!extra_desc) {
381 return_ACPI_STATUS(AE_NOT_EXIST);
382 }
383
384 /* Get the Region node */
385
386 node = obj_desc->region.node;
387
388 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
389 (ACPI_TYPE_REGION, node, NULL));
390
391 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
392 acpi_ut_get_node_name(node),
393 extra_desc->extra.aml_start));
394
395 /* Execute the argument AML */
396
397 status = acpi_ds_execute_arguments(node, node->parent,
398 extra_desc->extra.aml_length,
399 extra_desc->extra.aml_start);
400 if (ACPI_FAILURE(status)) {
401 return_ACPI_STATUS(status);
402 }
403
404 /* Validate the region address/length via the host OS */
405
406 status = acpi_os_validate_address(obj_desc->region.space_id,
407 obj_desc->region.address,
408 (acpi_size) obj_desc->region.length,
409 acpi_ut_get_node_name(node));
410
411 if (ACPI_FAILURE(status)) {
412 /*
413 * Invalid address/length. We will emit an error message and mark
414 * the region as invalid, so that it will cause an additional error if
415 * it is ever used. Then return AE_OK.
416 */
417 ACPI_EXCEPTION((AE_INFO, status,
418 "During address validation of OpRegion [%4.4s]",
419 node->name.ascii));
420 obj_desc->common.flags |= AOPOBJ_INVALID;
421 status = AE_OK;
422 }
423
424 return_ACPI_STATUS(status);
425}
426
427/*******************************************************************************
428 *
429 * FUNCTION: acpi_ds_initialize_region 68 * FUNCTION: acpi_ds_initialize_region
430 * 69 *
431 * PARAMETERS: obj_handle - Region namespace node 70 * PARAMETERS: obj_handle - Region namespace node
@@ -826,8 +465,9 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
826 * 465 *
827 * RETURN: Status 466 * RETURN: Status
828 * 467 *
829 * DESCRIPTION: Get region address and length 468 * DESCRIPTION: Get region address and length.
830 * Called from acpi_ds_exec_end_op during data_table_region parse tree walk 469 * Called from acpi_ds_exec_end_op during data_table_region parse
470 * tree walk.
831 * 471 *
832 ******************************************************************************/ 472 ******************************************************************************/
833 473
@@ -1114,360 +754,3 @@ acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
1114 acpi_ut_remove_reference(operand_desc); 754 acpi_ut_remove_reference(operand_desc);
1115 return_ACPI_STATUS(status); 755 return_ACPI_STATUS(status);
1116} 756}
1117
1118/*******************************************************************************
1119 *
1120 * FUNCTION: acpi_ds_exec_begin_control_op
1121 *
1122 * PARAMETERS: walk_list - The list that owns the walk stack
1123 * Op - The control Op
1124 *
1125 * RETURN: Status
1126 *
1127 * DESCRIPTION: Handles all control ops encountered during control method
1128 * execution.
1129 *
1130 ******************************************************************************/
1131
1132acpi_status
1133acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
1134 union acpi_parse_object *op)
1135{
1136 acpi_status status = AE_OK;
1137 union acpi_generic_state *control_state;
1138
1139 ACPI_FUNCTION_NAME(ds_exec_begin_control_op);
1140
1141 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
1142 op->common.aml_opcode, walk_state));
1143
1144 switch (op->common.aml_opcode) {
1145 case AML_WHILE_OP:
1146
1147 /*
1148 * If this is an additional iteration of a while loop, continue.
1149 * There is no need to allocate a new control state.
1150 */
1151 if (walk_state->control_state) {
1152 if (walk_state->control_state->control.aml_predicate_start
1153 == (walk_state->parser_state.aml - 1)) {
1154
1155 /* Reset the state to start-of-loop */
1156
1157 walk_state->control_state->common.state =
1158 ACPI_CONTROL_CONDITIONAL_EXECUTING;
1159 break;
1160 }
1161 }
1162
1163 /*lint -fallthrough */
1164
1165 case AML_IF_OP:
1166
1167 /*
1168 * IF/WHILE: Create a new control state to manage these
1169 * constructs. We need to manage these as a stack, in order
1170 * to handle nesting.
1171 */
1172 control_state = acpi_ut_create_control_state();
1173 if (!control_state) {
1174 status = AE_NO_MEMORY;
1175 break;
1176 }
1177 /*
1178 * Save a pointer to the predicate for multiple executions
1179 * of a loop
1180 */
1181 control_state->control.aml_predicate_start =
1182 walk_state->parser_state.aml - 1;
1183 control_state->control.package_end =
1184 walk_state->parser_state.pkg_end;
1185 control_state->control.opcode = op->common.aml_opcode;
1186
1187 /* Push the control state on this walk's control stack */
1188
1189 acpi_ut_push_generic_state(&walk_state->control_state,
1190 control_state);
1191 break;
1192
1193 case AML_ELSE_OP:
1194
1195 /* Predicate is in the state object */
1196 /* If predicate is true, the IF was executed, ignore ELSE part */
1197
1198 if (walk_state->last_predicate) {
1199 status = AE_CTRL_TRUE;
1200 }
1201
1202 break;
1203
1204 case AML_RETURN_OP:
1205
1206 break;
1207
1208 default:
1209 break;
1210 }
1211
1212 return (status);
1213}
1214
1215/*******************************************************************************
1216 *
1217 * FUNCTION: acpi_ds_exec_end_control_op
1218 *
1219 * PARAMETERS: walk_list - The list that owns the walk stack
1220 * Op - The control Op
1221 *
1222 * RETURN: Status
1223 *
1224 * DESCRIPTION: Handles all control ops encountered during control method
1225 * execution.
1226 *
1227 ******************************************************************************/
1228
1229acpi_status
1230acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1231 union acpi_parse_object * op)
1232{
1233 acpi_status status = AE_OK;
1234 union acpi_generic_state *control_state;
1235
1236 ACPI_FUNCTION_NAME(ds_exec_end_control_op);
1237
1238 switch (op->common.aml_opcode) {
1239 case AML_IF_OP:
1240
1241 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
1242
1243 /*
1244 * Save the result of the predicate in case there is an
1245 * ELSE to come
1246 */
1247 walk_state->last_predicate =
1248 (u8) walk_state->control_state->common.value;
1249
1250 /*
1251 * Pop the control state that was created at the start
1252 * of the IF and free it
1253 */
1254 control_state =
1255 acpi_ut_pop_generic_state(&walk_state->control_state);
1256 acpi_ut_delete_generic_state(control_state);
1257 break;
1258
1259 case AML_ELSE_OP:
1260
1261 break;
1262
1263 case AML_WHILE_OP:
1264
1265 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
1266
1267 control_state = walk_state->control_state;
1268 if (control_state->common.value) {
1269
1270 /* Predicate was true, the body of the loop was just executed */
1271
1272 /*
1273 * This loop counter mechanism allows the interpreter to escape
1274 * possibly infinite loops. This can occur in poorly written AML
1275 * when the hardware does not respond within a while loop and the
1276 * loop does not implement a timeout.
1277 */
1278 control_state->control.loop_count++;
1279 if (control_state->control.loop_count >
1280 ACPI_MAX_LOOP_ITERATIONS) {
1281 status = AE_AML_INFINITE_LOOP;
1282 break;
1283 }
1284
1285 /*
1286 * Go back and evaluate the predicate and maybe execute the loop
1287 * another time
1288 */
1289 status = AE_CTRL_PENDING;
1290 walk_state->aml_last_while =
1291 control_state->control.aml_predicate_start;
1292 break;
1293 }
1294
1295 /* Predicate was false, terminate this while loop */
1296
1297 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1298 "[WHILE_OP] termination! Op=%p\n", op));
1299
1300 /* Pop this control state and free it */
1301
1302 control_state =
1303 acpi_ut_pop_generic_state(&walk_state->control_state);
1304 acpi_ut_delete_generic_state(control_state);
1305 break;
1306
1307 case AML_RETURN_OP:
1308
1309 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1310 "[RETURN_OP] Op=%p Arg=%p\n", op,
1311 op->common.value.arg));
1312
1313 /*
1314 * One optional operand -- the return value
1315 * It can be either an immediate operand or a result that
1316 * has been bubbled up the tree
1317 */
1318 if (op->common.value.arg) {
1319
1320 /* Since we have a real Return(), delete any implicit return */
1321
1322 acpi_ds_clear_implicit_return(walk_state);
1323
1324 /* Return statement has an immediate operand */
1325
1326 status =
1327 acpi_ds_create_operands(walk_state,
1328 op->common.value.arg);
1329 if (ACPI_FAILURE(status)) {
1330 return (status);
1331 }
1332
1333 /*
1334 * If value being returned is a Reference (such as
1335 * an arg or local), resolve it now because it may
1336 * cease to exist at the end of the method.
1337 */
1338 status =
1339 acpi_ex_resolve_to_value(&walk_state->operands[0],
1340 walk_state);
1341 if (ACPI_FAILURE(status)) {
1342 return (status);
1343 }
1344
1345 /*
1346 * Get the return value and save as the last result
1347 * value. This is the only place where walk_state->return_desc
1348 * is set to anything other than zero!
1349 */
1350 walk_state->return_desc = walk_state->operands[0];
1351 } else if (walk_state->result_count) {
1352
1353 /* Since we have a real Return(), delete any implicit return */
1354
1355 acpi_ds_clear_implicit_return(walk_state);
1356
1357 /*
1358 * The return value has come from a previous calculation.
1359 *
1360 * If value being returned is a Reference (such as
1361 * an arg or local), resolve it now because it may
1362 * cease to exist at the end of the method.
1363 *
1364 * Allow references created by the Index operator to return unchanged.
1365 */
1366 if ((ACPI_GET_DESCRIPTOR_TYPE
1367 (walk_state->results->results.obj_desc[0]) ==
1368 ACPI_DESC_TYPE_OPERAND)
1369 && ((walk_state->results->results.obj_desc[0])->
1370 common.type == ACPI_TYPE_LOCAL_REFERENCE)
1371 && ((walk_state->results->results.obj_desc[0])->
1372 reference.class != ACPI_REFCLASS_INDEX)) {
1373 status =
1374 acpi_ex_resolve_to_value(&walk_state->
1375 results->results.
1376 obj_desc[0],
1377 walk_state);
1378 if (ACPI_FAILURE(status)) {
1379 return (status);
1380 }
1381 }
1382
1383 walk_state->return_desc =
1384 walk_state->results->results.obj_desc[0];
1385 } else {
1386 /* No return operand */
1387
1388 if (walk_state->num_operands) {
1389 acpi_ut_remove_reference(walk_state->
1390 operands[0]);
1391 }
1392
1393 walk_state->operands[0] = NULL;
1394 walk_state->num_operands = 0;
1395 walk_state->return_desc = NULL;
1396 }
1397
1398 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1399 "Completed RETURN_OP State=%p, RetVal=%p\n",
1400 walk_state, walk_state->return_desc));
1401
1402 /* End the control method execution right now */
1403
1404 status = AE_CTRL_TERMINATE;
1405 break;
1406
1407 case AML_NOOP_OP:
1408
1409 /* Just do nothing! */
1410 break;
1411
1412 case AML_BREAK_POINT_OP:
1413
1414 /*
1415 * Set the single-step flag. This will cause the debugger (if present)
1416 * to break to the console within the AML debugger at the start of the
1417 * next AML instruction.
1418 */
1419 ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
1420 ACPI_DEBUGGER_EXEC(acpi_os_printf
1421 ("**break** Executed AML BreakPoint opcode\n"));
1422
1423 /* Call to the OSL in case OS wants a piece of the action */
1424
1425 status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
1426 "Executed AML Breakpoint opcode");
1427 break;
1428
1429 case AML_BREAK_OP:
1430 case AML_CONTINUE_OP: /* ACPI 2.0 */
1431
1432 /* Pop and delete control states until we find a while */
1433
1434 while (walk_state->control_state &&
1435 (walk_state->control_state->control.opcode !=
1436 AML_WHILE_OP)) {
1437 control_state =
1438 acpi_ut_pop_generic_state(&walk_state->
1439 control_state);
1440 acpi_ut_delete_generic_state(control_state);
1441 }
1442
1443 /* No while found? */
1444
1445 if (!walk_state->control_state) {
1446 return (AE_AML_NO_WHILE);
1447 }
1448
1449 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
1450
1451 walk_state->aml_last_while =
1452 walk_state->control_state->control.package_end;
1453
1454 /* Return status depending on opcode */
1455
1456 if (op->common.aml_opcode == AML_BREAK_OP) {
1457 status = AE_CTRL_BREAK;
1458 } else {
1459 status = AE_CTRL_CONTINUE;
1460 }
1461 break;
1462
1463 default:
1464
1465 ACPI_ERROR((AE_INFO, "Unknown control opcode=0x%X Op=%p",
1466 op->common.aml_opcode, op));
1467
1468 status = AE_AML_BAD_OPCODE;
1469 break;
1470 }
1471
1472 return (status);
1473}
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index 15135c25aa9b..2c477ce172fa 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index d555b374e314..fe40e4c6554f 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -300,10 +300,25 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
300 * we must enter this object into the namespace. The created 300 * we must enter this object into the namespace. The created
301 * object is temporary and will be deleted upon completion of 301 * object is temporary and will be deleted upon completion of
302 * the execution of this method. 302 * the execution of this method.
303 *
304 * Note 10/2010: Except for the Scope() op. This opcode does
305 * not actually create a new object, it refers to an existing
306 * object. However, for Scope(), we want to indeed open a
307 * new scope.
303 */ 308 */
304 status = acpi_ds_load2_begin_op(walk_state, NULL); 309 if (op->common.aml_opcode != AML_SCOPE_OP) {
310 status =
311 acpi_ds_load2_begin_op(walk_state, NULL);
312 } else {
313 status =
314 acpi_ds_scope_stack_push(op->named.node,
315 op->named.node->
316 type, walk_state);
317 if (ACPI_FAILURE(status)) {
318 return_ACPI_STATUS(status);
319 }
320 }
305 } 321 }
306
307 break; 322 break;
308 323
309 case AML_CLASS_EXECUTE: 324 case AML_CLASS_EXECUTE:
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
index 140a9d002959..324acec1179a 100644
--- a/drivers/acpi/acpica/dswload.c
+++ b/drivers/acpi/acpica/dswload.c
@@ -1,11 +1,11 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks 3 * Module Name: dswload - Dispatcher first pass namespace load callbacks
4 * 4 *
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,7 +48,6 @@
48#include "acdispat.h" 48#include "acdispat.h"
49#include "acinterp.h" 49#include "acinterp.h"
50#include "acnamesp.h" 50#include "acnamesp.h"
51#include "acevents.h"
52 51
53#ifdef ACPI_ASL_COMPILER 52#ifdef ACPI_ASL_COMPILER
54#include <acpi/acdisasm.h> 53#include <acpi/acdisasm.h>
@@ -451,7 +450,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
451 status = 450 status =
452 acpi_ex_create_region(op->named.data, 451 acpi_ex_create_region(op->named.data,
453 op->named.length, 452 op->named.length,
454 REGION_DATA_TABLE, 453 ACPI_ADR_SPACE_DATA_TABLE,
455 walk_state); 454 walk_state);
456 if (ACPI_FAILURE(status)) { 455 if (ACPI_FAILURE(status)) {
457 return_ACPI_STATUS(status); 456 return_ACPI_STATUS(status);
@@ -537,670 +536,3 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
537 536
538 return_ACPI_STATUS(status); 537 return_ACPI_STATUS(status);
539} 538}
540
541/*******************************************************************************
542 *
543 * FUNCTION: acpi_ds_load2_begin_op
544 *
545 * PARAMETERS: walk_state - Current state of the parse tree walk
546 * out_op - Wher to return op if a new one is created
547 *
548 * RETURN: Status
549 *
550 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
551 *
552 ******************************************************************************/
553
554acpi_status
555acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
556 union acpi_parse_object **out_op)
557{
558 union acpi_parse_object *op;
559 struct acpi_namespace_node *node;
560 acpi_status status;
561 acpi_object_type object_type;
562 char *buffer_ptr;
563 u32 flags;
564
565 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
566
567 op = walk_state->op;
568 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
569 walk_state));
570
571 if (op) {
572 if ((walk_state->control_state) &&
573 (walk_state->control_state->common.state ==
574 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
575
576 /* We are executing a while loop outside of a method */
577
578 status = acpi_ds_exec_begin_op(walk_state, out_op);
579 return_ACPI_STATUS(status);
580 }
581
582 /* We only care about Namespace opcodes here */
583
584 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
585 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
586 (!(walk_state->op_info->flags & AML_NAMED))) {
587 return_ACPI_STATUS(AE_OK);
588 }
589
590 /* Get the name we are going to enter or lookup in the namespace */
591
592 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
593
594 /* For Namepath op, get the path string */
595
596 buffer_ptr = op->common.value.string;
597 if (!buffer_ptr) {
598
599 /* No name, just exit */
600
601 return_ACPI_STATUS(AE_OK);
602 }
603 } else {
604 /* Get name from the op */
605
606 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
607 }
608 } else {
609 /* Get the namestring from the raw AML */
610
611 buffer_ptr =
612 acpi_ps_get_next_namestring(&walk_state->parser_state);
613 }
614
615 /* Map the opcode into an internal object type */
616
617 object_type = walk_state->op_info->object_type;
618
619 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
620 "State=%p Op=%p Type=%X\n", walk_state, op,
621 object_type));
622
623 switch (walk_state->opcode) {
624 case AML_FIELD_OP:
625 case AML_BANK_FIELD_OP:
626 case AML_INDEX_FIELD_OP:
627
628 node = NULL;
629 status = AE_OK;
630 break;
631
632 case AML_INT_NAMEPATH_OP:
633 /*
634 * The name_path is an object reference to an existing object.
635 * Don't enter the name into the namespace, but look it up
636 * for use later.
637 */
638 status =
639 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
640 object_type, ACPI_IMODE_EXECUTE,
641 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
642 break;
643
644 case AML_SCOPE_OP:
645
646 /* Special case for Scope(\) -> refers to the Root node */
647
648 if (op && (op->named.node == acpi_gbl_root_node)) {
649 node = op->named.node;
650
651 status =
652 acpi_ds_scope_stack_push(node, object_type,
653 walk_state);
654 if (ACPI_FAILURE(status)) {
655 return_ACPI_STATUS(status);
656 }
657 } else {
658 /*
659 * The Path is an object reference to an existing object.
660 * Don't enter the name into the namespace, but look it up
661 * for use later.
662 */
663 status =
664 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
665 object_type, ACPI_IMODE_EXECUTE,
666 ACPI_NS_SEARCH_PARENT, walk_state,
667 &(node));
668 if (ACPI_FAILURE(status)) {
669#ifdef ACPI_ASL_COMPILER
670 if (status == AE_NOT_FOUND) {
671 status = AE_OK;
672 } else {
673 ACPI_ERROR_NAMESPACE(buffer_ptr,
674 status);
675 }
676#else
677 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
678#endif
679 return_ACPI_STATUS(status);
680 }
681 }
682
683 /*
684 * We must check to make sure that the target is
685 * one of the opcodes that actually opens a scope
686 */
687 switch (node->type) {
688 case ACPI_TYPE_ANY:
689 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
690 case ACPI_TYPE_DEVICE:
691 case ACPI_TYPE_POWER:
692 case ACPI_TYPE_PROCESSOR:
693 case ACPI_TYPE_THERMAL:
694
695 /* These are acceptable types */
696 break;
697
698 case ACPI_TYPE_INTEGER:
699 case ACPI_TYPE_STRING:
700 case ACPI_TYPE_BUFFER:
701
702 /*
703 * These types we will allow, but we will change the type.
704 * This enables some existing code of the form:
705 *
706 * Name (DEB, 0)
707 * Scope (DEB) { ... }
708 */
709 ACPI_WARNING((AE_INFO,
710 "Type override - [%4.4s] had invalid type (%s) "
711 "for Scope operator, changed to type ANY\n",
712 acpi_ut_get_node_name(node),
713 acpi_ut_get_type_name(node->type)));
714
715 node->type = ACPI_TYPE_ANY;
716 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
717 break;
718
719 default:
720
721 /* All other types are an error */
722
723 ACPI_ERROR((AE_INFO,
724 "Invalid type (%s) for target of "
725 "Scope operator [%4.4s] (Cannot override)",
726 acpi_ut_get_type_name(node->type),
727 acpi_ut_get_node_name(node)));
728
729 return (AE_AML_OPERAND_TYPE);
730 }
731 break;
732
733 default:
734
735 /* All other opcodes */
736
737 if (op && op->common.node) {
738
739 /* This op/node was previously entered into the namespace */
740
741 node = op->common.node;
742
743 if (acpi_ns_opens_scope(object_type)) {
744 status =
745 acpi_ds_scope_stack_push(node, object_type,
746 walk_state);
747 if (ACPI_FAILURE(status)) {
748 return_ACPI_STATUS(status);
749 }
750 }
751
752 return_ACPI_STATUS(AE_OK);
753 }
754
755 /*
756 * Enter the named type into the internal namespace. We enter the name
757 * as we go downward in the parse tree. Any necessary subobjects that
758 * involve arguments to the opcode must be created as we go back up the
759 * parse tree later.
760 *
761 * Note: Name may already exist if we are executing a deferred opcode.
762 */
763 if (walk_state->deferred_node) {
764
765 /* This name is already in the namespace, get the node */
766
767 node = walk_state->deferred_node;
768 status = AE_OK;
769 break;
770 }
771
772 flags = ACPI_NS_NO_UPSEARCH;
773 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
774
775 /* Execution mode, node cannot already exist, node is temporary */
776
777 flags |= ACPI_NS_ERROR_IF_FOUND;
778
779 if (!
780 (walk_state->
781 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
782 flags |= ACPI_NS_TEMPORARY;
783 }
784 }
785
786 /* Add new entry or lookup existing entry */
787
788 status =
789 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
790 object_type, ACPI_IMODE_LOAD_PASS2, flags,
791 walk_state, &node);
792
793 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
794 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
795 "***New Node [%4.4s] %p is temporary\n",
796 acpi_ut_get_node_name(node), node));
797 }
798 break;
799 }
800
801 if (ACPI_FAILURE(status)) {
802 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
803 return_ACPI_STATUS(status);
804 }
805
806 if (!op) {
807
808 /* Create a new op */
809
810 op = acpi_ps_alloc_op(walk_state->opcode);
811 if (!op) {
812 return_ACPI_STATUS(AE_NO_MEMORY);
813 }
814
815 /* Initialize the new op */
816
817 if (node) {
818 op->named.name = node->name.integer;
819 }
820 *out_op = op;
821 }
822
823 /*
824 * Put the Node in the "op" object that the parser uses, so we
825 * can get it again quickly when this scope is closed
826 */
827 op->common.node = node;
828 return_ACPI_STATUS(status);
829}
830
831/*******************************************************************************
832 *
833 * FUNCTION: acpi_ds_load2_end_op
834 *
835 * PARAMETERS: walk_state - Current state of the parse tree walk
836 *
837 * RETURN: Status
838 *
839 * DESCRIPTION: Ascending callback used during the loading of the namespace,
840 * both control methods and everything else.
841 *
842 ******************************************************************************/
843
844acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
845{
846 union acpi_parse_object *op;
847 acpi_status status = AE_OK;
848 acpi_object_type object_type;
849 struct acpi_namespace_node *node;
850 union acpi_parse_object *arg;
851 struct acpi_namespace_node *new_node;
852#ifndef ACPI_NO_METHOD_EXECUTION
853 u32 i;
854 u8 region_space;
855#endif
856
857 ACPI_FUNCTION_TRACE(ds_load2_end_op);
858
859 op = walk_state->op;
860 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
861 walk_state->op_info->name, op, walk_state));
862
863 /* Check if opcode had an associated namespace object */
864
865 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
866 return_ACPI_STATUS(AE_OK);
867 }
868
869 if (op->common.aml_opcode == AML_SCOPE_OP) {
870 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
871 "Ending scope Op=%p State=%p\n", op,
872 walk_state));
873 }
874
875 object_type = walk_state->op_info->object_type;
876
877 /*
878 * Get the Node/name from the earlier lookup
879 * (It was saved in the *op structure)
880 */
881 node = op->common.node;
882
883 /*
884 * Put the Node on the object stack (Contains the ACPI Name of
885 * this object)
886 */
887 walk_state->operands[0] = (void *)node;
888 walk_state->num_operands = 1;
889
890 /* Pop the scope stack */
891
892 if (acpi_ns_opens_scope(object_type) &&
893 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
894 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
895 "(%s) Popping scope for Op %p\n",
896 acpi_ut_get_type_name(object_type), op));
897
898 status = acpi_ds_scope_stack_pop(walk_state);
899 if (ACPI_FAILURE(status)) {
900 goto cleanup;
901 }
902 }
903
904 /*
905 * Named operations are as follows:
906 *
907 * AML_ALIAS
908 * AML_BANKFIELD
909 * AML_CREATEBITFIELD
910 * AML_CREATEBYTEFIELD
911 * AML_CREATEDWORDFIELD
912 * AML_CREATEFIELD
913 * AML_CREATEQWORDFIELD
914 * AML_CREATEWORDFIELD
915 * AML_DATA_REGION
916 * AML_DEVICE
917 * AML_EVENT
918 * AML_FIELD
919 * AML_INDEXFIELD
920 * AML_METHOD
921 * AML_METHODCALL
922 * AML_MUTEX
923 * AML_NAME
924 * AML_NAMEDFIELD
925 * AML_OPREGION
926 * AML_POWERRES
927 * AML_PROCESSOR
928 * AML_SCOPE
929 * AML_THERMALZONE
930 */
931
932 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
933 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
934 acpi_ps_get_opcode_name(op->common.aml_opcode),
935 walk_state, op, node));
936
937 /* Decode the opcode */
938
939 arg = op->common.value.arg;
940
941 switch (walk_state->op_info->type) {
942#ifndef ACPI_NO_METHOD_EXECUTION
943
944 case AML_TYPE_CREATE_FIELD:
945 /*
946 * Create the field object, but the field buffer and index must
947 * be evaluated later during the execution phase
948 */
949 status = acpi_ds_create_buffer_field(op, walk_state);
950 break;
951
952 case AML_TYPE_NAMED_FIELD:
953 /*
954 * If we are executing a method, initialize the field
955 */
956 if (walk_state->method_node) {
957 status = acpi_ds_init_field_objects(op, walk_state);
958 }
959
960 switch (op->common.aml_opcode) {
961 case AML_INDEX_FIELD_OP:
962
963 status =
964 acpi_ds_create_index_field(op,
965 (acpi_handle) arg->
966 common.node, walk_state);
967 break;
968
969 case AML_BANK_FIELD_OP:
970
971 status =
972 acpi_ds_create_bank_field(op, arg->common.node,
973 walk_state);
974 break;
975
976 case AML_FIELD_OP:
977
978 status =
979 acpi_ds_create_field(op, arg->common.node,
980 walk_state);
981 break;
982
983 default:
984 /* All NAMED_FIELD opcodes must be handled above */
985 break;
986 }
987 break;
988
989 case AML_TYPE_NAMED_SIMPLE:
990
991 status = acpi_ds_create_operands(walk_state, arg);
992 if (ACPI_FAILURE(status)) {
993 goto cleanup;
994 }
995
996 switch (op->common.aml_opcode) {
997 case AML_PROCESSOR_OP:
998
999 status = acpi_ex_create_processor(walk_state);
1000 break;
1001
1002 case AML_POWER_RES_OP:
1003
1004 status = acpi_ex_create_power_resource(walk_state);
1005 break;
1006
1007 case AML_MUTEX_OP:
1008
1009 status = acpi_ex_create_mutex(walk_state);
1010 break;
1011
1012 case AML_EVENT_OP:
1013
1014 status = acpi_ex_create_event(walk_state);
1015 break;
1016
1017 case AML_ALIAS_OP:
1018
1019 status = acpi_ex_create_alias(walk_state);
1020 break;
1021
1022 default:
1023 /* Unknown opcode */
1024
1025 status = AE_OK;
1026 goto cleanup;
1027 }
1028
1029 /* Delete operands */
1030
1031 for (i = 1; i < walk_state->num_operands; i++) {
1032 acpi_ut_remove_reference(walk_state->operands[i]);
1033 walk_state->operands[i] = NULL;
1034 }
1035
1036 break;
1037#endif /* ACPI_NO_METHOD_EXECUTION */
1038
1039 case AML_TYPE_NAMED_COMPLEX:
1040
1041 switch (op->common.aml_opcode) {
1042#ifndef ACPI_NO_METHOD_EXECUTION
1043 case AML_REGION_OP:
1044 case AML_DATA_REGION_OP:
1045
1046 if (op->common.aml_opcode == AML_REGION_OP) {
1047 region_space = (acpi_adr_space_type)
1048 ((op->common.value.arg)->common.value.
1049 integer);
1050 } else {
1051 region_space = REGION_DATA_TABLE;
1052 }
1053
1054 /*
1055 * The op_region is not fully parsed at this time. The only valid
1056 * argument is the space_id. (We must save the address of the
1057 * AML of the address and length operands)
1058 *
1059 * If we have a valid region, initialize it. The namespace is
1060 * unlocked at this point.
1061 *
1062 * Need to unlock interpreter if it is locked (if we are running
1063 * a control method), in order to allow _REG methods to be run
1064 * during acpi_ev_initialize_region.
1065 */
1066 if (walk_state->method_node) {
1067 /*
1068 * Executing a method: initialize the region and unlock
1069 * the interpreter
1070 */
1071 status =
1072 acpi_ex_create_region(op->named.data,
1073 op->named.length,
1074 region_space,
1075 walk_state);
1076 if (ACPI_FAILURE(status)) {
1077 return (status);
1078 }
1079
1080 acpi_ex_exit_interpreter();
1081 }
1082
1083 status =
1084 acpi_ev_initialize_region
1085 (acpi_ns_get_attached_object(node), FALSE);
1086 if (walk_state->method_node) {
1087 acpi_ex_enter_interpreter();
1088 }
1089
1090 if (ACPI_FAILURE(status)) {
1091 /*
1092 * If AE_NOT_EXIST is returned, it is not fatal
1093 * because many regions get created before a handler
1094 * is installed for said region.
1095 */
1096 if (AE_NOT_EXIST == status) {
1097 status = AE_OK;
1098 }
1099 }
1100 break;
1101
1102 case AML_NAME_OP:
1103
1104 status = acpi_ds_create_node(walk_state, node, op);
1105 break;
1106
1107 case AML_METHOD_OP:
1108 /*
1109 * method_op pkg_length name_string method_flags term_list
1110 *
1111 * Note: We must create the method node/object pair as soon as we
1112 * see the method declaration. This allows later pass1 parsing
1113 * of invocations of the method (need to know the number of
1114 * arguments.)
1115 */
1116 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1117 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
1118 walk_state, op, op->named.node));
1119
1120 if (!acpi_ns_get_attached_object(op->named.node)) {
1121 walk_state->operands[0] =
1122 ACPI_CAST_PTR(void, op->named.node);
1123 walk_state->num_operands = 1;
1124
1125 status =
1126 acpi_ds_create_operands(walk_state,
1127 op->common.value.
1128 arg);
1129 if (ACPI_SUCCESS(status)) {
1130 status =
1131 acpi_ex_create_method(op->named.
1132 data,
1133 op->named.
1134 length,
1135 walk_state);
1136 }
1137 walk_state->operands[0] = NULL;
1138 walk_state->num_operands = 0;
1139
1140 if (ACPI_FAILURE(status)) {
1141 return_ACPI_STATUS(status);
1142 }
1143 }
1144 break;
1145
1146#endif /* ACPI_NO_METHOD_EXECUTION */
1147
1148 default:
1149 /* All NAMED_COMPLEX opcodes must be handled above */
1150 break;
1151 }
1152 break;
1153
1154 case AML_CLASS_INTERNAL:
1155
1156 /* case AML_INT_NAMEPATH_OP: */
1157 break;
1158
1159 case AML_CLASS_METHOD_CALL:
1160
1161 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
1162 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
1163 walk_state, op, node));
1164
1165 /*
1166 * Lookup the method name and save the Node
1167 */
1168 status =
1169 acpi_ns_lookup(walk_state->scope_info,
1170 arg->common.value.string, ACPI_TYPE_ANY,
1171 ACPI_IMODE_LOAD_PASS2,
1172 ACPI_NS_SEARCH_PARENT |
1173 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
1174 &(new_node));
1175 if (ACPI_SUCCESS(status)) {
1176 /*
1177 * Make sure that what we found is indeed a method
1178 * We didn't search for a method on purpose, to see if the name
1179 * would resolve
1180 */
1181 if (new_node->type != ACPI_TYPE_METHOD) {
1182 status = AE_AML_OPERAND_TYPE;
1183 }
1184
1185 /* We could put the returned object (Node) on the object stack for
1186 * later, but for now, we will put it in the "op" object that the
1187 * parser uses, so we can get it again at the end of this scope
1188 */
1189 op->common.node = new_node;
1190 } else {
1191 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
1192 }
1193 break;
1194
1195 default:
1196 break;
1197 }
1198
1199 cleanup:
1200
1201 /* Remove the Node pushed at the very beginning */
1202
1203 walk_state->operands[0] = NULL;
1204 walk_state->num_operands = 0;
1205 return_ACPI_STATUS(status);
1206}
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
new file mode 100644
index 000000000000..976318138c56
--- /dev/null
+++ b/drivers/acpi/acpica/dswload2.c
@@ -0,0 +1,720 @@
1/******************************************************************************
2 *
3 * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acparser.h"
47#include "amlcode.h"
48#include "acdispat.h"
49#include "acinterp.h"
50#include "acnamesp.h"
51#include "acevents.h"
52
53#define _COMPONENT ACPI_DISPATCHER
54ACPI_MODULE_NAME("dswload2")
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ds_load2_begin_op
59 *
60 * PARAMETERS: walk_state - Current state of the parse tree walk
61 * out_op - Wher to return op if a new one is created
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
66 *
67 ******************************************************************************/
68acpi_status
69acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
70 union acpi_parse_object **out_op)
71{
72 union acpi_parse_object *op;
73 struct acpi_namespace_node *node;
74 acpi_status status;
75 acpi_object_type object_type;
76 char *buffer_ptr;
77 u32 flags;
78
79 ACPI_FUNCTION_TRACE(ds_load2_begin_op);
80
81 op = walk_state->op;
82 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
83 walk_state));
84
85 if (op) {
86 if ((walk_state->control_state) &&
87 (walk_state->control_state->common.state ==
88 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
89
90 /* We are executing a while loop outside of a method */
91
92 status = acpi_ds_exec_begin_op(walk_state, out_op);
93 return_ACPI_STATUS(status);
94 }
95
96 /* We only care about Namespace opcodes here */
97
98 if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
99 (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
100 (!(walk_state->op_info->flags & AML_NAMED))) {
101 return_ACPI_STATUS(AE_OK);
102 }
103
104 /* Get the name we are going to enter or lookup in the namespace */
105
106 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
107
108 /* For Namepath op, get the path string */
109
110 buffer_ptr = op->common.value.string;
111 if (!buffer_ptr) {
112
113 /* No name, just exit */
114
115 return_ACPI_STATUS(AE_OK);
116 }
117 } else {
118 /* Get name from the op */
119
120 buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
121 }
122 } else {
123 /* Get the namestring from the raw AML */
124
125 buffer_ptr =
126 acpi_ps_get_next_namestring(&walk_state->parser_state);
127 }
128
129 /* Map the opcode into an internal object type */
130
131 object_type = walk_state->op_info->object_type;
132
133 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
134 "State=%p Op=%p Type=%X\n", walk_state, op,
135 object_type));
136
137 switch (walk_state->opcode) {
138 case AML_FIELD_OP:
139 case AML_BANK_FIELD_OP:
140 case AML_INDEX_FIELD_OP:
141
142 node = NULL;
143 status = AE_OK;
144 break;
145
146 case AML_INT_NAMEPATH_OP:
147 /*
148 * The name_path is an object reference to an existing object.
149 * Don't enter the name into the namespace, but look it up
150 * for use later.
151 */
152 status =
153 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
154 object_type, ACPI_IMODE_EXECUTE,
155 ACPI_NS_SEARCH_PARENT, walk_state, &(node));
156 break;
157
158 case AML_SCOPE_OP:
159
160 /* Special case for Scope(\) -> refers to the Root node */
161
162 if (op && (op->named.node == acpi_gbl_root_node)) {
163 node = op->named.node;
164
165 status =
166 acpi_ds_scope_stack_push(node, object_type,
167 walk_state);
168 if (ACPI_FAILURE(status)) {
169 return_ACPI_STATUS(status);
170 }
171 } else {
172 /*
173 * The Path is an object reference to an existing object.
174 * Don't enter the name into the namespace, but look it up
175 * for use later.
176 */
177 status =
178 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
179 object_type, ACPI_IMODE_EXECUTE,
180 ACPI_NS_SEARCH_PARENT, walk_state,
181 &(node));
182 if (ACPI_FAILURE(status)) {
183#ifdef ACPI_ASL_COMPILER
184 if (status == AE_NOT_FOUND) {
185 status = AE_OK;
186 } else {
187 ACPI_ERROR_NAMESPACE(buffer_ptr,
188 status);
189 }
190#else
191 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
192#endif
193 return_ACPI_STATUS(status);
194 }
195 }
196
197 /*
198 * We must check to make sure that the target is
199 * one of the opcodes that actually opens a scope
200 */
201 switch (node->type) {
202 case ACPI_TYPE_ANY:
203 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
204 case ACPI_TYPE_DEVICE:
205 case ACPI_TYPE_POWER:
206 case ACPI_TYPE_PROCESSOR:
207 case ACPI_TYPE_THERMAL:
208
209 /* These are acceptable types */
210 break;
211
212 case ACPI_TYPE_INTEGER:
213 case ACPI_TYPE_STRING:
214 case ACPI_TYPE_BUFFER:
215
216 /*
217 * These types we will allow, but we will change the type.
218 * This enables some existing code of the form:
219 *
220 * Name (DEB, 0)
221 * Scope (DEB) { ... }
222 */
223 ACPI_WARNING((AE_INFO,
224 "Type override - [%4.4s] had invalid type (%s) "
225 "for Scope operator, changed to type ANY\n",
226 acpi_ut_get_node_name(node),
227 acpi_ut_get_type_name(node->type)));
228
229 node->type = ACPI_TYPE_ANY;
230 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
231 break;
232
233 default:
234
235 /* All other types are an error */
236
237 ACPI_ERROR((AE_INFO,
238 "Invalid type (%s) for target of "
239 "Scope operator [%4.4s] (Cannot override)",
240 acpi_ut_get_type_name(node->type),
241 acpi_ut_get_node_name(node)));
242
243 return (AE_AML_OPERAND_TYPE);
244 }
245 break;
246
247 default:
248
249 /* All other opcodes */
250
251 if (op && op->common.node) {
252
253 /* This op/node was previously entered into the namespace */
254
255 node = op->common.node;
256
257 if (acpi_ns_opens_scope(object_type)) {
258 status =
259 acpi_ds_scope_stack_push(node, object_type,
260 walk_state);
261 if (ACPI_FAILURE(status)) {
262 return_ACPI_STATUS(status);
263 }
264 }
265
266 return_ACPI_STATUS(AE_OK);
267 }
268
269 /*
270 * Enter the named type into the internal namespace. We enter the name
271 * as we go downward in the parse tree. Any necessary subobjects that
272 * involve arguments to the opcode must be created as we go back up the
273 * parse tree later.
274 *
275 * Note: Name may already exist if we are executing a deferred opcode.
276 */
277 if (walk_state->deferred_node) {
278
279 /* This name is already in the namespace, get the node */
280
281 node = walk_state->deferred_node;
282 status = AE_OK;
283 break;
284 }
285
286 flags = ACPI_NS_NO_UPSEARCH;
287 if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
288
289 /* Execution mode, node cannot already exist, node is temporary */
290
291 flags |= ACPI_NS_ERROR_IF_FOUND;
292
293 if (!
294 (walk_state->
295 parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
296 flags |= ACPI_NS_TEMPORARY;
297 }
298 }
299
300 /* Add new entry or lookup existing entry */
301
302 status =
303 acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
304 object_type, ACPI_IMODE_LOAD_PASS2, flags,
305 walk_state, &node);
306
307 if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
308 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
309 "***New Node [%4.4s] %p is temporary\n",
310 acpi_ut_get_node_name(node), node));
311 }
312 break;
313 }
314
315 if (ACPI_FAILURE(status)) {
316 ACPI_ERROR_NAMESPACE(buffer_ptr, status);
317 return_ACPI_STATUS(status);
318 }
319
320 if (!op) {
321
322 /* Create a new op */
323
324 op = acpi_ps_alloc_op(walk_state->opcode);
325 if (!op) {
326 return_ACPI_STATUS(AE_NO_MEMORY);
327 }
328
329 /* Initialize the new op */
330
331 if (node) {
332 op->named.name = node->name.integer;
333 }
334 *out_op = op;
335 }
336
337 /*
338 * Put the Node in the "op" object that the parser uses, so we
339 * can get it again quickly when this scope is closed
340 */
341 op->common.node = node;
342 return_ACPI_STATUS(status);
343}
344
345/*******************************************************************************
346 *
347 * FUNCTION: acpi_ds_load2_end_op
348 *
349 * PARAMETERS: walk_state - Current state of the parse tree walk
350 *
351 * RETURN: Status
352 *
353 * DESCRIPTION: Ascending callback used during the loading of the namespace,
354 * both control methods and everything else.
355 *
356 ******************************************************************************/
357
358acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
359{
360 union acpi_parse_object *op;
361 acpi_status status = AE_OK;
362 acpi_object_type object_type;
363 struct acpi_namespace_node *node;
364 union acpi_parse_object *arg;
365 struct acpi_namespace_node *new_node;
366#ifndef ACPI_NO_METHOD_EXECUTION
367 u32 i;
368 u8 region_space;
369#endif
370
371 ACPI_FUNCTION_TRACE(ds_load2_end_op);
372
373 op = walk_state->op;
374 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
375 walk_state->op_info->name, op, walk_state));
376
377 /* Check if opcode had an associated namespace object */
378
379 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
380 return_ACPI_STATUS(AE_OK);
381 }
382
383 if (op->common.aml_opcode == AML_SCOPE_OP) {
384 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
385 "Ending scope Op=%p State=%p\n", op,
386 walk_state));
387 }
388
389 object_type = walk_state->op_info->object_type;
390
391 /*
392 * Get the Node/name from the earlier lookup
393 * (It was saved in the *op structure)
394 */
395 node = op->common.node;
396
397 /*
398 * Put the Node on the object stack (Contains the ACPI Name of
399 * this object)
400 */
401 walk_state->operands[0] = (void *)node;
402 walk_state->num_operands = 1;
403
404 /* Pop the scope stack */
405
406 if (acpi_ns_opens_scope(object_type) &&
407 (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
408 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
409 "(%s) Popping scope for Op %p\n",
410 acpi_ut_get_type_name(object_type), op));
411
412 status = acpi_ds_scope_stack_pop(walk_state);
413 if (ACPI_FAILURE(status)) {
414 goto cleanup;
415 }
416 }
417
418 /*
419 * Named operations are as follows:
420 *
421 * AML_ALIAS
422 * AML_BANKFIELD
423 * AML_CREATEBITFIELD
424 * AML_CREATEBYTEFIELD
425 * AML_CREATEDWORDFIELD
426 * AML_CREATEFIELD
427 * AML_CREATEQWORDFIELD
428 * AML_CREATEWORDFIELD
429 * AML_DATA_REGION
430 * AML_DEVICE
431 * AML_EVENT
432 * AML_FIELD
433 * AML_INDEXFIELD
434 * AML_METHOD
435 * AML_METHODCALL
436 * AML_MUTEX
437 * AML_NAME
438 * AML_NAMEDFIELD
439 * AML_OPREGION
440 * AML_POWERRES
441 * AML_PROCESSOR
442 * AML_SCOPE
443 * AML_THERMALZONE
444 */
445
446 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
447 "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
448 acpi_ps_get_opcode_name(op->common.aml_opcode),
449 walk_state, op, node));
450
451 /* Decode the opcode */
452
453 arg = op->common.value.arg;
454
455 switch (walk_state->op_info->type) {
456#ifndef ACPI_NO_METHOD_EXECUTION
457
458 case AML_TYPE_CREATE_FIELD:
459 /*
460 * Create the field object, but the field buffer and index must
461 * be evaluated later during the execution phase
462 */
463 status = acpi_ds_create_buffer_field(op, walk_state);
464 break;
465
466 case AML_TYPE_NAMED_FIELD:
467 /*
468 * If we are executing a method, initialize the field
469 */
470 if (walk_state->method_node) {
471 status = acpi_ds_init_field_objects(op, walk_state);
472 }
473
474 switch (op->common.aml_opcode) {
475 case AML_INDEX_FIELD_OP:
476
477 status =
478 acpi_ds_create_index_field(op,
479 (acpi_handle) arg->
480 common.node, walk_state);
481 break;
482
483 case AML_BANK_FIELD_OP:
484
485 status =
486 acpi_ds_create_bank_field(op, arg->common.node,
487 walk_state);
488 break;
489
490 case AML_FIELD_OP:
491
492 status =
493 acpi_ds_create_field(op, arg->common.node,
494 walk_state);
495 break;
496
497 default:
498 /* All NAMED_FIELD opcodes must be handled above */
499 break;
500 }
501 break;
502
503 case AML_TYPE_NAMED_SIMPLE:
504
505 status = acpi_ds_create_operands(walk_state, arg);
506 if (ACPI_FAILURE(status)) {
507 goto cleanup;
508 }
509
510 switch (op->common.aml_opcode) {
511 case AML_PROCESSOR_OP:
512
513 status = acpi_ex_create_processor(walk_state);
514 break;
515
516 case AML_POWER_RES_OP:
517
518 status = acpi_ex_create_power_resource(walk_state);
519 break;
520
521 case AML_MUTEX_OP:
522
523 status = acpi_ex_create_mutex(walk_state);
524 break;
525
526 case AML_EVENT_OP:
527
528 status = acpi_ex_create_event(walk_state);
529 break;
530
531 case AML_ALIAS_OP:
532
533 status = acpi_ex_create_alias(walk_state);
534 break;
535
536 default:
537 /* Unknown opcode */
538
539 status = AE_OK;
540 goto cleanup;
541 }
542
543 /* Delete operands */
544
545 for (i = 1; i < walk_state->num_operands; i++) {
546 acpi_ut_remove_reference(walk_state->operands[i]);
547 walk_state->operands[i] = NULL;
548 }
549
550 break;
551#endif /* ACPI_NO_METHOD_EXECUTION */
552
553 case AML_TYPE_NAMED_COMPLEX:
554
555 switch (op->common.aml_opcode) {
556#ifndef ACPI_NO_METHOD_EXECUTION
557 case AML_REGION_OP:
558 case AML_DATA_REGION_OP:
559
560 if (op->common.aml_opcode == AML_REGION_OP) {
561 region_space = (acpi_adr_space_type)
562 ((op->common.value.arg)->common.value.
563 integer);
564 } else {
565 region_space = ACPI_ADR_SPACE_DATA_TABLE;
566 }
567
568 /*
569 * The op_region is not fully parsed at this time. The only valid
570 * argument is the space_id. (We must save the address of the
571 * AML of the address and length operands)
572 *
573 * If we have a valid region, initialize it. The namespace is
574 * unlocked at this point.
575 *
576 * Need to unlock interpreter if it is locked (if we are running
577 * a control method), in order to allow _REG methods to be run
578 * during acpi_ev_initialize_region.
579 */
580 if (walk_state->method_node) {
581 /*
582 * Executing a method: initialize the region and unlock
583 * the interpreter
584 */
585 status =
586 acpi_ex_create_region(op->named.data,
587 op->named.length,
588 region_space,
589 walk_state);
590 if (ACPI_FAILURE(status)) {
591 return (status);
592 }
593
594 acpi_ex_exit_interpreter();
595 }
596
597 status =
598 acpi_ev_initialize_region
599 (acpi_ns_get_attached_object(node), FALSE);
600 if (walk_state->method_node) {
601 acpi_ex_enter_interpreter();
602 }
603
604 if (ACPI_FAILURE(status)) {
605 /*
606 * If AE_NOT_EXIST is returned, it is not fatal
607 * because many regions get created before a handler
608 * is installed for said region.
609 */
610 if (AE_NOT_EXIST == status) {
611 status = AE_OK;
612 }
613 }
614 break;
615
616 case AML_NAME_OP:
617
618 status = acpi_ds_create_node(walk_state, node, op);
619 break;
620
621 case AML_METHOD_OP:
622 /*
623 * method_op pkg_length name_string method_flags term_list
624 *
625 * Note: We must create the method node/object pair as soon as we
626 * see the method declaration. This allows later pass1 parsing
627 * of invocations of the method (need to know the number of
628 * arguments.)
629 */
630 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
631 "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
632 walk_state, op, op->named.node));
633
634 if (!acpi_ns_get_attached_object(op->named.node)) {
635 walk_state->operands[0] =
636 ACPI_CAST_PTR(void, op->named.node);
637 walk_state->num_operands = 1;
638
639 status =
640 acpi_ds_create_operands(walk_state,
641 op->common.value.
642 arg);
643 if (ACPI_SUCCESS(status)) {
644 status =
645 acpi_ex_create_method(op->named.
646 data,
647 op->named.
648 length,
649 walk_state);
650 }
651 walk_state->operands[0] = NULL;
652 walk_state->num_operands = 0;
653
654 if (ACPI_FAILURE(status)) {
655 return_ACPI_STATUS(status);
656 }
657 }
658 break;
659
660#endif /* ACPI_NO_METHOD_EXECUTION */
661
662 default:
663 /* All NAMED_COMPLEX opcodes must be handled above */
664 break;
665 }
666 break;
667
668 case AML_CLASS_INTERNAL:
669
670 /* case AML_INT_NAMEPATH_OP: */
671 break;
672
673 case AML_CLASS_METHOD_CALL:
674
675 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
676 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
677 walk_state, op, node));
678
679 /*
680 * Lookup the method name and save the Node
681 */
682 status =
683 acpi_ns_lookup(walk_state->scope_info,
684 arg->common.value.string, ACPI_TYPE_ANY,
685 ACPI_IMODE_LOAD_PASS2,
686 ACPI_NS_SEARCH_PARENT |
687 ACPI_NS_DONT_OPEN_SCOPE, walk_state,
688 &(new_node));
689 if (ACPI_SUCCESS(status)) {
690 /*
691 * Make sure that what we found is indeed a method
692 * We didn't search for a method on purpose, to see if the name
693 * would resolve
694 */
695 if (new_node->type != ACPI_TYPE_METHOD) {
696 status = AE_AML_OPERAND_TYPE;
697 }
698
699 /* We could put the returned object (Node) on the object stack for
700 * later, but for now, we will put it in the "op" object that the
701 * parser uses, so we can get it again at the end of this scope
702 */
703 op->common.node = new_node;
704 } else {
705 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
706 }
707 break;
708
709 default:
710 break;
711 }
712
713 cleanup:
714
715 /* Remove the Node pushed at the very beginning */
716
717 walk_state->operands[0] = NULL;
718 walk_state->num_operands = 0;
719 return_ACPI_STATUS(status);
720}
diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c
index d1e701709dac..76a661fc1e09 100644
--- a/drivers/acpi/acpica/dswscope.c
+++ b/drivers/acpi/acpica/dswscope.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c
index 83155dd8671e..a6c374ef9914 100644
--- a/drivers/acpi/acpica/dswstate.c
+++ b/drivers/acpi/acpica/dswstate.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index 303618889da0..d458b041e651 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -95,47 +95,6 @@ acpi_status acpi_ev_initialize_events(void)
95 95
96/******************************************************************************* 96/*******************************************************************************
97 * 97 *
98 * FUNCTION: acpi_ev_install_fadt_gpes
99 *
100 * PARAMETERS: None
101 *
102 * RETURN: Status
103 *
104 * DESCRIPTION: Completes initialization of the FADT-defined GPE blocks
105 * (0 and 1). The HW must be fully initialized at this point,
106 * including global lock support.
107 *
108 ******************************************************************************/
109
110acpi_status acpi_ev_install_fadt_gpes(void)
111{
112 acpi_status status;
113
114 ACPI_FUNCTION_TRACE(ev_install_fadt_gpes);
115
116 /* Namespace must be locked */
117
118 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
119 if (ACPI_FAILURE(status)) {
120 return (status);
121 }
122
123 /* FADT GPE Block 0 */
124
125 (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
126 acpi_gbl_gpe_fadt_blocks[0]);
127
128 /* FADT GPE Block 1 */
129
130 (void)acpi_ev_initialize_gpe_block(acpi_gbl_fadt_gpe_device,
131 acpi_gbl_gpe_fadt_blocks[1]);
132
133 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
134 return_ACPI_STATUS(AE_OK);
135}
136
137/*******************************************************************************
138 *
139 * FUNCTION: acpi_ev_install_xrupt_handlers 98 * FUNCTION: acpi_ev_install_xrupt_handlers
140 * 99 *
141 * PARAMETERS: None 100 * PARAMETERS: None
@@ -258,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void)
258 status_bit_mask) 217 status_bit_mask)
259 && (fixed_enable & acpi_gbl_fixed_event_info[i]. 218 && (fixed_enable & acpi_gbl_fixed_event_info[i].
260 enable_bit_mask)) { 219 enable_bit_mask)) {
220 /*
221 * Found an active (signalled) event. Invoke global event
222 * handler if present.
223 */
224 acpi_fixed_event_count[i]++;
225 if (acpi_gbl_global_event_handler) {
226 acpi_gbl_global_event_handler
227 (ACPI_EVENT_TYPE_FIXED, NULL, i,
228 acpi_gbl_global_event_handler_context);
229 }
261 230
262 /* Found an active (signalled) event */
263 acpi_os_fixed_event_count(i);
264 int_status |= acpi_ev_fixed_event_dispatch(i); 231 int_status |= acpi_ev_fixed_event_dispatch(i);
265 } 232 }
266 } 233 }
diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c
new file mode 100644
index 000000000000..56a562a1e5d7
--- /dev/null
+++ b/drivers/acpi/acpica/evglock.c
@@ -0,0 +1,335 @@
1/******************************************************************************
2 *
3 * Module Name: evglock - Global Lock support
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acevents.h"
47#include "acinterp.h"
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evglock")
51
52/* Local prototypes */
53static u32 acpi_ev_global_lock_handler(void *context);
54
55/*******************************************************************************
56 *
57 * FUNCTION: acpi_ev_init_global_lock_handler
58 *
59 * PARAMETERS: None
60 *
61 * RETURN: Status
62 *
63 * DESCRIPTION: Install a handler for the global lock release event
64 *
65 ******************************************************************************/
66
67acpi_status acpi_ev_init_global_lock_handler(void)
68{
69 acpi_status status;
70
71 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
72
73 /* Attempt installation of the global lock handler */
74
75 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
76 acpi_ev_global_lock_handler,
77 NULL);
78
79 /*
80 * If the global lock does not exist on this platform, the attempt to
81 * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
82 * Map to AE_OK, but mark global lock as not present. Any attempt to
83 * actually use the global lock will be flagged with an error.
84 */
85 acpi_gbl_global_lock_present = FALSE;
86 if (status == AE_NO_HARDWARE_RESPONSE) {
87 ACPI_ERROR((AE_INFO,
88 "No response from Global Lock hardware, disabling lock"));
89
90 return_ACPI_STATUS(AE_OK);
91 }
92
93 status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
94 if (ACPI_FAILURE(status)) {
95 return_ACPI_STATUS(status);
96 }
97
98 acpi_gbl_global_lock_pending = FALSE;
99 acpi_gbl_global_lock_present = TRUE;
100 return_ACPI_STATUS(status);
101}
102
103/*******************************************************************************
104 *
105 * FUNCTION: acpi_ev_remove_global_lock_handler
106 *
107 * PARAMETERS: None
108 *
109 * RETURN: Status
110 *
111 * DESCRIPTION: Remove the handler for the Global Lock
112 *
113 ******************************************************************************/
114
115acpi_status acpi_ev_remove_global_lock_handler(void)
116{
117 acpi_status status;
118
119 ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
120
121 acpi_gbl_global_lock_present = FALSE;
122 status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
123 acpi_ev_global_lock_handler);
124
125 return_ACPI_STATUS(status);
126}
127
128/*******************************************************************************
129 *
130 * FUNCTION: acpi_ev_global_lock_handler
131 *
132 * PARAMETERS: Context - From thread interface, not used
133 *
134 * RETURN: ACPI_INTERRUPT_HANDLED
135 *
136 * DESCRIPTION: Invoked directly from the SCI handler when a global lock
137 * release interrupt occurs. If there is actually a pending
138 * request for the lock, signal the waiting thread.
139 *
140 ******************************************************************************/
141
142static u32 acpi_ev_global_lock_handler(void *context)
143{
144 acpi_status status;
145 acpi_cpu_flags flags;
146
147 flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
148
149 /*
150 * If a request for the global lock is not actually pending,
151 * we are done. This handles "spurious" global lock interrupts
152 * which are possible (and have been seen) with bad BIOSs.
153 */
154 if (!acpi_gbl_global_lock_pending) {
155 goto cleanup_and_exit;
156 }
157
158 /*
159 * Send a unit to the global lock semaphore. The actual acquisition
160 * of the global lock will be performed by the waiting thread.
161 */
162 status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
163 if (ACPI_FAILURE(status)) {
164 ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
165 }
166
167 acpi_gbl_global_lock_pending = FALSE;
168
169 cleanup_and_exit:
170
171 acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
172 return (ACPI_INTERRUPT_HANDLED);
173}
174
175/******************************************************************************
176 *
177 * FUNCTION: acpi_ev_acquire_global_lock
178 *
179 * PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
180 *
181 * RETURN: Status
182 *
183 * DESCRIPTION: Attempt to gain ownership of the Global Lock.
184 *
185 * MUTEX: Interpreter must be locked
186 *
187 * Note: The original implementation allowed multiple threads to "acquire" the
188 * Global Lock, and the OS would hold the lock until the last thread had
189 * released it. However, this could potentially starve the BIOS out of the
190 * lock, especially in the case where there is a tight handshake between the
191 * Embedded Controller driver and the BIOS. Therefore, this implementation
192 * allows only one thread to acquire the HW Global Lock at a time, and makes
193 * the global lock appear as a standard mutex on the OS side.
194 *
195 *****************************************************************************/
196
197acpi_status acpi_ev_acquire_global_lock(u16 timeout)
198{
199 acpi_cpu_flags flags;
200 acpi_status status;
201 u8 acquired = FALSE;
202
203 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
204
205 /*
206 * Only one thread can acquire the GL at a time, the global_lock_mutex
207 * enforces this. This interface releases the interpreter if we must wait.
208 */
209 status =
210 acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex.
211 os_mutex, timeout);
212 if (ACPI_FAILURE(status)) {
213 return_ACPI_STATUS(status);
214 }
215
216 /*
217 * Update the global lock handle and check for wraparound. The handle is
218 * only used for the external global lock interfaces, but it is updated
219 * here to properly handle the case where a single thread may acquire the
220 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
221 * handle is therefore updated on the first acquire from a given thread
222 * regardless of where the acquisition request originated.
223 */
224 acpi_gbl_global_lock_handle++;
225 if (acpi_gbl_global_lock_handle == 0) {
226 acpi_gbl_global_lock_handle = 1;
227 }
228
229 /*
230 * Make sure that a global lock actually exists. If not, just
231 * treat the lock as a standard mutex.
232 */
233 if (!acpi_gbl_global_lock_present) {
234 acpi_gbl_global_lock_acquired = TRUE;
235 return_ACPI_STATUS(AE_OK);
236 }
237
238 flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
239
240 do {
241
242 /* Attempt to acquire the actual hardware lock */
243
244 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
245 if (acquired) {
246 acpi_gbl_global_lock_acquired = TRUE;
247 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
248 "Acquired hardware Global Lock\n"));
249 break;
250 }
251
252 /*
253 * Did not get the lock. The pending bit was set above, and
254 * we must now wait until we receive the global lock
255 * released interrupt.
256 */
257 acpi_gbl_global_lock_pending = TRUE;
258 acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
259
260 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
261 "Waiting for hardware Global Lock\n"));
262
263 /*
264 * Wait for handshake with the global lock interrupt handler.
265 * This interface releases the interpreter if we must wait.
266 */
267 status =
268 acpi_ex_system_wait_semaphore
269 (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
270
271 flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
272
273 } while (ACPI_SUCCESS(status));
274
275 acpi_gbl_global_lock_pending = FALSE;
276 acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
277
278 return_ACPI_STATUS(status);
279}
280
281/*******************************************************************************
282 *
283 * FUNCTION: acpi_ev_release_global_lock
284 *
285 * PARAMETERS: None
286 *
287 * RETURN: Status
288 *
289 * DESCRIPTION: Releases ownership of the Global Lock.
290 *
291 ******************************************************************************/
292
293acpi_status acpi_ev_release_global_lock(void)
294{
295 u8 pending = FALSE;
296 acpi_status status = AE_OK;
297
298 ACPI_FUNCTION_TRACE(ev_release_global_lock);
299
300 /* Lock must be already acquired */
301
302 if (!acpi_gbl_global_lock_acquired) {
303 ACPI_WARNING((AE_INFO,
304 "Cannot release the ACPI Global Lock, it has not been acquired"));
305 return_ACPI_STATUS(AE_NOT_ACQUIRED);
306 }
307
308 if (acpi_gbl_global_lock_present) {
309
310 /* Allow any thread to release the lock */
311
312 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
313
314 /*
315 * If the pending bit was set, we must write GBL_RLS to the control
316 * register
317 */
318 if (pending) {
319 status =
320 acpi_write_bit_register
321 (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
322 ACPI_ENABLE_EVENT);
323 }
324
325 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
326 "Released hardware Global Lock\n"));
327 }
328
329 acpi_gbl_global_lock_acquired = FALSE;
330
331 /* Release the local GL mutex */
332
333 acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
334 return_ACPI_STATUS(status);
335}
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f226eac314db..65c79add3b19 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("evgpe")
52/* Local prototypes */ 52/* Local prototypes */
53static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); 53static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context);
54 54
55static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context);
56
55/******************************************************************************* 57/*******************************************************************************
56 * 58 *
57 * FUNCTION: acpi_ev_update_gpe_enable_mask 59 * FUNCTION: acpi_ev_update_gpe_enable_mask
@@ -102,7 +104,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
102 * 104 *
103 * RETURN: Status 105 * RETURN: Status
104 * 106 *
105 * DESCRIPTION: Clear the given GPE from stale events and enable it. 107 * DESCRIPTION: Clear a GPE of stale events and enable it.
106 * 108 *
107 ******************************************************************************/ 109 ******************************************************************************/
108acpi_status 110acpi_status
@@ -113,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
113 ACPI_FUNCTION_TRACE(ev_enable_gpe); 115 ACPI_FUNCTION_TRACE(ev_enable_gpe);
114 116
115 /* 117 /*
116 * We will only allow a GPE to be enabled if it has either an 118 * We will only allow a GPE to be enabled if it has either an associated
117 * associated method (_Lxx/_Exx) or a handler. Otherwise, the 119 * method (_Lxx/_Exx) or a handler, or is using the implicit notify
118 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the 120 * feature. Otherwise, the GPE will be immediately disabled by
119 * first time it fires. 121 * acpi_ev_gpe_dispatch the first time it fires.
120 */ 122 */
121 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { 123 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
124 ACPI_GPE_DISPATCH_NONE) {
122 return_ACPI_STATUS(AE_NO_HANDLER); 125 return_ACPI_STATUS(AE_NO_HANDLER);
123 } 126 }
124 127
@@ -137,9 +140,9 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
137 140
138/******************************************************************************* 141/*******************************************************************************
139 * 142 *
140 * FUNCTION: acpi_raw_enable_gpe 143 * FUNCTION: acpi_ev_add_gpe_reference
141 * 144 *
142 * PARAMETERS: gpe_event_info - GPE to enable 145 * PARAMETERS: gpe_event_info - Add a reference to this GPE
143 * 146 *
144 * RETURN: Status 147 * RETURN: Status
145 * 148 *
@@ -148,16 +151,21 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
148 * 151 *
149 ******************************************************************************/ 152 ******************************************************************************/
150 153
151acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) 154acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
152{ 155{
153 acpi_status status = AE_OK; 156 acpi_status status = AE_OK;
154 157
158 ACPI_FUNCTION_TRACE(ev_add_gpe_reference);
159
155 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { 160 if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
156 return_ACPI_STATUS(AE_LIMIT); 161 return_ACPI_STATUS(AE_LIMIT);
157 } 162 }
158 163
159 gpe_event_info->runtime_count++; 164 gpe_event_info->runtime_count++;
160 if (gpe_event_info->runtime_count == 1) { 165 if (gpe_event_info->runtime_count == 1) {
166
167 /* Enable on first reference */
168
161 status = acpi_ev_update_gpe_enable_mask(gpe_event_info); 169 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
162 if (ACPI_SUCCESS(status)) { 170 if (ACPI_SUCCESS(status)) {
163 status = acpi_ev_enable_gpe(gpe_event_info); 171 status = acpi_ev_enable_gpe(gpe_event_info);
@@ -173,9 +181,9 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
173 181
174/******************************************************************************* 182/*******************************************************************************
175 * 183 *
176 * FUNCTION: acpi_raw_disable_gpe 184 * FUNCTION: acpi_ev_remove_gpe_reference
177 * 185 *
178 * PARAMETERS: gpe_event_info - GPE to disable 186 * PARAMETERS: gpe_event_info - Remove a reference to this GPE
179 * 187 *
180 * RETURN: Status 188 * RETURN: Status
181 * 189 *
@@ -184,16 +192,21 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
184 * 192 *
185 ******************************************************************************/ 193 ******************************************************************************/
186 194
187acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) 195acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info)
188{ 196{
189 acpi_status status = AE_OK; 197 acpi_status status = AE_OK;
190 198
199 ACPI_FUNCTION_TRACE(ev_remove_gpe_reference);
200
191 if (!gpe_event_info->runtime_count) { 201 if (!gpe_event_info->runtime_count) {
192 return_ACPI_STATUS(AE_LIMIT); 202 return_ACPI_STATUS(AE_LIMIT);
193 } 203 }
194 204
195 gpe_event_info->runtime_count--; 205 gpe_event_info->runtime_count--;
196 if (!gpe_event_info->runtime_count) { 206 if (!gpe_event_info->runtime_count) {
207
208 /* Disable on last reference */
209
197 status = acpi_ev_update_gpe_enable_mask(gpe_event_info); 210 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
198 if (ACPI_SUCCESS(status)) { 211 if (ACPI_SUCCESS(status)) {
199 status = acpi_hw_low_set_gpe(gpe_event_info, 212 status = acpi_hw_low_set_gpe(gpe_event_info,
@@ -360,6 +373,15 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
360 373
361 gpe_register_info = &gpe_block->register_info[i]; 374 gpe_register_info = &gpe_block->register_info[i];
362 375
376 /*
377 * Optimization: If there are no GPEs enabled within this
378 * register, we can safely ignore the entire register.
379 */
380 if (!(gpe_register_info->enable_for_run |
381 gpe_register_info->enable_for_wake)) {
382 continue;
383 }
384
363 /* Read the Status Register */ 385 /* Read the Status Register */
364 386
365 status = 387 status =
@@ -379,7 +401,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
379 } 401 }
380 402
381 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, 403 ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
382 "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", 404 "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
383 gpe_register_info->base_gpe_number, 405 gpe_register_info->base_gpe_number,
384 status_reg, enable_reg)); 406 status_reg, enable_reg));
385 407
@@ -405,7 +427,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
405 * or method. 427 * or method.
406 */ 428 */
407 int_status |= 429 int_status |=
408 acpi_ev_gpe_dispatch(&gpe_block-> 430 acpi_ev_gpe_dispatch(gpe_block->
431 node,
432 &gpe_block->
409 event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); 433 event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
410 } 434 }
411 } 435 }
@@ -435,19 +459,29 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
435 * an interrupt handler. 459 * an interrupt handler.
436 * 460 *
437 ******************************************************************************/ 461 ******************************************************************************/
438static void acpi_ev_asynch_enable_gpe(void *context);
439 462
440static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) 463static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
441{ 464{
442 struct acpi_gpe_event_info *gpe_event_info = (void *)context; 465 struct acpi_gpe_event_info *gpe_event_info = context;
443 acpi_status status; 466 acpi_status status;
444 struct acpi_gpe_event_info local_gpe_event_info; 467 struct acpi_gpe_event_info *local_gpe_event_info;
445 struct acpi_evaluate_info *info; 468 struct acpi_evaluate_info *info;
469 struct acpi_gpe_notify_object *notify_object;
446 470
447 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); 471 ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
448 472
473 /* Allocate a local GPE block */
474
475 local_gpe_event_info =
476 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
477 if (!local_gpe_event_info) {
478 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
479 return_VOID;
480 }
481
449 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); 482 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
450 if (ACPI_FAILURE(status)) { 483 if (ACPI_FAILURE(status)) {
484 ACPI_FREE(local_gpe_event_info);
451 return_VOID; 485 return_VOID;
452 } 486 }
453 487
@@ -455,6 +489,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
455 489
456 if (!acpi_ev_valid_gpe_event(gpe_event_info)) { 490 if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
457 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); 491 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
492 ACPI_FREE(local_gpe_event_info);
458 return_VOID; 493 return_VOID;
459 } 494 }
460 495
@@ -462,7 +497,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
462 * Take a snapshot of the GPE info for this level - we copy the info to 497 * Take a snapshot of the GPE info for this level - we copy the info to
463 * prevent a race condition with remove_handler/remove_block. 498 * prevent a race condition with remove_handler/remove_block.
464 */ 499 */
465 ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, 500 ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
466 sizeof(struct acpi_gpe_event_info)); 501 sizeof(struct acpi_gpe_event_info));
467 502
468 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); 503 status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
@@ -470,12 +505,34 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
470 return_VOID; 505 return_VOID;
471 } 506 }
472 507
473 /* 508 /* Do the correct dispatch - normal method or implicit notify */
474 * Must check for control method type dispatch one more time to avoid a 509
475 * race with ev_gpe_install_handler 510 switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
476 */ 511 case ACPI_GPE_DISPATCH_NOTIFY:
477 if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == 512
478 ACPI_GPE_DISPATCH_METHOD) { 513 /*
514 * Implicit notify.
515 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
516 * NOTE: the request is queued for execution after this method
517 * completes. The notify handlers are NOT invoked synchronously
518 * from this thread -- because handlers may in turn run other
519 * control methods.
520 */
521 status = acpi_ev_queue_notify_request(
522 local_gpe_event_info->dispatch.device.node,
523 ACPI_NOTIFY_DEVICE_WAKE);
524
525 notify_object = local_gpe_event_info->dispatch.device.next;
526 while (ACPI_SUCCESS(status) && notify_object) {
527 status = acpi_ev_queue_notify_request(
528 notify_object->node,
529 ACPI_NOTIFY_DEVICE_WAKE);
530 notify_object = notify_object->next;
531 }
532
533 break;
534
535 case ACPI_GPE_DISPATCH_METHOD:
479 536
480 /* Allocate the evaluation information block */ 537 /* Allocate the evaluation information block */
481 538
@@ -488,7 +545,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
488 * control method that corresponds to this GPE 545 * control method that corresponds to this GPE
489 */ 546 */
490 info->prefix_node = 547 info->prefix_node =
491 local_gpe_event_info.dispatch.method_node; 548 local_gpe_event_info->dispatch.method_node;
492 info->flags = ACPI_IGNORE_RETURN_VALUE; 549 info->flags = ACPI_IGNORE_RETURN_VALUE;
493 550
494 status = acpi_ns_evaluate(info); 551 status = acpi_ns_evaluate(info);
@@ -499,46 +556,98 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
499 ACPI_EXCEPTION((AE_INFO, status, 556 ACPI_EXCEPTION((AE_INFO, status,
500 "while evaluating GPE method [%4.4s]", 557 "while evaluating GPE method [%4.4s]",
501 acpi_ut_get_node_name 558 acpi_ut_get_node_name
502 (local_gpe_event_info.dispatch. 559 (local_gpe_event_info->dispatch.
503 method_node))); 560 method_node)));
504 } 561 }
562
563 break;
564
565 default:
566 return_VOID; /* Should never happen */
505 } 567 }
568
506 /* Defer enabling of GPE until all notify handlers are done */ 569 /* Defer enabling of GPE until all notify handlers are done */
507 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, 570
508 gpe_event_info); 571 status = acpi_os_execute(OSL_NOTIFY_HANDLER,
572 acpi_ev_asynch_enable_gpe,
573 local_gpe_event_info);
574 if (ACPI_FAILURE(status)) {
575 ACPI_FREE(local_gpe_event_info);
576 }
509 return_VOID; 577 return_VOID;
510} 578}
511 579
512static void acpi_ev_asynch_enable_gpe(void *context) 580
581/*******************************************************************************
582 *
583 * FUNCTION: acpi_ev_asynch_enable_gpe
584 *
585 * PARAMETERS: Context (gpe_event_info) - Info for this GPE
586 * Callback from acpi_os_execute
587 *
588 * RETURN: None
589 *
590 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
591 * complete (i.e., finish execution of Notify)
592 *
593 ******************************************************************************/
594
595static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
513{ 596{
514 struct acpi_gpe_event_info *gpe_event_info = context; 597 struct acpi_gpe_event_info *gpe_event_info = context;
598
599 (void)acpi_ev_finish_gpe(gpe_event_info);
600
601 ACPI_FREE(gpe_event_info);
602 return;
603}
604
605
606/*******************************************************************************
607 *
608 * FUNCTION: acpi_ev_finish_gpe
609 *
610 * PARAMETERS: gpe_event_info - Info for this GPE
611 *
612 * RETURN: Status
613 *
614 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
615 * of a GPE method or a synchronous or asynchronous GPE handler.
616 *
617 ******************************************************************************/
618
619acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info)
620{
515 acpi_status status; 621 acpi_status status;
622
516 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == 623 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
517 ACPI_GPE_LEVEL_TRIGGERED) { 624 ACPI_GPE_LEVEL_TRIGGERED) {
518 /* 625 /*
519 * GPE is level-triggered, we clear the GPE status bit after handling 626 * GPE is level-triggered, we clear the GPE status bit after
520 * the event. 627 * handling the event.
521 */ 628 */
522 status = acpi_hw_clear_gpe(gpe_event_info); 629 status = acpi_hw_clear_gpe(gpe_event_info);
523 if (ACPI_FAILURE(status)) { 630 if (ACPI_FAILURE(status)) {
524 return_VOID; 631 return (status);
525 } 632 }
526 } 633 }
527 634
528 /* 635 /*
529 * Enable this GPE, conditionally. This means that the GPE will only be 636 * Enable this GPE, conditionally. This means that the GPE will
530 * physically enabled if the enable_for_run bit is set in the event_info 637 * only be physically enabled if the enable_for_run bit is set
638 * in the event_info.
531 */ 639 */
532 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); 640 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE);
533 641 return (AE_OK);
534 return_VOID;
535} 642}
536 643
644
537/******************************************************************************* 645/*******************************************************************************
538 * 646 *
539 * FUNCTION: acpi_ev_gpe_dispatch 647 * FUNCTION: acpi_ev_gpe_dispatch
540 * 648 *
541 * PARAMETERS: gpe_event_info - Info for this GPE 649 * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1
650 * gpe_event_info - Info for this GPE
542 * gpe_number - Number relative to the parent GPE block 651 * gpe_number - Number relative to the parent GPE block
543 * 652 *
544 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 653 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
@@ -551,13 +660,22 @@ static void acpi_ev_asynch_enable_gpe(void *context)
551 ******************************************************************************/ 660 ******************************************************************************/
552 661
553u32 662u32
554acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) 663acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
664 struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
555{ 665{
556 acpi_status status; 666 acpi_status status;
667 u32 return_value;
557 668
558 ACPI_FUNCTION_TRACE(ev_gpe_dispatch); 669 ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
559 670
560 acpi_os_gpe_count(gpe_number); 671 /* Invoke global event handler if present */
672
673 acpi_gpe_count++;
674 if (acpi_gbl_global_event_handler) {
675 acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
676 gpe_number,
677 acpi_gbl_global_event_handler_context);
678 }
561 679
562 /* 680 /*
563 * If edge-triggered, clear the GPE status bit now. Note that 681 * If edge-triggered, clear the GPE status bit now. Note that
@@ -568,59 +686,55 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
568 status = acpi_hw_clear_gpe(gpe_event_info); 686 status = acpi_hw_clear_gpe(gpe_event_info);
569 if (ACPI_FAILURE(status)) { 687 if (ACPI_FAILURE(status)) {
570 ACPI_EXCEPTION((AE_INFO, status, 688 ACPI_EXCEPTION((AE_INFO, status,
571 "Unable to clear GPE[0x%2X]", 689 "Unable to clear GPE%02X", gpe_number));
572 gpe_number));
573 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); 690 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
574 } 691 }
575 } 692 }
576 693
577 /* 694 /*
578 * Dispatch the GPE to either an installed handler, or the control method 695 * Always disable the GPE so that it does not keep firing before
579 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke 696 * any asynchronous activity completes (either from the execution
580 * it and do not attempt to run the method. If there is neither a handler 697 * of a GPE method or an asynchronous GPE handler.)
581 * nor a method, we disable this GPE to prevent further such pointless 698 *
582 * events from firing. 699 * If there is no handler or method to run, just disable the
700 * GPE and leave it disabled permanently to prevent further such
701 * pointless events from firing.
702 */
703 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
704 if (ACPI_FAILURE(status)) {
705 ACPI_EXCEPTION((AE_INFO, status,
706 "Unable to disable GPE%02X", gpe_number));
707 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
708 }
709
710 /*
711 * Dispatch the GPE to either an installed handler or the control
712 * method associated with this GPE (_Lxx or _Exx). If a handler
713 * exists, we invoke it and do not attempt to run the method.
714 * If there is neither a handler nor a method, leave the GPE
715 * disabled.
583 */ 716 */
584 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { 717 switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
585 case ACPI_GPE_DISPATCH_HANDLER: 718 case ACPI_GPE_DISPATCH_HANDLER:
586 719
587 /* 720 /* Invoke the installed handler (at interrupt level) */
588 * Invoke the installed handler (at interrupt level)
589 * Ignore return status for now.
590 * TBD: leave GPE disabled on error?
591 */
592 (void)gpe_event_info->dispatch.handler->address(gpe_event_info->
593 dispatch.
594 handler->
595 context);
596 721
597 /* It is now safe to clear level-triggered events. */ 722 return_value =
723 gpe_event_info->dispatch.handler->address(gpe_device,
724 gpe_number,
725 gpe_event_info->
726 dispatch.handler->
727 context);
598 728
599 if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == 729 /* If requested, clear (if level-triggered) and reenable the GPE */
600 ACPI_GPE_LEVEL_TRIGGERED) { 730
601 status = acpi_hw_clear_gpe(gpe_event_info); 731 if (return_value & ACPI_REENABLE_GPE) {
602 if (ACPI_FAILURE(status)) { 732 (void)acpi_ev_finish_gpe(gpe_event_info);
603 ACPI_EXCEPTION((AE_INFO, status,
604 "Unable to clear GPE[0x%2X]",
605 gpe_number));
606 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
607 }
608 } 733 }
609 break; 734 break;
610 735
611 case ACPI_GPE_DISPATCH_METHOD: 736 case ACPI_GPE_DISPATCH_METHOD:
612 737 case ACPI_GPE_DISPATCH_NOTIFY:
613 /*
614 * Disable the GPE, so it doesn't keep firing before the method has a
615 * chance to run (it runs asynchronously with interrupts enabled).
616 */
617 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
618 if (ACPI_FAILURE(status)) {
619 ACPI_EXCEPTION((AE_INFO, status,
620 "Unable to disable GPE[0x%2X]",
621 gpe_number));
622 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
623 }
624 738
625 /* 739 /*
626 * Execute the method associated with the GPE 740 * Execute the method associated with the GPE
@@ -631,7 +745,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
631 gpe_event_info); 745 gpe_event_info);
632 if (ACPI_FAILURE(status)) { 746 if (ACPI_FAILURE(status)) {
633 ACPI_EXCEPTION((AE_INFO, status, 747 ACPI_EXCEPTION((AE_INFO, status,
634 "Unable to queue handler for GPE[0x%2X] - event disabled", 748 "Unable to queue handler for GPE%2X - event disabled",
635 gpe_number)); 749 gpe_number));
636 } 750 }
637 break; 751 break;
@@ -644,20 +758,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
644 * a GPE to be enabled if it has no handler or method. 758 * a GPE to be enabled if it has no handler or method.
645 */ 759 */
646 ACPI_ERROR((AE_INFO, 760 ACPI_ERROR((AE_INFO,
647 "No handler or method for GPE[0x%2X], disabling event", 761 "No handler or method for GPE%02X, disabling event",
648 gpe_number)); 762 gpe_number));
649 763
650 /*
651 * Disable the GPE. The GPE will remain disabled a handler
652 * is installed or ACPICA is restarted.
653 */
654 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
655 if (ACPI_FAILURE(status)) {
656 ACPI_EXCEPTION((AE_INFO, status,
657 "Unable to disable GPE[0x%2X]",
658 gpe_number));
659 return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
660 }
661 break; 764 break;
662 } 765 }
663 766
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 85445fb5844e..ca2c41a53311 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -361,6 +361,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
361 361
362 gpe_block->node = gpe_device; 362 gpe_block->node = gpe_device;
363 gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); 363 gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
364 gpe_block->initialized = FALSE;
364 gpe_block->register_count = register_count; 365 gpe_block->register_count = register_count;
365 gpe_block->block_base_number = gpe_block_base_number; 366 gpe_block->block_base_number = gpe_block_base_number;
366 367
@@ -385,11 +386,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
385 return_ACPI_STATUS(status); 386 return_ACPI_STATUS(status);
386 } 387 }
387 388
389 acpi_gbl_all_gpes_initialized = FALSE;
390
388 /* Find all GPE methods (_Lxx or_Exx) for this block */ 391 /* Find all GPE methods (_Lxx or_Exx) for this block */
389 392
390 walk_info.gpe_block = gpe_block; 393 walk_info.gpe_block = gpe_block;
391 walk_info.gpe_device = gpe_device; 394 walk_info.gpe_device = gpe_device;
392 walk_info.enable_this_gpe = FALSE;
393 walk_info.execute_by_owner_id = FALSE; 395 walk_info.execute_by_owner_id = FALSE;
394 396
395 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device, 397 status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
@@ -421,48 +423,45 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
421 * 423 *
422 * FUNCTION: acpi_ev_initialize_gpe_block 424 * FUNCTION: acpi_ev_initialize_gpe_block
423 * 425 *
424 * PARAMETERS: gpe_device - Handle to the parent GPE block 426 * PARAMETERS: acpi_gpe_callback
425 * gpe_block - Gpe Block info
426 * 427 *
427 * RETURN: Status 428 * RETURN: Status
428 * 429 *
429 * DESCRIPTION: Initialize and enable a GPE block. First find and run any 430 * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
430 * _PRT methods associated with the block, then enable the 431 * associated methods.
431 * appropriate GPEs.
432 * Note: Assumes namespace is locked. 432 * Note: Assumes namespace is locked.
433 * 433 *
434 ******************************************************************************/ 434 ******************************************************************************/
435 435
436acpi_status 436acpi_status
437acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, 437acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
438 struct acpi_gpe_block_info *gpe_block) 438 struct acpi_gpe_block_info *gpe_block,
439 void *ignored)
439{ 440{
440 acpi_status status; 441 acpi_status status;
441 struct acpi_gpe_event_info *gpe_event_info; 442 struct acpi_gpe_event_info *gpe_event_info;
442 u32 gpe_enabled_count; 443 u32 gpe_enabled_count;
443 u32 gpe_index; 444 u32 gpe_index;
444 u32 gpe_number;
445 u32 i; 445 u32 i;
446 u32 j; 446 u32 j;
447 447
448 ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); 448 ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
449 449
450 /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */ 450 /*
451 451 * Ignore a null GPE block (e.g., if no GPE block 1 exists), and
452 if (!gpe_block) { 452 * any GPE blocks that have been initialized already.
453 */
454 if (!gpe_block || gpe_block->initialized) {
453 return_ACPI_STATUS(AE_OK); 455 return_ACPI_STATUS(AE_OK);
454 } 456 }
455 457
456 /* 458 /*
457 * Enable all GPEs that have a corresponding method. Any other GPEs 459 * Enable all GPEs that have a corresponding method and have the
458 * within this block must be enabled via the acpi_enable_gpe interface. 460 * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
461 * must be enabled via the acpi_enable_gpe() interface.
459 */ 462 */
460 gpe_enabled_count = 0; 463 gpe_enabled_count = 0;
461 464
462 if (gpe_device == acpi_gbl_fadt_gpe_device) {
463 gpe_device = NULL;
464 }
465
466 for (i = 0; i < gpe_block->register_count; i++) { 465 for (i = 0; i < gpe_block->register_count; i++) {
467 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 466 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
468 467
@@ -470,27 +469,24 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
470 469
471 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; 470 gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
472 gpe_event_info = &gpe_block->event_info[gpe_index]; 471 gpe_event_info = &gpe_block->event_info[gpe_index];
473 gpe_number = gpe_index + gpe_block->block_base_number;
474
475 /* Ignore GPEs that have no corresponding _Lxx/_Exx method */
476
477 if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD)) {
478 continue;
479 }
480 472
481 /* 473 /*
482 * If the GPE has already been enabled for runtime 474 * Ignore GPEs that have no corresponding _Lxx/_Exx method
483 * signaling, make sure it remains enabled, but do not 475 * and GPEs that are used to wake the system
484 * increment its reference counter.
485 */ 476 */
486 status = gpe_event_info->runtime_count ? 477 if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
487 acpi_ev_enable_gpe(gpe_event_info) : 478 ACPI_GPE_DISPATCH_NONE)
488 acpi_enable_gpe(gpe_device, gpe_number); 479 || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
480 == ACPI_GPE_DISPATCH_HANDLER)
481 || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
482 continue;
483 }
489 484
485 status = acpi_ev_add_gpe_reference(gpe_event_info);
490 if (ACPI_FAILURE(status)) { 486 if (ACPI_FAILURE(status)) {
491 ACPI_EXCEPTION((AE_INFO, status, 487 ACPI_EXCEPTION((AE_INFO, status,
492 "Could not enable GPE 0x%02X", 488 "Could not enable GPE 0x%02X",
493 gpe_number)); 489 gpe_index + gpe_block->block_base_number));
494 continue; 490 continue;
495 } 491 }
496 492
@@ -504,5 +500,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
504 gpe_enabled_count)); 500 gpe_enabled_count));
505 } 501 }
506 502
503 gpe_block->initialized = TRUE;
504
507 return_ACPI_STATUS(AE_OK); 505 return_ACPI_STATUS(AE_OK);
508} 506}
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c
index 3084c5de1bba..ce9aa9f9a972 100644
--- a/drivers/acpi/acpica/evgpeinit.c
+++ b/drivers/acpi/acpica/evgpeinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,11 +45,27 @@
45#include "accommon.h" 45#include "accommon.h"
46#include "acevents.h" 46#include "acevents.h"
47#include "acnamesp.h" 47#include "acnamesp.h"
48#include "acinterp.h"
49 48
50#define _COMPONENT ACPI_EVENTS 49#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evgpeinit") 50ACPI_MODULE_NAME("evgpeinit")
52 51
52/*
53 * Note: History of _PRW support in ACPICA
54 *
55 * Originally (2000 - 2010), the GPE initialization code performed a walk of
56 * the entire namespace to execute the _PRW methods and detect all GPEs
57 * capable of waking the system.
58 *
59 * As of 10/2010, the _PRW method execution has been removed since it is
60 * actually unnecessary. The host OS must in fact execute all _PRW methods
61 * in order to identify the device/power-resource dependencies. We now put
62 * the onus on the host OS to identify the wake GPEs as part of this process
63 * and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This
64 * not only reduces the complexity of the ACPICA initialization code, but in
65 * some cases (on systems with very large namespaces) it should reduce the
66 * kernel boot time as well.
67 */
68
53/******************************************************************************* 69/*******************************************************************************
54 * 70 *
55 * FUNCTION: acpi_ev_gpe_initialize 71 * FUNCTION: acpi_ev_gpe_initialize
@@ -210,8 +226,7 @@ acpi_status acpi_ev_gpe_initialize(void)
210 * 226 *
211 * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a 227 * DESCRIPTION: Check for new GPE methods (_Lxx/_Exx) made available as a
212 * result of a Load() or load_table() operation. If new GPE 228 * result of a Load() or load_table() operation. If new GPE
213 * methods have been installed, register the new methods and 229 * methods have been installed, register the new methods.
214 * enable and runtime GPEs that are associated with them.
215 * 230 *
216 ******************************************************************************/ 231 ******************************************************************************/
217 232
@@ -223,7 +238,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
223 acpi_status status = AE_OK; 238 acpi_status status = AE_OK;
224 239
225 /* 240 /*
226 * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. 241 * Find any _Lxx/_Exx GPE methods that have just been loaded.
227 * 242 *
228 * Any GPEs that correspond to new _Lxx/_Exx methods are immediately 243 * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
229 * enabled. 244 * enabled.
@@ -236,10 +251,9 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
236 return; 251 return;
237 } 252 }
238 253
254 walk_info.count = 0;
239 walk_info.owner_id = table_owner_id; 255 walk_info.owner_id = table_owner_id;
240 walk_info.execute_by_owner_id = TRUE; 256 walk_info.execute_by_owner_id = TRUE;
241 walk_info.count = 0;
242 walk_info.enable_this_gpe = TRUE;
243 257
244 /* Walk the interrupt level descriptor list */ 258 /* Walk the interrupt level descriptor list */
245 259
@@ -300,9 +314,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id)
300 * xx - is the GPE number [in HEX] 314 * xx - is the GPE number [in HEX]
301 * 315 *
302 * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods 316 * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods
303 * with that owner. 317 * with that owner.
304 * If walk_info->enable_this_gpe is TRUE, the GPE that is referred to by a GPE
305 * method is immediately enabled (Used for Load/load_table operators)
306 * 318 *
307 ******************************************************************************/ 319 ******************************************************************************/
308 320
@@ -315,8 +327,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
315 struct acpi_gpe_walk_info *walk_info = 327 struct acpi_gpe_walk_info *walk_info =
316 ACPI_CAST_PTR(struct acpi_gpe_walk_info, context); 328 ACPI_CAST_PTR(struct acpi_gpe_walk_info, context);
317 struct acpi_gpe_event_info *gpe_event_info; 329 struct acpi_gpe_event_info *gpe_event_info;
318 struct acpi_namespace_node *gpe_device;
319 acpi_status status;
320 u32 gpe_number; 330 u32 gpe_number;
321 char name[ACPI_NAME_SIZE + 1]; 331 char name[ACPI_NAME_SIZE + 1];
322 u8 type; 332 u8 type;
@@ -414,36 +424,17 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
414 return_ACPI_STATUS(AE_OK); 424 return_ACPI_STATUS(AE_OK);
415 } 425 }
416 426
427 /* Disable the GPE in case it's been enabled already. */
428 (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
429
417 /* 430 /*
418 * Add the GPE information from above to the gpe_event_info block for 431 * Add the GPE information from above to the gpe_event_info block for
419 * use during dispatch of this GPE. 432 * use during dispatch of this GPE.
420 */ 433 */
434 gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK);
421 gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); 435 gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD);
422 gpe_event_info->dispatch.method_node = method_node; 436 gpe_event_info->dispatch.method_node = method_node;
423 437
424 /*
425 * Enable this GPE if requested. This only happens when during the
426 * execution of a Load or load_table operator. We have found a new
427 * GPE method and want to immediately enable the GPE if it is a
428 * runtime GPE.
429 */
430 if (walk_info->enable_this_gpe) {
431
432 walk_info->count++;
433 gpe_device = walk_info->gpe_device;
434
435 if (gpe_device == acpi_gbl_fadt_gpe_device) {
436 gpe_device = NULL;
437 }
438
439 status = acpi_enable_gpe(gpe_device, gpe_number);
440 if (ACPI_FAILURE(status)) {
441 ACPI_EXCEPTION((AE_INFO, status,
442 "Could not enable GPE 0x%02X",
443 gpe_number));
444 }
445 }
446
447 ACPI_DEBUG_PRINT((ACPI_DB_LOAD, 438 ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
448 "Registered GPE method %s as GPE number 0x%.2X\n", 439 "Registered GPE method %s as GPE number 0x%.2X\n",
449 name, gpe_number)); 440 name, gpe_number));
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c
index 19a0e513ea48..80a81d0c4a80 100644
--- a/drivers/acpi/acpica/evgpeutil.c
+++ b/drivers/acpi/acpica/evgpeutil.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -154,6 +154,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
154 154
155/******************************************************************************* 155/*******************************************************************************
156 * 156 *
157 * FUNCTION: acpi_ev_get_gpe_device
158 *
159 * PARAMETERS: GPE_WALK_CALLBACK
160 *
161 * RETURN: Status
162 *
163 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
164 * block device. NULL if the GPE is one of the FADT-defined GPEs.
165 *
166 ******************************************************************************/
167
168acpi_status
169acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
170 struct acpi_gpe_block_info *gpe_block, void *context)
171{
172 struct acpi_gpe_device_info *info = context;
173
174 /* Increment Index by the number of GPEs in this block */
175
176 info->next_block_base_index += gpe_block->gpe_count;
177
178 if (info->index < info->next_block_base_index) {
179 /*
180 * The GPE index is within this block, get the node. Leave the node
181 * NULL for the FADT-defined GPEs
182 */
183 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
184 info->gpe_device = gpe_block->node;
185 }
186
187 info->status = AE_OK;
188 return (AE_CTRL_END);
189 }
190
191 return (AE_OK);
192}
193
194/*******************************************************************************
195 *
157 * FUNCTION: acpi_ev_get_gpe_xrupt_block 196 * FUNCTION: acpi_ev_get_gpe_xrupt_block
158 * 197 *
159 * PARAMETERS: interrupt_number - Interrupt for a GPE block 198 * PARAMETERS: interrupt_number - Interrupt for a GPE block
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index df0aea9a8cfd..d0b331844427 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
45#include "accommon.h" 45#include "accommon.h"
46#include "acevents.h" 46#include "acevents.h"
47#include "acnamesp.h" 47#include "acnamesp.h"
48#include "acinterp.h"
49 48
50#define _COMPONENT ACPI_EVENTS 49#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evmisc") 50ACPI_MODULE_NAME("evmisc")
@@ -53,10 +52,6 @@ ACPI_MODULE_NAME("evmisc")
53/* Local prototypes */ 52/* Local prototypes */
54static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context); 53static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
55 54
56static u32 acpi_ev_global_lock_handler(void *context);
57
58static acpi_status acpi_ev_remove_global_lock_handler(void);
59
60/******************************************************************************* 55/*******************************************************************************
61 * 56 *
62 * FUNCTION: acpi_ev_is_notify_object 57 * FUNCTION: acpi_ev_is_notify_object
@@ -275,290 +270,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
275 acpi_ut_delete_generic_state(notify_info); 270 acpi_ut_delete_generic_state(notify_info);
276} 271}
277 272
278/*******************************************************************************
279 *
280 * FUNCTION: acpi_ev_global_lock_handler
281 *
282 * PARAMETERS: Context - From thread interface, not used
283 *
284 * RETURN: ACPI_INTERRUPT_HANDLED
285 *
286 * DESCRIPTION: Invoked directly from the SCI handler when a global lock
287 * release interrupt occurs. Attempt to acquire the global lock,
288 * if successful, signal the thread waiting for the lock.
289 *
290 * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
291 * this is not possible for some reason, a separate thread will have to be
292 * scheduled to do this.
293 *
294 ******************************************************************************/
295
296static u32 acpi_ev_global_lock_handler(void *context)
297{
298 u8 acquired = FALSE;
299
300 /*
301 * Attempt to get the lock.
302 *
303 * If we don't get it now, it will be marked pending and we will
304 * take another interrupt when it becomes free.
305 */
306 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
307 if (acquired) {
308
309 /* Got the lock, now wake all threads waiting for it */
310
311 acpi_gbl_global_lock_acquired = TRUE;
312 /* Send a unit to the semaphore */
313
314 if (ACPI_FAILURE
315 (acpi_os_signal_semaphore
316 (acpi_gbl_global_lock_semaphore, 1))) {
317 ACPI_ERROR((AE_INFO,
318 "Could not signal Global Lock semaphore"));
319 }
320 }
321
322 return (ACPI_INTERRUPT_HANDLED);
323}
324
325/*******************************************************************************
326 *
327 * FUNCTION: acpi_ev_init_global_lock_handler
328 *
329 * PARAMETERS: None
330 *
331 * RETURN: Status
332 *
333 * DESCRIPTION: Install a handler for the global lock release event
334 *
335 ******************************************************************************/
336
337acpi_status acpi_ev_init_global_lock_handler(void)
338{
339 acpi_status status;
340
341 ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
342
343 /* Attempt installation of the global lock handler */
344
345 status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
346 acpi_ev_global_lock_handler,
347 NULL);
348
349 /*
350 * If the global lock does not exist on this platform, the attempt to
351 * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
352 * Map to AE_OK, but mark global lock as not present. Any attempt to
353 * actually use the global lock will be flagged with an error.
354 */
355 if (status == AE_NO_HARDWARE_RESPONSE) {
356 ACPI_ERROR((AE_INFO,
357 "No response from Global Lock hardware, disabling lock"));
358
359 acpi_gbl_global_lock_present = FALSE;
360 return_ACPI_STATUS(AE_OK);
361 }
362
363 acpi_gbl_global_lock_present = TRUE;
364 return_ACPI_STATUS(status);
365}
366
367/*******************************************************************************
368 *
369 * FUNCTION: acpi_ev_remove_global_lock_handler
370 *
371 * PARAMETERS: None
372 *
373 * RETURN: Status
374 *
375 * DESCRIPTION: Remove the handler for the Global Lock
376 *
377 ******************************************************************************/
378
379static acpi_status acpi_ev_remove_global_lock_handler(void)
380{
381 acpi_status status;
382
383 ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
384
385 acpi_gbl_global_lock_present = FALSE;
386 status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
387 acpi_ev_global_lock_handler);
388
389 return_ACPI_STATUS(status);
390}
391
392/******************************************************************************
393 *
394 * FUNCTION: acpi_ev_acquire_global_lock
395 *
396 * PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
397 *
398 * RETURN: Status
399 *
400 * DESCRIPTION: Attempt to gain ownership of the Global Lock.
401 *
402 * MUTEX: Interpreter must be locked
403 *
404 * Note: The original implementation allowed multiple threads to "acquire" the
405 * Global Lock, and the OS would hold the lock until the last thread had
406 * released it. However, this could potentially starve the BIOS out of the
407 * lock, especially in the case where there is a tight handshake between the
408 * Embedded Controller driver and the BIOS. Therefore, this implementation
409 * allows only one thread to acquire the HW Global Lock at a time, and makes
410 * the global lock appear as a standard mutex on the OS side.
411 *
412 *****************************************************************************/
413static acpi_thread_id acpi_ev_global_lock_thread_id;
414static int acpi_ev_global_lock_acquired;
415
416acpi_status acpi_ev_acquire_global_lock(u16 timeout)
417{
418 acpi_status status = AE_OK;
419 u8 acquired = FALSE;
420
421 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
422
423 /*
424 * Only one thread can acquire the GL at a time, the global_lock_mutex
425 * enforces this. This interface releases the interpreter if we must wait.
426 */
427 status = acpi_ex_system_wait_mutex(
428 acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
429 if (status == AE_TIME) {
430 if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
431 acpi_ev_global_lock_acquired++;
432 return AE_OK;
433 }
434 }
435
436 if (ACPI_FAILURE(status)) {
437 status = acpi_ex_system_wait_mutex(
438 acpi_gbl_global_lock_mutex->mutex.os_mutex,
439 timeout);
440 }
441 if (ACPI_FAILURE(status)) {
442 return_ACPI_STATUS(status);
443 }
444
445 acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
446 acpi_ev_global_lock_acquired++;
447
448 /*
449 * Update the global lock handle and check for wraparound. The handle is
450 * only used for the external global lock interfaces, but it is updated
451 * here to properly handle the case where a single thread may acquire the
452 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
453 * handle is therefore updated on the first acquire from a given thread
454 * regardless of where the acquisition request originated.
455 */
456 acpi_gbl_global_lock_handle++;
457 if (acpi_gbl_global_lock_handle == 0) {
458 acpi_gbl_global_lock_handle = 1;
459 }
460
461 /*
462 * Make sure that a global lock actually exists. If not, just treat the
463 * lock as a standard mutex.
464 */
465 if (!acpi_gbl_global_lock_present) {
466 acpi_gbl_global_lock_acquired = TRUE;
467 return_ACPI_STATUS(AE_OK);
468 }
469
470 /* Attempt to acquire the actual hardware lock */
471
472 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
473 if (acquired) {
474
475 /* We got the lock */
476
477 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
478 "Acquired hardware Global Lock\n"));
479
480 acpi_gbl_global_lock_acquired = TRUE;
481 return_ACPI_STATUS(AE_OK);
482 }
483
484 /*
485 * Did not get the lock. The pending bit was set above, and we must now
486 * wait until we get the global lock released interrupt.
487 */
488 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
489
490 /*
491 * Wait for handshake with the global lock interrupt handler.
492 * This interface releases the interpreter if we must wait.
493 */
494 status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
495 ACPI_WAIT_FOREVER);
496
497 return_ACPI_STATUS(status);
498}
499
500/*******************************************************************************
501 *
502 * FUNCTION: acpi_ev_release_global_lock
503 *
504 * PARAMETERS: None
505 *
506 * RETURN: Status
507 *
508 * DESCRIPTION: Releases ownership of the Global Lock.
509 *
510 ******************************************************************************/
511
512acpi_status acpi_ev_release_global_lock(void)
513{
514 u8 pending = FALSE;
515 acpi_status status = AE_OK;
516
517 ACPI_FUNCTION_TRACE(ev_release_global_lock);
518
519 /* Lock must be already acquired */
520
521 if (!acpi_gbl_global_lock_acquired) {
522 ACPI_WARNING((AE_INFO,
523 "Cannot release the ACPI Global Lock, it has not been acquired"));
524 return_ACPI_STATUS(AE_NOT_ACQUIRED);
525 }
526
527 acpi_ev_global_lock_acquired--;
528 if (acpi_ev_global_lock_acquired > 0) {
529 return AE_OK;
530 }
531
532 if (acpi_gbl_global_lock_present) {
533
534 /* Allow any thread to release the lock */
535
536 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
537
538 /*
539 * If the pending bit was set, we must write GBL_RLS to the control
540 * register
541 */
542 if (pending) {
543 status =
544 acpi_write_bit_register
545 (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
546 ACPI_ENABLE_EVENT);
547 }
548
549 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
550 "Released hardware Global Lock\n"));
551 }
552
553 acpi_gbl_global_lock_acquired = FALSE;
554
555 /* Release the local GL mutex */
556 acpi_ev_global_lock_thread_id = NULL;
557 acpi_ev_global_lock_acquired = 0;
558 acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
559 return_ACPI_STATUS(status);
560}
561
562/****************************************************************************** 273/******************************************************************************
563 * 274 *
564 * FUNCTION: acpi_ev_terminate 275 * FUNCTION: acpi_ev_terminate
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 98fd210e87b2..f0edf5c43c03 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,8 @@ static u8
55acpi_ev_has_default_handler(struct acpi_namespace_node *node, 55acpi_ev_has_default_handler(struct acpi_namespace_node *node,
56 acpi_adr_space_type space_id); 56 acpi_adr_space_type space_id);
57 57
58static void acpi_ev_orphan_ec_reg_method(void);
59
58static acpi_status 60static acpi_status
59acpi_ev_reg_run(acpi_handle obj_handle, 61acpi_ev_reg_run(acpi_handle obj_handle,
60 u32 level, void *context, void **return_value); 62 u32 level, void *context, void **return_value);
@@ -231,6 +233,8 @@ acpi_status acpi_ev_initialize_op_regions(void)
231 } 233 }
232 } 234 }
233 235
236 acpi_gbl_reg_methods_executed = TRUE;
237
234 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 238 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
235 return_ACPI_STATUS(status); 239 return_ACPI_STATUS(status);
236} 240}
@@ -559,7 +563,9 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
559 563
560 /* Now stop region accesses by executing the _REG method */ 564 /* Now stop region accesses by executing the _REG method */
561 565
562 status = acpi_ev_execute_reg_method(region_obj, 0); 566 status =
567 acpi_ev_execute_reg_method(region_obj,
568 ACPI_REG_DISCONNECT);
563 if (ACPI_FAILURE(status)) { 569 if (ACPI_FAILURE(status)) {
564 ACPI_EXCEPTION((AE_INFO, status, 570 ACPI_EXCEPTION((AE_INFO, status,
565 "from region _REG, [%s]", 571 "from region _REG, [%s]",
@@ -1060,6 +1066,12 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
1060 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, 1066 ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1061 NULL, &space_id, NULL); 1067 NULL, &space_id, NULL);
1062 1068
1069 /* Special case for EC: handle "orphan" _REG methods with no region */
1070
1071 if (space_id == ACPI_ADR_SPACE_EC) {
1072 acpi_ev_orphan_ec_reg_method();
1073 }
1074
1063 return_ACPI_STATUS(status); 1075 return_ACPI_STATUS(status);
1064} 1076}
1065 1077
@@ -1118,6 +1130,113 @@ acpi_ev_reg_run(acpi_handle obj_handle,
1118 return (AE_OK); 1130 return (AE_OK);
1119 } 1131 }
1120 1132
1121 status = acpi_ev_execute_reg_method(obj_desc, 1); 1133 status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
1122 return (status); 1134 return (status);
1123} 1135}
1136
1137/*******************************************************************************
1138 *
1139 * FUNCTION: acpi_ev_orphan_ec_reg_method
1140 *
1141 * PARAMETERS: None
1142 *
1143 * RETURN: None
1144 *
1145 * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
1146 * device. This is a _REG method that has no corresponding region
1147 * within the EC device scope. The orphan _REG method appears to
1148 * have been enabled by the description of the ECDT in the ACPI
1149 * specification: "The availability of the region space can be
1150 * detected by providing a _REG method object underneath the
1151 * Embedded Controller device."
1152 *
1153 * To quickly access the EC device, we use the EC_ID that appears
1154 * within the ECDT. Otherwise, we would need to perform a time-
1155 * consuming namespace walk, executing _HID methods to find the
1156 * EC device.
1157 *
1158 ******************************************************************************/
1159
1160static void acpi_ev_orphan_ec_reg_method(void)
1161{
1162 struct acpi_table_ecdt *table;
1163 acpi_status status;
1164 struct acpi_object_list args;
1165 union acpi_object objects[2];
1166 struct acpi_namespace_node *ec_device_node;
1167 struct acpi_namespace_node *reg_method;
1168 struct acpi_namespace_node *next_node;
1169
1170 ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
1171
1172 /* Get the ECDT (if present in system) */
1173
1174 status = acpi_get_table(ACPI_SIG_ECDT, 0,
1175 ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
1176 &table));
1177 if (ACPI_FAILURE(status)) {
1178 return_VOID;
1179 }
1180
1181 /* We need a valid EC_ID string */
1182
1183 if (!(*table->id)) {
1184 return_VOID;
1185 }
1186
1187 /* Namespace is currently locked, must release */
1188
1189 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
1190
1191 /* Get a handle to the EC device referenced in the ECDT */
1192
1193 status = acpi_get_handle(NULL,
1194 ACPI_CAST_PTR(char, table->id),
1195 ACPI_CAST_PTR(acpi_handle, &ec_device_node));
1196 if (ACPI_FAILURE(status)) {
1197 goto exit;
1198 }
1199
1200 /* Get a handle to a _REG method immediately under the EC device */
1201
1202 status = acpi_get_handle(ec_device_node,
1203 METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
1204 &reg_method));
1205 if (ACPI_FAILURE(status)) {
1206 goto exit;
1207 }
1208
1209 /*
1210 * Execute the _REG method only if there is no Operation Region in
1211 * this scope with the Embedded Controller space ID. Otherwise, it
1212 * will already have been executed. Note, this allows for Regions
1213 * with other space IDs to be present; but the code below will then
1214 * execute the _REG method with the EC space ID argument.
1215 */
1216 next_node = acpi_ns_get_next_node(ec_device_node, NULL);
1217 while (next_node) {
1218 if ((next_node->type == ACPI_TYPE_REGION) &&
1219 (next_node->object) &&
1220 (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
1221 goto exit; /* Do not execute _REG */
1222 }
1223 next_node = acpi_ns_get_next_node(ec_device_node, next_node);
1224 }
1225
1226 /* Evaluate the _REG(EC,Connect) method */
1227
1228 args.count = 2;
1229 args.pointer = objects;
1230 objects[0].type = ACPI_TYPE_INTEGER;
1231 objects[0].integer.value = ACPI_ADR_SPACE_EC;
1232 objects[1].type = ACPI_TYPE_INTEGER;
1233 objects[1].integer.value = ACPI_REG_CONNECT;
1234
1235 status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
1236
1237 exit:
1238 /* We ignore all errors from above, don't care */
1239
1240 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
1241 return_VOID;
1242}
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index f40d271bf568..55a5d35ef34a 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -289,8 +289,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
289 } 289 }
290 290
291 /* 291 /*
292 * Get the PCI device and function numbers from the _ADR object contained 292 * Get the PCI device and function numbers from the _ADR object
293 * in the parent's scope. 293 * contained in the parent's scope.
294 */ 294 */
295 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, 295 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
296 pci_device_node, &pci_value); 296 pci_device_node, &pci_value);
@@ -320,9 +320,15 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
320 pci_id->bus = ACPI_LOWORD(pci_value); 320 pci_id->bus = ACPI_LOWORD(pci_value);
321 } 321 }
322 322
323 /* Complete this device's pci_id */ 323 /* Complete/update the PCI ID for this device */
324 324
325 acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id); 325 status =
326 acpi_hw_derive_pci_id(pci_id, pci_root_node,
327 region_obj->region.node);
328 if (ACPI_FAILURE(status)) {
329 ACPI_FREE(pci_id);
330 return_ACPI_STATUS(status);
331 }
326 332
327 *region_context = pci_id; 333 *region_context = pci_id;
328 return_ACPI_STATUS(AE_OK); 334 return_ACPI_STATUS(AE_OK);
@@ -584,9 +590,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
584 * See acpi_ns_exec_module_code 590 * See acpi_ns_exec_module_code
585 */ 591 */
586 if (obj_desc->method. 592 if (obj_desc->method.
587 flags & AOPOBJ_MODULE_LEVEL) { 593 info_flags & ACPI_METHOD_MODULE_LEVEL) {
588 handler_obj = 594 handler_obj =
589 obj_desc->method.extra.handler; 595 obj_desc->method.dispatch.handler;
590 } 596 }
591 break; 597 break;
592 598
@@ -631,7 +637,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
631 637
632 status = 638 status =
633 acpi_ev_execute_reg_method 639 acpi_ev_execute_reg_method
634 (region_obj, 1); 640 (region_obj, ACPI_REG_CONNECT);
635 641
636 if (acpi_ns_locked) { 642 if (acpi_ns_locked) {
637 status = 643 status =
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c
index 8dfbaa96e422..2ebd40e1a3ef 100644
--- a/drivers/acpi/acpica/evsci.c
+++ b/drivers/acpi/acpica/evsci.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 14e48add32fa..e1141402dbed 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
92 92
93ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) 93ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
94#endif /* ACPI_FUTURE_USAGE */ 94#endif /* ACPI_FUTURE_USAGE */
95
96/*******************************************************************************
97 *
98 * FUNCTION: acpi_install_global_event_handler
99 *
100 * PARAMETERS: Handler - Pointer to the global event handler function
101 * Context - Value passed to the handler on each event
102 *
103 * RETURN: Status
104 *
105 * DESCRIPTION: Saves the pointer to the handler function. The global handler
106 * is invoked upon each incoming GPE and Fixed Event. It is
107 * invoked at interrupt level at the time of the event dispatch.
108 * Can be used to update event counters, etc.
109 *
110 ******************************************************************************/
111acpi_status
112acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context)
113{
114 acpi_status status;
115
116 ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
117
118 /* Parameter validation */
119
120 if (!handler) {
121 return_ACPI_STATUS(AE_BAD_PARAMETER);
122 }
123
124 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
125 if (ACPI_FAILURE(status)) {
126 return_ACPI_STATUS(status);
127 }
128
129 /* Don't allow two handlers. */
130
131 if (acpi_gbl_global_event_handler) {
132 status = AE_ALREADY_EXISTS;
133 goto cleanup;
134 }
135
136 acpi_gbl_global_event_handler = handler;
137 acpi_gbl_global_event_handler_context = context;
138
139 cleanup:
140 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
141 return_ACPI_STATUS(status);
142}
143
144ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
145
95/******************************************************************************* 146/*******************************************************************************
96 * 147 *
97 * FUNCTION: acpi_install_fixed_event_handler 148 * FUNCTION: acpi_install_fixed_event_handler
@@ -671,10 +722,10 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
671acpi_status 722acpi_status
672acpi_install_gpe_handler(acpi_handle gpe_device, 723acpi_install_gpe_handler(acpi_handle gpe_device,
673 u32 gpe_number, 724 u32 gpe_number,
674 u32 type, acpi_event_handler address, void *context) 725 u32 type, acpi_gpe_handler address, void *context)
675{ 726{
676 struct acpi_gpe_event_info *gpe_event_info; 727 struct acpi_gpe_event_info *gpe_event_info;
677 struct acpi_handler_info *handler; 728 struct acpi_gpe_handler_info *handler;
678 acpi_status status; 729 acpi_status status;
679 acpi_cpu_flags flags; 730 acpi_cpu_flags flags;
680 731
@@ -693,7 +744,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
693 744
694 /* Allocate memory for the handler object */ 745 /* Allocate memory for the handler object */
695 746
696 handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); 747 handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
697 if (!handler) { 748 if (!handler) {
698 status = AE_NO_MEMORY; 749 status = AE_NO_MEMORY;
699 goto unlock_and_exit; 750 goto unlock_and_exit;
@@ -722,19 +773,20 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
722 handler->address = address; 773 handler->address = address;
723 handler->context = context; 774 handler->context = context;
724 handler->method_node = gpe_event_info->dispatch.method_node; 775 handler->method_node = gpe_event_info->dispatch.method_node;
725 handler->orig_flags = gpe_event_info->flags & 776 handler->original_flags = gpe_event_info->flags &
726 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 777 (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
727 778
728 /* 779 /*
729 * If the GPE is associated with a method and it cannot wake up the 780 * If the GPE is associated with a method, it might have been enabled
730 * system from sleep states, it was enabled automatically during 781 * automatically during initialization, in which case it has to be
731 * initialization, so it has to be disabled now to avoid spurious 782 * disabled now to avoid spurious execution of the handler.
732 * execution of the handler.
733 */ 783 */
734 784
735 if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) 785 if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
736 && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) 786 && gpe_event_info->runtime_count) {
737 (void)acpi_raw_disable_gpe(gpe_event_info); 787 handler->originally_enabled = 1;
788 (void)acpi_ev_remove_gpe_reference(gpe_event_info);
789 }
738 790
739 /* Install the handler */ 791 /* Install the handler */
740 792
@@ -776,10 +828,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
776 ******************************************************************************/ 828 ******************************************************************************/
777acpi_status 829acpi_status
778acpi_remove_gpe_handler(acpi_handle gpe_device, 830acpi_remove_gpe_handler(acpi_handle gpe_device,
779 u32 gpe_number, acpi_event_handler address) 831 u32 gpe_number, acpi_gpe_handler address)
780{ 832{
781 struct acpi_gpe_event_info *gpe_event_info; 833 struct acpi_gpe_event_info *gpe_event_info;
782 struct acpi_handler_info *handler; 834 struct acpi_gpe_handler_info *handler;
783 acpi_status status; 835 acpi_status status;
784 acpi_cpu_flags flags; 836 acpi_cpu_flags flags;
785 837
@@ -834,17 +886,17 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
834 gpe_event_info->dispatch.method_node = handler->method_node; 886 gpe_event_info->dispatch.method_node = handler->method_node;
835 gpe_event_info->flags &= 887 gpe_event_info->flags &=
836 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 888 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
837 gpe_event_info->flags |= handler->orig_flags; 889 gpe_event_info->flags |= handler->original_flags;
838 890
839 /* 891 /*
840 * If the GPE was previously associated with a method and it cannot wake 892 * If the GPE was previously associated with a method and it was
841 * up the system from sleep states, it should be enabled at this point 893 * enabled, it should be enabled at this point to restore the
842 * to restore the post-initialization configuration. 894 * post-initialization configuration.
843 */ 895 */
844 896
845 if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) 897 if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD)
846 && !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) 898 && handler->originally_enabled)
847 (void)acpi_raw_enable_gpe(gpe_event_info); 899 (void)acpi_ev_add_gpe_reference(gpe_event_info);
848 900
849 /* Now we can free the handler object */ 901 /* Now we can free the handler object */
850 902
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 304825528d48..c57b5c707a77 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -43,18 +43,11 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include "accommon.h" 45#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48#include "actables.h" 46#include "actables.h"
49 47
50#define _COMPONENT ACPI_EVENTS 48#define _COMPONENT ACPI_EVENTS
51ACPI_MODULE_NAME("evxfevnt") 49ACPI_MODULE_NAME("evxfevnt")
52 50
53/* Local prototypes */
54static acpi_status
55acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56 struct acpi_gpe_block_info *gpe_block, void *context);
57
58/******************************************************************************* 51/*******************************************************************************
59 * 52 *
60 * FUNCTION: acpi_enable 53 * FUNCTION: acpi_enable
@@ -213,194 +206,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event)
213 206
214/******************************************************************************* 207/*******************************************************************************
215 * 208 *
216 * FUNCTION: acpi_gpe_wakeup
217 *
218 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
219 * gpe_number - GPE level within the GPE block
220 * Action - Enable or Disable
221 *
222 * RETURN: Status
223 *
224 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
225 *
226 ******************************************************************************/
227acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
228{
229 acpi_status status = AE_OK;
230 struct acpi_gpe_event_info *gpe_event_info;
231 struct acpi_gpe_register_info *gpe_register_info;
232 acpi_cpu_flags flags;
233 u32 register_bit;
234
235 ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
236
237 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
238
239 /* Ensure that we have a valid GPE number */
240
241 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
242 if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
243 status = AE_BAD_PARAMETER;
244 goto unlock_and_exit;
245 }
246
247 gpe_register_info = gpe_event_info->register_info;
248 if (!gpe_register_info) {
249 status = AE_NOT_EXIST;
250 goto unlock_and_exit;
251 }
252
253 register_bit =
254 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
255
256 /* Perform the action */
257
258 switch (action) {
259 case ACPI_GPE_ENABLE:
260 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
261 (u8)register_bit);
262 break;
263
264 case ACPI_GPE_DISABLE:
265 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
266 (u8)register_bit);
267 break;
268
269 default:
270 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
271 status = AE_BAD_PARAMETER;
272 break;
273 }
274
275unlock_and_exit:
276 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
277 return_ACPI_STATUS(status);
278}
279
280ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
281
282/*******************************************************************************
283 *
284 * FUNCTION: acpi_enable_gpe
285 *
286 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
287 * gpe_number - GPE level within the GPE block
288 *
289 * RETURN: Status
290 *
291 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
292 * hardware-enabled.
293 *
294 ******************************************************************************/
295acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
296{
297 acpi_status status = AE_BAD_PARAMETER;
298 struct acpi_gpe_event_info *gpe_event_info;
299 acpi_cpu_flags flags;
300
301 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
302
303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
304
305 /* Ensure that we have a valid GPE number */
306
307 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
308 if (gpe_event_info) {
309 status = acpi_raw_enable_gpe(gpe_event_info);
310 }
311
312 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
313 return_ACPI_STATUS(status);
314}
315ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
316
317/*******************************************************************************
318 *
319 * FUNCTION: acpi_disable_gpe
320 *
321 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
322 * gpe_number - GPE level within the GPE block
323 *
324 * RETURN: Status
325 *
326 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
327 * removed, only then is the GPE disabled (for runtime GPEs), or
328 * the GPE mask bit disabled (for wake GPEs)
329 *
330 ******************************************************************************/
331acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
332{
333 acpi_status status = AE_BAD_PARAMETER;
334 struct acpi_gpe_event_info *gpe_event_info;
335 acpi_cpu_flags flags;
336
337 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
338
339 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
340
341 /* Ensure that we have a valid GPE number */
342
343 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
344 if (gpe_event_info) {
345 status = acpi_raw_disable_gpe(gpe_event_info) ;
346 }
347
348 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
349 return_ACPI_STATUS(status);
350}
351ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
352
353/*******************************************************************************
354 *
355 * FUNCTION: acpi_gpe_can_wake
356 *
357 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
358 * gpe_number - GPE level within the GPE block
359 *
360 * RETURN: Status
361 *
362 * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE
363 * has a corresponding method and is currently enabled, disable it
364 * (GPEs with corresponding methods are enabled unconditionally
365 * during initialization, but GPEs that can wake up are expected
366 * to be initially disabled).
367 *
368 ******************************************************************************/
369acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
370{
371 acpi_status status = AE_OK;
372 struct acpi_gpe_event_info *gpe_event_info;
373 acpi_cpu_flags flags;
374
375 ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
376
377 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
378
379 /* Ensure that we have a valid GPE number */
380
381 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
382 if (!gpe_event_info) {
383 status = AE_BAD_PARAMETER;
384 goto unlock_and_exit;
385 }
386
387 if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
388 goto unlock_and_exit;
389 }
390
391 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
392 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) {
393 (void)acpi_raw_disable_gpe(gpe_event_info);
394 }
395
396unlock_and_exit:
397 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
398 return_ACPI_STATUS(status);
399}
400ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
401
402/*******************************************************************************
403 *
404 * FUNCTION: acpi_disable_event 209 * FUNCTION: acpi_disable_event
405 * 210 *
406 * PARAMETERS: Event - The fixed eventto be enabled 211 * PARAMETERS: Event - The fixed eventto be enabled
@@ -492,44 +297,6 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event)
492 297
493/******************************************************************************* 298/*******************************************************************************
494 * 299 *
495 * FUNCTION: acpi_clear_gpe
496 *
497 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
498 * gpe_number - GPE level within the GPE block
499 *
500 * RETURN: Status
501 *
502 * DESCRIPTION: Clear an ACPI event (general purpose)
503 *
504 ******************************************************************************/
505acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
506{
507 acpi_status status = AE_OK;
508 struct acpi_gpe_event_info *gpe_event_info;
509 acpi_cpu_flags flags;
510
511 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
512
513 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
514
515 /* Ensure that we have a valid GPE number */
516
517 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
518 if (!gpe_event_info) {
519 status = AE_BAD_PARAMETER;
520 goto unlock_and_exit;
521 }
522
523 status = acpi_hw_clear_gpe(gpe_event_info);
524
525 unlock_and_exit:
526 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
527 return_ACPI_STATUS(status);
528}
529
530ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
531/*******************************************************************************
532 *
533 * FUNCTION: acpi_get_event_status 300 * FUNCTION: acpi_get_event_status
534 * 301 *
535 * PARAMETERS: Event - The fixed event 302 * PARAMETERS: Event - The fixed event
@@ -584,343 +351,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
584} 351}
585 352
586ACPI_EXPORT_SYMBOL(acpi_get_event_status) 353ACPI_EXPORT_SYMBOL(acpi_get_event_status)
587
588/*******************************************************************************
589 *
590 * FUNCTION: acpi_get_gpe_status
591 *
592 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
593 * gpe_number - GPE level within the GPE block
594 * event_status - Where the current status of the event will
595 * be returned
596 *
597 * RETURN: Status
598 *
599 * DESCRIPTION: Get status of an event (general purpose)
600 *
601 ******************************************************************************/
602acpi_status
603acpi_get_gpe_status(acpi_handle gpe_device,
604 u32 gpe_number, acpi_event_status *event_status)
605{
606 acpi_status status = AE_OK;
607 struct acpi_gpe_event_info *gpe_event_info;
608 acpi_cpu_flags flags;
609
610 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
611
612 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
613
614 /* Ensure that we have a valid GPE number */
615
616 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
617 if (!gpe_event_info) {
618 status = AE_BAD_PARAMETER;
619 goto unlock_and_exit;
620 }
621
622 /* Obtain status on the requested GPE number */
623
624 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
625
626 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
627 *event_status |= ACPI_EVENT_FLAG_HANDLE;
628
629 unlock_and_exit:
630 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
631 return_ACPI_STATUS(status);
632}
633
634ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
635/*******************************************************************************
636 *
637 * FUNCTION: acpi_install_gpe_block
638 *
639 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
640 * gpe_block_address - Address and space_iD
641 * register_count - Number of GPE register pairs in the block
642 * interrupt_number - H/W interrupt for the block
643 *
644 * RETURN: Status
645 *
646 * DESCRIPTION: Create and Install a block of GPE registers
647 *
648 ******************************************************************************/
649acpi_status
650acpi_install_gpe_block(acpi_handle gpe_device,
651 struct acpi_generic_address *gpe_block_address,
652 u32 register_count, u32 interrupt_number)
653{
654 acpi_status status;
655 union acpi_operand_object *obj_desc;
656 struct acpi_namespace_node *node;
657 struct acpi_gpe_block_info *gpe_block;
658
659 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
660
661 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
662 return_ACPI_STATUS(AE_BAD_PARAMETER);
663 }
664
665 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
666 if (ACPI_FAILURE(status)) {
667 return (status);
668 }
669
670 node = acpi_ns_validate_handle(gpe_device);
671 if (!node) {
672 status = AE_BAD_PARAMETER;
673 goto unlock_and_exit;
674 }
675
676 /*
677 * For user-installed GPE Block Devices, the gpe_block_base_number
678 * is always zero
679 */
680 status =
681 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
682 interrupt_number, &gpe_block);
683 if (ACPI_FAILURE(status)) {
684 goto unlock_and_exit;
685 }
686
687 /* Install block in the device_object attached to the node */
688
689 obj_desc = acpi_ns_get_attached_object(node);
690 if (!obj_desc) {
691
692 /*
693 * No object, create a new one (Device nodes do not always have
694 * an attached object)
695 */
696 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
697 if (!obj_desc) {
698 status = AE_NO_MEMORY;
699 goto unlock_and_exit;
700 }
701
702 status =
703 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
704
705 /* Remove local reference to the object */
706
707 acpi_ut_remove_reference(obj_desc);
708
709 if (ACPI_FAILURE(status)) {
710 goto unlock_and_exit;
711 }
712 }
713
714 /* Now install the GPE block in the device_object */
715
716 obj_desc->device.gpe_block = gpe_block;
717
718 /* Enable the runtime GPEs in the new block */
719
720 status = acpi_ev_initialize_gpe_block(node, gpe_block);
721
722 unlock_and_exit:
723 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
724 return_ACPI_STATUS(status);
725}
726
727ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
728
729/*******************************************************************************
730 *
731 * FUNCTION: acpi_remove_gpe_block
732 *
733 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
734 *
735 * RETURN: Status
736 *
737 * DESCRIPTION: Remove a previously installed block of GPE registers
738 *
739 ******************************************************************************/
740acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
741{
742 union acpi_operand_object *obj_desc;
743 acpi_status status;
744 struct acpi_namespace_node *node;
745
746 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
747
748 if (!gpe_device) {
749 return_ACPI_STATUS(AE_BAD_PARAMETER);
750 }
751
752 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
753 if (ACPI_FAILURE(status)) {
754 return (status);
755 }
756
757 node = acpi_ns_validate_handle(gpe_device);
758 if (!node) {
759 status = AE_BAD_PARAMETER;
760 goto unlock_and_exit;
761 }
762
763 /* Get the device_object attached to the node */
764
765 obj_desc = acpi_ns_get_attached_object(node);
766 if (!obj_desc || !obj_desc->device.gpe_block) {
767 return_ACPI_STATUS(AE_NULL_OBJECT);
768 }
769
770 /* Delete the GPE block (but not the device_object) */
771
772 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
773 if (ACPI_SUCCESS(status)) {
774 obj_desc->device.gpe_block = NULL;
775 }
776
777 unlock_and_exit:
778 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
779 return_ACPI_STATUS(status);
780}
781
782ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
783
784/*******************************************************************************
785 *
786 * FUNCTION: acpi_get_gpe_device
787 *
788 * PARAMETERS: Index - System GPE index (0-current_gpe_count)
789 * gpe_device - Where the parent GPE Device is returned
790 *
791 * RETURN: Status
792 *
793 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
794 * gpe device indicates that the gpe number is contained in one of
795 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
796 *
797 ******************************************************************************/
798acpi_status
799acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
800{
801 struct acpi_gpe_device_info info;
802 acpi_status status;
803
804 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
805
806 if (!gpe_device) {
807 return_ACPI_STATUS(AE_BAD_PARAMETER);
808 }
809
810 if (index >= acpi_current_gpe_count) {
811 return_ACPI_STATUS(AE_NOT_EXIST);
812 }
813
814 /* Setup and walk the GPE list */
815
816 info.index = index;
817 info.status = AE_NOT_EXIST;
818 info.gpe_device = NULL;
819 info.next_block_base_index = 0;
820
821 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
822 if (ACPI_FAILURE(status)) {
823 return_ACPI_STATUS(status);
824 }
825
826 *gpe_device = info.gpe_device;
827 return_ACPI_STATUS(info.status);
828}
829
830ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
831
832/*******************************************************************************
833 *
834 * FUNCTION: acpi_ev_get_gpe_device
835 *
836 * PARAMETERS: GPE_WALK_CALLBACK
837 *
838 * RETURN: Status
839 *
840 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
841 * block device. NULL if the GPE is one of the FADT-defined GPEs.
842 *
843 ******************************************************************************/
844static acpi_status
845acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
846 struct acpi_gpe_block_info *gpe_block, void *context)
847{
848 struct acpi_gpe_device_info *info = context;
849
850 /* Increment Index by the number of GPEs in this block */
851
852 info->next_block_base_index += gpe_block->gpe_count;
853
854 if (info->index < info->next_block_base_index) {
855 /*
856 * The GPE index is within this block, get the node. Leave the node
857 * NULL for the FADT-defined GPEs
858 */
859 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
860 info->gpe_device = gpe_block->node;
861 }
862
863 info->status = AE_OK;
864 return (AE_CTRL_END);
865 }
866
867 return (AE_OK);
868}
869
870/******************************************************************************
871 *
872 * FUNCTION: acpi_disable_all_gpes
873 *
874 * PARAMETERS: None
875 *
876 * RETURN: Status
877 *
878 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
879 *
880 ******************************************************************************/
881
882acpi_status acpi_disable_all_gpes(void)
883{
884 acpi_status status;
885
886 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
887
888 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
889 if (ACPI_FAILURE(status)) {
890 return_ACPI_STATUS(status);
891 }
892
893 status = acpi_hw_disable_all_gpes();
894 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
895
896 return_ACPI_STATUS(status);
897}
898
899/******************************************************************************
900 *
901 * FUNCTION: acpi_enable_all_runtime_gpes
902 *
903 * PARAMETERS: None
904 *
905 * RETURN: Status
906 *
907 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
908 *
909 ******************************************************************************/
910
911acpi_status acpi_enable_all_runtime_gpes(void)
912{
913 acpi_status status;
914
915 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
916
917 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
918 if (ACPI_FAILURE(status)) {
919 return_ACPI_STATUS(status);
920 }
921
922 status = acpi_hw_enable_all_runtime_gpes();
923 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
924
925 return_ACPI_STATUS(status);
926}
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
new file mode 100644
index 000000000000..52aaff3df562
--- /dev/null
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -0,0 +1,696 @@
1/******************************************************************************
2 *
3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evxfgpe")
51
52/******************************************************************************
53 *
54 * FUNCTION: acpi_update_all_gpes
55 *
56 * PARAMETERS: None
57 *
58 * RETURN: Status
59 *
60 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
61 * associated _Lxx or _Exx methods and are not pointed to by any
62 * device _PRW methods (this indicates that these GPEs are
63 * generally intended for system or device wakeup. Such GPEs
64 * have to be enabled directly when the devices whose _PRW
65 * methods point to them are set up for wakeup signaling.)
66 *
67 * NOTE: Should be called after any GPEs are added to the system. Primarily,
68 * after the system _PRW methods have been run, but also after a GPE Block
69 * Device has been added or if any new GPE methods have been added via a
70 * dynamic table load.
71 *
72 ******************************************************************************/
73
74acpi_status acpi_update_all_gpes(void)
75{
76 acpi_status status;
77
78 ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
79
80 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
81 if (ACPI_FAILURE(status)) {
82 return_ACPI_STATUS(status);
83 }
84
85 if (acpi_gbl_all_gpes_initialized) {
86 goto unlock_and_exit;
87 }
88
89 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
90 if (ACPI_SUCCESS(status)) {
91 acpi_gbl_all_gpes_initialized = TRUE;
92 }
93
94unlock_and_exit:
95 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
96
97 return_ACPI_STATUS(status);
98}
99
100ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
101
102/*******************************************************************************
103 *
104 * FUNCTION: acpi_enable_gpe
105 *
106 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
107 * gpe_number - GPE level within the GPE block
108 *
109 * RETURN: Status
110 *
111 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
112 * hardware-enabled.
113 *
114 ******************************************************************************/
115
116acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
117{
118 acpi_status status = AE_BAD_PARAMETER;
119 struct acpi_gpe_event_info *gpe_event_info;
120 acpi_cpu_flags flags;
121
122 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
123
124 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
125
126 /* Ensure that we have a valid GPE number */
127
128 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
129 if (gpe_event_info) {
130 status = acpi_ev_add_gpe_reference(gpe_event_info);
131 }
132
133 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
134 return_ACPI_STATUS(status);
135}
136ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
137
138/*******************************************************************************
139 *
140 * FUNCTION: acpi_disable_gpe
141 *
142 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
143 * gpe_number - GPE level within the GPE block
144 *
145 * RETURN: Status
146 *
147 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
148 * removed, only then is the GPE disabled (for runtime GPEs), or
149 * the GPE mask bit disabled (for wake GPEs)
150 *
151 ******************************************************************************/
152
153acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
154{
155 acpi_status status = AE_BAD_PARAMETER;
156 struct acpi_gpe_event_info *gpe_event_info;
157 acpi_cpu_flags flags;
158
159 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
160
161 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
162
163 /* Ensure that we have a valid GPE number */
164
165 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
166 if (gpe_event_info) {
167 status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
168 }
169
170 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
171 return_ACPI_STATUS(status);
172}
173ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
174
175
176/*******************************************************************************
177 *
178 * FUNCTION: acpi_setup_gpe_for_wake
179 *
180 * PARAMETERS: wake_device - Device associated with the GPE (via _PRW)
181 * gpe_device - Parent GPE Device. NULL for GPE0/GPE1
182 * gpe_number - GPE level within the GPE block
183 *
184 * RETURN: Status
185 *
186 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
187 * interface is intended to be used as the host executes the
188 * _PRW methods (Power Resources for Wake) in the system tables.
189 * Each _PRW appears under a Device Object (The wake_device), and
190 * contains the info for the wake GPE associated with the
191 * wake_device.
192 *
193 ******************************************************************************/
194acpi_status
195acpi_setup_gpe_for_wake(acpi_handle wake_device,
196 acpi_handle gpe_device, u32 gpe_number)
197{
198 acpi_status status = AE_BAD_PARAMETER;
199 struct acpi_gpe_event_info *gpe_event_info;
200 struct acpi_namespace_node *device_node;
201 struct acpi_gpe_notify_object *notify_object;
202 acpi_cpu_flags flags;
203 u8 gpe_dispatch_mask;
204
205 ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
206
207 /* Parameter Validation */
208
209 if (!wake_device) {
210 /*
211 * By forcing wake_device to be valid, we automatically enable the
212 * implicit notify feature on all hosts.
213 */
214 return_ACPI_STATUS(AE_BAD_PARAMETER);
215 }
216
217 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
218
219 /* Ensure that we have a valid GPE number */
220
221 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
222 if (!gpe_event_info) {
223 goto unlock_and_exit;
224 }
225
226 if (wake_device == ACPI_ROOT_OBJECT) {
227 goto out;
228 }
229
230 /*
231 * If there is no method or handler for this GPE, then the
232 * wake_device will be notified whenever this GPE fires (aka
233 * "implicit notify") Note: The GPE is assumed to be
234 * level-triggered (for windows compatibility).
235 */
236 gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK;
237 if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE
238 && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) {
239 goto out;
240 }
241
242 /* Validate wake_device is of type Device */
243
244 device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
245 if (device_node->type != ACPI_TYPE_DEVICE) {
246 goto unlock_and_exit;
247 }
248
249 if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) {
250 gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
251 ACPI_GPE_LEVEL_TRIGGERED);
252 gpe_event_info->dispatch.device.node = device_node;
253 gpe_event_info->dispatch.device.next = NULL;
254 } else {
255 /* There are multiple devices to notify implicitly. */
256
257 notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object));
258 if (!notify_object) {
259 status = AE_NO_MEMORY;
260 goto unlock_and_exit;
261 }
262
263 notify_object->node = device_node;
264 notify_object->next = gpe_event_info->dispatch.device.next;
265 gpe_event_info->dispatch.device.next = notify_object;
266 }
267
268 out:
269 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
270 status = AE_OK;
271
272 unlock_and_exit:
273 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
274 return_ACPI_STATUS(status);
275}
276ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
277
278/*******************************************************************************
279 *
280 * FUNCTION: acpi_set_gpe_wake_mask
281 *
282 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
283 * gpe_number - GPE level within the GPE block
284 * Action - Enable or Disable
285 *
286 * RETURN: Status
287 *
288 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
289 * already be marked as a WAKE GPE.
290 *
291 ******************************************************************************/
292
293acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
294{
295 acpi_status status = AE_OK;
296 struct acpi_gpe_event_info *gpe_event_info;
297 struct acpi_gpe_register_info *gpe_register_info;
298 acpi_cpu_flags flags;
299 u32 register_bit;
300
301 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
302
303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
304
305 /*
306 * Ensure that we have a valid GPE number and that this GPE is in
307 * fact a wake GPE
308 */
309 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
310 if (!gpe_event_info) {
311 status = AE_BAD_PARAMETER;
312 goto unlock_and_exit;
313 }
314
315 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
316 status = AE_TYPE;
317 goto unlock_and_exit;
318 }
319
320 gpe_register_info = gpe_event_info->register_info;
321 if (!gpe_register_info) {
322 status = AE_NOT_EXIST;
323 goto unlock_and_exit;
324 }
325
326 register_bit =
327 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
328
329 /* Perform the action */
330
331 switch (action) {
332 case ACPI_GPE_ENABLE:
333 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
334 (u8)register_bit);
335 break;
336
337 case ACPI_GPE_DISABLE:
338 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
339 (u8)register_bit);
340 break;
341
342 default:
343 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
344 status = AE_BAD_PARAMETER;
345 break;
346 }
347
348unlock_and_exit:
349 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
350 return_ACPI_STATUS(status);
351}
352
353ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
354
355/*******************************************************************************
356 *
357 * FUNCTION: acpi_clear_gpe
358 *
359 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
360 * gpe_number - GPE level within the GPE block
361 *
362 * RETURN: Status
363 *
364 * DESCRIPTION: Clear an ACPI event (general purpose)
365 *
366 ******************************************************************************/
367acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
368{
369 acpi_status status = AE_OK;
370 struct acpi_gpe_event_info *gpe_event_info;
371 acpi_cpu_flags flags;
372
373 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
374
375 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
376
377 /* Ensure that we have a valid GPE number */
378
379 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
380 if (!gpe_event_info) {
381 status = AE_BAD_PARAMETER;
382 goto unlock_and_exit;
383 }
384
385 status = acpi_hw_clear_gpe(gpe_event_info);
386
387 unlock_and_exit:
388 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
389 return_ACPI_STATUS(status);
390}
391
392ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
393
394/*******************************************************************************
395 *
396 * FUNCTION: acpi_get_gpe_status
397 *
398 * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
399 * gpe_number - GPE level within the GPE block
400 * event_status - Where the current status of the event will
401 * be returned
402 *
403 * RETURN: Status
404 *
405 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
406 *
407 ******************************************************************************/
408acpi_status
409acpi_get_gpe_status(acpi_handle gpe_device,
410 u32 gpe_number, acpi_event_status *event_status)
411{
412 acpi_status status = AE_OK;
413 struct acpi_gpe_event_info *gpe_event_info;
414 acpi_cpu_flags flags;
415
416 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
417
418 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
419
420 /* Ensure that we have a valid GPE number */
421
422 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
423 if (!gpe_event_info) {
424 status = AE_BAD_PARAMETER;
425 goto unlock_and_exit;
426 }
427
428 /* Obtain status on the requested GPE number */
429
430 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
431
432 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
433 *event_status |= ACPI_EVENT_FLAG_HANDLE;
434
435 unlock_and_exit:
436 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
437 return_ACPI_STATUS(status);
438}
439
440ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
441
442/******************************************************************************
443 *
444 * FUNCTION: acpi_disable_all_gpes
445 *
446 * PARAMETERS: None
447 *
448 * RETURN: Status
449 *
450 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
451 *
452 ******************************************************************************/
453
454acpi_status acpi_disable_all_gpes(void)
455{
456 acpi_status status;
457
458 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
459
460 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
461 if (ACPI_FAILURE(status)) {
462 return_ACPI_STATUS(status);
463 }
464
465 status = acpi_hw_disable_all_gpes();
466 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
467
468 return_ACPI_STATUS(status);
469}
470
471ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
472
473/******************************************************************************
474 *
475 * FUNCTION: acpi_enable_all_runtime_gpes
476 *
477 * PARAMETERS: None
478 *
479 * RETURN: Status
480 *
481 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
482 *
483 ******************************************************************************/
484
485acpi_status acpi_enable_all_runtime_gpes(void)
486{
487 acpi_status status;
488
489 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
490
491 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
492 if (ACPI_FAILURE(status)) {
493 return_ACPI_STATUS(status);
494 }
495
496 status = acpi_hw_enable_all_runtime_gpes();
497 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
498
499 return_ACPI_STATUS(status);
500}
501
502ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
503
504/*******************************************************************************
505 *
506 * FUNCTION: acpi_install_gpe_block
507 *
508 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
509 * gpe_block_address - Address and space_iD
510 * register_count - Number of GPE register pairs in the block
511 * interrupt_number - H/W interrupt for the block
512 *
513 * RETURN: Status
514 *
515 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
516 * enabled here.
517 *
518 ******************************************************************************/
519acpi_status
520acpi_install_gpe_block(acpi_handle gpe_device,
521 struct acpi_generic_address *gpe_block_address,
522 u32 register_count, u32 interrupt_number)
523{
524 acpi_status status;
525 union acpi_operand_object *obj_desc;
526 struct acpi_namespace_node *node;
527 struct acpi_gpe_block_info *gpe_block;
528
529 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
530
531 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
532 return_ACPI_STATUS(AE_BAD_PARAMETER);
533 }
534
535 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
536 if (ACPI_FAILURE(status)) {
537 return (status);
538 }
539
540 node = acpi_ns_validate_handle(gpe_device);
541 if (!node) {
542 status = AE_BAD_PARAMETER;
543 goto unlock_and_exit;
544 }
545
546 /*
547 * For user-installed GPE Block Devices, the gpe_block_base_number
548 * is always zero
549 */
550 status =
551 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
552 interrupt_number, &gpe_block);
553 if (ACPI_FAILURE(status)) {
554 goto unlock_and_exit;
555 }
556
557 /* Install block in the device_object attached to the node */
558
559 obj_desc = acpi_ns_get_attached_object(node);
560 if (!obj_desc) {
561
562 /*
563 * No object, create a new one (Device nodes do not always have
564 * an attached object)
565 */
566 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
567 if (!obj_desc) {
568 status = AE_NO_MEMORY;
569 goto unlock_and_exit;
570 }
571
572 status =
573 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
574
575 /* Remove local reference to the object */
576
577 acpi_ut_remove_reference(obj_desc);
578
579 if (ACPI_FAILURE(status)) {
580 goto unlock_and_exit;
581 }
582 }
583
584 /* Now install the GPE block in the device_object */
585
586 obj_desc->device.gpe_block = gpe_block;
587
588 unlock_and_exit:
589 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
590 return_ACPI_STATUS(status);
591}
592
593ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
594
595/*******************************************************************************
596 *
597 * FUNCTION: acpi_remove_gpe_block
598 *
599 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
600 *
601 * RETURN: Status
602 *
603 * DESCRIPTION: Remove a previously installed block of GPE registers
604 *
605 ******************************************************************************/
606acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
607{
608 union acpi_operand_object *obj_desc;
609 acpi_status status;
610 struct acpi_namespace_node *node;
611
612 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
613
614 if (!gpe_device) {
615 return_ACPI_STATUS(AE_BAD_PARAMETER);
616 }
617
618 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
619 if (ACPI_FAILURE(status)) {
620 return (status);
621 }
622
623 node = acpi_ns_validate_handle(gpe_device);
624 if (!node) {
625 status = AE_BAD_PARAMETER;
626 goto unlock_and_exit;
627 }
628
629 /* Get the device_object attached to the node */
630
631 obj_desc = acpi_ns_get_attached_object(node);
632 if (!obj_desc || !obj_desc->device.gpe_block) {
633 return_ACPI_STATUS(AE_NULL_OBJECT);
634 }
635
636 /* Delete the GPE block (but not the device_object) */
637
638 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
639 if (ACPI_SUCCESS(status)) {
640 obj_desc->device.gpe_block = NULL;
641 }
642
643 unlock_and_exit:
644 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
645 return_ACPI_STATUS(status);
646}
647
648ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
649
650/*******************************************************************************
651 *
652 * FUNCTION: acpi_get_gpe_device
653 *
654 * PARAMETERS: Index - System GPE index (0-current_gpe_count)
655 * gpe_device - Where the parent GPE Device is returned
656 *
657 * RETURN: Status
658 *
659 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
660 * gpe device indicates that the gpe number is contained in one of
661 * the FADT-defined gpe blocks. Otherwise, the GPE block device.
662 *
663 ******************************************************************************/
664acpi_status
665acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
666{
667 struct acpi_gpe_device_info info;
668 acpi_status status;
669
670 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
671
672 if (!gpe_device) {
673 return_ACPI_STATUS(AE_BAD_PARAMETER);
674 }
675
676 if (index >= acpi_current_gpe_count) {
677 return_ACPI_STATUS(AE_NOT_EXIST);
678 }
679
680 /* Setup and walk the GPE list */
681
682 info.index = index;
683 info.status = AE_NOT_EXIST;
684 info.gpe_device = NULL;
685 info.next_block_base_index = 0;
686
687 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
688 if (ACPI_FAILURE(status)) {
689 return_ACPI_STATUS(status);
690 }
691
692 *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
693 return_ACPI_STATUS(info.status);
694}
695
696ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 541cbc1544d5..00cd95692a91 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -64,6 +64,12 @@ ACPI_MODULE_NAME("evxfregn")
64 * 64 *
65 * DESCRIPTION: Install a handler for all op_regions of a given space_id. 65 * DESCRIPTION: Install a handler for all op_regions of a given space_id.
66 * 66 *
67 * NOTE: This function should only be called after acpi_enable_subsystem has
68 * been called. This is because any _REG methods associated with the Space ID
69 * are executed here, and these methods can only be safely executed after
70 * the default handlers have been installed and the hardware has been
71 * initialized (via acpi_enable_subsystem.)
72 *
67 ******************************************************************************/ 73 ******************************************************************************/
68acpi_status 74acpi_status
69acpi_install_address_space_handler(acpi_handle device, 75acpi_install_address_space_handler(acpi_handle device,
@@ -104,6 +110,37 @@ acpi_install_address_space_handler(acpi_handle device,
104 goto unlock_and_exit; 110 goto unlock_and_exit;
105 } 111 }
106 112
113 /*
114 * For the default space_iDs, (the IDs for which there are default region handlers
115 * installed) Only execute the _REG methods if the global initialization _REG
116 * methods have already been run (via acpi_initialize_objects). In other words,
117 * we will defer the execution of the _REG methods for these space_iDs until
118 * execution of acpi_initialize_objects. This is done because we need the handlers
119 * for the default spaces (mem/io/pci/table) to be installed before we can run
120 * any control methods (or _REG methods). There is known BIOS code that depends
121 * on this.
122 *
123 * For all other space_iDs, we can safely execute the _REG methods immediately.
124 * This means that for IDs like embedded_controller, this function should be called
125 * only after acpi_enable_subsystem has been called.
126 */
127 switch (space_id) {
128 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
129 case ACPI_ADR_SPACE_SYSTEM_IO:
130 case ACPI_ADR_SPACE_PCI_CONFIG:
131 case ACPI_ADR_SPACE_DATA_TABLE:
132
133 if (!acpi_gbl_reg_methods_executed) {
134
135 /* We will defer execution of the _REG methods for this space */
136 goto unlock_and_exit;
137 }
138 break;
139
140 default:
141 break;
142 }
143
107 /* Run all _REG methods for this address space */ 144 /* Run all _REG methods for this address space */
108 145
109 status = acpi_ev_execute_reg_methods(node, space_id); 146 status = acpi_ev_execute_reg_methods(node, space_id);
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 18832205b631..745a42b401f5 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index b73bc50c5b76..74162a11817d 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c
index 3c61b48c73f5..110711afada8 100644
--- a/drivers/acpi/acpica/excreate.c
+++ b/drivers/acpi/acpica/excreate.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -305,7 +305,8 @@ acpi_ex_create_region(u8 * aml_start,
305 * range 305 * range
306 */ 306 */
307 if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) && 307 if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
308 (region_space < ACPI_USER_REGION_BEGIN)) { 308 (region_space < ACPI_USER_REGION_BEGIN) &&
309 (region_space != ACPI_ADR_SPACE_DATA_TABLE)) {
309 ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X", 310 ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X",
310 region_space)); 311 region_space));
311 return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID); 312 return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
@@ -482,13 +483,11 @@ acpi_ex_create_method(u8 * aml_start,
482 obj_desc->method.aml_length = aml_length; 483 obj_desc->method.aml_length = aml_length;
483 484
484 /* 485 /*
485 * Disassemble the method flags. Split off the Arg Count 486 * Disassemble the method flags. Split off the arg_count, Serialized
486 * for efficiency 487 * flag, and sync_level for efficiency.
487 */ 488 */
488 method_flags = (u8) operand[1]->integer.value; 489 method_flags = (u8) operand[1]->integer.value;
489 490
490 obj_desc->method.method_flags =
491 (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
492 obj_desc->method.param_count = 491 obj_desc->method.param_count =
493 (u8) (method_flags & AML_METHOD_ARG_COUNT); 492 (u8) (method_flags & AML_METHOD_ARG_COUNT);
494 493
@@ -497,6 +496,8 @@ acpi_ex_create_method(u8 * aml_start,
497 * created for this method when it is parsed. 496 * created for this method when it is parsed.
498 */ 497 */
499 if (method_flags & AML_METHOD_SERIALIZED) { 498 if (method_flags & AML_METHOD_SERIALIZED) {
499 obj_desc->method.info_flags = ACPI_METHOD_SERIALIZED;
500
500 /* 501 /*
501 * ACPI 1.0: sync_level = 0 502 * ACPI 1.0: sync_level = 0
502 * ACPI 2.0: sync_level = sync_level in method declaration 503 * ACPI 2.0: sync_level = sync_level in method declaration
diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c
index be8c98b480d7..c7a2f1edd282 100644
--- a/drivers/acpi/acpica/exdebug.c
+++ b/drivers/acpi/acpica/exdebug.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index f067bbb0d961..61b8c0e8b74d 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -122,7 +122,7 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = {
122 122
123static struct acpi_exdump_info acpi_ex_dump_method[9] = { 123static struct acpi_exdump_info acpi_ex_dump_method[9] = {
124 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, 124 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL},
125 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, 125 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.info_flags), "Info Flags"},
126 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), 126 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count),
127 "Parameter Count"}, 127 "Parameter Count"},
128 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, 128 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"},
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index f17d2ff0031b..0bde2230c028 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index 047217303a4b..f915a7f3f921 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
119 } 119 }
120 120
121 /* 121 /*
122 * Exit now for SMBus or IPMI address space, it has a non-linear address space 122 * Exit now for SMBus or IPMI address space, it has a non-linear
123 * and the request cannot be directly validated 123 * address space and the request cannot be directly validated
124 */ 124 */
125 if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || 125 if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS ||
126 rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { 126 rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) {
@@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
147 * (Region length is specified in bytes) 147 * (Region length is specified in bytes)
148 */ 148 */
149 if (rgn_desc->region.length < 149 if (rgn_desc->region.length <
150 (obj_desc->common_field.base_byte_offset + 150 (obj_desc->common_field.base_byte_offset + field_datum_byte_offset +
151 field_datum_byte_offset +
152 obj_desc->common_field.access_byte_width)) { 151 obj_desc->common_field.access_byte_width)) {
153 if (acpi_gbl_enable_interpreter_slack) { 152 if (acpi_gbl_enable_interpreter_slack) {
154 /* 153 /*
@@ -281,13 +280,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
281 if (ACPI_FAILURE(status)) { 280 if (ACPI_FAILURE(status)) {
282 if (status == AE_NOT_IMPLEMENTED) { 281 if (status == AE_NOT_IMPLEMENTED) {
283 ACPI_ERROR((AE_INFO, 282 ACPI_ERROR((AE_INFO,
284 "Region %s(0x%X) not implemented", 283 "Region %s (ID=%u) not implemented",
285 acpi_ut_get_region_name(rgn_desc->region. 284 acpi_ut_get_region_name(rgn_desc->region.
286 space_id), 285 space_id),
287 rgn_desc->region.space_id)); 286 rgn_desc->region.space_id));
288 } else if (status == AE_NOT_EXIST) { 287 } else if (status == AE_NOT_EXIST) {
289 ACPI_ERROR((AE_INFO, 288 ACPI_ERROR((AE_INFO,
290 "Region %s(0x%X) has no handler", 289 "Region %s (ID=%u) has no handler",
291 acpi_ut_get_region_name(rgn_desc->region. 290 acpi_ut_get_region_name(rgn_desc->region.
292 space_id), 291 space_id),
293 rgn_desc->region.space_id)); 292 rgn_desc->region.space_id));
@@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
680 u32 buffer_tail_bits; 679 u32 buffer_tail_bits;
681 u32 datum_count; 680 u32 datum_count;
682 u32 field_datum_count; 681 u32 field_datum_count;
682 u32 access_bit_width;
683 u32 i; 683 u32 i;
684 684
685 ACPI_FUNCTION_TRACE(ex_extract_from_field); 685 ACPI_FUNCTION_TRACE(ex_extract_from_field);
@@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
694 694
695 return_ACPI_STATUS(AE_BUFFER_OVERFLOW); 695 return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
696 } 696 }
697
697 ACPI_MEMSET(buffer, 0, buffer_length); 698 ACPI_MEMSET(buffer, 0, buffer_length);
699 access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
700
701 /* Handle the simple case here */
702
703 if ((obj_desc->common_field.start_field_bit_offset == 0) &&
704 (obj_desc->common_field.bit_length == access_bit_width)) {
705 status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ);
706 return_ACPI_STATUS(status);
707 }
708
709/* TBD: Move to common setup code */
710
711 /* Field algorithm is limited to sizeof(u64), truncate if needed */
712
713 if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
714 obj_desc->common_field.access_byte_width = sizeof(u64);
715 access_bit_width = sizeof(u64) * 8;
716 }
698 717
699 /* Compute the number of datums (access width data items) */ 718 /* Compute the number of datums (access width data items) */
700 719
701 datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, 720 datum_count =
702 obj_desc->common_field.access_bit_width); 721 ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
722 access_bit_width);
723
703 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + 724 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
704 obj_desc->common_field. 725 obj_desc->common_field.
705 start_field_bit_offset, 726 start_field_bit_offset,
706 obj_desc->common_field.
707 access_bit_width); 727 access_bit_width);
708 728
709 /* Priming read from the field */ 729 /* Priming read from the field */
@@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
738 * This avoids the differences in behavior between different compilers 758 * This avoids the differences in behavior between different compilers
739 * concerning shift values larger than the target data width. 759 * concerning shift values larger than the target data width.
740 */ 760 */
741 if ((obj_desc->common_field.access_bit_width - 761 if (access_bit_width -
742 obj_desc->common_field.start_field_bit_offset) < 762 obj_desc->common_field.start_field_bit_offset <
743 ACPI_INTEGER_BIT_SIZE) { 763 ACPI_INTEGER_BIT_SIZE) {
744 merged_datum |= 764 merged_datum |=
745 raw_datum << (obj_desc->common_field. 765 raw_datum << (access_bit_width -
746 access_bit_width -
747 obj_desc->common_field. 766 obj_desc->common_field.
748 start_field_bit_offset); 767 start_field_bit_offset);
749 } 768 }
@@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
765 784
766 /* Mask off any extra bits in the last datum */ 785 /* Mask off any extra bits in the last datum */
767 786
768 buffer_tail_bits = obj_desc->common_field.bit_length % 787 buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
769 obj_desc->common_field.access_bit_width;
770 if (buffer_tail_bits) { 788 if (buffer_tail_bits) {
771 merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); 789 merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
772 } 790 }
@@ -798,6 +816,7 @@ acpi_status
798acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, 816acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
799 void *buffer, u32 buffer_length) 817 void *buffer, u32 buffer_length)
800{ 818{
819 void *new_buffer;
801 acpi_status status; 820 acpi_status status;
802 u64 mask; 821 u64 mask;
803 u64 width_mask; 822 u64 width_mask;
@@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
808 u32 buffer_tail_bits; 827 u32 buffer_tail_bits;
809 u32 datum_count; 828 u32 datum_count;
810 u32 field_datum_count; 829 u32 field_datum_count;
811 u32 i; 830 u32 access_bit_width;
812 u32 required_length; 831 u32 required_length;
813 void *new_buffer; 832 u32 i;
814 833
815 ACPI_FUNCTION_TRACE(ex_insert_into_field); 834 ACPI_FUNCTION_TRACE(ex_insert_into_field);
816 835
@@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
844 buffer_length = required_length; 863 buffer_length = required_length;
845 } 864 }
846 865
866/* TBD: Move to common setup code */
867
868 /* Algo is limited to sizeof(u64), so cut the access_byte_width */
869 if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
870 obj_desc->common_field.access_byte_width = sizeof(u64);
871 }
872
873 access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
874
847 /* 875 /*
848 * Create the bitmasks used for bit insertion. 876 * Create the bitmasks used for bit insertion.
849 * Note: This if/else is used to bypass compiler differences with the 877 * Note: This if/else is used to bypass compiler differences with the
850 * shift operator 878 * shift operator
851 */ 879 */
852 if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { 880 if (access_bit_width == ACPI_INTEGER_BIT_SIZE) {
853 width_mask = ACPI_UINT64_MAX; 881 width_mask = ACPI_UINT64_MAX;
854 } else { 882 } else {
855 width_mask = 883 width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
856 ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
857 access_bit_width);
858 } 884 }
859 885
860 mask = width_mask & 886 mask = width_mask &
@@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
863 /* Compute the number of datums (access width data items) */ 889 /* Compute the number of datums (access width data items) */
864 890
865 datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, 891 datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
866 obj_desc->common_field.access_bit_width); 892 access_bit_width);
867 893
868 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + 894 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
869 obj_desc->common_field. 895 obj_desc->common_field.
870 start_field_bit_offset, 896 start_field_bit_offset,
871 obj_desc->common_field.
872 access_bit_width); 897 access_bit_width);
873 898
874 /* Get initial Datum from the input buffer */ 899 /* Get initial Datum from the input buffer */
@@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
905 * This avoids the differences in behavior between different compilers 930 * This avoids the differences in behavior between different compilers
906 * concerning shift values larger than the target data width. 931 * concerning shift values larger than the target data width.
907 */ 932 */
908 if ((obj_desc->common_field.access_bit_width - 933 if ((access_bit_width -
909 obj_desc->common_field.start_field_bit_offset) < 934 obj_desc->common_field.start_field_bit_offset) <
910 ACPI_INTEGER_BIT_SIZE) { 935 ACPI_INTEGER_BIT_SIZE) {
911 merged_datum = 936 merged_datum =
912 raw_datum >> (obj_desc->common_field. 937 raw_datum >> (access_bit_width -
913 access_bit_width -
914 obj_desc->common_field. 938 obj_desc->common_field.
915 start_field_bit_offset); 939 start_field_bit_offset);
916 } else { 940 } else {
@@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
929 ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, 953 ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
930 ACPI_MIN(obj_desc->common_field.access_byte_width, 954 ACPI_MIN(obj_desc->common_field.access_byte_width,
931 buffer_length - buffer_offset)); 955 buffer_length - buffer_offset));
956
932 merged_datum |= 957 merged_datum |=
933 raw_datum << obj_desc->common_field.start_field_bit_offset; 958 raw_datum << obj_desc->common_field.start_field_bit_offset;
934 } 959 }
@@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
937 962
938 buffer_tail_bits = (obj_desc->common_field.bit_length + 963 buffer_tail_bits = (obj_desc->common_field.bit_length +
939 obj_desc->common_field.start_field_bit_offset) % 964 obj_desc->common_field.start_field_bit_offset) %
940 obj_desc->common_field.access_bit_width; 965 access_bit_width;
941 if (buffer_tail_bits) { 966 if (buffer_tail_bits) {
942 mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); 967 mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
943 } 968 }
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 95db4be0877b..703d88ed0b3d 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
index f73be97043c0..be1c56ead653 100644
--- a/drivers/acpi/acpica/exmutex.c
+++ b/drivers/acpi/acpica/exmutex.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -336,7 +336,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc)
336 336
337 /* Clear mutex info */ 337 /* Clear mutex info */
338 338
339 obj_desc->mutex.thread_id = NULL; 339 obj_desc->mutex.thread_id = 0;
340 return_ACPI_STATUS(status); 340 return_ACPI_STATUS(status);
341} 341}
342 342
@@ -393,10 +393,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
393 if ((owner_thread->thread_id != walk_state->thread->thread_id) && 393 if ((owner_thread->thread_id != walk_state->thread->thread_id) &&
394 (obj_desc != acpi_gbl_global_lock_mutex)) { 394 (obj_desc != acpi_gbl_global_lock_mutex)) {
395 ACPI_ERROR((AE_INFO, 395 ACPI_ERROR((AE_INFO,
396 "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", 396 "Thread %u cannot release Mutex [%4.4s] acquired by thread %u",
397 ACPI_CAST_PTR(void, walk_state->thread->thread_id), 397 (u32)walk_state->thread->thread_id,
398 acpi_ut_get_node_name(obj_desc->mutex.node), 398 acpi_ut_get_node_name(obj_desc->mutex.node),
399 ACPI_CAST_PTR(void, owner_thread->thread_id))); 399 (u32)owner_thread->thread_id));
400 return_ACPI_STATUS(AE_AML_NOT_OWNER); 400 return_ACPI_STATUS(AE_AML_NOT_OWNER);
401 } 401 }
402 402
@@ -488,7 +488,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
488 /* Mark mutex unowned */ 488 /* Mark mutex unowned */
489 489
490 obj_desc->mutex.owner_thread = NULL; 490 obj_desc->mutex.owner_thread = NULL;
491 obj_desc->mutex.thread_id = NULL; 491 obj_desc->mutex.thread_id = 0;
492 492
493 /* Update Thread sync_level (Last mutex is the important one) */ 493 /* Update Thread sync_level (Last mutex is the important one) */
494 494
diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c
index d11e539ef763..49ec049c157e 100644
--- a/drivers/acpi/acpica/exnames.c
+++ b/drivers/acpi/acpica/exnames.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index 84e4d185aa25..236ead14b7f7 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 10e104cf0fb9..2571b4a310f4 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index 7a08d23befcd..1b48d9d28c9a 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c
index 4b50730cf9a0..f4a2787e8e92 100644
--- a/drivers/acpi/acpica/exoparg6.c
+++ b/drivers/acpi/acpica/exoparg6.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index 98a331d2249b..cc95e2000406 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -355,12 +355,10 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
355 return_ACPI_STATUS(AE_AML_OPERAND_VALUE); 355 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
356 } 356 }
357 357
358 /* Setup width (access granularity) fields */ 358 /* Setup width (access granularity) fields (values are: 1, 2, 4, 8) */
359 359
360 obj_desc->common_field.access_byte_width = (u8) 360 obj_desc->common_field.access_byte_width = (u8)
361 ACPI_DIV_8(access_bit_width); /* 1, 2, 4, 8 */ 361 ACPI_DIV_8(access_bit_width);
362
363 obj_desc->common_field.access_bit_width = (u8) access_bit_width;
364 362
365 /* 363 /*
366 * base_byte_offset is the address of the start of the field within the 364 * base_byte_offset is the address of the start of the field within the
@@ -405,8 +403,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
405{ 403{
406 union acpi_operand_object *obj_desc; 404 union acpi_operand_object *obj_desc;
407 union acpi_operand_object *second_desc = NULL; 405 union acpi_operand_object *second_desc = NULL;
408 u32 type;
409 acpi_status status; 406 acpi_status status;
407 u32 access_byte_width;
408 u32 type;
410 409
411 ACPI_FUNCTION_TRACE(ex_prep_field_value); 410 ACPI_FUNCTION_TRACE(ex_prep_field_value);
412 411
@@ -421,8 +420,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
421 type = acpi_ns_get_type(info->region_node); 420 type = acpi_ns_get_type(info->region_node);
422 if (type != ACPI_TYPE_REGION) { 421 if (type != ACPI_TYPE_REGION) {
423 ACPI_ERROR((AE_INFO, 422 ACPI_ERROR((AE_INFO,
424 "Needed Region, found type 0x%X (%s)", 423 "Needed Region, found type 0x%X (%s)", type,
425 type, acpi_ut_get_type_name(type))); 424 acpi_ut_get_type_name(type)));
426 425
427 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 426 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
428 } 427 }
@@ -438,7 +437,8 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
438 /* Initialize areas of the object that are common to all fields */ 437 /* Initialize areas of the object that are common to all fields */
439 438
440 obj_desc->common_field.node = info->field_node; 439 obj_desc->common_field.node = info->field_node;
441 status = acpi_ex_prep_common_field_object(obj_desc, info->field_flags, 440 status = acpi_ex_prep_common_field_object(obj_desc,
441 info->field_flags,
442 info->attribute, 442 info->attribute,
443 info->field_bit_position, 443 info->field_bit_position,
444 info->field_bit_length); 444 info->field_bit_length);
@@ -455,26 +455,25 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
455 obj_desc->field.region_obj = 455 obj_desc->field.region_obj =
456 acpi_ns_get_attached_object(info->region_node); 456 acpi_ns_get_attached_object(info->region_node);
457 457
458 /* An additional reference for the container */ 458 /* Allow full data read from EC address space */
459 459
460 acpi_ut_add_reference(obj_desc->field.region_obj); 460 if ((obj_desc->field.region_obj->region.space_id ==
461 ACPI_ADR_SPACE_EC)
462 && (obj_desc->common_field.bit_length > 8)) {
463 access_byte_width =
464 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.
465 bit_length);
466
467 /* Maximum byte width supported is 255 */
461 468
462 /* allow full data read from EC address space */ 469 if (access_byte_width < 256) {
463 if (obj_desc->field.region_obj->region.space_id ==
464 ACPI_ADR_SPACE_EC) {
465 if (obj_desc->common_field.bit_length > 8) {
466 unsigned width =
467 ACPI_ROUND_BITS_UP_TO_BYTES(
468 obj_desc->common_field.bit_length);
469 // access_bit_width is u8, don't overflow it
470 if (width > 8)
471 width = 8;
472 obj_desc->common_field.access_byte_width = 470 obj_desc->common_field.access_byte_width =
473 width; 471 (u8)access_byte_width;
474 obj_desc->common_field.access_bit_width =
475 8 * width;
476 } 472 }
477 } 473 }
474 /* An additional reference for the container */
475
476 acpi_ut_add_reference(obj_desc->field.region_obj);
478 477
479 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 478 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
480 "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", 479 "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n",
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 8819d2ac5aee..f0d5e14f1f2c 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -353,7 +353,6 @@ acpi_ex_pci_config_space_handler(u32 function,
353 acpi_status status = AE_OK; 353 acpi_status status = AE_OK;
354 struct acpi_pci_id *pci_id; 354 struct acpi_pci_id *pci_id;
355 u16 pci_register; 355 u16 pci_register;
356 u32 value32;
357 356
358 ACPI_FUNCTION_TRACE(ex_pci_config_space_handler); 357 ACPI_FUNCTION_TRACE(ex_pci_config_space_handler);
359 358
@@ -381,8 +380,7 @@ acpi_ex_pci_config_space_handler(u32 function,
381 case ACPI_READ: 380 case ACPI_READ:
382 381
383 status = acpi_os_read_pci_configuration(pci_id, pci_register, 382 status = acpi_os_read_pci_configuration(pci_id, pci_register,
384 &value32, bit_width); 383 value, bit_width);
385 *value = value32;
386 break; 384 break;
387 385
388 case ACPI_WRITE: 386 case ACPI_WRITE:
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index 1fa4289a687e..55997e46948b 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index 7ca35ea8acea..db502cd7d934 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index 8c97cfd6a0fd..e3bb00ccdff5 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index 1624436ba4c5..c0c8842dd344 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index d4af684620ca..a979017d56b8 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -7,7 +7,7 @@
7 *****************************************************************************/ 7 *****************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2010, Intel Corp. 10 * Copyright (C) 2000 - 2011, Intel Corp.
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c
index e972b667b09b..dc665cc554de 100644
--- a/drivers/acpi/acpica/exstorob.c
+++ b/drivers/acpi/acpica/exstorob.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c
index 675aaa91a770..df66e7b686be 100644
--- a/drivers/acpi/acpica/exsystem.c
+++ b/drivers/acpi/acpica/exsystem.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 4093522eed45..8ad93146dd32 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index b44274a0b62c..fc380d3d45ab 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 14750db2a1b8..f610d88a66be 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -62,10 +62,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
62 * PARAMETERS: gpe_event_info - Info block for the GPE 62 * PARAMETERS: gpe_event_info - Info block for the GPE
63 * gpe_register_info - Info block for the GPE register 63 * gpe_register_info - Info block for the GPE register
64 * 64 *
65 * RETURN: Status 65 * RETURN: Register mask with a one in the GPE bit position
66 * 66 *
67 * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given 67 * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
68 * GPE set. 68 * correct position for the input GPE.
69 * 69 *
70 ******************************************************************************/ 70 ******************************************************************************/
71 71
@@ -85,12 +85,12 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
85 * 85 *
86 * RETURN: Status 86 * RETURN: Status
87 * 87 *
88 * DESCRIPTION: Enable or disable a single GPE in its enable register. 88 * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
89 * 89 *
90 ******************************************************************************/ 90 ******************************************************************************/
91 91
92acpi_status 92acpi_status
93acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) 93acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
94{ 94{
95 struct acpi_gpe_register_info *gpe_register_info; 95 struct acpi_gpe_register_info *gpe_register_info;
96 acpi_status status; 96 acpi_status status;
@@ -113,14 +113,20 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
113 return (status); 113 return (status);
114 } 114 }
115 115
116 /* Set ot clear just the bit that corresponds to this GPE */ 116 /* Set or clear just the bit that corresponds to this GPE */
117 117
118 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, 118 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
119 gpe_register_info); 119 gpe_register_info);
120 switch (action) { 120 switch (action) {
121 case ACPI_GPE_COND_ENABLE: 121 case ACPI_GPE_CONDITIONAL_ENABLE:
122 if (!(register_bit & gpe_register_info->enable_for_run)) 122
123 /* Only enable if the enable_for_run bit is set */
124
125 if (!(register_bit & gpe_register_info->enable_for_run)) {
123 return (AE_BAD_PARAMETER); 126 return (AE_BAD_PARAMETER);
127 }
128
129 /*lint -fallthrough */
124 130
125 case ACPI_GPE_ENABLE: 131 case ACPI_GPE_ENABLE:
126 ACPI_SET_BIT(enable_mask, register_bit); 132 ACPI_SET_BIT(enable_mask, register_bit);
@@ -131,7 +137,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action)
131 break; 137 break;
132 138
133 default: 139 default:
134 ACPI_ERROR((AE_INFO, "Invalid action\n")); 140 ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action));
135 return (AE_BAD_PARAMETER); 141 return (AE_BAD_PARAMETER);
136 } 142 }
137 143
@@ -168,13 +174,13 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
168 return (AE_NOT_EXIST); 174 return (AE_NOT_EXIST);
169 } 175 }
170 176
171 register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
172 gpe_register_info);
173
174 /* 177 /*
175 * Write a one to the appropriate bit in the status register to 178 * Write a one to the appropriate bit in the status register to
176 * clear this GPE. 179 * clear this GPE.
177 */ 180 */
181 register_bit =
182 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
183
178 status = acpi_hw_write(register_bit, 184 status = acpi_hw_write(register_bit,
179 &gpe_register_info->status_address); 185 &gpe_register_info->status_address);
180 186
@@ -201,8 +207,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
201 u32 in_byte; 207 u32 in_byte;
202 u32 register_bit; 208 u32 register_bit;
203 struct acpi_gpe_register_info *gpe_register_info; 209 struct acpi_gpe_register_info *gpe_register_info;
204 acpi_status status;
205 acpi_event_status local_event_status = 0; 210 acpi_event_status local_event_status = 0;
211 acpi_status status;
206 212
207 ACPI_FUNCTION_ENTRY(); 213 ACPI_FUNCTION_ENTRY();
208 214
diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c
new file mode 100644
index 000000000000..050fd227951b
--- /dev/null
+++ b/drivers/acpi/acpica/hwpci.c
@@ -0,0 +1,412 @@
1/*******************************************************************************
2 *
3 * Module Name: hwpci - Obtain PCI bus, device, and function numbers
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46
47#define _COMPONENT ACPI_NAMESPACE
48ACPI_MODULE_NAME("hwpci")
49
50/* PCI configuration space values */
51#define PCI_CFG_HEADER_TYPE_REG 0x0E
52#define PCI_CFG_PRIMARY_BUS_NUMBER_REG 0x18
53#define PCI_CFG_SECONDARY_BUS_NUMBER_REG 0x19
54/* PCI header values */
55#define PCI_HEADER_TYPE_MASK 0x7F
56#define PCI_TYPE_BRIDGE 0x01
57#define PCI_TYPE_CARDBUS_BRIDGE 0x02
58typedef struct acpi_pci_device {
59 acpi_handle device;
60 struct acpi_pci_device *next;
61
62} acpi_pci_device;
63
64/* Local prototypes */
65
66static acpi_status
67acpi_hw_build_pci_list(acpi_handle root_pci_device,
68 acpi_handle pci_region,
69 struct acpi_pci_device **return_list_head);
70
71static acpi_status
72acpi_hw_process_pci_list(struct acpi_pci_id *pci_id,
73 struct acpi_pci_device *list_head);
74
75static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head);
76
77static acpi_status
78acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id,
79 acpi_handle pci_device,
80 u16 *bus_number, u8 *is_bridge);
81
82/*******************************************************************************
83 *
84 * FUNCTION: acpi_hw_derive_pci_id
85 *
86 * PARAMETERS: pci_id - Initial values for the PCI ID. May be
87 * modified by this function.
88 * root_pci_device - A handle to a PCI device object. This
89 * object must be a PCI Root Bridge having a
90 * _HID value of either PNP0A03 or PNP0A08
91 * pci_region - A handle to a PCI configuration space
92 * Operation Region being initialized
93 *
94 * RETURN: Status
95 *
96 * DESCRIPTION: This function derives a full PCI ID for a PCI device,
97 * consisting of a Segment number, Bus number, Device number,
98 * and function code.
99 *
100 * The PCI hardware dynamically configures PCI bus numbers
101 * depending on the bus topology discovered during system
102 * initialization. This function is invoked during configuration
103 * of a PCI_Config Operation Region in order to (possibly) update
104 * the Bus/Device/Function numbers in the pci_id with the actual
105 * values as determined by the hardware and operating system
106 * configuration.
107 *
108 * The pci_id parameter is initially populated during the Operation
109 * Region initialization. This function is then called, and is
110 * will make any necessary modifications to the Bus, Device, or
111 * Function number PCI ID subfields as appropriate for the
112 * current hardware and OS configuration.
113 *
114 * NOTE: Created 08/2010. Replaces the previous OSL acpi_os_derive_pci_id
115 * interface since this feature is OS-independent. This module
116 * specifically avoids any use of recursion by building a local
117 * temporary device list.
118 *
119 ******************************************************************************/
120
121acpi_status
122acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id,
123 acpi_handle root_pci_device, acpi_handle pci_region)
124{
125 acpi_status status;
126 struct acpi_pci_device *list_head = NULL;
127
128 ACPI_FUNCTION_TRACE(hw_derive_pci_id);
129
130 if (!pci_id) {
131 return_ACPI_STATUS(AE_BAD_PARAMETER);
132 }
133
134 /* Build a list of PCI devices, from pci_region up to root_pci_device */
135
136 status =
137 acpi_hw_build_pci_list(root_pci_device, pci_region, &list_head);
138 if (ACPI_SUCCESS(status)) {
139
140 /* Walk the list, updating the PCI device/function/bus numbers */
141
142 status = acpi_hw_process_pci_list(pci_id, list_head);
143 }
144
145 /* Always delete the list */
146
147 acpi_hw_delete_pci_list(list_head);
148 return_ACPI_STATUS(status);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_hw_build_pci_list
154 *
155 * PARAMETERS: root_pci_device - A handle to a PCI device object. This
156 * object is guaranteed to be a PCI Root
157 * Bridge having a _HID value of either
158 * PNP0A03 or PNP0A08
159 * pci_region - A handle to the PCI configuration space
160 * Operation Region
161 * return_list_head - Where the PCI device list is returned
162 *
163 * RETURN: Status
164 *
165 * DESCRIPTION: Builds a list of devices from the input PCI region up to the
166 * Root PCI device for this namespace subtree.
167 *
168 ******************************************************************************/
169
170static acpi_status
171acpi_hw_build_pci_list(acpi_handle root_pci_device,
172 acpi_handle pci_region,
173 struct acpi_pci_device **return_list_head)
174{
175 acpi_handle current_device;
176 acpi_handle parent_device;
177 acpi_status status;
178 struct acpi_pci_device *list_element;
179 struct acpi_pci_device *list_head = NULL;
180
181 /*
182 * Ascend namespace branch until the root_pci_device is reached, building
183 * a list of device nodes. Loop will exit when either the PCI device is
184 * found, or the root of the namespace is reached.
185 */
186 current_device = pci_region;
187 while (1) {
188 status = acpi_get_parent(current_device, &parent_device);
189 if (ACPI_FAILURE(status)) {
190 return (status);
191 }
192
193 /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */
194
195 if (parent_device == root_pci_device) {
196 *return_list_head = list_head;
197 return (AE_OK);
198 }
199
200 list_element = ACPI_ALLOCATE(sizeof(struct acpi_pci_device));
201 if (!list_element) {
202 return (AE_NO_MEMORY);
203 }
204
205 /* Put new element at the head of the list */
206
207 list_element->next = list_head;
208 list_element->device = parent_device;
209 list_head = list_element;
210
211 current_device = parent_device;
212 }
213}
214
215/*******************************************************************************
216 *
217 * FUNCTION: acpi_hw_process_pci_list
218 *
219 * PARAMETERS: pci_id - Initial values for the PCI ID. May be
220 * modified by this function.
221 * list_head - Device list created by
222 * acpi_hw_build_pci_list
223 *
224 * RETURN: Status
225 *
226 * DESCRIPTION: Walk downward through the PCI device list, getting the device
227 * info for each, via the PCI configuration space and updating
228 * the PCI ID as necessary. Deletes the list during traversal.
229 *
230 ******************************************************************************/
231
232static acpi_status
233acpi_hw_process_pci_list(struct acpi_pci_id *pci_id,
234 struct acpi_pci_device *list_head)
235{
236 acpi_status status = AE_OK;
237 struct acpi_pci_device *info;
238 u16 bus_number;
239 u8 is_bridge = TRUE;
240
241 ACPI_FUNCTION_NAME(hw_process_pci_list);
242
243 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
244 "Input PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n",
245 pci_id->segment, pci_id->bus, pci_id->device,
246 pci_id->function));
247
248 bus_number = pci_id->bus;
249
250 /*
251 * Descend down the namespace tree, collecting PCI device, function,
252 * and bus numbers. bus_number is only important for PCI bridges.
253 * Algorithm: As we descend the tree, use the last valid PCI device,
254 * function, and bus numbers that are discovered, and assign them
255 * to the PCI ID for the target device.
256 */
257 info = list_head;
258 while (info) {
259 status = acpi_hw_get_pci_device_info(pci_id, info->device,
260 &bus_number, &is_bridge);
261 if (ACPI_FAILURE(status)) {
262 return_ACPI_STATUS(status);
263 }
264
265 info = info->next;
266 }
267
268 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
269 "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X "
270 "Status %X BusNumber %X IsBridge %X\n",
271 pci_id->segment, pci_id->bus, pci_id->device,
272 pci_id->function, status, bus_number, is_bridge));
273
274 return_ACPI_STATUS(AE_OK);
275}
276
277/*******************************************************************************
278 *
279 * FUNCTION: acpi_hw_delete_pci_list
280 *
281 * PARAMETERS: list_head - Device list created by
282 * acpi_hw_build_pci_list
283 *
284 * RETURN: None
285 *
286 * DESCRIPTION: Free the entire PCI list.
287 *
288 ******************************************************************************/
289
290static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head)
291{
292 struct acpi_pci_device *next;
293 struct acpi_pci_device *previous;
294
295 next = list_head;
296 while (next) {
297 previous = next;
298 next = previous->next;
299 ACPI_FREE(previous);
300 }
301}
302
303/*******************************************************************************
304 *
305 * FUNCTION: acpi_hw_get_pci_device_info
306 *
307 * PARAMETERS: pci_id - Initial values for the PCI ID. May be
308 * modified by this function.
309 * pci_device - Handle for the PCI device object
310 * bus_number - Where a PCI bridge bus number is returned
311 * is_bridge - Return value, indicates if this PCI
312 * device is a PCI bridge
313 *
314 * RETURN: Status
315 *
316 * DESCRIPTION: Get the device info for a single PCI device object. Get the
317 * _ADR (contains PCI device and function numbers), and for PCI
318 * bridge devices, get the bus number from PCI configuration
319 * space.
320 *
321 ******************************************************************************/
322
323static acpi_status
324acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id,
325 acpi_handle pci_device,
326 u16 *bus_number, u8 *is_bridge)
327{
328 acpi_status status;
329 acpi_object_type object_type;
330 u64 return_value;
331 u64 pci_value;
332
333 /* We only care about objects of type Device */
334
335 status = acpi_get_type(pci_device, &object_type);
336 if (ACPI_FAILURE(status)) {
337 return (status);
338 }
339
340 if (object_type != ACPI_TYPE_DEVICE) {
341 return (AE_OK);
342 }
343
344 /* We need an _ADR. Ignore device if not present */
345
346 status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
347 pci_device, &return_value);
348 if (ACPI_FAILURE(status)) {
349 return (AE_OK);
350 }
351
352 /*
353 * From _ADR, get the PCI Device and Function and
354 * update the PCI ID.
355 */
356 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(return_value));
357 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(return_value));
358
359 /*
360 * If the previous device was a bridge, use the previous
361 * device bus number
362 */
363 if (*is_bridge) {
364 pci_id->bus = *bus_number;
365 }
366
367 /*
368 * Get the bus numbers from PCI Config space:
369 *
370 * First, get the PCI header_type
371 */
372 *is_bridge = FALSE;
373 status = acpi_os_read_pci_configuration(pci_id,
374 PCI_CFG_HEADER_TYPE_REG,
375 &pci_value, 8);
376 if (ACPI_FAILURE(status)) {
377 return (status);
378 }
379
380 /* We only care about bridges (1=pci_bridge, 2=card_bus_bridge) */
381
382 pci_value &= PCI_HEADER_TYPE_MASK;
383
384 if ((pci_value != PCI_TYPE_BRIDGE) &&
385 (pci_value != PCI_TYPE_CARDBUS_BRIDGE)) {
386 return (AE_OK);
387 }
388
389 /* Bridge: Get the Primary bus_number */
390
391 status = acpi_os_read_pci_configuration(pci_id,
392 PCI_CFG_PRIMARY_BUS_NUMBER_REG,
393 &pci_value, 8);
394 if (ACPI_FAILURE(status)) {
395 return (status);
396 }
397
398 *is_bridge = TRUE;
399 pci_id->bus = (u16)pci_value;
400
401 /* Bridge: Get the Secondary bus_number */
402
403 status = acpi_os_read_pci_configuration(pci_id,
404 PCI_CFG_SECONDARY_BUS_NUMBER_REG,
405 &pci_value, 8);
406 if (ACPI_FAILURE(status)) {
407 return (status);
408 }
409
410 *bus_number = (u16)pci_value;
411 return (AE_OK);
412}
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 5d1273b660ae..55accb7018bb 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -7,7 +7,7 @@
7 ******************************************************************************/ 7 ******************************************************************************/
8 8
9/* 9/*
10 * Copyright (C) 2000 - 2010, Intel Corp. 10 * Copyright (C) 2000 - 2011, Intel Corp.
11 * All rights reserved. 11 * All rights reserved.
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index 3796811276ac..2ac28bbe8827 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c
index 1ef8e0bb250b..9c8eb71a12fb 100644
--- a/drivers/acpi/acpica/hwtimer.c
+++ b/drivers/acpi/acpica/hwtimer.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index e1d9c777b213..5f1605874655 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index 50cc3be77724..f75f81ad15c9 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -80,14 +80,14 @@ acpi_status acpi_reset(void)
80 80
81 if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { 81 if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
82 /* 82 /*
83 * For I/O space, write directly to the OSL. This bypasses the port 83 * For I/O space, write directly to the OSL. This
84 * validation mechanism, which may block a valid write to the reset 84 * bypasses the port validation mechanism, which may
85 * register. 85 * block a valid write to the reset register. Spec
86 * section 4.7.3.6 requires register width to be 8.
86 */ 87 */
87 status = 88 status =
88 acpi_os_write_port((acpi_io_address) reset_reg->address, 89 acpi_os_write_port((acpi_io_address) reset_reg->address,
89 acpi_gbl_FADT.reset_value, 90 acpi_gbl_FADT.reset_value, 8);
90 reset_reg->bit_width);
91 } else { 91 } else {
92 /* Write the reset value to the reset register */ 92 /* Write the reset value to the reset register */
93 93
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 0cd925be5fc1..d93172fd15a8 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -163,9 +163,9 @@ acpi_status acpi_ns_root_initialize(void)
163#else 163#else
164 /* Mark this as a very SPECIAL method */ 164 /* Mark this as a very SPECIAL method */
165 165
166 obj_desc->method.method_flags = 166 obj_desc->method.info_flags =
167 AML_METHOD_INTERNAL_ONLY; 167 ACPI_METHOD_INTERNAL_ONLY;
168 obj_desc->method.extra.implementation = 168 obj_desc->method.dispatch.implementation =
169 acpi_ut_osi_implementation; 169 acpi_ut_osi_implementation;
170#endif 170#endif
171 break; 171 break;
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index 1e5ff803d9ad..1d0ef15d158f 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -234,8 +234,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
234 * modified the namespace. This is used for cleanup when the 234 * modified the namespace. This is used for cleanup when the
235 * method exits. 235 * method exits.
236 */ 236 */
237 walk_state->method_desc->method.flags |= 237 walk_state->method_desc->method.info_flags |=
238 AOPOBJ_MODIFIED_NAMESPACE; 238 ACPI_METHOD_MODIFIED_NAMESPACE;
239 } 239 }
240 } 240 }
241 241
@@ -341,6 +341,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
341{ 341{
342 struct acpi_namespace_node *child_node = NULL; 342 struct acpi_namespace_node *child_node = NULL;
343 u32 level = 1; 343 u32 level = 1;
344 acpi_status status;
344 345
345 ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); 346 ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree);
346 347
@@ -348,6 +349,13 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
348 return_VOID; 349 return_VOID;
349 } 350 }
350 351
352 /* Lock namespace for possible update */
353
354 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
355 if (ACPI_FAILURE(status)) {
356 return_VOID;
357 }
358
351 /* 359 /*
352 * Traverse the tree of objects until we bubble back up 360 * Traverse the tree of objects until we bubble back up
353 * to where we started. 361 * to where we started.
@@ -397,6 +405,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
397 } 405 }
398 } 406 }
399 407
408 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
400 return_VOID; 409 return_VOID;
401} 410}
402 411
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index a54dc39e304b..b683cc2ff9d3 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -624,9 +624,22 @@ acpi_ns_dump_objects(acpi_object_type type,
624 acpi_owner_id owner_id, acpi_handle start_handle) 624 acpi_owner_id owner_id, acpi_handle start_handle)
625{ 625{
626 struct acpi_walk_info info; 626 struct acpi_walk_info info;
627 acpi_status status;
627 628
628 ACPI_FUNCTION_ENTRY(); 629 ACPI_FUNCTION_ENTRY();
629 630
631 /*
632 * Just lock the entire namespace for the duration of the dump.
633 * We don't want any changes to the namespace during this time,
634 * especially the temporary nodes since we are going to display
635 * them also.
636 */
637 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
638 if (ACPI_FAILURE(status)) {
639 acpi_os_printf("Could not acquire namespace mutex\n");
640 return;
641 }
642
630 info.debug_level = ACPI_LV_TABLES; 643 info.debug_level = ACPI_LV_TABLES;
631 info.owner_id = owner_id; 644 info.owner_id = owner_id;
632 info.display_type = display_type; 645 info.display_type = display_type;
@@ -636,6 +649,8 @@ acpi_ns_dump_objects(acpi_object_type type,
636 ACPI_NS_WALK_TEMP_NODES, 649 ACPI_NS_WALK_TEMP_NODES,
637 acpi_ns_dump_one_object, NULL, 650 acpi_ns_dump_one_object, NULL,
638 (void *)&info, NULL); 651 (void *)&info, NULL);
652
653 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
639} 654}
640#endif /* ACPI_FUTURE_USAGE */ 655#endif /* ACPI_FUTURE_USAGE */
641 656
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c
index d2a97921e249..2ed294b7a4db 100644
--- a/drivers/acpi/acpica/nsdumpdv.c
+++ b/drivers/acpi/acpica/nsdumpdv.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index f52829cc294b..c1bd02b1a058 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -389,7 +389,7 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
389 * acpi_gbl_root_node->Object is NULL at PASS1. 389 * acpi_gbl_root_node->Object is NULL at PASS1.
390 */ 390 */
391 if ((type == ACPI_TYPE_DEVICE) && parent_node->object) { 391 if ((type == ACPI_TYPE_DEVICE) && parent_node->object) {
392 method_obj->method.extra.handler = 392 method_obj->method.dispatch.handler =
393 parent_node->object->device.handler; 393 parent_node->object->device.handler;
394 } 394 }
395 395
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 660a2728908d..fd7c6380e294 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -577,9 +577,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
577 * as possible (without an NMI being received in the middle of 577 * as possible (without an NMI being received in the middle of
578 * this) - so disable NMIs and initialize the device: 578 * this) - so disable NMIs and initialize the device:
579 */ 579 */
580 acpi_nmi_disable();
581 status = acpi_ns_evaluate(info); 580 status = acpi_ns_evaluate(info);
582 acpi_nmi_enable();
583 581
584 if (ACPI_SUCCESS(status)) { 582 if (ACPI_SUCCESS(status)) {
585 walk_info->num_INI++; 583 walk_info->num_INI++;
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index df18be94fefe..5f7dc691c183 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c
index d3104af57e13..d5fa520c3de5 100644
--- a/drivers/acpi/acpica/nsnames.c
+++ b/drivers/acpi/acpica/nsnames.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 41a9213dd5af..3bb8bf105ea2 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index 5808c89e9fac..b3234fa795b8 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 7096bcda0c72..9fb03fa8ffde 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index d1c136692667..ac7b854b0bd7 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -74,7 +74,6 @@ ACPI_MODULE_NAME("nsrepair")
74 * 74 *
75 * Additional possible repairs: 75 * Additional possible repairs:
76 * 76 *
77 * Optional/unnecessary NULL package elements removed
78 * Required package elements that are NULL replaced by Integer/String/Buffer 77 * Required package elements that are NULL replaced by Integer/String/Buffer
79 * Incorrect standalone package wrapped with required outer package 78 * Incorrect standalone package wrapped with required outer package
80 * 79 *
@@ -623,16 +622,12 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
623 ACPI_FUNCTION_NAME(ns_remove_null_elements); 622 ACPI_FUNCTION_NAME(ns_remove_null_elements);
624 623
625 /* 624 /*
626 * PTYPE1 packages contain no subpackages. 625 * We can safely remove all NULL elements from these package types:
627 * PTYPE2 packages contain a variable number of sub-packages. We can 626 * PTYPE1_VAR packages contain a variable number of simple data types.
628 * safely remove all NULL elements from the PTYPE2 packages. 627 * PTYPE2 packages contain a variable number of sub-packages.
629 */ 628 */
630 switch (package_type) { 629 switch (package_type) {
631 case ACPI_PTYPE1_FIXED:
632 case ACPI_PTYPE1_VAR: 630 case ACPI_PTYPE1_VAR:
633 case ACPI_PTYPE1_OPTION:
634 return;
635
636 case ACPI_PTYPE2: 631 case ACPI_PTYPE2:
637 case ACPI_PTYPE2_COUNT: 632 case ACPI_PTYPE2_COUNT:
638 case ACPI_PTYPE2_PKG_COUNT: 633 case ACPI_PTYPE2_PKG_COUNT:
@@ -642,6 +637,8 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
642 break; 637 break;
643 638
644 default: 639 default:
640 case ACPI_PTYPE1_FIXED:
641 case ACPI_PTYPE1_OPTION:
645 return; 642 return;
646 } 643 }
647 644
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c
index 4009498fbabd..973883babee1 100644
--- a/drivers/acpi/acpica/nsrepair2.c
+++ b/drivers/acpi/acpica/nsrepair2.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -74,10 +74,18 @@ acpi_ns_repair_ALR(struct acpi_predefined_data *data,
74 union acpi_operand_object **return_object_ptr); 74 union acpi_operand_object **return_object_ptr);
75 75
76static acpi_status 76static acpi_status
77acpi_ns_repair_CID(struct acpi_predefined_data *data,
78 union acpi_operand_object **return_object_ptr);
79
80static acpi_status
77acpi_ns_repair_FDE(struct acpi_predefined_data *data, 81acpi_ns_repair_FDE(struct acpi_predefined_data *data,
78 union acpi_operand_object **return_object_ptr); 82 union acpi_operand_object **return_object_ptr);
79 83
80static acpi_status 84static acpi_status
85acpi_ns_repair_HID(struct acpi_predefined_data *data,
86 union acpi_operand_object **return_object_ptr);
87
88static acpi_status
81acpi_ns_repair_PSS(struct acpi_predefined_data *data, 89acpi_ns_repair_PSS(struct acpi_predefined_data *data,
82 union acpi_operand_object **return_object_ptr); 90 union acpi_operand_object **return_object_ptr);
83 91
@@ -108,8 +116,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
108 * As necessary: 116 * As necessary:
109 * 117 *
110 * _ALR: Sort the list ascending by ambient_illuminance 118 * _ALR: Sort the list ascending by ambient_illuminance
119 * _CID: Strings: uppercase all, remove any leading asterisk
111 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs 120 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
112 * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs 121 * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
122 * _HID: Strings: uppercase all, remove any leading asterisk
113 * _PSS: Sort the list descending by Power 123 * _PSS: Sort the list descending by Power
114 * _TSS: Sort the list descending by Power 124 * _TSS: Sort the list descending by Power
115 * 125 *
@@ -122,8 +132,10 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
122 */ 132 */
123static const struct acpi_repair_info acpi_ns_repairable_names[] = { 133static const struct acpi_repair_info acpi_ns_repairable_names[] = {
124 {"_ALR", acpi_ns_repair_ALR}, 134 {"_ALR", acpi_ns_repair_ALR},
135 {"_CID", acpi_ns_repair_CID},
125 {"_FDE", acpi_ns_repair_FDE}, 136 {"_FDE", acpi_ns_repair_FDE},
126 {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */ 137 {"_GTM", acpi_ns_repair_FDE}, /* _GTM has same repair as _FDE */
138 {"_HID", acpi_ns_repair_HID},
127 {"_PSS", acpi_ns_repair_PSS}, 139 {"_PSS", acpi_ns_repair_PSS},
128 {"_TSS", acpi_ns_repair_TSS}, 140 {"_TSS", acpi_ns_repair_TSS},
129 {{0, 0, 0, 0}, NULL} /* Table terminator */ 141 {{0, 0, 0, 0}, NULL} /* Table terminator */
@@ -321,6 +333,157 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
321 333
322/****************************************************************************** 334/******************************************************************************
323 * 335 *
336 * FUNCTION: acpi_ns_repair_CID
337 *
338 * PARAMETERS: Data - Pointer to validation data structure
339 * return_object_ptr - Pointer to the object returned from the
340 * evaluation of a method or object
341 *
342 * RETURN: Status. AE_OK if object is OK or was repaired successfully
343 *
344 * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
345 * letters are uppercase and that there is no leading asterisk.
346 * If a Package, ensure same for all string elements.
347 *
348 *****************************************************************************/
349
350static acpi_status
351acpi_ns_repair_CID(struct acpi_predefined_data *data,
352 union acpi_operand_object **return_object_ptr)
353{
354 acpi_status status;
355 union acpi_operand_object *return_object = *return_object_ptr;
356 union acpi_operand_object **element_ptr;
357 union acpi_operand_object *original_element;
358 u16 original_ref_count;
359 u32 i;
360
361 /* Check for _CID as a simple string */
362
363 if (return_object->common.type == ACPI_TYPE_STRING) {
364 status = acpi_ns_repair_HID(data, return_object_ptr);
365 return (status);
366 }
367
368 /* Exit if not a Package */
369
370 if (return_object->common.type != ACPI_TYPE_PACKAGE) {
371 return (AE_OK);
372 }
373
374 /* Examine each element of the _CID package */
375
376 element_ptr = return_object->package.elements;
377 for (i = 0; i < return_object->package.count; i++) {
378 original_element = *element_ptr;
379 original_ref_count = original_element->common.reference_count;
380
381 status = acpi_ns_repair_HID(data, element_ptr);
382 if (ACPI_FAILURE(status)) {
383 return (status);
384 }
385
386 /* Take care with reference counts */
387
388 if (original_element != *element_ptr) {
389
390 /* Element was replaced */
391
392 (*element_ptr)->common.reference_count =
393 original_ref_count;
394
395 acpi_ut_remove_reference(original_element);
396 }
397
398 element_ptr++;
399 }
400
401 return (AE_OK);
402}
403
404/******************************************************************************
405 *
406 * FUNCTION: acpi_ns_repair_HID
407 *
408 * PARAMETERS: Data - Pointer to validation data structure
409 * return_object_ptr - Pointer to the object returned from the
410 * evaluation of a method or object
411 *
412 * RETURN: Status. AE_OK if object is OK or was repaired successfully
413 *
414 * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
415 * letters are uppercase and that there is no leading asterisk.
416 *
417 *****************************************************************************/
418
419static acpi_status
420acpi_ns_repair_HID(struct acpi_predefined_data *data,
421 union acpi_operand_object **return_object_ptr)
422{
423 union acpi_operand_object *return_object = *return_object_ptr;
424 union acpi_operand_object *new_string;
425 char *source;
426 char *dest;
427
428 ACPI_FUNCTION_NAME(ns_repair_HID);
429
430 /* We only care about string _HID objects (not integers) */
431
432 if (return_object->common.type != ACPI_TYPE_STRING) {
433 return (AE_OK);
434 }
435
436 if (return_object->string.length == 0) {
437 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
438 "Invalid zero-length _HID or _CID string"));
439
440 /* Return AE_OK anyway, let driver handle it */
441
442 data->flags |= ACPI_OBJECT_REPAIRED;
443 return (AE_OK);
444 }
445
446 /* It is simplest to always create a new string object */
447
448 new_string = acpi_ut_create_string_object(return_object->string.length);
449 if (!new_string) {
450 return (AE_NO_MEMORY);
451 }
452
453 /*
454 * Remove a leading asterisk if present. For some unknown reason, there
455 * are many machines in the field that contains IDs like this.
456 *
457 * Examples: "*PNP0C03", "*ACPI0003"
458 */
459 source = return_object->string.pointer;
460 if (*source == '*') {
461 source++;
462 new_string->string.length--;
463
464 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
465 "%s: Removed invalid leading asterisk\n",
466 data->pathname));
467 }
468
469 /*
470 * Copy and uppercase the string. From the ACPI specification:
471 *
472 * A valid PNP ID must be of the form "AAA####" where A is an uppercase
473 * letter and # is a hex digit. A valid ACPI ID must be of the form
474 * "ACPI####" where # is a hex digit.
475 */
476 for (dest = new_string->string.pointer; *source; dest++, source++) {
477 *dest = (char)ACPI_TOUPPER(*source);
478 }
479
480 acpi_ut_remove_reference(return_object);
481 *return_object_ptr = new_string;
482 return (AE_OK);
483}
484
485/******************************************************************************
486 *
324 * FUNCTION: acpi_ns_repair_TSS 487 * FUNCTION: acpi_ns_repair_TSS
325 * 488 *
326 * PARAMETERS: Data - Pointer to validation data structure 489 * PARAMETERS: Data - Pointer to validation data structure
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 41102a84272f..28b0d7a62b99 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index e1add3491b04..cb1b104a69a2 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -60,104 +60,6 @@ acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search);
60 60
61/******************************************************************************* 61/*******************************************************************************
62 * 62 *
63 * FUNCTION: acpi_ns_report_error
64 *
65 * PARAMETERS: module_name - Caller's module name (for error output)
66 * line_number - Caller's line number (for error output)
67 * internal_name - Name or path of the namespace node
68 * lookup_status - Exception code from NS lookup
69 *
70 * RETURN: None
71 *
72 * DESCRIPTION: Print warning message with full pathname
73 *
74 ******************************************************************************/
75
76void
77acpi_ns_report_error(const char *module_name,
78 u32 line_number,
79 const char *internal_name, acpi_status lookup_status)
80{
81 acpi_status status;
82 u32 bad_name;
83 char *name = NULL;
84
85 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
86
87 if (lookup_status == AE_BAD_CHARACTER) {
88
89 /* There is a non-ascii character in the name */
90
91 ACPI_MOVE_32_TO_32(&bad_name,
92 ACPI_CAST_PTR(u32, internal_name));
93 acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
94 } else {
95 /* Convert path to external format */
96
97 status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
98 internal_name, NULL, &name);
99
100 /* Print target name */
101
102 if (ACPI_SUCCESS(status)) {
103 acpi_os_printf("[%s]", name);
104 } else {
105 acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
106 }
107
108 if (name) {
109 ACPI_FREE(name);
110 }
111 }
112
113 acpi_os_printf(" Namespace lookup failure, %s\n",
114 acpi_format_exception(lookup_status));
115}
116
117/*******************************************************************************
118 *
119 * FUNCTION: acpi_ns_report_method_error
120 *
121 * PARAMETERS: module_name - Caller's module name (for error output)
122 * line_number - Caller's line number (for error output)
123 * Message - Error message to use on failure
124 * prefix_node - Prefix relative to the path
125 * Path - Path to the node (optional)
126 * method_status - Execution status
127 *
128 * RETURN: None
129 *
130 * DESCRIPTION: Print warning message with full pathname
131 *
132 ******************************************************************************/
133
134void
135acpi_ns_report_method_error(const char *module_name,
136 u32 line_number,
137 const char *message,
138 struct acpi_namespace_node *prefix_node,
139 const char *path, acpi_status method_status)
140{
141 acpi_status status;
142 struct acpi_namespace_node *node = prefix_node;
143
144 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
145
146 if (path) {
147 status =
148 acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
149 &node);
150 if (ACPI_FAILURE(status)) {
151 acpi_os_printf("[Could not get node by pathname]");
152 }
153 }
154
155 acpi_ns_print_node_pathname(node, message);
156 acpi_os_printf(", %s\n", acpi_format_exception(method_status));
157}
158
159/*******************************************************************************
160 *
161 * FUNCTION: acpi_ns_print_node_pathname 63 * FUNCTION: acpi_ns_print_node_pathname
162 * 64 *
163 * PARAMETERS: Node - Object 65 * PARAMETERS: Node - Object
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 2cd5be8fe10f..345f0c3c6ad2 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index ebef8a7fd707..c53f0040e490 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c
index b01e45a415e3..3fd4526f3dba 100644
--- a/drivers/acpi/acpica/nsxfname.c
+++ b/drivers/acpi/acpica/nsxfname.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
@@ -603,10 +603,9 @@ acpi_status acpi_install_method(u8 *buffer)
603 method_obj->method.param_count = (u8) 603 method_obj->method.param_count = (u8)
604 (method_flags & AML_METHOD_ARG_COUNT); 604 (method_flags & AML_METHOD_ARG_COUNT);
605 605
606 method_obj->method.method_flags = (u8)
607 (method_flags & ~AML_METHOD_ARG_COUNT);
608
609 if (method_flags & AML_METHOD_SERIALIZED) { 606 if (method_flags & AML_METHOD_SERIALIZED) {
607 method_obj->method.info_flags = ACPI_METHOD_SERIALIZED;
608
610 method_obj->method.sync_level = (u8) 609 method_obj->method.sync_level = (u8)
611 ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); 610 ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
612 } 611 }
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c
index a1f04e9b8030..db7660f8b869 100644
--- a/drivers/acpi/acpica/nsxfobj.c
+++ b/drivers/acpi/acpica/nsxfobj.c
@@ -6,7 +6,7 @@
6 ******************************************************************************/ 6 ******************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
index 7df1a4c95274..e1fad0ee0136 100644
--- a/drivers/acpi/acpica/psargs.c
+++ b/drivers/acpi/acpica/psargs.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 2f2e7760938c..01dd70d1de51 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -655,7 +655,7 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op,
655 method_obj->method.aml_start = aml_start; 655 method_obj->method.aml_start = aml_start;
656 method_obj->method.aml_length = aml_length; 656 method_obj->method.aml_length = aml_length;
657 method_obj->method.owner_id = owner_id; 657 method_obj->method.owner_id = owner_id;
658 method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; 658 method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
659 659
660 /* 660 /*
661 * Save the parent node in next_object. This is cheating, but we 661 * Save the parent node in next_object. This is cheating, but we
diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c
index 2b0c3be2b1b8..bed08de7528c 100644
--- a/drivers/acpi/acpica/psopcode.c
+++ b/drivers/acpi/acpica/psopcode.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index 8d81542194d4..9bb0cbd37b5e 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -55,7 +55,6 @@
55#include "acparser.h" 55#include "acparser.h"
56#include "acdispat.h" 56#include "acdispat.h"
57#include "amlcode.h" 57#include "amlcode.h"
58#include "acnamesp.h"
59#include "acinterp.h" 58#include "acinterp.h"
60 59
61#define _COMPONENT ACPI_PARSER 60#define _COMPONENT ACPI_PARSER
@@ -539,24 +538,16 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
539 /* Check for possible multi-thread reentrancy problem */ 538 /* Check for possible multi-thread reentrancy problem */
540 539
541 if ((status == AE_ALREADY_EXISTS) && 540 if ((status == AE_ALREADY_EXISTS) &&
542 (!walk_state->method_desc->method.mutex)) { 541 (!(walk_state->method_desc->method.
543 ACPI_INFO((AE_INFO, 542 info_flags & ACPI_METHOD_SERIALIZED))) {
544 "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
545 walk_state->method_node->name.
546 ascii));
547
548 /* 543 /*
549 * Method tried to create an object twice. The probable cause is 544 * Method is not serialized and tried to create an object
550 * that the method cannot handle reentrancy. 545 * twice. The probable cause is that the method cannot
551 * 546 * handle reentrancy. Mark as "pending serialized" now, and
552 * The method is marked not_serialized, but it tried to create 547 * then mark "serialized" when the last thread exits.
553 * a named object, causing the second thread entrance to fail.
554 * Workaround this problem by marking the method permanently
555 * as Serialized.
556 */ 548 */
557 walk_state->method_desc->method.method_flags |= 549 walk_state->method_desc->method.info_flags |=
558 AML_METHOD_SERIALIZED; 550 ACPI_METHOD_SERIALIZED_PENDING;
559 walk_state->method_desc->method.sync_level = 0;
560 } 551 }
561 } 552 }
562 553
diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c
index 40e2b279ea12..a5faa1323a02 100644
--- a/drivers/acpi/acpica/psscope.c
+++ b/drivers/acpi/acpica/psscope.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c
index d4b970c3630b..f1464c03aa42 100644
--- a/drivers/acpi/acpica/pstree.c
+++ b/drivers/acpi/acpica/pstree.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c
index fe29eee5adb1..7eda78503422 100644
--- a/drivers/acpi/acpica/psutils.c
+++ b/drivers/acpi/acpica/psutils.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c
index 8abb9629443d..3312d6368bf1 100644
--- a/drivers/acpi/acpica/pswalk.c
+++ b/drivers/acpi/acpica/pswalk.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c
index c42f067cff9d..8086805d4494 100644
--- a/drivers/acpi/acpica/psxface.c
+++ b/drivers/acpi/acpica/psxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,6 @@
47#include "acdispat.h" 47#include "acdispat.h"
48#include "acinterp.h" 48#include "acinterp.h"
49#include "actables.h" 49#include "actables.h"
50#include "amlcode.h"
51 50
52#define _COMPONENT ACPI_PARSER 51#define _COMPONENT ACPI_PARSER
53ACPI_MODULE_NAME("psxface") 52ACPI_MODULE_NAME("psxface")
@@ -285,15 +284,15 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
285 goto cleanup; 284 goto cleanup;
286 } 285 }
287 286
288 if (info->obj_desc->method.flags & AOPOBJ_MODULE_LEVEL) { 287 if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
289 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; 288 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
290 } 289 }
291 290
292 /* Invoke an internal method if necessary */ 291 /* Invoke an internal method if necessary */
293 292
294 if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { 293 if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
295 status = 294 status =
296 info->obj_desc->method.extra.implementation(walk_state); 295 info->obj_desc->method.dispatch.implementation(walk_state);
297 info->return_object = walk_state->return_desc; 296 info->return_object = walk_state->return_desc;
298 297
299 /* Cleanup states */ 298 /* Cleanup states */
diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c
index 226c806ae986..9e66f9078426 100644
--- a/drivers/acpi/acpica/rsaddr.c
+++ b/drivers/acpi/acpica/rsaddr.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index d6ebf7ec622d..3a8a89ec2ca4 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index c80a2eea3a01..4ce6e1147e80 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c
index f859b0386fe4..33db7520c74b 100644
--- a/drivers/acpi/acpica/rsdump.c
+++ b/drivers/acpi/acpica/rsdump.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c
index 1fd868b964fd..f9ea60872aa4 100644
--- a/drivers/acpi/acpica/rsinfo.c
+++ b/drivers/acpi/acpica/rsinfo.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c
index 33bff17c0bbc..0c7efef008be 100644
--- a/drivers/acpi/acpica/rsio.c
+++ b/drivers/acpi/acpica/rsio.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c
index 545da40d7fa7..50b8ad211167 100644
--- a/drivers/acpi/acpica/rsirq.c
+++ b/drivers/acpi/acpica/rsirq.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c
index 7335f22aac20..1bfcef736c50 100644
--- a/drivers/acpi/acpica/rslist.c
+++ b/drivers/acpi/acpica/rslist.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c
index 887b8ba8c432..7cc6d8625f1e 100644
--- a/drivers/acpi/acpica/rsmemory.c
+++ b/drivers/acpi/acpica/rsmemory.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c
index f8cd9e87d987..410264b22a29 100644
--- a/drivers/acpi/acpica/rsmisc.c
+++ b/drivers/acpi/acpica/rsmisc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c
index 491191e6cf69..231811e56939 100644
--- a/drivers/acpi/acpica/rsutils.c
+++ b/drivers/acpi/acpica/rsutils.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
index 9f6a6e7e1c8e..2ff657a28f26 100644
--- a/drivers/acpi/acpica/rsxface.c
+++ b/drivers/acpi/acpica/rsxface.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 1728cb9bf600..6f5588e62c0a 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -49,7 +49,7 @@
49ACPI_MODULE_NAME("tbfadt") 49ACPI_MODULE_NAME("tbfadt")
50 50
51/* Local prototypes */ 51/* Local prototypes */
52static inline void 52static ACPI_INLINE void
53acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, 53acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
54 u8 space_id, u8 byte_width, u64 address); 54 u8 space_id, u8 byte_width, u64 address);
55 55
@@ -181,7 +181,7 @@ static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
181 * 181 *
182 ******************************************************************************/ 182 ******************************************************************************/
183 183
184static inline void 184static ACPI_INLINE void
185acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, 185acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
186 u8 space_id, u8 byte_width, u64 address) 186 u8 space_id, u8 byte_width, u64 address)
187{ 187{
@@ -384,8 +384,11 @@ static void acpi_tb_convert_fadt(void)
384 * 384 *
385 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at 385 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
386 * offset 45, 55, 95, and the word located at offset 109, 110. 386 * offset 45, 55, 95, and the word located at offset 109, 110.
387 *
388 * Note: The FADT revision value is unreliable. Only the length can be
389 * trusted.
387 */ 390 */
388 if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) { 391 if (acpi_gbl_FADT.header.length <= ACPI_FADT_V2_SIZE) {
389 acpi_gbl_FADT.preferred_profile = 0; 392 acpi_gbl_FADT.preferred_profile = 0;
390 acpi_gbl_FADT.pstate_control = 0; 393 acpi_gbl_FADT.pstate_control = 0;
391 acpi_gbl_FADT.cst_control = 0; 394 acpi_gbl_FADT.cst_control = 0;
diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c
index 989d5c867864..a55cb2bb5abb 100644
--- a/drivers/acpi/acpica/tbfind.c
+++ b/drivers/acpi/acpica/tbfind.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 83d7af8d0905..48db0944ce4a 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 34f9c2bc5e1f..0f2d395feaba 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 4a8b9e6ea57a..4b7085dfc683 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -6,7 +6,7 @@
6 *****************************************************************************/ 6 *****************************************************************************/
7 7
8/* 8/*
9 * Copyright (C) 2000 - 2010, Intel Corp. 9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved. 10 * All rights reserved.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index fd2c07d1d3ac..7eb6c6cc1edf 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c
index 8f0896281567..0a697351cf69 100644
--- a/drivers/acpi/acpica/utalloc.c
+++ b/drivers/acpi/acpica/utalloc.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index 6fef83f04bcd..aded299a2fa8 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
index 983510640059..a9bcd816dc29 100644
--- a/drivers/acpi/acpica/utdebug.c
+++ b/drivers/acpi/acpica/utdebug.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -179,9 +179,8 @@ acpi_debug_print(u32 requested_debug_level,
179 if (thread_id != acpi_gbl_prev_thread_id) { 179 if (thread_id != acpi_gbl_prev_thread_id) {
180 if (ACPI_LV_THREADS & acpi_dbg_level) { 180 if (ACPI_LV_THREADS & acpi_dbg_level) {
181 acpi_os_printf 181 acpi_os_printf
182 ("\n**** Context Switch from TID %p to TID %p ****\n\n", 182 ("\n**** Context Switch from TID %u to TID %u ****\n\n",
183 ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), 183 (u32)acpi_gbl_prev_thread_id, (u32)thread_id);
184 ACPI_CAST_PTR(void, thread_id));
185 } 184 }
186 185
187 acpi_gbl_prev_thread_id = thread_id; 186 acpi_gbl_prev_thread_id = thread_id;
@@ -194,7 +193,7 @@ acpi_debug_print(u32 requested_debug_level,
194 acpi_os_printf("%8s-%04ld ", module_name, line_number); 193 acpi_os_printf("%8s-%04ld ", module_name, line_number);
195 194
196 if (ACPI_LV_THREADS & acpi_dbg_level) { 195 if (ACPI_LV_THREADS & acpi_dbg_level) {
197 acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); 196 acpi_os_printf("[%u] ", (u32)thread_id);
198 } 197 }
199 198
200 acpi_os_printf("[%02ld] %-22.22s: ", 199 acpi_os_printf("[%02ld] %-22.22s: ",
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c
new file mode 100644
index 000000000000..97cb36f85ce9
--- /dev/null
+++ b/drivers/acpi/acpica/utdecode.c
@@ -0,0 +1,549 @@
1/******************************************************************************
2 *
3 * Module Name: utdecode - Utility decoding routines (value-to-string)
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acnamesp.h"
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utdecode")
50
51/*******************************************************************************
52 *
53 * FUNCTION: acpi_format_exception
54 *
55 * PARAMETERS: Status - The acpi_status code to be formatted
56 *
57 * RETURN: A string containing the exception text. A valid pointer is
58 * always returned.
59 *
60 * DESCRIPTION: This function translates an ACPI exception into an ASCII string
61 * It is here instead of utxface.c so it is always present.
62 *
63 ******************************************************************************/
64const char *acpi_format_exception(acpi_status status)
65{
66 const char *exception = NULL;
67
68 ACPI_FUNCTION_ENTRY();
69
70 exception = acpi_ut_validate_exception(status);
71 if (!exception) {
72
73 /* Exception code was not recognized */
74
75 ACPI_ERROR((AE_INFO,
76 "Unknown exception code: 0x%8.8X", status));
77
78 exception = "UNKNOWN_STATUS_CODE";
79 }
80
81 return (ACPI_CAST_PTR(const char, exception));
82}
83
84ACPI_EXPORT_SYMBOL(acpi_format_exception)
85
86/*
87 * Properties of the ACPI Object Types, both internal and external.
88 * The table is indexed by values of acpi_object_type
89 */
90const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = {
91 ACPI_NS_NORMAL, /* 00 Any */
92 ACPI_NS_NORMAL, /* 01 Number */
93 ACPI_NS_NORMAL, /* 02 String */
94 ACPI_NS_NORMAL, /* 03 Buffer */
95 ACPI_NS_NORMAL, /* 04 Package */
96 ACPI_NS_NORMAL, /* 05 field_unit */
97 ACPI_NS_NEWSCOPE, /* 06 Device */
98 ACPI_NS_NORMAL, /* 07 Event */
99 ACPI_NS_NEWSCOPE, /* 08 Method */
100 ACPI_NS_NORMAL, /* 09 Mutex */
101 ACPI_NS_NORMAL, /* 10 Region */
102 ACPI_NS_NEWSCOPE, /* 11 Power */
103 ACPI_NS_NEWSCOPE, /* 12 Processor */
104 ACPI_NS_NEWSCOPE, /* 13 Thermal */
105 ACPI_NS_NORMAL, /* 14 buffer_field */
106 ACPI_NS_NORMAL, /* 15 ddb_handle */
107 ACPI_NS_NORMAL, /* 16 Debug Object */
108 ACPI_NS_NORMAL, /* 17 def_field */
109 ACPI_NS_NORMAL, /* 18 bank_field */
110 ACPI_NS_NORMAL, /* 19 index_field */
111 ACPI_NS_NORMAL, /* 20 Reference */
112 ACPI_NS_NORMAL, /* 21 Alias */
113 ACPI_NS_NORMAL, /* 22 method_alias */
114 ACPI_NS_NORMAL, /* 23 Notify */
115 ACPI_NS_NORMAL, /* 24 Address Handler */
116 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
117 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
118 ACPI_NS_NEWSCOPE, /* 27 Scope */
119 ACPI_NS_NORMAL, /* 28 Extra */
120 ACPI_NS_NORMAL, /* 29 Data */
121 ACPI_NS_NORMAL /* 30 Invalid */
122};
123
124/*******************************************************************************
125 *
126 * FUNCTION: acpi_ut_hex_to_ascii_char
127 *
128 * PARAMETERS: Integer - Contains the hex digit
129 * Position - bit position of the digit within the
130 * integer (multiple of 4)
131 *
132 * RETURN: The converted Ascii character
133 *
134 * DESCRIPTION: Convert a hex digit to an Ascii character
135 *
136 ******************************************************************************/
137
138/* Hex to ASCII conversion table */
139
140static const char acpi_gbl_hex_to_ascii[] = {
141 '0', '1', '2', '3', '4', '5', '6', '7',
142 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
143};
144
145char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
146{
147
148 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
149}
150
151/*******************************************************************************
152 *
153 * FUNCTION: acpi_ut_get_region_name
154 *
155 * PARAMETERS: Space ID - ID for the region
156 *
157 * RETURN: Decoded region space_id name
158 *
159 * DESCRIPTION: Translate a Space ID into a name string (Debug only)
160 *
161 ******************************************************************************/
162
163/* Region type decoding */
164
165const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
166 "SystemMemory",
167 "SystemIO",
168 "PCI_Config",
169 "EmbeddedControl",
170 "SMBus",
171 "SystemCMOS",
172 "PCIBARTarget",
173 "IPMI"
174};
175
176char *acpi_ut_get_region_name(u8 space_id)
177{
178
179 if (space_id >= ACPI_USER_REGION_BEGIN) {
180 return ("UserDefinedRegion");
181 } else if (space_id == ACPI_ADR_SPACE_DATA_TABLE) {
182 return ("DataTable");
183 } else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
184 return ("FunctionalFixedHW");
185 } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
186 return ("InvalidSpaceId");
187 }
188
189 return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id]));
190}
191
192/*******************************************************************************
193 *
194 * FUNCTION: acpi_ut_get_event_name
195 *
196 * PARAMETERS: event_id - Fixed event ID
197 *
198 * RETURN: Decoded event ID name
199 *
200 * DESCRIPTION: Translate a Event ID into a name string (Debug only)
201 *
202 ******************************************************************************/
203
204/* Event type decoding */
205
206static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
207 "PM_Timer",
208 "GlobalLock",
209 "PowerButton",
210 "SleepButton",
211 "RealTimeClock",
212};
213
214char *acpi_ut_get_event_name(u32 event_id)
215{
216
217 if (event_id > ACPI_EVENT_MAX) {
218 return ("InvalidEventID");
219 }
220
221 return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id]));
222}
223
224/*******************************************************************************
225 *
226 * FUNCTION: acpi_ut_get_type_name
227 *
228 * PARAMETERS: Type - An ACPI object type
229 *
230 * RETURN: Decoded ACPI object type name
231 *
232 * DESCRIPTION: Translate a Type ID into a name string (Debug only)
233 *
234 ******************************************************************************/
235
236/*
237 * Elements of acpi_gbl_ns_type_names below must match
238 * one-to-one with values of acpi_object_type
239 *
240 * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
241 * when stored in a table it really means that we have thus far seen no
242 * evidence to indicate what type is actually going to be stored for this entry.
243 */
244static const char acpi_gbl_bad_type[] = "UNDEFINED";
245
246/* Printable names of the ACPI object types */
247
248static const char *acpi_gbl_ns_type_names[] = {
249 /* 00 */ "Untyped",
250 /* 01 */ "Integer",
251 /* 02 */ "String",
252 /* 03 */ "Buffer",
253 /* 04 */ "Package",
254 /* 05 */ "FieldUnit",
255 /* 06 */ "Device",
256 /* 07 */ "Event",
257 /* 08 */ "Method",
258 /* 09 */ "Mutex",
259 /* 10 */ "Region",
260 /* 11 */ "Power",
261 /* 12 */ "Processor",
262 /* 13 */ "Thermal",
263 /* 14 */ "BufferField",
264 /* 15 */ "DdbHandle",
265 /* 16 */ "DebugObject",
266 /* 17 */ "RegionField",
267 /* 18 */ "BankField",
268 /* 19 */ "IndexField",
269 /* 20 */ "Reference",
270 /* 21 */ "Alias",
271 /* 22 */ "MethodAlias",
272 /* 23 */ "Notify",
273 /* 24 */ "AddrHandler",
274 /* 25 */ "ResourceDesc",
275 /* 26 */ "ResourceFld",
276 /* 27 */ "Scope",
277 /* 28 */ "Extra",
278 /* 29 */ "Data",
279 /* 30 */ "Invalid"
280};
281
282char *acpi_ut_get_type_name(acpi_object_type type)
283{
284
285 if (type > ACPI_TYPE_INVALID) {
286 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
287 }
288
289 return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type]));
290}
291
292char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
293{
294
295 if (!obj_desc) {
296 return ("[NULL Object Descriptor]");
297 }
298
299 return (acpi_ut_get_type_name(obj_desc->common.type));
300}
301
302/*******************************************************************************
303 *
304 * FUNCTION: acpi_ut_get_node_name
305 *
306 * PARAMETERS: Object - A namespace node
307 *
308 * RETURN: ASCII name of the node
309 *
310 * DESCRIPTION: Validate the node and return the node's ACPI name.
311 *
312 ******************************************************************************/
313
314char *acpi_ut_get_node_name(void *object)
315{
316 struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
317
318 /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
319
320 if (!object) {
321 return ("NULL");
322 }
323
324 /* Check for Root node */
325
326 if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) {
327 return ("\"\\\" ");
328 }
329
330 /* Descriptor must be a namespace node */
331
332 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
333 return ("####");
334 }
335
336 /*
337 * Ensure name is valid. The name was validated/repaired when the node
338 * was created, but make sure it has not been corrupted.
339 */
340 acpi_ut_repair_name(node->name.ascii);
341
342 /* Return the name */
343
344 return (node->name.ascii);
345}
346
347/*******************************************************************************
348 *
349 * FUNCTION: acpi_ut_get_descriptor_name
350 *
351 * PARAMETERS: Object - An ACPI object
352 *
353 * RETURN: Decoded name of the descriptor type
354 *
355 * DESCRIPTION: Validate object and return the descriptor type
356 *
357 ******************************************************************************/
358
359/* Printable names of object descriptor types */
360
361static const char *acpi_gbl_desc_type_names[] = {
362 /* 00 */ "Not a Descriptor",
363 /* 01 */ "Cached",
364 /* 02 */ "State-Generic",
365 /* 03 */ "State-Update",
366 /* 04 */ "State-Package",
367 /* 05 */ "State-Control",
368 /* 06 */ "State-RootParseScope",
369 /* 07 */ "State-ParseScope",
370 /* 08 */ "State-WalkScope",
371 /* 09 */ "State-Result",
372 /* 10 */ "State-Notify",
373 /* 11 */ "State-Thread",
374 /* 12 */ "Walk",
375 /* 13 */ "Parser",
376 /* 14 */ "Operand",
377 /* 15 */ "Node"
378};
379
380char *acpi_ut_get_descriptor_name(void *object)
381{
382
383 if (!object) {
384 return ("NULL OBJECT");
385 }
386
387 if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
388 return ("Not a Descriptor");
389 }
390
391 return (ACPI_CAST_PTR(char,
392 acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE
393 (object)]));
394
395}
396
397/*******************************************************************************
398 *
399 * FUNCTION: acpi_ut_get_reference_name
400 *
401 * PARAMETERS: Object - An ACPI reference object
402 *
403 * RETURN: Decoded name of the type of reference
404 *
405 * DESCRIPTION: Decode a reference object sub-type to a string.
406 *
407 ******************************************************************************/
408
409/* Printable names of reference object sub-types */
410
411static const char *acpi_gbl_ref_class_names[] = {
412 /* 00 */ "Local",
413 /* 01 */ "Argument",
414 /* 02 */ "RefOf",
415 /* 03 */ "Index",
416 /* 04 */ "DdbHandle",
417 /* 05 */ "Named Object",
418 /* 06 */ "Debug"
419};
420
421const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
422{
423
424 if (!object) {
425 return ("NULL Object");
426 }
427
428 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
429 return ("Not an Operand object");
430 }
431
432 if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
433 return ("Not a Reference object");
434 }
435
436 if (object->reference.class > ACPI_REFCLASS_MAX) {
437 return ("Unknown Reference class");
438 }
439
440 return (acpi_gbl_ref_class_names[object->reference.class]);
441}
442
443#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
444/*
445 * Strings and procedures used for debug only
446 */
447
448/*******************************************************************************
449 *
450 * FUNCTION: acpi_ut_get_mutex_name
451 *
452 * PARAMETERS: mutex_id - The predefined ID for this mutex.
453 *
454 * RETURN: Decoded name of the internal mutex
455 *
456 * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
457 *
458 ******************************************************************************/
459
460/* Names for internal mutex objects, used for debug output */
461
462static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
463 "ACPI_MTX_Interpreter",
464 "ACPI_MTX_Namespace",
465 "ACPI_MTX_Tables",
466 "ACPI_MTX_Events",
467 "ACPI_MTX_Caches",
468 "ACPI_MTX_Memory",
469 "ACPI_MTX_CommandComplete",
470 "ACPI_MTX_CommandReady"
471};
472
473char *acpi_ut_get_mutex_name(u32 mutex_id)
474{
475
476 if (mutex_id > ACPI_MAX_MUTEX) {
477 return ("Invalid Mutex ID");
478 }
479
480 return (acpi_gbl_mutex_names[mutex_id]);
481}
482
483/*******************************************************************************
484 *
485 * FUNCTION: acpi_ut_get_notify_name
486 *
487 * PARAMETERS: notify_value - Value from the Notify() request
488 *
489 * RETURN: Decoded name for the notify value
490 *
491 * DESCRIPTION: Translate a Notify Value to a notify namestring.
492 *
493 ******************************************************************************/
494
495/* Names for Notify() values, used for debug output */
496
497static const char *acpi_gbl_notify_value_names[] = {
498 "Bus Check",
499 "Device Check",
500 "Device Wake",
501 "Eject Request",
502 "Device Check Light",
503 "Frequency Mismatch",
504 "Bus Mode Mismatch",
505 "Power Fault",
506 "Capabilities Check",
507 "Device PLD Check",
508 "Reserved",
509 "System Locality Update"
510};
511
512const char *acpi_ut_get_notify_name(u32 notify_value)
513{
514
515 if (notify_value <= ACPI_NOTIFY_MAX) {
516 return (acpi_gbl_notify_value_names[notify_value]);
517 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
518 return ("Reserved");
519 } else { /* Greater or equal to 0x80 */
520
521 return ("**Device Specific**");
522 }
523}
524#endif
525
526/*******************************************************************************
527 *
528 * FUNCTION: acpi_ut_valid_object_type
529 *
530 * PARAMETERS: Type - Object type to be validated
531 *
532 * RETURN: TRUE if valid object type, FALSE otherwise
533 *
534 * DESCRIPTION: Validate an object type
535 *
536 ******************************************************************************/
537
538u8 acpi_ut_valid_object_type(acpi_object_type type)
539{
540
541 if (type > ACPI_TYPE_LOCAL_MAX) {
542
543 /* Note: Assumes all TYPEs are contiguous (external/local) */
544
545 return (FALSE);
546 }
547
548 return (TRUE);
549}
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index ed794cd033ea..31f5a7832ef1 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 6dfdeb653490..18f73c9d10bc 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,153 +48,6 @@
48#define _COMPONENT ACPI_UTILITIES 48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("uteval") 49ACPI_MODULE_NAME("uteval")
50 50
51/*
52 * Strings supported by the _OSI predefined (internal) method.
53 *
54 * March 2009: Removed "Linux" as this host no longer wants to respond true
55 * for this string. Basically, the only safe OS strings are windows-related
56 * and in many or most cases represent the only test path within the
57 * BIOS-provided ASL code.
58 *
59 * The second element of each entry is used to track the newest version of
60 * Windows that the BIOS has requested.
61 */
62static struct acpi_interface_info acpi_interfaces_supported[] = {
63 /* Operating System Vendor Strings */
64
65 {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */
66 {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */
67 {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
68 {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
69 {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
70 {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
71 {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
72 {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
73 {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
74 {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
75
76 /* Feature Group Strings */
77
78 {"Extended Address Space Descriptor", 0}
79
80 /*
81 * All "optional" feature group strings (features that are implemented
82 * by the host) should be implemented in the host version of
83 * acpi_os_validate_interface and should not be added here.
84 */
85};
86
87/*******************************************************************************
88 *
89 * FUNCTION: acpi_ut_osi_implementation
90 *
91 * PARAMETERS: walk_state - Current walk state
92 *
93 * RETURN: Status
94 *
95 * DESCRIPTION: Implementation of the _OSI predefined control method
96 *
97 ******************************************************************************/
98
99acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
100{
101 acpi_status status;
102 union acpi_operand_object *string_desc;
103 union acpi_operand_object *return_desc;
104 u32 return_value;
105 u32 i;
106
107 ACPI_FUNCTION_TRACE(ut_osi_implementation);
108
109 /* Validate the string input argument */
110
111 string_desc = walk_state->arguments[0].object;
112 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
113 return_ACPI_STATUS(AE_TYPE);
114 }
115
116 /* Create a return object */
117
118 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
119 if (!return_desc) {
120 return_ACPI_STATUS(AE_NO_MEMORY);
121 }
122
123 /* Default return value is 0, NOT SUPPORTED */
124
125 return_value = 0;
126
127 /* Compare input string to static table of supported interfaces */
128
129 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
130 if (!ACPI_STRCMP(string_desc->string.pointer,
131 acpi_interfaces_supported[i].name)) {
132 /*
133 * The interface is supported.
134 * Update the osi_data if necessary. We keep track of the latest
135 * version of Windows that has been requested by the BIOS.
136 */
137 if (acpi_interfaces_supported[i].value >
138 acpi_gbl_osi_data) {
139 acpi_gbl_osi_data =
140 acpi_interfaces_supported[i].value;
141 }
142
143 return_value = ACPI_UINT32_MAX;
144 goto exit;
145 }
146 }
147
148 /*
149 * Did not match the string in the static table, call the host OSL to
150 * check for a match with one of the optional strings (such as
151 * "Module Device", "3.0 Thermal Model", etc.)
152 */
153 status = acpi_os_validate_interface(string_desc->string.pointer);
154 if (ACPI_SUCCESS(status)) {
155
156 /* The interface is supported */
157
158 return_value = ACPI_UINT32_MAX;
159 }
160
161exit:
162 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
163 "ACPI: BIOS _OSI(%s) is %ssupported\n",
164 string_desc->string.pointer, return_value == 0 ? "not " : ""));
165
166 /* Complete the return value */
167
168 return_desc->integer.value = return_value;
169 walk_state->return_desc = return_desc;
170 return_ACPI_STATUS (AE_OK);
171}
172
173/*******************************************************************************
174 *
175 * FUNCTION: acpi_osi_invalidate
176 *
177 * PARAMETERS: interface_string
178 *
179 * RETURN: Status
180 *
181 * DESCRIPTION: invalidate string in pre-defiend _OSI string list
182 *
183 ******************************************************************************/
184
185acpi_status acpi_osi_invalidate(char *interface)
186{
187 int i;
188
189 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
190 if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
191 *acpi_interfaces_supported[i].name = '\0';
192 return AE_OK;
193 }
194 }
195 return AE_NOT_FOUND;
196}
197
198/******************************************************************************* 51/*******************************************************************************
199 * 52 *
200 * FUNCTION: acpi_ut_evaluate_object 53 * FUNCTION: acpi_ut_evaluate_object
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index 0558747579ef..833a38a9c905 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,7 +45,6 @@
45 45
46#include <acpi/acpi.h> 46#include <acpi/acpi.h>
47#include "accommon.h" 47#include "accommon.h"
48#include "acnamesp.h"
49 48
50#define _COMPONENT ACPI_UTILITIES 49#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utglobal") 50ACPI_MODULE_NAME("utglobal")
@@ -107,43 +106,6 @@ const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = {
107 106
108/******************************************************************************* 107/*******************************************************************************
109 * 108 *
110 * FUNCTION: acpi_format_exception
111 *
112 * PARAMETERS: Status - The acpi_status code to be formatted
113 *
114 * RETURN: A string containing the exception text. A valid pointer is
115 * always returned.
116 *
117 * DESCRIPTION: This function translates an ACPI exception into an ASCII string
118 * It is here instead of utxface.c so it is always present.
119 *
120 ******************************************************************************/
121
122const char *acpi_format_exception(acpi_status status)
123{
124 const char *exception = NULL;
125
126 ACPI_FUNCTION_ENTRY();
127
128 exception = acpi_ut_validate_exception(status);
129 if (!exception) {
130
131 /* Exception code was not recognized */
132
133 ACPI_ERROR((AE_INFO,
134 "Unknown exception code: 0x%8.8X", status));
135
136 exception = "UNKNOWN_STATUS_CODE";
137 dump_stack();
138 }
139
140 return (ACPI_CAST_PTR(const char, exception));
141}
142
143ACPI_EXPORT_SYMBOL(acpi_format_exception)
144
145/*******************************************************************************
146 *
147 * Namespace globals 109 * Namespace globals
148 * 110 *
149 ******************************************************************************/ 111 ******************************************************************************/
@@ -154,14 +116,16 @@ ACPI_EXPORT_SYMBOL(acpi_format_exception)
154 * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run 116 * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
155 * during the initialization sequence. 117 * during the initialization sequence.
156 * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to 118 * 2) _TZ_ is defined to be a thermal zone in order to allow ASL code to
157 * perform a Notify() operation on it. 119 * perform a Notify() operation on it. 09/2010: Changed to type Device.
120 * This still allows notifies, but does not confuse host code that
121 * searches for valid thermal_zone objects.
158 */ 122 */
159const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = { 123const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
160 {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, 124 {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
161 {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL}, 125 {"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
162 {"_SB_", ACPI_TYPE_DEVICE, NULL}, 126 {"_SB_", ACPI_TYPE_DEVICE, NULL},
163 {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL}, 127 {"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
164 {"_TZ_", ACPI_TYPE_THERMAL, NULL}, 128 {"_TZ_", ACPI_TYPE_DEVICE, NULL},
165 {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL}, 129 {"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
166 {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, 130 {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
167 {"_GL_", ACPI_TYPE_MUTEX, (char *)1}, 131 {"_GL_", ACPI_TYPE_MUTEX, (char *)1},
@@ -175,71 +139,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
175 {NULL, ACPI_TYPE_ANY, NULL} 139 {NULL, ACPI_TYPE_ANY, NULL}
176}; 140};
177 141
178/*
179 * Properties of the ACPI Object Types, both internal and external.
180 * The table is indexed by values of acpi_object_type
181 */
182const u8 acpi_gbl_ns_properties[] = {
183 ACPI_NS_NORMAL, /* 00 Any */
184 ACPI_NS_NORMAL, /* 01 Number */
185 ACPI_NS_NORMAL, /* 02 String */
186 ACPI_NS_NORMAL, /* 03 Buffer */
187 ACPI_NS_NORMAL, /* 04 Package */
188 ACPI_NS_NORMAL, /* 05 field_unit */
189 ACPI_NS_NEWSCOPE, /* 06 Device */
190 ACPI_NS_NORMAL, /* 07 Event */
191 ACPI_NS_NEWSCOPE, /* 08 Method */
192 ACPI_NS_NORMAL, /* 09 Mutex */
193 ACPI_NS_NORMAL, /* 10 Region */
194 ACPI_NS_NEWSCOPE, /* 11 Power */
195 ACPI_NS_NEWSCOPE, /* 12 Processor */
196 ACPI_NS_NEWSCOPE, /* 13 Thermal */
197 ACPI_NS_NORMAL, /* 14 buffer_field */
198 ACPI_NS_NORMAL, /* 15 ddb_handle */
199 ACPI_NS_NORMAL, /* 16 Debug Object */
200 ACPI_NS_NORMAL, /* 17 def_field */
201 ACPI_NS_NORMAL, /* 18 bank_field */
202 ACPI_NS_NORMAL, /* 19 index_field */
203 ACPI_NS_NORMAL, /* 20 Reference */
204 ACPI_NS_NORMAL, /* 21 Alias */
205 ACPI_NS_NORMAL, /* 22 method_alias */
206 ACPI_NS_NORMAL, /* 23 Notify */
207 ACPI_NS_NORMAL, /* 24 Address Handler */
208 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 25 Resource Desc */
209 ACPI_NS_NEWSCOPE | ACPI_NS_LOCAL, /* 26 Resource Field */
210 ACPI_NS_NEWSCOPE, /* 27 Scope */
211 ACPI_NS_NORMAL, /* 28 Extra */
212 ACPI_NS_NORMAL, /* 29 Data */
213 ACPI_NS_NORMAL /* 30 Invalid */
214};
215
216/* Hex to ASCII conversion table */
217
218static const char acpi_gbl_hex_to_ascii[] = {
219 '0', '1', '2', '3', '4', '5', '6', '7',
220 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
221};
222
223/*******************************************************************************
224 *
225 * FUNCTION: acpi_ut_hex_to_ascii_char
226 *
227 * PARAMETERS: Integer - Contains the hex digit
228 * Position - bit position of the digit within the
229 * integer (multiple of 4)
230 *
231 * RETURN: The converted Ascii character
232 *
233 * DESCRIPTION: Convert a hex digit to an Ascii character
234 *
235 ******************************************************************************/
236
237char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
238{
239
240 return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
241}
242
243/****************************************************************************** 142/******************************************************************************
244 * 143 *
245 * Event and Hardware globals 144 * Event and Hardware globals
@@ -339,386 +238,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
339 238
340/******************************************************************************* 239/*******************************************************************************
341 * 240 *
342 * FUNCTION: acpi_ut_get_region_name
343 *
344 * PARAMETERS: None.
345 *
346 * RETURN: Status
347 *
348 * DESCRIPTION: Translate a Space ID into a name string (Debug only)
349 *
350 ******************************************************************************/
351
352/* Region type decoding */
353
354const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = {
355 "SystemMemory",
356 "SystemIO",
357 "PCI_Config",
358 "EmbeddedControl",
359 "SMBus",
360 "SystemCMOS",
361 "PCIBARTarget",
362 "IPMI",
363 "DataTable"
364};
365
366char *acpi_ut_get_region_name(u8 space_id)
367{
368
369 if (space_id >= ACPI_USER_REGION_BEGIN) {
370 return ("UserDefinedRegion");
371 } else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
372 return ("InvalidSpaceId");
373 }
374
375 return (ACPI_CAST_PTR(char, acpi_gbl_region_types[space_id]));
376}
377
378/*******************************************************************************
379 *
380 * FUNCTION: acpi_ut_get_event_name
381 *
382 * PARAMETERS: None.
383 *
384 * RETURN: Status
385 *
386 * DESCRIPTION: Translate a Event ID into a name string (Debug only)
387 *
388 ******************************************************************************/
389
390/* Event type decoding */
391
392static const char *acpi_gbl_event_types[ACPI_NUM_FIXED_EVENTS] = {
393 "PM_Timer",
394 "GlobalLock",
395 "PowerButton",
396 "SleepButton",
397 "RealTimeClock",
398};
399
400char *acpi_ut_get_event_name(u32 event_id)
401{
402
403 if (event_id > ACPI_EVENT_MAX) {
404 return ("InvalidEventID");
405 }
406
407 return (ACPI_CAST_PTR(char, acpi_gbl_event_types[event_id]));
408}
409
410/*******************************************************************************
411 *
412 * FUNCTION: acpi_ut_get_type_name
413 *
414 * PARAMETERS: None.
415 *
416 * RETURN: Status
417 *
418 * DESCRIPTION: Translate a Type ID into a name string (Debug only)
419 *
420 ******************************************************************************/
421
422/*
423 * Elements of acpi_gbl_ns_type_names below must match
424 * one-to-one with values of acpi_object_type
425 *
426 * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching;
427 * when stored in a table it really means that we have thus far seen no
428 * evidence to indicate what type is actually going to be stored for this entry.
429 */
430static const char acpi_gbl_bad_type[] = "UNDEFINED";
431
432/* Printable names of the ACPI object types */
433
434static const char *acpi_gbl_ns_type_names[] = {
435 /* 00 */ "Untyped",
436 /* 01 */ "Integer",
437 /* 02 */ "String",
438 /* 03 */ "Buffer",
439 /* 04 */ "Package",
440 /* 05 */ "FieldUnit",
441 /* 06 */ "Device",
442 /* 07 */ "Event",
443 /* 08 */ "Method",
444 /* 09 */ "Mutex",
445 /* 10 */ "Region",
446 /* 11 */ "Power",
447 /* 12 */ "Processor",
448 /* 13 */ "Thermal",
449 /* 14 */ "BufferField",
450 /* 15 */ "DdbHandle",
451 /* 16 */ "DebugObject",
452 /* 17 */ "RegionField",
453 /* 18 */ "BankField",
454 /* 19 */ "IndexField",
455 /* 20 */ "Reference",
456 /* 21 */ "Alias",
457 /* 22 */ "MethodAlias",
458 /* 23 */ "Notify",
459 /* 24 */ "AddrHandler",
460 /* 25 */ "ResourceDesc",
461 /* 26 */ "ResourceFld",
462 /* 27 */ "Scope",
463 /* 28 */ "Extra",
464 /* 29 */ "Data",
465 /* 30 */ "Invalid"
466};
467
468char *acpi_ut_get_type_name(acpi_object_type type)
469{
470
471 if (type > ACPI_TYPE_INVALID) {
472 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
473 }
474
475 return (ACPI_CAST_PTR(char, acpi_gbl_ns_type_names[type]));
476}
477
478char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
479{
480
481 if (!obj_desc) {
482 return ("[NULL Object Descriptor]");
483 }
484
485 return (acpi_ut_get_type_name(obj_desc->common.type));
486}
487
488/*******************************************************************************
489 *
490 * FUNCTION: acpi_ut_get_node_name
491 *
492 * PARAMETERS: Object - A namespace node
493 *
494 * RETURN: Pointer to a string
495 *
496 * DESCRIPTION: Validate the node and return the node's ACPI name.
497 *
498 ******************************************************************************/
499
500char *acpi_ut_get_node_name(void *object)
501{
502 struct acpi_namespace_node *node = (struct acpi_namespace_node *)object;
503
504 /* Must return a string of exactly 4 characters == ACPI_NAME_SIZE */
505
506 if (!object) {
507 return ("NULL");
508 }
509
510 /* Check for Root node */
511
512 if ((object == ACPI_ROOT_OBJECT) || (object == acpi_gbl_root_node)) {
513 return ("\"\\\" ");
514 }
515
516 /* Descriptor must be a namespace node */
517
518 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
519 return ("####");
520 }
521
522 /* Name must be a valid ACPI name */
523
524 if (!acpi_ut_valid_acpi_name(node->name.integer)) {
525 node->name.integer = acpi_ut_repair_name(node->name.ascii);
526 }
527
528 /* Return the name */
529
530 return (node->name.ascii);
531}
532
533/*******************************************************************************
534 *
535 * FUNCTION: acpi_ut_get_descriptor_name
536 *
537 * PARAMETERS: Object - An ACPI object
538 *
539 * RETURN: Pointer to a string
540 *
541 * DESCRIPTION: Validate object and return the descriptor type
542 *
543 ******************************************************************************/
544
545/* Printable names of object descriptor types */
546
547static const char *acpi_gbl_desc_type_names[] = {
548 /* 00 */ "Invalid",
549 /* 01 */ "Cached",
550 /* 02 */ "State-Generic",
551 /* 03 */ "State-Update",
552 /* 04 */ "State-Package",
553 /* 05 */ "State-Control",
554 /* 06 */ "State-RootParseScope",
555 /* 07 */ "State-ParseScope",
556 /* 08 */ "State-WalkScope",
557 /* 09 */ "State-Result",
558 /* 10 */ "State-Notify",
559 /* 11 */ "State-Thread",
560 /* 12 */ "Walk",
561 /* 13 */ "Parser",
562 /* 14 */ "Operand",
563 /* 15 */ "Node"
564};
565
566char *acpi_ut_get_descriptor_name(void *object)
567{
568
569 if (!object) {
570 return ("NULL OBJECT");
571 }
572
573 if (ACPI_GET_DESCRIPTOR_TYPE(object) > ACPI_DESC_TYPE_MAX) {
574 return (ACPI_CAST_PTR(char, acpi_gbl_bad_type));
575 }
576
577 return (ACPI_CAST_PTR(char,
578 acpi_gbl_desc_type_names[ACPI_GET_DESCRIPTOR_TYPE
579 (object)]));
580
581}
582
583/*******************************************************************************
584 *
585 * FUNCTION: acpi_ut_get_reference_name
586 *
587 * PARAMETERS: Object - An ACPI reference object
588 *
589 * RETURN: Pointer to a string
590 *
591 * DESCRIPTION: Decode a reference object sub-type to a string.
592 *
593 ******************************************************************************/
594
595/* Printable names of reference object sub-types */
596
597static const char *acpi_gbl_ref_class_names[] = {
598 /* 00 */ "Local",
599 /* 01 */ "Argument",
600 /* 02 */ "RefOf",
601 /* 03 */ "Index",
602 /* 04 */ "DdbHandle",
603 /* 05 */ "Named Object",
604 /* 06 */ "Debug"
605};
606
607const char *acpi_ut_get_reference_name(union acpi_operand_object *object)
608{
609 if (!object)
610 return "NULL Object";
611
612 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND)
613 return "Not an Operand object";
614
615 if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE)
616 return "Not a Reference object";
617
618 if (object->reference.class > ACPI_REFCLASS_MAX)
619 return "Unknown Reference class";
620
621 return acpi_gbl_ref_class_names[object->reference.class];
622}
623
624#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
625/*
626 * Strings and procedures used for debug only
627 */
628
629/*******************************************************************************
630 *
631 * FUNCTION: acpi_ut_get_mutex_name
632 *
633 * PARAMETERS: mutex_id - The predefined ID for this mutex.
634 *
635 * RETURN: String containing the name of the mutex. Always returns a valid
636 * pointer.
637 *
638 * DESCRIPTION: Translate a mutex ID into a name string (Debug only)
639 *
640 ******************************************************************************/
641
642char *acpi_ut_get_mutex_name(u32 mutex_id)
643{
644
645 if (mutex_id > ACPI_MAX_MUTEX) {
646 return ("Invalid Mutex ID");
647 }
648
649 return (acpi_gbl_mutex_names[mutex_id]);
650}
651
652/*******************************************************************************
653 *
654 * FUNCTION: acpi_ut_get_notify_name
655 *
656 * PARAMETERS: notify_value - Value from the Notify() request
657 *
658 * RETURN: String corresponding to the Notify Value.
659 *
660 * DESCRIPTION: Translate a Notify Value to a notify namestring.
661 *
662 ******************************************************************************/
663
664/* Names for Notify() values, used for debug output */
665
666static const char *acpi_gbl_notify_value_names[] = {
667 "Bus Check",
668 "Device Check",
669 "Device Wake",
670 "Eject Request",
671 "Device Check Light",
672 "Frequency Mismatch",
673 "Bus Mode Mismatch",
674 "Power Fault",
675 "Capabilities Check",
676 "Device PLD Check",
677 "Reserved",
678 "System Locality Update"
679};
680
681const char *acpi_ut_get_notify_name(u32 notify_value)
682{
683
684 if (notify_value <= ACPI_NOTIFY_MAX) {
685 return (acpi_gbl_notify_value_names[notify_value]);
686 } else if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
687 return ("Reserved");
688 } else { /* Greater or equal to 0x80 */
689
690 return ("**Device Specific**");
691 }
692}
693#endif
694
695/*******************************************************************************
696 *
697 * FUNCTION: acpi_ut_valid_object_type
698 *
699 * PARAMETERS: Type - Object type to be validated
700 *
701 * RETURN: TRUE if valid object type, FALSE otherwise
702 *
703 * DESCRIPTION: Validate an object type
704 *
705 ******************************************************************************/
706
707u8 acpi_ut_valid_object_type(acpi_object_type type)
708{
709
710 if (type > ACPI_TYPE_LOCAL_MAX) {
711
712 /* Note: Assumes all TYPEs are contiguous (external/local) */
713
714 return (FALSE);
715 }
716
717 return (TRUE);
718}
719
720/*******************************************************************************
721 *
722 * FUNCTION: acpi_ut_init_globals 241 * FUNCTION: acpi_ut_init_globals
723 * 242 *
724 * PARAMETERS: None 243 * PARAMETERS: None
@@ -766,6 +285,7 @@ acpi_status acpi_ut_init_globals(void)
766 acpi_gbl_gpe_fadt_blocks[0] = NULL; 285 acpi_gbl_gpe_fadt_blocks[0] = NULL;
767 acpi_gbl_gpe_fadt_blocks[1] = NULL; 286 acpi_gbl_gpe_fadt_blocks[1] = NULL;
768 acpi_current_gpe_count = 0; 287 acpi_current_gpe_count = 0;
288 acpi_gbl_all_gpes_initialized = FALSE;
769 289
770 /* Global handlers */ 290 /* Global handlers */
771 291
@@ -774,6 +294,8 @@ acpi_status acpi_ut_init_globals(void)
774 acpi_gbl_exception_handler = NULL; 294 acpi_gbl_exception_handler = NULL;
775 acpi_gbl_init_handler = NULL; 295 acpi_gbl_init_handler = NULL;
776 acpi_gbl_table_handler = NULL; 296 acpi_gbl_table_handler = NULL;
297 acpi_gbl_interface_handler = NULL;
298 acpi_gbl_global_event_handler = NULL;
777 299
778 /* Global Lock support */ 300 /* Global Lock support */
779 301
@@ -800,6 +322,8 @@ acpi_status acpi_ut_init_globals(void)
800 acpi_gbl_debugger_configuration = DEBUGGER_THREADING; 322 acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
801 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; 323 acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
802 acpi_gbl_osi_data = 0; 324 acpi_gbl_osi_data = 0;
325 acpi_gbl_osi_mutex = NULL;
326 acpi_gbl_reg_methods_executed = FALSE;
803 327
804 /* Hardware oriented */ 328 /* Hardware oriented */
805 329
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c
index 1397fadd0d4b..b679ea693545 100644
--- a/drivers/acpi/acpica/utids.c
+++ b/drivers/acpi/acpica/utids.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,42 +48,6 @@
48#define _COMPONENT ACPI_UTILITIES 48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utids") 49ACPI_MODULE_NAME("utids")
50 50
51/* Local prototypes */
52static void acpi_ut_copy_id_string(char *destination, char *source);
53
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_ut_copy_id_string
57 *
58 * PARAMETERS: Destination - Where to copy the string
59 * Source - Source string
60 *
61 * RETURN: None
62 *
63 * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
64 * Performs removal of a leading asterisk if present -- workaround
65 * for a known issue on a bunch of machines.
66 *
67 ******************************************************************************/
68
69static void acpi_ut_copy_id_string(char *destination, char *source)
70{
71
72 /*
73 * Workaround for ID strings that have a leading asterisk. This construct
74 * is not allowed by the ACPI specification (ID strings must be
75 * alphanumeric), but enough existing machines have this embedded in their
76 * ID strings that the following code is useful.
77 */
78 if (*source == '*') {
79 source++;
80 }
81
82 /* Do the actual copy */
83
84 ACPI_STRCPY(destination, source);
85}
86
87/******************************************************************************* 51/*******************************************************************************
88 * 52 *
89 * FUNCTION: acpi_ut_execute_HID 53 * FUNCTION: acpi_ut_execute_HID
@@ -101,7 +65,6 @@ static void acpi_ut_copy_id_string(char *destination, char *source)
101 * NOTE: Internal function, no parameter validation 65 * NOTE: Internal function, no parameter validation
102 * 66 *
103 ******************************************************************************/ 67 ******************************************************************************/
104
105acpi_status 68acpi_status
106acpi_ut_execute_HID(struct acpi_namespace_node *device_node, 69acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
107 struct acpica_device_id **return_id) 70 struct acpica_device_id **return_id)
@@ -147,7 +110,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
147 if (obj_desc->common.type == ACPI_TYPE_INTEGER) { 110 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
148 acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); 111 acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
149 } else { 112 } else {
150 acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); 113 ACPI_STRCPY(hid->string, obj_desc->string.pointer);
151 } 114 }
152 115
153 hid->length = length; 116 hid->length = length;
@@ -224,7 +187,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
224 if (obj_desc->common.type == ACPI_TYPE_INTEGER) { 187 if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
225 acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); 188 acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
226 } else { 189 } else {
227 acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); 190 ACPI_STRCPY(uid->string, obj_desc->string.pointer);
228 } 191 }
229 192
230 uid->length = length; 193 uid->length = length;
@@ -357,8 +320,8 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
357 320
358 /* Copy the String CID from the returned object */ 321 /* Copy the String CID from the returned object */
359 322
360 acpi_ut_copy_id_string(next_id_string, 323 ACPI_STRCPY(next_id_string,
361 cid_objects[i]->string.pointer); 324 cid_objects[i]->string.pointer);
362 length = cid_objects[i]->string.length + 1; 325 length = cid_objects[i]->string.length + 1;
363 } 326 }
364 327
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c
index a39c93dac719..191b6828cce9 100644
--- a/drivers/acpi/acpica/utinit.c
+++ b/drivers/acpi/acpica/utinit.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -117,6 +117,10 @@ void acpi_ut_subsystem_shutdown(void)
117 /* Close the acpi_event Handling */ 117 /* Close the acpi_event Handling */
118 118
119 acpi_ev_terminate(); 119 acpi_ev_terminate();
120
121 /* Delete any dynamic _OSI interfaces */
122
123 acpi_ut_interface_terminate();
120#endif 124#endif
121 125
122 /* Close the Namespace */ 126 /* Close the Namespace */
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c
index b081cd46a15f..f6bb75c6faf5 100644
--- a/drivers/acpi/acpica/utlock.c
+++ b/drivers/acpi/acpica/utlock.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c
index 35059a14eb72..ce481da9bb45 100644
--- a/drivers/acpi/acpica/utmath.c
+++ b/drivers/acpi/acpica/utmath.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -48,11 +48,27 @@
48ACPI_MODULE_NAME("utmath") 48ACPI_MODULE_NAME("utmath")
49 49
50/* 50/*
51 * Support for double-precision integer divide. This code is included here 51 * Optional support for 64-bit double-precision integer divide. This code
52 * in order to support kernel environments where the double-precision math 52 * is configurable and is implemented in order to support 32-bit kernel
53 * library is not available. 53 * environments where a 64-bit double-precision math library is not available.
54 *
55 * Support for a more normal 64-bit divide/modulo (with check for a divide-
56 * by-zero) appears after this optional section of code.
54 */ 57 */
55#ifndef ACPI_USE_NATIVE_DIVIDE 58#ifndef ACPI_USE_NATIVE_DIVIDE
59/* Structures used only for 64-bit divide */
60typedef struct uint64_struct {
61 u32 lo;
62 u32 hi;
63
64} uint64_struct;
65
66typedef union uint64_overlay {
67 u64 full;
68 struct uint64_struct part;
69
70} uint64_overlay;
71
56/******************************************************************************* 72/*******************************************************************************
57 * 73 *
58 * FUNCTION: acpi_ut_short_divide 74 * FUNCTION: acpi_ut_short_divide
@@ -69,6 +85,7 @@ ACPI_MODULE_NAME("utmath")
69 * 32-bit remainder. 85 * 32-bit remainder.
70 * 86 *
71 ******************************************************************************/ 87 ******************************************************************************/
88
72acpi_status 89acpi_status
73acpi_ut_short_divide(u64 dividend, 90acpi_ut_short_divide(u64 dividend,
74 u32 divisor, u64 *out_quotient, u32 *out_remainder) 91 u32 divisor, u64 *out_quotient, u32 *out_remainder)
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index e8d0724ee403..c33a852d4f42 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -50,11 +50,6 @@
50#define _COMPONENT ACPI_UTILITIES 50#define _COMPONENT ACPI_UTILITIES
51ACPI_MODULE_NAME("utmisc") 51ACPI_MODULE_NAME("utmisc")
52 52
53/*
54 * Common suffix for messages
55 */
56#define ACPI_COMMON_MSG_SUFFIX \
57 acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
58/******************************************************************************* 53/*******************************************************************************
59 * 54 *
60 * FUNCTION: acpi_ut_validate_exception 55 * FUNCTION: acpi_ut_validate_exception
@@ -1044,160 +1039,3 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
1044 1039
1045 return_ACPI_STATUS(AE_AML_INTERNAL); 1040 return_ACPI_STATUS(AE_AML_INTERNAL);
1046} 1041}
1047
1048/*******************************************************************************
1049 *
1050 * FUNCTION: acpi_error, acpi_exception, acpi_warning, acpi_info
1051 *
1052 * PARAMETERS: module_name - Caller's module name (for error output)
1053 * line_number - Caller's line number (for error output)
1054 * Format - Printf format string + additional args
1055 *
1056 * RETURN: None
1057 *
1058 * DESCRIPTION: Print message with module/line/version info
1059 *
1060 ******************************************************************************/
1061
1062void ACPI_INTERNAL_VAR_XFACE
1063acpi_error(const char *module_name, u32 line_number, const char *format, ...)
1064{
1065 va_list args;
1066
1067 acpi_os_printf("ACPI Error: ");
1068
1069 va_start(args, format);
1070 acpi_os_vprintf(format, args);
1071 ACPI_COMMON_MSG_SUFFIX;
1072 va_end(args);
1073}
1074
1075void ACPI_INTERNAL_VAR_XFACE
1076acpi_exception(const char *module_name,
1077 u32 line_number, acpi_status status, const char *format, ...)
1078{
1079 va_list args;
1080
1081 acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status));
1082
1083 va_start(args, format);
1084 acpi_os_vprintf(format, args);
1085 ACPI_COMMON_MSG_SUFFIX;
1086 va_end(args);
1087}
1088
1089void ACPI_INTERNAL_VAR_XFACE
1090acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
1091{
1092 va_list args;
1093
1094 acpi_os_printf("ACPI Warning: ");
1095
1096 va_start(args, format);
1097 acpi_os_vprintf(format, args);
1098 ACPI_COMMON_MSG_SUFFIX;
1099 va_end(args);
1100}
1101
1102void ACPI_INTERNAL_VAR_XFACE
1103acpi_info(const char *module_name, u32 line_number, const char *format, ...)
1104{
1105 va_list args;
1106
1107 acpi_os_printf("ACPI: ");
1108
1109 va_start(args, format);
1110 acpi_os_vprintf(format, args);
1111 acpi_os_printf("\n");
1112 va_end(args);
1113}
1114
1115ACPI_EXPORT_SYMBOL(acpi_error)
1116ACPI_EXPORT_SYMBOL(acpi_exception)
1117ACPI_EXPORT_SYMBOL(acpi_warning)
1118ACPI_EXPORT_SYMBOL(acpi_info)
1119
1120/*******************************************************************************
1121 *
1122 * FUNCTION: acpi_ut_predefined_warning
1123 *
1124 * PARAMETERS: module_name - Caller's module name (for error output)
1125 * line_number - Caller's line number (for error output)
1126 * Pathname - Full pathname to the node
1127 * node_flags - From Namespace node for the method/object
1128 * Format - Printf format string + additional args
1129 *
1130 * RETURN: None
1131 *
1132 * DESCRIPTION: Warnings for the predefined validation module. Messages are
1133 * only emitted the first time a problem with a particular
1134 * method/object is detected. This prevents a flood of error
1135 * messages for methods that are repeatedly evaluated.
1136 *
1137******************************************************************************/
1138
1139void ACPI_INTERNAL_VAR_XFACE
1140acpi_ut_predefined_warning(const char *module_name,
1141 u32 line_number,
1142 char *pathname,
1143 u8 node_flags, const char *format, ...)
1144{
1145 va_list args;
1146
1147 /*
1148 * Warning messages for this method/object will be disabled after the
1149 * first time a validation fails or an object is successfully repaired.
1150 */
1151 if (node_flags & ANOBJ_EVALUATED) {
1152 return;
1153 }
1154
1155 acpi_os_printf("ACPI Warning for %s: ", pathname);
1156
1157 va_start(args, format);
1158 acpi_os_vprintf(format, args);
1159 ACPI_COMMON_MSG_SUFFIX;
1160 va_end(args);
1161}
1162
1163/*******************************************************************************
1164 *
1165 * FUNCTION: acpi_ut_predefined_info
1166 *
1167 * PARAMETERS: module_name - Caller's module name (for error output)
1168 * line_number - Caller's line number (for error output)
1169 * Pathname - Full pathname to the node
1170 * node_flags - From Namespace node for the method/object
1171 * Format - Printf format string + additional args
1172 *
1173 * RETURN: None
1174 *
1175 * DESCRIPTION: Info messages for the predefined validation module. Messages
1176 * are only emitted the first time a problem with a particular
1177 * method/object is detected. This prevents a flood of
1178 * messages for methods that are repeatedly evaluated.
1179 *
1180 ******************************************************************************/
1181
1182void ACPI_INTERNAL_VAR_XFACE
1183acpi_ut_predefined_info(const char *module_name,
1184 u32 line_number,
1185 char *pathname, u8 node_flags, const char *format, ...)
1186{
1187 va_list args;
1188
1189 /*
1190 * Warning messages for this method/object will be disabled after the
1191 * first time a validation fails or an object is successfully repaired.
1192 */
1193 if (node_flags & ANOBJ_EVALUATED) {
1194 return;
1195 }
1196
1197 acpi_os_printf("ACPI Info for %s: ", pathname);
1198
1199 va_start(args, format);
1200 acpi_os_vprintf(format, args);
1201 ACPI_COMMON_MSG_SUFFIX;
1202 va_end(args);
1203}
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index f5cca3a1300c..7d797e2baecd 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -83,8 +83,21 @@ acpi_status acpi_ut_mutex_initialize(void)
83 83
84 /* Create the spinlocks for use at interrupt level */ 84 /* Create the spinlocks for use at interrupt level */
85 85
86 spin_lock_init(acpi_gbl_gpe_lock); 86 status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
87 spin_lock_init(acpi_gbl_hardware_lock); 87 if (ACPI_FAILURE (status)) {
88 return_ACPI_STATUS (status);
89 }
90
91 status = acpi_os_create_lock (&acpi_gbl_hardware_lock);
92 if (ACPI_FAILURE (status)) {
93 return_ACPI_STATUS (status);
94 }
95
96 /* Mutex for _OSI support */
97 status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
98 if (ACPI_FAILURE(status)) {
99 return_ACPI_STATUS(status);
100 }
88 101
89 /* Create the reader/writer lock for namespace access */ 102 /* Create the reader/writer lock for namespace access */
90 103
@@ -117,6 +130,8 @@ void acpi_ut_mutex_terminate(void)
117 acpi_ut_delete_mutex(i); 130 acpi_ut_delete_mutex(i);
118 } 131 }
119 132
133 acpi_os_delete_mutex(acpi_gbl_osi_mutex);
134
120 /* Delete the spinlocks */ 135 /* Delete the spinlocks */
121 136
122 acpi_os_delete_lock(acpi_gbl_gpe_lock); 137 acpi_os_delete_lock(acpi_gbl_gpe_lock);
@@ -220,18 +235,17 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
220 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { 235 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
221 if (i == mutex_id) { 236 if (i == mutex_id) {
222 ACPI_ERROR((AE_INFO, 237 ACPI_ERROR((AE_INFO,
223 "Mutex [%s] already acquired by this thread [%p]", 238 "Mutex [%s] already acquired by this thread [%u]",
224 acpi_ut_get_mutex_name 239 acpi_ut_get_mutex_name
225 (mutex_id), 240 (mutex_id),
226 ACPI_CAST_PTR(void, 241 (u32)this_thread_id));
227 this_thread_id)));
228 242
229 return (AE_ALREADY_ACQUIRED); 243 return (AE_ALREADY_ACQUIRED);
230 } 244 }
231 245
232 ACPI_ERROR((AE_INFO, 246 ACPI_ERROR((AE_INFO,
233 "Invalid acquire order: Thread %p owns [%s], wants [%s]", 247 "Invalid acquire order: Thread %u owns [%s], wants [%s]",
234 ACPI_CAST_PTR(void, this_thread_id), 248 (u32)this_thread_id,
235 acpi_ut_get_mutex_name(i), 249 acpi_ut_get_mutex_name(i),
236 acpi_ut_get_mutex_name(mutex_id))); 250 acpi_ut_get_mutex_name(mutex_id)));
237 251
@@ -242,24 +256,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
242#endif 256#endif
243 257
244 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 258 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
245 "Thread %p attempting to acquire Mutex [%s]\n", 259 "Thread %u attempting to acquire Mutex [%s]\n",
246 ACPI_CAST_PTR(void, this_thread_id), 260 (u32)this_thread_id,
247 acpi_ut_get_mutex_name(mutex_id))); 261 acpi_ut_get_mutex_name(mutex_id)));
248 262
249 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, 263 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
250 ACPI_WAIT_FOREVER); 264 ACPI_WAIT_FOREVER);
251 if (ACPI_SUCCESS(status)) { 265 if (ACPI_SUCCESS(status)) {
252 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 266 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
253 "Thread %p acquired Mutex [%s]\n", 267 "Thread %u acquired Mutex [%s]\n",
254 ACPI_CAST_PTR(void, this_thread_id), 268 (u32)this_thread_id,
255 acpi_ut_get_mutex_name(mutex_id))); 269 acpi_ut_get_mutex_name(mutex_id)));
256 270
257 acpi_gbl_mutex_info[mutex_id].use_count++; 271 acpi_gbl_mutex_info[mutex_id].use_count++;
258 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; 272 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
259 } else { 273 } else {
260 ACPI_EXCEPTION((AE_INFO, status, 274 ACPI_EXCEPTION((AE_INFO, status,
261 "Thread %p could not acquire Mutex [0x%X]", 275 "Thread %u could not acquire Mutex [0x%X]",
262 ACPI_CAST_PTR(void, this_thread_id), mutex_id)); 276 (u32)this_thread_id, mutex_id));
263 } 277 }
264 278
265 return (status); 279 return (status);
@@ -279,10 +293,14 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
279 293
280acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) 294acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
281{ 295{
296 acpi_thread_id this_thread_id;
297
282 ACPI_FUNCTION_NAME(ut_release_mutex); 298 ACPI_FUNCTION_NAME(ut_release_mutex);
283 299
284 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", 300 this_thread_id = acpi_os_get_thread_id();
285 ACPI_CAST_PTR(void, acpi_os_get_thread_id()), 301
302 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
303 (u32)this_thread_id,
286 acpi_ut_get_mutex_name(mutex_id))); 304 acpi_ut_get_mutex_name(mutex_id)));
287 305
288 if (mutex_id > ACPI_MAX_MUTEX) { 306 if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index fd1fa2749ea5..188340a017b4 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c
new file mode 100644
index 000000000000..1fb10cb8f11d
--- /dev/null
+++ b/drivers/acpi/acpica/utosi.c
@@ -0,0 +1,380 @@
1/******************************************************************************
2 *
3 * Module Name: utosi - Support for the _OSI predefined control method
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46
47#define _COMPONENT ACPI_UTILITIES
48ACPI_MODULE_NAME("utosi")
49
50/*
51 * Strings supported by the _OSI predefined control method (which is
52 * implemented internally within this module.)
53 *
54 * March 2009: Removed "Linux" as this host no longer wants to respond true
55 * for this string. Basically, the only safe OS strings are windows-related
56 * and in many or most cases represent the only test path within the
57 * BIOS-provided ASL code.
58 *
59 * The last element of each entry is used to track the newest version of
60 * Windows that the BIOS has requested.
61 */
62static struct acpi_interface_info acpi_default_supported_interfaces[] = {
63 /* Operating System Vendor Strings */
64
65 {"Windows 2000", NULL, 0, ACPI_OSI_WIN_2000}, /* Windows 2000 */
66 {"Windows 2001", NULL, 0, ACPI_OSI_WIN_XP}, /* Windows XP */
67 {"Windows 2001 SP1", NULL, 0, ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
68 {"Windows 2001.1", NULL, 0, ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
69 {"Windows 2001 SP2", NULL, 0, ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
70 {"Windows 2001.1 SP1", NULL, 0, ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
71 {"Windows 2006", NULL, 0, ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
72 {"Windows 2006.1", NULL, 0, ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
73 {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
74 {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
75 {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
76
77 /* Feature Group Strings */
78
79 {"Extended Address Space Descriptor", NULL, 0, 0}
80
81 /*
82 * All "optional" feature group strings (features that are implemented
83 * by the host) should be dynamically added by the host via
84 * acpi_install_interface and should not be manually added here.
85 *
86 * Examples of optional feature group strings:
87 *
88 * "Module Device"
89 * "Processor Device"
90 * "3.0 Thermal Model"
91 * "3.0 _SCP Extensions"
92 * "Processor Aggregator Device"
93 */
94};
95
96/*******************************************************************************
97 *
98 * FUNCTION: acpi_ut_initialize_interfaces
99 *
100 * PARAMETERS: None
101 *
102 * RETURN: Status
103 *
104 * DESCRIPTION: Initialize the global _OSI supported interfaces list
105 *
106 ******************************************************************************/
107
108acpi_status acpi_ut_initialize_interfaces(void)
109{
110 u32 i;
111
112 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
113 acpi_gbl_supported_interfaces = acpi_default_supported_interfaces;
114
115 /* Link the static list of supported interfaces */
116
117 for (i = 0;
118 i < (ACPI_ARRAY_LENGTH(acpi_default_supported_interfaces) - 1);
119 i++) {
120 acpi_default_supported_interfaces[i].next =
121 &acpi_default_supported_interfaces[(acpi_size) i + 1];
122 }
123
124 acpi_os_release_mutex(acpi_gbl_osi_mutex);
125 return (AE_OK);
126}
127
128/*******************************************************************************
129 *
130 * FUNCTION: acpi_ut_interface_terminate
131 *
132 * PARAMETERS: None
133 *
134 * RETURN: None
135 *
136 * DESCRIPTION: Delete all interfaces in the global list. Sets
137 * acpi_gbl_supported_interfaces to NULL.
138 *
139 ******************************************************************************/
140
141void acpi_ut_interface_terminate(void)
142{
143 struct acpi_interface_info *next_interface;
144
145 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
146 next_interface = acpi_gbl_supported_interfaces;
147
148 while (next_interface) {
149 acpi_gbl_supported_interfaces = next_interface->next;
150
151 /* Only interfaces added at runtime can be freed */
152
153 if (next_interface->flags & ACPI_OSI_DYNAMIC) {
154 ACPI_FREE(next_interface->name);
155 ACPI_FREE(next_interface);
156 }
157
158 next_interface = acpi_gbl_supported_interfaces;
159 }
160
161 acpi_os_release_mutex(acpi_gbl_osi_mutex);
162}
163
164/*******************************************************************************
165 *
166 * FUNCTION: acpi_ut_install_interface
167 *
168 * PARAMETERS: interface_name - The interface to install
169 *
170 * RETURN: Status
171 *
172 * DESCRIPTION: Install the interface into the global interface list.
173 * Caller MUST hold acpi_gbl_osi_mutex
174 *
175 ******************************************************************************/
176
177acpi_status acpi_ut_install_interface(acpi_string interface_name)
178{
179 struct acpi_interface_info *interface_info;
180
181 /* Allocate info block and space for the name string */
182
183 interface_info =
184 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_interface_info));
185 if (!interface_info) {
186 return (AE_NO_MEMORY);
187 }
188
189 interface_info->name =
190 ACPI_ALLOCATE_ZEROED(ACPI_STRLEN(interface_name) + 1);
191 if (!interface_info->name) {
192 ACPI_FREE(interface_info);
193 return (AE_NO_MEMORY);
194 }
195
196 /* Initialize new info and insert at the head of the global list */
197
198 ACPI_STRCPY(interface_info->name, interface_name);
199 interface_info->flags = ACPI_OSI_DYNAMIC;
200 interface_info->next = acpi_gbl_supported_interfaces;
201
202 acpi_gbl_supported_interfaces = interface_info;
203 return (AE_OK);
204}
205
206/*******************************************************************************
207 *
208 * FUNCTION: acpi_ut_remove_interface
209 *
210 * PARAMETERS: interface_name - The interface to remove
211 *
212 * RETURN: Status
213 *
214 * DESCRIPTION: Remove the interface from the global interface list.
215 * Caller MUST hold acpi_gbl_osi_mutex
216 *
217 ******************************************************************************/
218
219acpi_status acpi_ut_remove_interface(acpi_string interface_name)
220{
221 struct acpi_interface_info *previous_interface;
222 struct acpi_interface_info *next_interface;
223
224 previous_interface = next_interface = acpi_gbl_supported_interfaces;
225 while (next_interface) {
226 if (!ACPI_STRCMP(interface_name, next_interface->name)) {
227
228 /* Found: name is in either the static list or was added at runtime */
229
230 if (next_interface->flags & ACPI_OSI_DYNAMIC) {
231
232 /* Interface was added dynamically, remove and free it */
233
234 if (previous_interface == next_interface) {
235 acpi_gbl_supported_interfaces =
236 next_interface->next;
237 } else {
238 previous_interface->next =
239 next_interface->next;
240 }
241
242 ACPI_FREE(next_interface->name);
243 ACPI_FREE(next_interface);
244 } else {
245 /*
246 * Interface is in static list. If marked invalid, then it
247 * does not actually exist. Else, mark it invalid.
248 */
249 if (next_interface->flags & ACPI_OSI_INVALID) {
250 return (AE_NOT_EXIST);
251 }
252
253 next_interface->flags |= ACPI_OSI_INVALID;
254 }
255
256 return (AE_OK);
257 }
258
259 previous_interface = next_interface;
260 next_interface = next_interface->next;
261 }
262
263 /* Interface was not found */
264
265 return (AE_NOT_EXIST);
266}
267
268/*******************************************************************************
269 *
270 * FUNCTION: acpi_ut_get_interface
271 *
272 * PARAMETERS: interface_name - The interface to find
273 *
274 * RETURN: struct acpi_interface_info if found. NULL if not found.
275 *
276 * DESCRIPTION: Search for the specified interface name in the global list.
277 * Caller MUST hold acpi_gbl_osi_mutex
278 *
279 ******************************************************************************/
280
281struct acpi_interface_info *acpi_ut_get_interface(acpi_string interface_name)
282{
283 struct acpi_interface_info *next_interface;
284
285 next_interface = acpi_gbl_supported_interfaces;
286 while (next_interface) {
287 if (!ACPI_STRCMP(interface_name, next_interface->name)) {
288 return (next_interface);
289 }
290
291 next_interface = next_interface->next;
292 }
293
294 return (NULL);
295}
296
297/*******************************************************************************
298 *
299 * FUNCTION: acpi_ut_osi_implementation
300 *
301 * PARAMETERS: walk_state - Current walk state
302 *
303 * RETURN: Status
304 *
305 * DESCRIPTION: Implementation of the _OSI predefined control method. When
306 * an invocation of _OSI is encountered in the system AML,
307 * control is transferred to this function.
308 *
309 ******************************************************************************/
310
311acpi_status acpi_ut_osi_implementation(struct acpi_walk_state * walk_state)
312{
313 union acpi_operand_object *string_desc;
314 union acpi_operand_object *return_desc;
315 struct acpi_interface_info *interface_info;
316 acpi_interface_handler interface_handler;
317 u32 return_value;
318
319 ACPI_FUNCTION_TRACE(ut_osi_implementation);
320
321 /* Validate the string input argument (from the AML caller) */
322
323 string_desc = walk_state->arguments[0].object;
324 if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
325 return_ACPI_STATUS(AE_TYPE);
326 }
327
328 /* Create a return object */
329
330 return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER);
331 if (!return_desc) {
332 return_ACPI_STATUS(AE_NO_MEMORY);
333 }
334
335 /* Default return value is 0, NOT SUPPORTED */
336
337 return_value = 0;
338 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
339
340 /* Lookup the interface in the global _OSI list */
341
342 interface_info = acpi_ut_get_interface(string_desc->string.pointer);
343 if (interface_info && !(interface_info->flags & ACPI_OSI_INVALID)) {
344 /*
345 * The interface is supported.
346 * Update the osi_data if necessary. We keep track of the latest
347 * version of Windows that has been requested by the BIOS.
348 */
349 if (interface_info->value > acpi_gbl_osi_data) {
350 acpi_gbl_osi_data = interface_info->value;
351 }
352
353 return_value = ACPI_UINT32_MAX;
354 }
355
356 acpi_os_release_mutex(acpi_gbl_osi_mutex);
357
358 /*
359 * Invoke an optional _OSI interface handler. The host OS may wish
360 * to do some interface-specific handling. For example, warn about
361 * certain interfaces or override the true/false support value.
362 */
363 interface_handler = acpi_gbl_interface_handler;
364 if (interface_handler) {
365 return_value =
366 interface_handler(string_desc->string.pointer,
367 return_value);
368 }
369
370 ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO,
371 "ACPI: BIOS _OSI(\"%s\") is %ssupported\n",
372 string_desc->string.pointer,
373 return_value == 0 ? "not " : ""));
374
375 /* Complete the return object */
376
377 return_desc->integer.value = return_value;
378 walk_state->return_desc = return_desc;
379 return_ACPI_STATUS(AE_OK);
380}
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
index 7965919000b1..6ffd3a8bdaa5 100644
--- a/drivers/acpi/acpica/utresrc.c
+++ b/drivers/acpi/acpica/utresrc.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("utresrc")
50#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER) 50#if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
51/* 51/*
52 * Strings used to decode resource descriptors. 52 * Strings used to decode resource descriptors.
53 * Used by both the disasssembler and the debugger resource dump routines 53 * Used by both the disassembler and the debugger resource dump routines
54 */ 54 */
55const char *acpi_gbl_bm_decode[] = { 55const char *acpi_gbl_bm_decode[] = {
56 "NotBusMaster", 56 "NotBusMaster",
diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c
index d35d109b8da2..30c21e1a9360 100644
--- a/drivers/acpi/acpica/utstate.c
+++ b/drivers/acpi/acpica/utstate.c
@@ -5,7 +5,7 @@
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index 7f8cefcb2b32..98ad125e14ff 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2010, Intel Corp. 8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -110,6 +110,15 @@ acpi_status __init acpi_initialize_subsystem(void)
110 return_ACPI_STATUS(status); 110 return_ACPI_STATUS(status);
111 } 111 }
112 112
113 /* Initialize the global OSI interfaces list with the static names */
114
115 status = acpi_ut_initialize_interfaces();
116 if (ACPI_FAILURE(status)) {
117 ACPI_EXCEPTION((AE_INFO, status,
118 "During OSI interfaces initialization"));
119 return_ACPI_STATUS(status);
120 }
121
113 /* If configured, initialize the AML debugger */ 122 /* If configured, initialize the AML debugger */
114 123
115 ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); 124 ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
@@ -290,19 +299,6 @@ acpi_status acpi_initialize_objects(u32 flags)
290 } 299 }
291 300
292 /* 301 /*
293 * Complete the GPE initialization for the GPE blocks defined in the FADT
294 * (GPE block 0 and 1).
295 *
296 * NOTE: Currently, there seems to be no need to run the _REG methods
297 * before enabling the GPEs.
298 */
299 if (!(flags & ACPI_NO_EVENT_INIT)) {
300 status = acpi_ev_install_fadt_gpes();
301 if (ACPI_FAILURE(status))
302 return (status);
303 }
304
305 /*
306 * Empty the caches (delete the cached objects) on the assumption that 302 * Empty the caches (delete the cached objects) on the assumption that
307 * the table load filled them up more than they will be at runtime -- 303 * the table load filled them up more than they will be at runtime --
308 * thus wasting non-paged memory. 304 * thus wasting non-paged memory.
@@ -506,6 +502,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function)
506 502
507ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) 503ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler)
508#endif /* ACPI_FUTURE_USAGE */ 504#endif /* ACPI_FUTURE_USAGE */
505
509/***************************************************************************** 506/*****************************************************************************
510 * 507 *
511 * FUNCTION: acpi_purge_cached_objects 508 * FUNCTION: acpi_purge_cached_objects
@@ -529,4 +526,117 @@ acpi_status acpi_purge_cached_objects(void)
529} 526}
530 527
531ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) 528ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects)
532#endif 529
530/*****************************************************************************
531 *
532 * FUNCTION: acpi_install_interface
533 *
534 * PARAMETERS: interface_name - The interface to install
535 *
536 * RETURN: Status
537 *
538 * DESCRIPTION: Install an _OSI interface to the global list
539 *
540 ****************************************************************************/
541acpi_status acpi_install_interface(acpi_string interface_name)
542{
543 acpi_status status;
544 struct acpi_interface_info *interface_info;
545
546 /* Parameter validation */
547
548 if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) {
549 return (AE_BAD_PARAMETER);
550 }
551
552 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
553
554 /* Check if the interface name is already in the global list */
555
556 interface_info = acpi_ut_get_interface(interface_name);
557 if (interface_info) {
558 /*
559 * The interface already exists in the list. This is OK if the
560 * interface has been marked invalid -- just clear the bit.
561 */
562 if (interface_info->flags & ACPI_OSI_INVALID) {
563 interface_info->flags &= ~ACPI_OSI_INVALID;
564 status = AE_OK;
565 } else {
566 status = AE_ALREADY_EXISTS;
567 }
568 } else {
569 /* New interface name, install into the global list */
570
571 status = acpi_ut_install_interface(interface_name);
572 }
573
574 acpi_os_release_mutex(acpi_gbl_osi_mutex);
575 return (status);
576}
577
578ACPI_EXPORT_SYMBOL(acpi_install_interface)
579
580/*****************************************************************************
581 *
582 * FUNCTION: acpi_remove_interface
583 *
584 * PARAMETERS: interface_name - The interface to remove
585 *
586 * RETURN: Status
587 *
588 * DESCRIPTION: Remove an _OSI interface from the global list
589 *
590 ****************************************************************************/
591acpi_status acpi_remove_interface(acpi_string interface_name)
592{
593 acpi_status status;
594
595 /* Parameter validation */
596
597 if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) {
598 return (AE_BAD_PARAMETER);
599 }
600
601 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
602
603 status = acpi_ut_remove_interface(interface_name);
604
605 acpi_os_release_mutex(acpi_gbl_osi_mutex);
606 return (status);
607}
608
609ACPI_EXPORT_SYMBOL(acpi_remove_interface)
610
611/*****************************************************************************
612 *
613 * FUNCTION: acpi_install_interface_handler
614 *
615 * PARAMETERS: Handler - The _OSI interface handler to install
616 * NULL means "remove existing handler"
617 *
618 * RETURN: Status
619 *
620 * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
621 * invoked during execution of the internal implementation of
622 * _OSI. A NULL handler simply removes any existing handler.
623 *
624 ****************************************************************************/
625acpi_status acpi_install_interface_handler(acpi_interface_handler handler)
626{
627 acpi_status status = AE_OK;
628
629 (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
630
631 if (handler && acpi_gbl_interface_handler) {
632 status = AE_ALREADY_EXISTS;
633 } else {
634 acpi_gbl_interface_handler = handler;
635 }
636
637 acpi_os_release_mutex(acpi_gbl_osi_mutex);
638 return (status);
639}
640
641ACPI_EXPORT_SYMBOL(acpi_install_interface_handler)
642#endif /* !ACPI_ASL_COMPILER */
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c
new file mode 100644
index 000000000000..916ae097c43c
--- /dev/null
+++ b/drivers/acpi/acpica/utxferror.c
@@ -0,0 +1,415 @@
1/*******************************************************************************
2 *
3 * Module Name: utxferror - Various error/warning output functions
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acnamesp.h"
47
48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utxferror")
50
51/*
52 * This module is used for the in-kernel ACPICA as well as the ACPICA
53 * tools/applications.
54 *
55 * For the i_aSL compiler case, the output is redirected to stderr so that
56 * any of the various ACPI errors and warnings do not appear in the output
57 * files, for either the compiler or disassembler portions of the tool.
58 */
59#ifdef ACPI_ASL_COMPILER
60#include <stdio.h>
61extern FILE *acpi_gbl_output_file;
62
63#define ACPI_MSG_REDIRECT_BEGIN \
64 FILE *output_file = acpi_gbl_output_file; \
65 acpi_os_redirect_output (stderr);
66
67#define ACPI_MSG_REDIRECT_END \
68 acpi_os_redirect_output (output_file);
69
70#else
71/*
72 * non-i_aSL case - no redirection, nothing to do
73 */
74#define ACPI_MSG_REDIRECT_BEGIN
75#define ACPI_MSG_REDIRECT_END
76#endif
77/*
78 * Common message prefixes
79 */
80#define ACPI_MSG_ERROR "ACPI Error: "
81#define ACPI_MSG_EXCEPTION "ACPI Exception: "
82#define ACPI_MSG_WARNING "ACPI Warning: "
83#define ACPI_MSG_INFO "ACPI: "
84/*
85 * Common message suffix
86 */
87#define ACPI_MSG_SUFFIX \
88 acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
89/*******************************************************************************
90 *
91 * FUNCTION: acpi_error
92 *
93 * PARAMETERS: module_name - Caller's module name (for error output)
94 * line_number - Caller's line number (for error output)
95 * Format - Printf format string + additional args
96 *
97 * RETURN: None
98 *
99 * DESCRIPTION: Print "ACPI Error" message with module/line/version info
100 *
101 ******************************************************************************/
102void ACPI_INTERNAL_VAR_XFACE
103acpi_error(const char *module_name, u32 line_number, const char *format, ...)
104{
105 va_list arg_list;
106
107 ACPI_MSG_REDIRECT_BEGIN;
108 acpi_os_printf(ACPI_MSG_ERROR);
109
110 va_start(arg_list, format);
111 acpi_os_vprintf(format, arg_list);
112 ACPI_MSG_SUFFIX;
113 va_end(arg_list);
114
115 ACPI_MSG_REDIRECT_END;
116}
117
118ACPI_EXPORT_SYMBOL(acpi_error)
119
120/*******************************************************************************
121 *
122 * FUNCTION: acpi_exception
123 *
124 * PARAMETERS: module_name - Caller's module name (for error output)
125 * line_number - Caller's line number (for error output)
126 * Status - Status to be formatted
127 * Format - Printf format string + additional args
128 *
129 * RETURN: None
130 *
131 * DESCRIPTION: Print "ACPI Exception" message with module/line/version info
132 * and decoded acpi_status.
133 *
134 ******************************************************************************/
135void ACPI_INTERNAL_VAR_XFACE
136acpi_exception(const char *module_name,
137 u32 line_number, acpi_status status, const char *format, ...)
138{
139 va_list arg_list;
140
141 ACPI_MSG_REDIRECT_BEGIN;
142 acpi_os_printf(ACPI_MSG_EXCEPTION "%s, ",
143 acpi_format_exception(status));
144
145 va_start(arg_list, format);
146 acpi_os_vprintf(format, arg_list);
147 ACPI_MSG_SUFFIX;
148 va_end(arg_list);
149
150 ACPI_MSG_REDIRECT_END;
151}
152
153ACPI_EXPORT_SYMBOL(acpi_exception)
154
155/*******************************************************************************
156 *
157 * FUNCTION: acpi_warning
158 *
159 * PARAMETERS: module_name - Caller's module name (for error output)
160 * line_number - Caller's line number (for error output)
161 * Format - Printf format string + additional args
162 *
163 * RETURN: None
164 *
165 * DESCRIPTION: Print "ACPI Warning" message with module/line/version info
166 *
167 ******************************************************************************/
168void ACPI_INTERNAL_VAR_XFACE
169acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
170{
171 va_list arg_list;
172
173 ACPI_MSG_REDIRECT_BEGIN;
174 acpi_os_printf(ACPI_MSG_WARNING);
175
176 va_start(arg_list, format);
177 acpi_os_vprintf(format, arg_list);
178 ACPI_MSG_SUFFIX;
179 va_end(arg_list);
180
181 ACPI_MSG_REDIRECT_END;
182}
183
184ACPI_EXPORT_SYMBOL(acpi_warning)
185
186/*******************************************************************************
187 *
188 * FUNCTION: acpi_info
189 *
190 * PARAMETERS: module_name - Caller's module name (for error output)
191 * line_number - Caller's line number (for error output)
192 * Format - Printf format string + additional args
193 *
194 * RETURN: None
195 *
196 * DESCRIPTION: Print generic "ACPI:" information message. There is no
197 * module/line/version info in order to keep the message simple.
198 *
199 * TBD: module_name and line_number args are not needed, should be removed.
200 *
201 ******************************************************************************/
202void ACPI_INTERNAL_VAR_XFACE
203acpi_info(const char *module_name, u32 line_number, const char *format, ...)
204{
205 va_list arg_list;
206
207 ACPI_MSG_REDIRECT_BEGIN;
208 acpi_os_printf(ACPI_MSG_INFO);
209
210 va_start(arg_list, format);
211 acpi_os_vprintf(format, arg_list);
212 acpi_os_printf("\n");
213 va_end(arg_list);
214
215 ACPI_MSG_REDIRECT_END;
216}
217
218ACPI_EXPORT_SYMBOL(acpi_info)
219
220/*
221 * The remainder of this module contains internal error functions that may
222 * be configured out.
223 */
224#if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP)
225/*******************************************************************************
226 *
227 * FUNCTION: acpi_ut_predefined_warning
228 *
229 * PARAMETERS: module_name - Caller's module name (for error output)
230 * line_number - Caller's line number (for error output)
231 * Pathname - Full pathname to the node
232 * node_flags - From Namespace node for the method/object
233 * Format - Printf format string + additional args
234 *
235 * RETURN: None
236 *
237 * DESCRIPTION: Warnings for the predefined validation module. Messages are
238 * only emitted the first time a problem with a particular
239 * method/object is detected. This prevents a flood of error
240 * messages for methods that are repeatedly evaluated.
241 *
242 ******************************************************************************/
243void ACPI_INTERNAL_VAR_XFACE
244acpi_ut_predefined_warning(const char *module_name,
245 u32 line_number,
246 char *pathname,
247 u8 node_flags, const char *format, ...)
248{
249 va_list arg_list;
250
251 /*
252 * Warning messages for this method/object will be disabled after the
253 * first time a validation fails or an object is successfully repaired.
254 */
255 if (node_flags & ANOBJ_EVALUATED) {
256 return;
257 }
258
259 acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname);
260
261 va_start(arg_list, format);
262 acpi_os_vprintf(format, arg_list);
263 ACPI_MSG_SUFFIX;
264 va_end(arg_list);
265}
266
267/*******************************************************************************
268 *
269 * FUNCTION: acpi_ut_predefined_info
270 *
271 * PARAMETERS: module_name - Caller's module name (for error output)
272 * line_number - Caller's line number (for error output)
273 * Pathname - Full pathname to the node
274 * node_flags - From Namespace node for the method/object
275 * Format - Printf format string + additional args
276 *
277 * RETURN: None
278 *
279 * DESCRIPTION: Info messages for the predefined validation module. Messages
280 * are only emitted the first time a problem with a particular
281 * method/object is detected. This prevents a flood of
282 * messages for methods that are repeatedly evaluated.
283 *
284 ******************************************************************************/
285
286void ACPI_INTERNAL_VAR_XFACE
287acpi_ut_predefined_info(const char *module_name,
288 u32 line_number,
289 char *pathname, u8 node_flags, const char *format, ...)
290{
291 va_list arg_list;
292
293 /*
294 * Warning messages for this method/object will be disabled after the
295 * first time a validation fails or an object is successfully repaired.
296 */
297 if (node_flags & ANOBJ_EVALUATED) {
298 return;
299 }
300
301 acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname);
302
303 va_start(arg_list, format);
304 acpi_os_vprintf(format, arg_list);
305 ACPI_MSG_SUFFIX;
306 va_end(arg_list);
307}
308
309/*******************************************************************************
310 *
311 * FUNCTION: acpi_ut_namespace_error
312 *
313 * PARAMETERS: module_name - Caller's module name (for error output)
314 * line_number - Caller's line number (for error output)
315 * internal_name - Name or path of the namespace node
316 * lookup_status - Exception code from NS lookup
317 *
318 * RETURN: None
319 *
320 * DESCRIPTION: Print error message with the full pathname for the NS node.
321 *
322 ******************************************************************************/
323
324void
325acpi_ut_namespace_error(const char *module_name,
326 u32 line_number,
327 const char *internal_name, acpi_status lookup_status)
328{
329 acpi_status status;
330 u32 bad_name;
331 char *name = NULL;
332
333 ACPI_MSG_REDIRECT_BEGIN;
334 acpi_os_printf(ACPI_MSG_ERROR);
335
336 if (lookup_status == AE_BAD_CHARACTER) {
337
338 /* There is a non-ascii character in the name */
339
340 ACPI_MOVE_32_TO_32(&bad_name,
341 ACPI_CAST_PTR(u32, internal_name));
342 acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name);
343 } else {
344 /* Convert path to external format */
345
346 status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
347 internal_name, NULL, &name);
348
349 /* Print target name */
350
351 if (ACPI_SUCCESS(status)) {
352 acpi_os_printf("[%s]", name);
353 } else {
354 acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
355 }
356
357 if (name) {
358 ACPI_FREE(name);
359 }
360 }
361
362 acpi_os_printf(" Namespace lookup failure, %s",
363 acpi_format_exception(lookup_status));
364
365 ACPI_MSG_SUFFIX;
366 ACPI_MSG_REDIRECT_END;
367}
368
369/*******************************************************************************
370 *
371 * FUNCTION: acpi_ut_method_error
372 *
373 * PARAMETERS: module_name - Caller's module name (for error output)
374 * line_number - Caller's line number (for error output)
375 * Message - Error message to use on failure
376 * prefix_node - Prefix relative to the path
377 * Path - Path to the node (optional)
378 * method_status - Execution status
379 *
380 * RETURN: None
381 *
382 * DESCRIPTION: Print error message with the full pathname for the method.
383 *
384 ******************************************************************************/
385
386void
387acpi_ut_method_error(const char *module_name,
388 u32 line_number,
389 const char *message,
390 struct acpi_namespace_node *prefix_node,
391 const char *path, acpi_status method_status)
392{
393 acpi_status status;
394 struct acpi_namespace_node *node = prefix_node;
395
396 ACPI_MSG_REDIRECT_BEGIN;
397 acpi_os_printf(ACPI_MSG_ERROR);
398
399 if (path) {
400 status =
401 acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
402 &node);
403 if (ACPI_FAILURE(status)) {
404 acpi_os_printf("[Could not get node by pathname]");
405 }
406 }
407
408 acpi_ns_print_node_pathname(node, message);
409 acpi_os_printf(", %s", acpi_format_exception(method_status));
410
411 ACPI_MSG_SUFFIX;
412 ACPI_MSG_REDIRECT_END;
413}
414
415#endif /* ACPI_NO_ERROR_MESSAGES */
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index fca34ccfd294..f739a70b1c70 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -1,5 +1,7 @@
1config ACPI_APEI 1config ACPI_APEI
2 bool "ACPI Platform Error Interface (APEI)" 2 bool "ACPI Platform Error Interface (APEI)"
3 select MISC_FILESYSTEMS
4 select PSTORE
3 depends on X86 5 depends on X86
4 help 6 help
5 APEI allows to report errors (for example from the chipset) 7 APEI allows to report errors (for example from the chipset)
@@ -21,6 +23,13 @@ config ACPI_APEI_GHES
21 by firmware to produce more valuable hardware error 23 by firmware to produce more valuable hardware error
22 information for Linux. 24 information for Linux.
23 25
26config ACPI_APEI_PCIEAER
27 bool "APEI PCIe AER logging/recovering support"
28 depends on ACPI_APEI && PCIEAER
29 help
30 PCIe AER errors may be reported via APEI firmware first mode.
31 Turn on this option to enable the corresponding support.
32
24config ACPI_APEI_EINJ 33config ACPI_APEI_EINJ
25 tristate "APEI Error INJection (EINJ)" 34 tristate "APEI Error INJection (EINJ)"
26 depends on ACPI_APEI && DEBUG_FS 35 depends on ACPI_APEI && DEBUG_FS
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index 18df1e940276..ef0581f2094d 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
109 return sizeof(*estatus) + estatus->data_length; 109 return sizeof(*estatus) + estatus->data_length;
110} 110}
111 111
112void apei_estatus_print(const char *pfx,
113 const struct acpi_hest_generic_status *estatus);
112int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); 114int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus);
113int apei_estatus_check(const struct acpi_hest_generic_status *estatus); 115int apei_estatus_check(const struct acpi_hest_generic_status *estatus);
114#endif 116#endif
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
index f4cf2fc4c8c1..5d4189464d63 100644
--- a/drivers/acpi/apei/cper.c
+++ b/drivers/acpi/apei/cper.c
@@ -29,6 +29,7 @@
29#include <linux/time.h> 29#include <linux/time.h>
30#include <linux/cper.h> 30#include <linux/cper.h>
31#include <linux/acpi.h> 31#include <linux/acpi.h>
32#include <linux/aer.h>
32 33
33/* 34/*
34 * CPER record ID need to be unique even after reboot, because record 35 * CPER record ID need to be unique even after reboot, because record
@@ -46,6 +47,326 @@ u64 cper_next_record_id(void)
46} 47}
47EXPORT_SYMBOL_GPL(cper_next_record_id); 48EXPORT_SYMBOL_GPL(cper_next_record_id);
48 49
50static const char *cper_severity_strs[] = {
51 "recoverable",
52 "fatal",
53 "corrected",
54 "info",
55};
56
57static const char *cper_severity_str(unsigned int severity)
58{
59 return severity < ARRAY_SIZE(cper_severity_strs) ?
60 cper_severity_strs[severity] : "unknown";
61}
62
63/*
64 * cper_print_bits - print strings for set bits
65 * @pfx: prefix for each line, including log level and prefix string
66 * @bits: bit mask
67 * @strs: string array, indexed by bit position
68 * @strs_size: size of the string array: @strs
69 *
70 * For each set bit in @bits, print the corresponding string in @strs.
71 * If the output length is longer than 80, multiple line will be
72 * printed, with @pfx is printed at the beginning of each line.
73 */
74void cper_print_bits(const char *pfx, unsigned int bits,
75 const char *strs[], unsigned int strs_size)
76{
77 int i, len = 0;
78 const char *str;
79 char buf[84];
80
81 for (i = 0; i < strs_size; i++) {
82 if (!(bits & (1U << i)))
83 continue;
84 str = strs[i];
85 if (!str)
86 continue;
87 if (len && len + strlen(str) + 2 > 80) {
88 printk("%s\n", buf);
89 len = 0;
90 }
91 if (!len)
92 len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
93 else
94 len += snprintf(buf+len, sizeof(buf)-len, ", %s", str);
95 }
96 if (len)
97 printk("%s\n", buf);
98}
99
100static const char *cper_proc_type_strs[] = {
101 "IA32/X64",
102 "IA64",
103};
104
105static const char *cper_proc_isa_strs[] = {
106 "IA32",
107 "IA64",
108 "X64",
109};
110
111static const char *cper_proc_error_type_strs[] = {
112 "cache error",
113 "TLB error",
114 "bus error",
115 "micro-architectural error",
116};
117
118static const char *cper_proc_op_strs[] = {
119 "unknown or generic",
120 "data read",
121 "data write",
122 "instruction execution",
123};
124
125static const char *cper_proc_flag_strs[] = {
126 "restartable",
127 "precise IP",
128 "overflow",
129 "corrected",
130};
131
132static void cper_print_proc_generic(const char *pfx,
133 const struct cper_sec_proc_generic *proc)
134{
135 if (proc->validation_bits & CPER_PROC_VALID_TYPE)
136 printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type,
137 proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ?
138 cper_proc_type_strs[proc->proc_type] : "unknown");
139 if (proc->validation_bits & CPER_PROC_VALID_ISA)
140 printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa,
141 proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ?
142 cper_proc_isa_strs[proc->proc_isa] : "unknown");
143 if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
144 printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type);
145 cper_print_bits(pfx, proc->proc_error_type,
146 cper_proc_error_type_strs,
147 ARRAY_SIZE(cper_proc_error_type_strs));
148 }
149 if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
150 printk("%s""operation: %d, %s\n", pfx, proc->operation,
151 proc->operation < ARRAY_SIZE(cper_proc_op_strs) ?
152 cper_proc_op_strs[proc->operation] : "unknown");
153 if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
154 printk("%s""flags: 0x%02x\n", pfx, proc->flags);
155 cper_print_bits(pfx, proc->flags, cper_proc_flag_strs,
156 ARRAY_SIZE(cper_proc_flag_strs));
157 }
158 if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
159 printk("%s""level: %d\n", pfx, proc->level);
160 if (proc->validation_bits & CPER_PROC_VALID_VERSION)
161 printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version);
162 if (proc->validation_bits & CPER_PROC_VALID_ID)
163 printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id);
164 if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS)
165 printk("%s""target_address: 0x%016llx\n",
166 pfx, proc->target_addr);
167 if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID)
168 printk("%s""requestor_id: 0x%016llx\n",
169 pfx, proc->requestor_id);
170 if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID)
171 printk("%s""responder_id: 0x%016llx\n",
172 pfx, proc->responder_id);
173 if (proc->validation_bits & CPER_PROC_VALID_IP)
174 printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
175}
176
177static const char *cper_mem_err_type_strs[] = {
178 "unknown",
179 "no error",
180 "single-bit ECC",
181 "multi-bit ECC",
182 "single-symbol chipkill ECC",
183 "multi-symbol chipkill ECC",
184 "master abort",
185 "target abort",
186 "parity error",
187 "watchdog timeout",
188 "invalid address",
189 "mirror Broken",
190 "memory sparing",
191 "scrub corrected error",
192 "scrub uncorrected error",
193};
194
195static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
196{
197 if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
198 printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
199 if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)
200 printk("%s""physical_address: 0x%016llx\n",
201 pfx, mem->physical_addr);
202 if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK)
203 printk("%s""physical_address_mask: 0x%016llx\n",
204 pfx, mem->physical_addr_mask);
205 if (mem->validation_bits & CPER_MEM_VALID_NODE)
206 printk("%s""node: %d\n", pfx, mem->node);
207 if (mem->validation_bits & CPER_MEM_VALID_CARD)
208 printk("%s""card: %d\n", pfx, mem->card);
209 if (mem->validation_bits & CPER_MEM_VALID_MODULE)
210 printk("%s""module: %d\n", pfx, mem->module);
211 if (mem->validation_bits & CPER_MEM_VALID_BANK)
212 printk("%s""bank: %d\n", pfx, mem->bank);
213 if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
214 printk("%s""device: %d\n", pfx, mem->device);
215 if (mem->validation_bits & CPER_MEM_VALID_ROW)
216 printk("%s""row: %d\n", pfx, mem->row);
217 if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
218 printk("%s""column: %d\n", pfx, mem->column);
219 if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
220 printk("%s""bit_position: %d\n", pfx, mem->bit_pos);
221 if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
222 printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id);
223 if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
224 printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id);
225 if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
226 printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id);
227 if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
228 u8 etype = mem->error_type;
229 printk("%s""error_type: %d, %s\n", pfx, etype,
230 etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
231 cper_mem_err_type_strs[etype] : "unknown");
232 }
233}
234
235static const char *cper_pcie_port_type_strs[] = {
236 "PCIe end point",
237 "legacy PCI end point",
238 "unknown",
239 "unknown",
240 "root port",
241 "upstream switch port",
242 "downstream switch port",
243 "PCIe to PCI/PCI-X bridge",
244 "PCI/PCI-X to PCIe bridge",
245 "root complex integrated endpoint device",
246 "root complex event collector",
247};
248
249static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
250 const struct acpi_hest_generic_data *gdata)
251{
252 if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
253 printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
254 pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
255 cper_pcie_port_type_strs[pcie->port_type] : "unknown");
256 if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
257 printk("%s""version: %d.%d\n", pfx,
258 pcie->version.major, pcie->version.minor);
259 if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS)
260 printk("%s""command: 0x%04x, status: 0x%04x\n", pfx,
261 pcie->command, pcie->status);
262 if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) {
263 const __u8 *p;
264 printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx,
265 pcie->device_id.segment, pcie->device_id.bus,
266 pcie->device_id.device, pcie->device_id.function);
267 printk("%s""slot: %d\n", pfx,
268 pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
269 printk("%s""secondary_bus: 0x%02x\n", pfx,
270 pcie->device_id.secondary_bus);
271 printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
272 pcie->device_id.vendor_id, pcie->device_id.device_id);
273 p = pcie->device_id.class_code;
274 printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]);
275 }
276 if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
277 printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
278 pcie->serial_number.lower, pcie->serial_number.upper);
279 if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS)
280 printk(
281 "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
282 pfx, pcie->bridge.secondary_status, pcie->bridge.control);
283#ifdef CONFIG_ACPI_APEI_PCIEAER
284 if (pcie->validation_bits & CPER_PCIE_VALID_AER_INFO) {
285 struct aer_capability_regs *aer_regs = (void *)pcie->aer_info;
286 cper_print_aer(pfx, gdata->error_severity, aer_regs);
287 }
288#endif
289}
290
291static const char *apei_estatus_section_flag_strs[] = {
292 "primary",
293 "containment warning",
294 "reset",
295 "threshold exceeded",
296 "resource not accessible",
297 "latent error",
298};
299
300static void apei_estatus_print_section(
301 const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
302{
303 uuid_le *sec_type = (uuid_le *)gdata->section_type;
304 __u16 severity;
305
306 severity = gdata->error_severity;
307 printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity,
308 cper_severity_str(severity));
309 printk("%s""flags: 0x%02x\n", pfx, gdata->flags);
310 cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs,
311 ARRAY_SIZE(apei_estatus_section_flag_strs));
312 if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
313 printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
314 if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
315 printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);
316
317 if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
318 struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
319 printk("%s""section_type: general processor error\n", pfx);
320 if (gdata->error_data_length >= sizeof(*proc_err))
321 cper_print_proc_generic(pfx, proc_err);
322 else
323 goto err_section_too_small;
324 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
325 struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
326 printk("%s""section_type: memory error\n", pfx);
327 if (gdata->error_data_length >= sizeof(*mem_err))
328 cper_print_mem(pfx, mem_err);
329 else
330 goto err_section_too_small;
331 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
332 struct cper_sec_pcie *pcie = (void *)(gdata + 1);
333 printk("%s""section_type: PCIe error\n", pfx);
334 if (gdata->error_data_length >= sizeof(*pcie))
335 cper_print_pcie(pfx, pcie, gdata);
336 else
337 goto err_section_too_small;
338 } else
339 printk("%s""section type: unknown, %pUl\n", pfx, sec_type);
340
341 return;
342
343err_section_too_small:
344 pr_err(FW_WARN "error section length is too small\n");
345}
346
347void apei_estatus_print(const char *pfx,
348 const struct acpi_hest_generic_status *estatus)
349{
350 struct acpi_hest_generic_data *gdata;
351 unsigned int data_len, gedata_len;
352 int sec_no = 0;
353 __u16 severity;
354
355 printk("%s""APEI generic hardware error status\n", pfx);
356 severity = estatus->error_severity;
357 printk("%s""severity: %d, %s\n", pfx, severity,
358 cper_severity_str(severity));
359 data_len = estatus->data_length;
360 gdata = (struct acpi_hest_generic_data *)(estatus + 1);
361 while (data_len > sizeof(*gdata)) {
362 gedata_len = gdata->error_data_length;
363 apei_estatus_print_section(pfx, gdata, sec_no);
364 data_len -= gedata_len + sizeof(*gdata);
365 sec_no++;
366 }
367}
368EXPORT_SYMBOL_GPL(apei_estatus_print);
369
49int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) 370int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
50{ 371{
51 if (estatus->data_length && 372 if (estatus->data_length &&
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index cf29df69380b..f74b2ea11f21 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -39,7 +39,7 @@
39#define EINJ_PFX "EINJ: " 39#define EINJ_PFX "EINJ: "
40 40
41#define SPIN_UNIT 100 /* 100ns */ 41#define SPIN_UNIT 100 /* 100ns */
42/* Firmware should respond within 1 miliseconds */ 42/* Firmware should respond within 1 milliseconds */
43#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) 43#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC)
44 44
45/* 45/*
@@ -101,6 +101,14 @@ static DEFINE_MUTEX(einj_mutex);
101 101
102static struct einj_parameter *einj_param; 102static struct einj_parameter *einj_param;
103 103
104#ifndef writeq
105static inline void writeq(__u64 val, volatile void __iomem *addr)
106{
107 writel(val, addr);
108 writel(val >> 32, addr+4);
109}
110#endif
111
104static void einj_exec_ctx_init(struct apei_exec_context *ctx) 112static void einj_exec_ctx_init(struct apei_exec_context *ctx)
105{ 113{
106 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), 114 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c
index da1228a9a544..a4cfb64c86a1 100644
--- a/drivers/acpi/apei/erst-dbg.c
+++ b/drivers/acpi/apei/erst-dbg.c
@@ -43,12 +43,27 @@ static DEFINE_MUTEX(erst_dbg_mutex);
43 43
44static int erst_dbg_open(struct inode *inode, struct file *file) 44static int erst_dbg_open(struct inode *inode, struct file *file)
45{ 45{
46 int rc, *pos;
47
46 if (erst_disable) 48 if (erst_disable)
47 return -ENODEV; 49 return -ENODEV;
48 50
51 pos = (int *)&file->private_data;
52
53 rc = erst_get_record_id_begin(pos);
54 if (rc)
55 return rc;
56
49 return nonseekable_open(inode, file); 57 return nonseekable_open(inode, file);
50} 58}
51 59
60static int erst_dbg_release(struct inode *inode, struct file *file)
61{
62 erst_get_record_id_end();
63
64 return 0;
65}
66
52static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 67static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
53{ 68{
54 int rc; 69 int rc;
@@ -79,18 +94,20 @@ static long erst_dbg_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
79static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf, 94static ssize_t erst_dbg_read(struct file *filp, char __user *ubuf,
80 size_t usize, loff_t *off) 95 size_t usize, loff_t *off)
81{ 96{
82 int rc; 97 int rc, *pos;
83 ssize_t len = 0; 98 ssize_t len = 0;
84 u64 id; 99 u64 id;
85 100
86 if (*off != 0) 101 if (*off)
87 return -EINVAL; 102 return -EINVAL;
88 103
89 if (mutex_lock_interruptible(&erst_dbg_mutex) != 0) 104 if (mutex_lock_interruptible(&erst_dbg_mutex) != 0)
90 return -EINTR; 105 return -EINTR;
91 106
107 pos = (int *)&filp->private_data;
108
92retry_next: 109retry_next:
93 rc = erst_get_next_record_id(&id); 110 rc = erst_get_record_id_next(pos, &id);
94 if (rc) 111 if (rc)
95 goto out; 112 goto out;
96 /* no more record */ 113 /* no more record */
@@ -181,9 +198,11 @@ out:
181static const struct file_operations erst_dbg_ops = { 198static const struct file_operations erst_dbg_ops = {
182 .owner = THIS_MODULE, 199 .owner = THIS_MODULE,
183 .open = erst_dbg_open, 200 .open = erst_dbg_open,
201 .release = erst_dbg_release,
184 .read = erst_dbg_read, 202 .read = erst_dbg_read,
185 .write = erst_dbg_write, 203 .write = erst_dbg_write,
186 .unlocked_ioctl = erst_dbg_ioctl, 204 .unlocked_ioctl = erst_dbg_ioctl,
205 .llseek = no_llseek,
187}; 206};
188 207
189static struct miscdevice erst_dbg_dev = { 208static struct miscdevice erst_dbg_dev = {
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 1211c03149e8..e6cef8e1b534 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -34,6 +34,7 @@
34#include <linux/cper.h> 34#include <linux/cper.h>
35#include <linux/nmi.h> 35#include <linux/nmi.h>
36#include <linux/hardirq.h> 36#include <linux/hardirq.h>
37#include <linux/pstore.h>
37#include <acpi/apei.h> 38#include <acpi/apei.h>
38 39
39#include "apei-internal.h" 40#include "apei-internal.h"
@@ -53,7 +54,7 @@
53 sizeof(struct acpi_table_erst))) 54 sizeof(struct acpi_table_erst)))
54 55
55#define SPIN_UNIT 100 /* 100ns */ 56#define SPIN_UNIT 100 /* 100ns */
56/* Firmware should respond within 1 miliseconds */ 57/* Firmware should respond within 1 milliseconds */
57#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC) 58#define FIRMWARE_TIMEOUT (1 * NSEC_PER_MSEC)
58#define FIRMWARE_MAX_STALL 50 /* 50us */ 59#define FIRMWARE_MAX_STALL 50 /* 50us */
59 60
@@ -86,7 +87,7 @@ static struct erst_erange {
86 * It is used to provide exclusive accessing for ERST Error Log 87 * It is used to provide exclusive accessing for ERST Error Log
87 * Address Range too. 88 * Address Range too.
88 */ 89 */
89static DEFINE_SPINLOCK(erst_lock); 90static DEFINE_RAW_SPINLOCK(erst_lock);
90 91
91static inline int erst_errno(int command_status) 92static inline int erst_errno(int command_status)
92{ 93{
@@ -421,14 +422,30 @@ ssize_t erst_get_record_count(void)
421 if (erst_disable) 422 if (erst_disable)
422 return -ENODEV; 423 return -ENODEV;
423 424
424 spin_lock_irqsave(&erst_lock, flags); 425 raw_spin_lock_irqsave(&erst_lock, flags);
425 count = __erst_get_record_count(); 426 count = __erst_get_record_count();
426 spin_unlock_irqrestore(&erst_lock, flags); 427 raw_spin_unlock_irqrestore(&erst_lock, flags);
427 428
428 return count; 429 return count;
429} 430}
430EXPORT_SYMBOL_GPL(erst_get_record_count); 431EXPORT_SYMBOL_GPL(erst_get_record_count);
431 432
433#define ERST_RECORD_ID_CACHE_SIZE_MIN 16
434#define ERST_RECORD_ID_CACHE_SIZE_MAX 1024
435
436struct erst_record_id_cache {
437 struct mutex lock;
438 u64 *entries;
439 int len;
440 int size;
441 int refcount;
442};
443
444static struct erst_record_id_cache erst_record_id_cache = {
445 .lock = __MUTEX_INITIALIZER(erst_record_id_cache.lock),
446 .refcount = 0,
447};
448
432static int __erst_get_next_record_id(u64 *record_id) 449static int __erst_get_next_record_id(u64 *record_id)
433{ 450{
434 struct apei_exec_context ctx; 451 struct apei_exec_context ctx;
@@ -443,26 +460,179 @@ static int __erst_get_next_record_id(u64 *record_id)
443 return 0; 460 return 0;
444} 461}
445 462
463int erst_get_record_id_begin(int *pos)
464{
465 int rc;
466
467 if (erst_disable)
468 return -ENODEV;
469
470 rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
471 if (rc)
472 return rc;
473 erst_record_id_cache.refcount++;
474 mutex_unlock(&erst_record_id_cache.lock);
475
476 *pos = 0;
477
478 return 0;
479}
480EXPORT_SYMBOL_GPL(erst_get_record_id_begin);
481
482/* erst_record_id_cache.lock must be held by caller */
483static int __erst_record_id_cache_add_one(void)
484{
485 u64 id, prev_id, first_id;
486 int i, rc;
487 u64 *entries;
488 unsigned long flags;
489
490 id = prev_id = first_id = APEI_ERST_INVALID_RECORD_ID;
491retry:
492 raw_spin_lock_irqsave(&erst_lock, flags);
493 rc = __erst_get_next_record_id(&id);
494 raw_spin_unlock_irqrestore(&erst_lock, flags);
495 if (rc == -ENOENT)
496 return 0;
497 if (rc)
498 return rc;
499 if (id == APEI_ERST_INVALID_RECORD_ID)
500 return 0;
501 /* can not skip current ID, or loop back to first ID */
502 if (id == prev_id || id == first_id)
503 return 0;
504 if (first_id == APEI_ERST_INVALID_RECORD_ID)
505 first_id = id;
506 prev_id = id;
507
508 entries = erst_record_id_cache.entries;
509 for (i = 0; i < erst_record_id_cache.len; i++) {
510 if (entries[i] == id)
511 break;
512 }
513 /* record id already in cache, try next */
514 if (i < erst_record_id_cache.len)
515 goto retry;
516 if (erst_record_id_cache.len >= erst_record_id_cache.size) {
517 int new_size, alloc_size;
518 u64 *new_entries;
519
520 new_size = erst_record_id_cache.size * 2;
521 new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN,
522 ERST_RECORD_ID_CACHE_SIZE_MAX);
523 if (new_size <= erst_record_id_cache.size) {
524 if (printk_ratelimit())
525 pr_warning(FW_WARN ERST_PFX
526 "too many record ID!\n");
527 return 0;
528 }
529 alloc_size = new_size * sizeof(entries[0]);
530 if (alloc_size < PAGE_SIZE)
531 new_entries = kmalloc(alloc_size, GFP_KERNEL);
532 else
533 new_entries = vmalloc(alloc_size);
534 if (!new_entries)
535 return -ENOMEM;
536 memcpy(new_entries, entries,
537 erst_record_id_cache.len * sizeof(entries[0]));
538 if (erst_record_id_cache.size < PAGE_SIZE)
539 kfree(entries);
540 else
541 vfree(entries);
542 erst_record_id_cache.entries = entries = new_entries;
543 erst_record_id_cache.size = new_size;
544 }
545 entries[i] = id;
546 erst_record_id_cache.len++;
547
548 return 1;
549}
550
446/* 551/*
447 * Get the record ID of an existing error record on the persistent 552 * Get the record ID of an existing error record on the persistent
448 * storage. If there is no error record on the persistent storage, the 553 * storage. If there is no error record on the persistent storage, the
449 * returned record_id is APEI_ERST_INVALID_RECORD_ID. 554 * returned record_id is APEI_ERST_INVALID_RECORD_ID.
450 */ 555 */
451int erst_get_next_record_id(u64 *record_id) 556int erst_get_record_id_next(int *pos, u64 *record_id)
452{ 557{
453 int rc; 558 int rc = 0;
454 unsigned long flags; 559 u64 *entries;
455 560
456 if (erst_disable) 561 if (erst_disable)
457 return -ENODEV; 562 return -ENODEV;
458 563
459 spin_lock_irqsave(&erst_lock, flags); 564 /* must be enclosed by erst_get_record_id_begin/end */
460 rc = __erst_get_next_record_id(record_id); 565 BUG_ON(!erst_record_id_cache.refcount);
461 spin_unlock_irqrestore(&erst_lock, flags); 566 BUG_ON(*pos < 0 || *pos > erst_record_id_cache.len);
567
568 mutex_lock(&erst_record_id_cache.lock);
569 entries = erst_record_id_cache.entries;
570 for (; *pos < erst_record_id_cache.len; (*pos)++)
571 if (entries[*pos] != APEI_ERST_INVALID_RECORD_ID)
572 break;
573 /* found next record id in cache */
574 if (*pos < erst_record_id_cache.len) {
575 *record_id = entries[*pos];
576 (*pos)++;
577 goto out_unlock;
578 }
579
580 /* Try to add one more record ID to cache */
581 rc = __erst_record_id_cache_add_one();
582 if (rc < 0)
583 goto out_unlock;
584 /* successfully add one new ID */
585 if (rc == 1) {
586 *record_id = erst_record_id_cache.entries[*pos];
587 (*pos)++;
588 rc = 0;
589 } else {
590 *pos = -1;
591 *record_id = APEI_ERST_INVALID_RECORD_ID;
592 }
593out_unlock:
594 mutex_unlock(&erst_record_id_cache.lock);
462 595
463 return rc; 596 return rc;
464} 597}
465EXPORT_SYMBOL_GPL(erst_get_next_record_id); 598EXPORT_SYMBOL_GPL(erst_get_record_id_next);
599
600/* erst_record_id_cache.lock must be held by caller */
601static void __erst_record_id_cache_compact(void)
602{
603 int i, wpos = 0;
604 u64 *entries;
605
606 if (erst_record_id_cache.refcount)
607 return;
608
609 entries = erst_record_id_cache.entries;
610 for (i = 0; i < erst_record_id_cache.len; i++) {
611 if (entries[i] == APEI_ERST_INVALID_RECORD_ID)
612 continue;
613 if (wpos != i)
614 memcpy(&entries[wpos], &entries[i], sizeof(entries[i]));
615 wpos++;
616 }
617 erst_record_id_cache.len = wpos;
618}
619
620void erst_get_record_id_end(void)
621{
622 /*
623 * erst_disable != 0 should be detected by invoker via the
624 * return value of erst_get_record_id_begin/next, so this
625 * function should not be called for erst_disable != 0.
626 */
627 BUG_ON(erst_disable);
628
629 mutex_lock(&erst_record_id_cache.lock);
630 erst_record_id_cache.refcount--;
631 BUG_ON(erst_record_id_cache.refcount < 0);
632 __erst_record_id_cache_compact();
633 mutex_unlock(&erst_record_id_cache.lock);
634}
635EXPORT_SYMBOL_GPL(erst_get_record_id_end);
466 636
467static int __erst_write_to_storage(u64 offset) 637static int __erst_write_to_storage(u64 offset)
468{ 638{
@@ -624,17 +794,17 @@ int erst_write(const struct cper_record_header *record)
624 return -EINVAL; 794 return -EINVAL;
625 795
626 if (erst_erange.attr & ERST_RANGE_NVRAM) { 796 if (erst_erange.attr & ERST_RANGE_NVRAM) {
627 if (!spin_trylock_irqsave(&erst_lock, flags)) 797 if (!raw_spin_trylock_irqsave(&erst_lock, flags))
628 return -EBUSY; 798 return -EBUSY;
629 rc = __erst_write_to_nvram(record); 799 rc = __erst_write_to_nvram(record);
630 spin_unlock_irqrestore(&erst_lock, flags); 800 raw_spin_unlock_irqrestore(&erst_lock, flags);
631 return rc; 801 return rc;
632 } 802 }
633 803
634 if (record->record_length > erst_erange.size) 804 if (record->record_length > erst_erange.size)
635 return -EINVAL; 805 return -EINVAL;
636 806
637 if (!spin_trylock_irqsave(&erst_lock, flags)) 807 if (!raw_spin_trylock_irqsave(&erst_lock, flags))
638 return -EBUSY; 808 return -EBUSY;
639 memcpy(erst_erange.vaddr, record, record->record_length); 809 memcpy(erst_erange.vaddr, record, record->record_length);
640 rcd_erange = erst_erange.vaddr; 810 rcd_erange = erst_erange.vaddr;
@@ -642,7 +812,7 @@ int erst_write(const struct cper_record_header *record)
642 memcpy(&rcd_erange->persistence_information, "ER", 2); 812 memcpy(&rcd_erange->persistence_information, "ER", 2);
643 813
644 rc = __erst_write_to_storage(0); 814 rc = __erst_write_to_storage(0);
645 spin_unlock_irqrestore(&erst_lock, flags); 815 raw_spin_unlock_irqrestore(&erst_lock, flags);
646 816
647 return rc; 817 return rc;
648} 818}
@@ -696,63 +866,41 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
696 if (erst_disable) 866 if (erst_disable)
697 return -ENODEV; 867 return -ENODEV;
698 868
699 spin_lock_irqsave(&erst_lock, flags); 869 raw_spin_lock_irqsave(&erst_lock, flags);
700 len = __erst_read(record_id, record, buflen); 870 len = __erst_read(record_id, record, buflen);
701 spin_unlock_irqrestore(&erst_lock, flags); 871 raw_spin_unlock_irqrestore(&erst_lock, flags);
702 return len; 872 return len;
703} 873}
704EXPORT_SYMBOL_GPL(erst_read); 874EXPORT_SYMBOL_GPL(erst_read);
705 875
706/*
707 * If return value > buflen, the buffer size is not big enough,
708 * else if return value = 0, there is no more record to read,
709 * else if return value < 0, something goes wrong,
710 * else everything is OK, and return value is record length
711 */
712ssize_t erst_read_next(struct cper_record_header *record, size_t buflen)
713{
714 int rc;
715 ssize_t len;
716 unsigned long flags;
717 u64 record_id;
718
719 if (erst_disable)
720 return -ENODEV;
721
722 spin_lock_irqsave(&erst_lock, flags);
723 rc = __erst_get_next_record_id(&record_id);
724 if (rc) {
725 spin_unlock_irqrestore(&erst_lock, flags);
726 return rc;
727 }
728 /* no more record */
729 if (record_id == APEI_ERST_INVALID_RECORD_ID) {
730 spin_unlock_irqrestore(&erst_lock, flags);
731 return 0;
732 }
733
734 len = __erst_read(record_id, record, buflen);
735 spin_unlock_irqrestore(&erst_lock, flags);
736
737 return len;
738}
739EXPORT_SYMBOL_GPL(erst_read_next);
740
741int erst_clear(u64 record_id) 876int erst_clear(u64 record_id)
742{ 877{
743 int rc; 878 int rc, i;
744 unsigned long flags; 879 unsigned long flags;
880 u64 *entries;
745 881
746 if (erst_disable) 882 if (erst_disable)
747 return -ENODEV; 883 return -ENODEV;
748 884
749 spin_lock_irqsave(&erst_lock, flags); 885 rc = mutex_lock_interruptible(&erst_record_id_cache.lock);
886 if (rc)
887 return rc;
888 raw_spin_lock_irqsave(&erst_lock, flags);
750 if (erst_erange.attr & ERST_RANGE_NVRAM) 889 if (erst_erange.attr & ERST_RANGE_NVRAM)
751 rc = __erst_clear_from_nvram(record_id); 890 rc = __erst_clear_from_nvram(record_id);
752 else 891 else
753 rc = __erst_clear_from_storage(record_id); 892 rc = __erst_clear_from_storage(record_id);
754 spin_unlock_irqrestore(&erst_lock, flags); 893 raw_spin_unlock_irqrestore(&erst_lock, flags);
755 894 if (rc)
895 goto out;
896 entries = erst_record_id_cache.entries;
897 for (i = 0; i < erst_record_id_cache.len; i++) {
898 if (entries[i] == record_id)
899 entries[i] = APEI_ERST_INVALID_RECORD_ID;
900 }
901 __erst_record_id_cache_compact();
902out:
903 mutex_unlock(&erst_record_id_cache.lock);
756 return rc; 904 return rc;
757} 905}
758EXPORT_SYMBOL_GPL(erst_clear); 906EXPORT_SYMBOL_GPL(erst_clear);
@@ -781,6 +929,157 @@ static int erst_check_table(struct acpi_table_erst *erst_tab)
781 return 0; 929 return 0;
782} 930}
783 931
932static int erst_open_pstore(struct pstore_info *psi);
933static int erst_close_pstore(struct pstore_info *psi);
934static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
935 struct timespec *time);
936static u64 erst_writer(enum pstore_type_id type, size_t size);
937
938static struct pstore_info erst_info = {
939 .owner = THIS_MODULE,
940 .name = "erst",
941 .open = erst_open_pstore,
942 .close = erst_close_pstore,
943 .read = erst_reader,
944 .write = erst_writer,
945 .erase = erst_clear
946};
947
948#define CPER_CREATOR_PSTORE \
949 UUID_LE(0x75a574e3, 0x5052, 0x4b29, 0x8a, 0x8e, 0xbe, 0x2c, \
950 0x64, 0x90, 0xb8, 0x9d)
951#define CPER_SECTION_TYPE_DMESG \
952 UUID_LE(0xc197e04e, 0xd545, 0x4a70, 0x9c, 0x17, 0xa5, 0x54, \
953 0x94, 0x19, 0xeb, 0x12)
954#define CPER_SECTION_TYPE_MCE \
955 UUID_LE(0xfe08ffbe, 0x95e4, 0x4be7, 0xbc, 0x73, 0x40, 0x96, \
956 0x04, 0x4a, 0x38, 0xfc)
957
958struct cper_pstore_record {
959 struct cper_record_header hdr;
960 struct cper_section_descriptor sec_hdr;
961 char data[];
962} __packed;
963
964static int reader_pos;
965
966static int erst_open_pstore(struct pstore_info *psi)
967{
968 int rc;
969
970 if (erst_disable)
971 return -ENODEV;
972
973 rc = erst_get_record_id_begin(&reader_pos);
974
975 return rc;
976}
977
978static int erst_close_pstore(struct pstore_info *psi)
979{
980 erst_get_record_id_end();
981
982 return 0;
983}
984
985static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
986 struct timespec *time)
987{
988 int rc;
989 ssize_t len = 0;
990 u64 record_id;
991 struct cper_pstore_record *rcd = (struct cper_pstore_record *)
992 (erst_info.buf - sizeof(*rcd));
993
994 if (erst_disable)
995 return -ENODEV;
996
997skip:
998 rc = erst_get_record_id_next(&reader_pos, &record_id);
999 if (rc)
1000 goto out;
1001
1002 /* no more record */
1003 if (record_id == APEI_ERST_INVALID_RECORD_ID) {
1004 rc = -1;
1005 goto out;
1006 }
1007
1008 len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
1009 erst_info.bufsize);
1010 /* The record may be cleared by others, try read next record */
1011 if (len == -ENOENT)
1012 goto skip;
1013 else if (len < 0) {
1014 rc = -1;
1015 goto out;
1016 }
1017 if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
1018 goto skip;
1019
1020 *id = record_id;
1021 if (uuid_le_cmp(rcd->sec_hdr.section_type,
1022 CPER_SECTION_TYPE_DMESG) == 0)
1023 *type = PSTORE_TYPE_DMESG;
1024 else if (uuid_le_cmp(rcd->sec_hdr.section_type,
1025 CPER_SECTION_TYPE_MCE) == 0)
1026 *type = PSTORE_TYPE_MCE;
1027 else
1028 *type = PSTORE_TYPE_UNKNOWN;
1029
1030 if (rcd->hdr.validation_bits & CPER_VALID_TIMESTAMP)
1031 time->tv_sec = rcd->hdr.timestamp;
1032 else
1033 time->tv_sec = 0;
1034 time->tv_nsec = 0;
1035
1036out:
1037 return (rc < 0) ? rc : (len - sizeof(*rcd));
1038}
1039
1040static u64 erst_writer(enum pstore_type_id type, size_t size)
1041{
1042 struct cper_pstore_record *rcd = (struct cper_pstore_record *)
1043 (erst_info.buf - sizeof(*rcd));
1044
1045 memset(rcd, 0, sizeof(*rcd));
1046 memcpy(rcd->hdr.signature, CPER_SIG_RECORD, CPER_SIG_SIZE);
1047 rcd->hdr.revision = CPER_RECORD_REV;
1048 rcd->hdr.signature_end = CPER_SIG_END;
1049 rcd->hdr.section_count = 1;
1050 rcd->hdr.error_severity = CPER_SEV_FATAL;
1051 /* timestamp valid. platform_id, partition_id are invalid */
1052 rcd->hdr.validation_bits = CPER_VALID_TIMESTAMP;
1053 rcd->hdr.timestamp = get_seconds();
1054 rcd->hdr.record_length = sizeof(*rcd) + size;
1055 rcd->hdr.creator_id = CPER_CREATOR_PSTORE;
1056 rcd->hdr.notification_type = CPER_NOTIFY_MCE;
1057 rcd->hdr.record_id = cper_next_record_id();
1058 rcd->hdr.flags = CPER_HW_ERROR_FLAGS_PREVERR;
1059
1060 rcd->sec_hdr.section_offset = sizeof(*rcd);
1061 rcd->sec_hdr.section_length = size;
1062 rcd->sec_hdr.revision = CPER_SEC_REV;
1063 /* fru_id and fru_text is invalid */
1064 rcd->sec_hdr.validation_bits = 0;
1065 rcd->sec_hdr.flags = CPER_SEC_PRIMARY;
1066 switch (type) {
1067 case PSTORE_TYPE_DMESG:
1068 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_DMESG;
1069 break;
1070 case PSTORE_TYPE_MCE:
1071 rcd->sec_hdr.section_type = CPER_SECTION_TYPE_MCE;
1072 break;
1073 default:
1074 return -EINVAL;
1075 }
1076 rcd->sec_hdr.section_severity = CPER_SEV_FATAL;
1077
1078 erst_write(&rcd->hdr);
1079
1080 return rcd->hdr.record_id;
1081}
1082
784static int __init erst_init(void) 1083static int __init erst_init(void)
785{ 1084{
786 int rc = 0; 1085 int rc = 0;
@@ -788,6 +1087,7 @@ static int __init erst_init(void)
788 struct apei_exec_context ctx; 1087 struct apei_exec_context ctx;
789 struct apei_resources erst_resources; 1088 struct apei_resources erst_resources;
790 struct resource *r; 1089 struct resource *r;
1090 char *buf;
791 1091
792 if (acpi_disabled) 1092 if (acpi_disabled)
793 goto err; 1093 goto err;
@@ -854,6 +1154,18 @@ static int __init erst_init(void)
854 if (!erst_erange.vaddr) 1154 if (!erst_erange.vaddr)
855 goto err_release_erange; 1155 goto err_release_erange;
856 1156
1157 buf = kmalloc(erst_erange.size, GFP_KERNEL);
1158 mutex_init(&erst_info.buf_mutex);
1159 if (buf) {
1160 erst_info.buf = buf + sizeof(struct cper_pstore_record);
1161 erst_info.bufsize = erst_erange.size -
1162 sizeof(struct cper_pstore_record);
1163 if (pstore_register(&erst_info)) {
1164 pr_info(ERST_PFX "Could not register with persistent store\n");
1165 kfree(buf);
1166 }
1167 }
1168
857 pr_info(ERST_PFX 1169 pr_info(ERST_PFX
858 "Error Record Serialization Table (ERST) support is initialized.\n"); 1170 "Error Record Serialization Table (ERST) support is initialized.\n");
859 1171
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0d505e59214d..f703b2881153 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -12,10 +12,6 @@
12 * For more information about Generic Hardware Error Source, please 12 * For more information about Generic Hardware Error Source, please
13 * refer to ACPI Specification version 4.0, section 17.3.2.6 13 * refer to ACPI Specification version 4.0, section 17.3.2.6
14 * 14 *
15 * Now, only SCI notification type and memory errors are
16 * supported. More notification type and hardware error type will be
17 * added later.
18 *
19 * Copyright 2010 Intel Corp. 15 * Copyright 2010 Intel Corp.
20 * Author: Huang Ying <ying.huang@intel.com> 16 * Author: Huang Ying <ying.huang@intel.com>
21 * 17 *
@@ -39,14 +35,18 @@
39#include <linux/acpi.h> 35#include <linux/acpi.h>
40#include <linux/io.h> 36#include <linux/io.h>
41#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/timer.h>
42#include <linux/cper.h> 39#include <linux/cper.h>
43#include <linux/kdebug.h> 40#include <linux/kdebug.h>
44#include <linux/platform_device.h> 41#include <linux/platform_device.h>
45#include <linux/mutex.h> 42#include <linux/mutex.h>
43#include <linux/ratelimit.h>
44#include <linux/vmalloc.h>
46#include <acpi/apei.h> 45#include <acpi/apei.h>
47#include <acpi/atomicio.h> 46#include <acpi/atomicio.h>
48#include <acpi/hed.h> 47#include <acpi/hed.h>
49#include <asm/mce.h> 48#include <asm/mce.h>
49#include <asm/tlbflush.h>
50 50
51#include "apei-internal.h" 51#include "apei-internal.h"
52 52
@@ -55,42 +55,131 @@
55#define GHES_ESTATUS_MAX_SIZE 65536 55#define GHES_ESTATUS_MAX_SIZE 65536
56 56
57/* 57/*
58 * One struct ghes is created for each generic hardware error 58 * One struct ghes is created for each generic hardware error source.
59 * source.
60 *
61 * It provides the context for APEI hardware error timer/IRQ/SCI/NMI 59 * It provides the context for APEI hardware error timer/IRQ/SCI/NMI
62 * handler. Handler for one generic hardware error source is only 60 * handler.
63 * triggered after the previous one is done. So handler can uses
64 * struct ghes without locking.
65 * 61 *
66 * estatus: memory buffer for error status block, allocated during 62 * estatus: memory buffer for error status block, allocated during
67 * HEST parsing. 63 * HEST parsing.
68 */ 64 */
69#define GHES_TO_CLEAR 0x0001 65#define GHES_TO_CLEAR 0x0001
66#define GHES_EXITING 0x0002
70 67
71struct ghes { 68struct ghes {
72 struct acpi_hest_generic *generic; 69 struct acpi_hest_generic *generic;
73 struct acpi_hest_generic_status *estatus; 70 struct acpi_hest_generic_status *estatus;
74 struct list_head list;
75 u64 buffer_paddr; 71 u64 buffer_paddr;
76 unsigned long flags; 72 unsigned long flags;
73 union {
74 struct list_head list;
75 struct timer_list timer;
76 unsigned int irq;
77 };
77}; 78};
78 79
80static int ghes_panic_timeout __read_mostly = 30;
81
79/* 82/*
80 * Error source lists, one list for each notification method. The 83 * All error sources notified with SCI shares one notifier function,
81 * members in lists are struct ghes. 84 * so they need to be linked and checked one by one. This is applied
85 * to NMI too.
82 * 86 *
83 * The list members are only added in HEST parsing and deleted during 87 * RCU is used for these lists, so ghes_list_mutex is only used for
84 * module_exit, that is, single-threaded. So no lock is needed for 88 * list changing, not for traversing.
85 * that.
86 *
87 * But the mutual exclusion is needed between members adding/deleting
88 * and timer/IRQ/SCI/NMI handler, which may traverse the list. RCU is
89 * used for that.
90 */ 89 */
91static LIST_HEAD(ghes_sci); 90static LIST_HEAD(ghes_sci);
91static LIST_HEAD(ghes_nmi);
92static DEFINE_MUTEX(ghes_list_mutex); 92static DEFINE_MUTEX(ghes_list_mutex);
93 93
94/*
95 * NMI may be triggered on any CPU, so ghes_nmi_lock is used for
96 * mutual exclusion.
97 */
98static DEFINE_RAW_SPINLOCK(ghes_nmi_lock);
99
100/*
101 * Because the memory area used to transfer hardware error information
102 * from BIOS to Linux can be determined only in NMI, IRQ or timer
103 * handler, but general ioremap can not be used in atomic context, so
104 * a special version of atomic ioremap is implemented for that.
105 */
106
107/*
108 * Two virtual pages are used, one for NMI context, the other for
109 * IRQ/PROCESS context
110 */
111#define GHES_IOREMAP_PAGES 2
112#define GHES_IOREMAP_NMI_PAGE(base) (base)
113#define GHES_IOREMAP_IRQ_PAGE(base) ((base) + PAGE_SIZE)
114
115/* virtual memory area for atomic ioremap */
116static struct vm_struct *ghes_ioremap_area;
117/*
118 * These 2 spinlock is used to prevent atomic ioremap virtual memory
119 * area from being mapped simultaneously.
120 */
121static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi);
122static DEFINE_SPINLOCK(ghes_ioremap_lock_irq);
123
124static int ghes_ioremap_init(void)
125{
126 ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES,
127 VM_IOREMAP, VMALLOC_START, VMALLOC_END);
128 if (!ghes_ioremap_area) {
129 pr_err(GHES_PFX "Failed to allocate virtual memory area for atomic ioremap.\n");
130 return -ENOMEM;
131 }
132
133 return 0;
134}
135
136static void ghes_ioremap_exit(void)
137{
138 free_vm_area(ghes_ioremap_area);
139}
140
141static void __iomem *ghes_ioremap_pfn_nmi(u64 pfn)
142{
143 unsigned long vaddr;
144
145 vaddr = (unsigned long)GHES_IOREMAP_NMI_PAGE(ghes_ioremap_area->addr);
146 ioremap_page_range(vaddr, vaddr + PAGE_SIZE,
147 pfn << PAGE_SHIFT, PAGE_KERNEL);
148
149 return (void __iomem *)vaddr;
150}
151
152static void __iomem *ghes_ioremap_pfn_irq(u64 pfn)
153{
154 unsigned long vaddr;
155
156 vaddr = (unsigned long)GHES_IOREMAP_IRQ_PAGE(ghes_ioremap_area->addr);
157 ioremap_page_range(vaddr, vaddr + PAGE_SIZE,
158 pfn << PAGE_SHIFT, PAGE_KERNEL);
159
160 return (void __iomem *)vaddr;
161}
162
163static void ghes_iounmap_nmi(void __iomem *vaddr_ptr)
164{
165 unsigned long vaddr = (unsigned long __force)vaddr_ptr;
166 void *base = ghes_ioremap_area->addr;
167
168 BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_NMI_PAGE(base));
169 unmap_kernel_range_noflush(vaddr, PAGE_SIZE);
170 __flush_tlb_one(vaddr);
171}
172
173static void ghes_iounmap_irq(void __iomem *vaddr_ptr)
174{
175 unsigned long vaddr = (unsigned long __force)vaddr_ptr;
176 void *base = ghes_ioremap_area->addr;
177
178 BUG_ON(vaddr != (unsigned long)GHES_IOREMAP_IRQ_PAGE(base));
179 unmap_kernel_range_noflush(vaddr, PAGE_SIZE);
180 __flush_tlb_one(vaddr);
181}
182
94static struct ghes *ghes_new(struct acpi_hest_generic *generic) 183static struct ghes *ghes_new(struct acpi_hest_generic *generic)
95{ 184{
96 struct ghes *ghes; 185 struct ghes *ghes;
@@ -101,7 +190,6 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
101 if (!ghes) 190 if (!ghes)
102 return ERR_PTR(-ENOMEM); 191 return ERR_PTR(-ENOMEM);
103 ghes->generic = generic; 192 ghes->generic = generic;
104 INIT_LIST_HEAD(&ghes->list);
105 rc = acpi_pre_map_gar(&generic->error_status_address); 193 rc = acpi_pre_map_gar(&generic->error_status_address);
106 if (rc) 194 if (rc)
107 goto err_free; 195 goto err_free;
@@ -153,27 +241,46 @@ static inline int ghes_severity(int severity)
153 case CPER_SEV_FATAL: 241 case CPER_SEV_FATAL:
154 return GHES_SEV_PANIC; 242 return GHES_SEV_PANIC;
155 default: 243 default:
156 /* Unkown, go panic */ 244 /* Unknown, go panic */
157 return GHES_SEV_PANIC; 245 return GHES_SEV_PANIC;
158 } 246 }
159} 247}
160 248
161/* SCI handler run in work queue, so ioremap can be used here */ 249static void ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len,
162static int ghes_copy_tofrom_phys(void *buffer, u64 paddr, u32 len, 250 int from_phys)
163 int from_phys)
164{ 251{
165 void *vaddr; 252 void __iomem *vaddr;
166 253 unsigned long flags = 0;
167 vaddr = ioremap_cache(paddr, len); 254 int in_nmi = in_nmi();
168 if (!vaddr) 255 u64 offset;
169 return -ENOMEM; 256 u32 trunk;
170 if (from_phys) 257
171 memcpy(buffer, vaddr, len); 258 while (len > 0) {
172 else 259 offset = paddr - (paddr & PAGE_MASK);
173 memcpy(vaddr, buffer, len); 260 if (in_nmi) {
174 iounmap(vaddr); 261 raw_spin_lock(&ghes_ioremap_lock_nmi);
175 262 vaddr = ghes_ioremap_pfn_nmi(paddr >> PAGE_SHIFT);
176 return 0; 263 } else {
264 spin_lock_irqsave(&ghes_ioremap_lock_irq, flags);
265 vaddr = ghes_ioremap_pfn_irq(paddr >> PAGE_SHIFT);
266 }
267 trunk = PAGE_SIZE - offset;
268 trunk = min(trunk, len);
269 if (from_phys)
270 memcpy_fromio(buffer, vaddr + offset, trunk);
271 else
272 memcpy_toio(vaddr + offset, buffer, trunk);
273 len -= trunk;
274 paddr += trunk;
275 buffer += trunk;
276 if (in_nmi) {
277 ghes_iounmap_nmi(vaddr);
278 raw_spin_unlock(&ghes_ioremap_lock_nmi);
279 } else {
280 ghes_iounmap_irq(vaddr);
281 spin_unlock_irqrestore(&ghes_ioremap_lock_irq, flags);
282 }
283 }
177} 284}
178 285
179static int ghes_read_estatus(struct ghes *ghes, int silent) 286static int ghes_read_estatus(struct ghes *ghes, int silent)
@@ -194,10 +301,8 @@ static int ghes_read_estatus(struct ghes *ghes, int silent)
194 if (!buf_paddr) 301 if (!buf_paddr)
195 return -ENOENT; 302 return -ENOENT;
196 303
197 rc = ghes_copy_tofrom_phys(ghes->estatus, buf_paddr, 304 ghes_copy_tofrom_phys(ghes->estatus, buf_paddr,
198 sizeof(*ghes->estatus), 1); 305 sizeof(*ghes->estatus), 1);
199 if (rc)
200 return rc;
201 if (!ghes->estatus->block_status) 306 if (!ghes->estatus->block_status)
202 return -ENOENT; 307 return -ENOENT;
203 308
@@ -212,17 +317,15 @@ static int ghes_read_estatus(struct ghes *ghes, int silent)
212 goto err_read_block; 317 goto err_read_block;
213 if (apei_estatus_check_header(ghes->estatus)) 318 if (apei_estatus_check_header(ghes->estatus))
214 goto err_read_block; 319 goto err_read_block;
215 rc = ghes_copy_tofrom_phys(ghes->estatus + 1, 320 ghes_copy_tofrom_phys(ghes->estatus + 1,
216 buf_paddr + sizeof(*ghes->estatus), 321 buf_paddr + sizeof(*ghes->estatus),
217 len - sizeof(*ghes->estatus), 1); 322 len - sizeof(*ghes->estatus), 1);
218 if (rc)
219 return rc;
220 if (apei_estatus_check(ghes->estatus)) 323 if (apei_estatus_check(ghes->estatus))
221 goto err_read_block; 324 goto err_read_block;
222 rc = 0; 325 rc = 0;
223 326
224err_read_block: 327err_read_block:
225 if (rc && !silent) 328 if (rc && !silent && printk_ratelimit())
226 pr_warning(FW_WARN GHES_PFX 329 pr_warning(FW_WARN GHES_PFX
227 "Failed to read error status block!\n"); 330 "Failed to read error status block!\n");
228 return rc; 331 return rc;
@@ -255,11 +358,26 @@ static void ghes_do_proc(struct ghes *ghes)
255 } 358 }
256#endif 359#endif
257 } 360 }
361}
258 362
259 if (!processed && printk_ratelimit()) 363static void ghes_print_estatus(const char *pfx, struct ghes *ghes)
260 pr_warning(GHES_PFX 364{
261 "Unknown error record from generic hardware error source: %d\n", 365 /* Not more than 2 messages every 5 seconds */
262 ghes->generic->header.source_id); 366 static DEFINE_RATELIMIT_STATE(ratelimit, 5*HZ, 2);
367
368 if (pfx == NULL) {
369 if (ghes_severity(ghes->estatus->error_severity) <=
370 GHES_SEV_CORRECTED)
371 pfx = KERN_WARNING HW_ERR;
372 else
373 pfx = KERN_ERR HW_ERR;
374 }
375 if (__ratelimit(&ratelimit)) {
376 printk(
377 "%s""Hardware error from APEI Generic Hardware Error Source: %d\n",
378 pfx, ghes->generic->header.source_id);
379 apei_estatus_print(pfx, ghes->estatus);
380 }
263} 381}
264 382
265static int ghes_proc(struct ghes *ghes) 383static int ghes_proc(struct ghes *ghes)
@@ -269,6 +387,7 @@ static int ghes_proc(struct ghes *ghes)
269 rc = ghes_read_estatus(ghes, 0); 387 rc = ghes_read_estatus(ghes, 0);
270 if (rc) 388 if (rc)
271 goto out; 389 goto out;
390 ghes_print_estatus(NULL, ghes);
272 ghes_do_proc(ghes); 391 ghes_do_proc(ghes);
273 392
274out: 393out:
@@ -276,6 +395,42 @@ out:
276 return 0; 395 return 0;
277} 396}
278 397
398static void ghes_add_timer(struct ghes *ghes)
399{
400 struct acpi_hest_generic *g = ghes->generic;
401 unsigned long expire;
402
403 if (!g->notify.poll_interval) {
404 pr_warning(FW_WARN GHES_PFX "Poll interval is 0 for generic hardware error source: %d, disabled.\n",
405 g->header.source_id);
406 return;
407 }
408 expire = jiffies + msecs_to_jiffies(g->notify.poll_interval);
409 ghes->timer.expires = round_jiffies_relative(expire);
410 add_timer(&ghes->timer);
411}
412
413static void ghes_poll_func(unsigned long data)
414{
415 struct ghes *ghes = (void *)data;
416
417 ghes_proc(ghes);
418 if (!(ghes->flags & GHES_EXITING))
419 ghes_add_timer(ghes);
420}
421
422static irqreturn_t ghes_irq_func(int irq, void *data)
423{
424 struct ghes *ghes = data;
425 int rc;
426
427 rc = ghes_proc(ghes);
428 if (rc)
429 return IRQ_NONE;
430
431 return IRQ_HANDLED;
432}
433
279static int ghes_notify_sci(struct notifier_block *this, 434static int ghes_notify_sci(struct notifier_block *this,
280 unsigned long event, void *data) 435 unsigned long event, void *data)
281{ 436{
@@ -292,10 +447,63 @@ static int ghes_notify_sci(struct notifier_block *this,
292 return ret; 447 return ret;
293} 448}
294 449
450static int ghes_notify_nmi(struct notifier_block *this,
451 unsigned long cmd, void *data)
452{
453 struct ghes *ghes, *ghes_global = NULL;
454 int sev, sev_global = -1;
455 int ret = NOTIFY_DONE;
456
457 if (cmd != DIE_NMI)
458 return ret;
459
460 raw_spin_lock(&ghes_nmi_lock);
461 list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
462 if (ghes_read_estatus(ghes, 1)) {
463 ghes_clear_estatus(ghes);
464 continue;
465 }
466 sev = ghes_severity(ghes->estatus->error_severity);
467 if (sev > sev_global) {
468 sev_global = sev;
469 ghes_global = ghes;
470 }
471 ret = NOTIFY_STOP;
472 }
473
474 if (ret == NOTIFY_DONE)
475 goto out;
476
477 if (sev_global >= GHES_SEV_PANIC) {
478 oops_begin();
479 ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global);
480 /* reboot to log the error! */
481 if (panic_timeout == 0)
482 panic_timeout = ghes_panic_timeout;
483 panic("Fatal hardware error!");
484 }
485
486 list_for_each_entry_rcu(ghes, &ghes_nmi, list) {
487 if (!(ghes->flags & GHES_TO_CLEAR))
488 continue;
489 /* Do not print estatus because printk is not NMI safe */
490 ghes_do_proc(ghes);
491 ghes_clear_estatus(ghes);
492 }
493
494out:
495 raw_spin_unlock(&ghes_nmi_lock);
496 return ret;
497}
498
295static struct notifier_block ghes_notifier_sci = { 499static struct notifier_block ghes_notifier_sci = {
296 .notifier_call = ghes_notify_sci, 500 .notifier_call = ghes_notify_sci,
297}; 501};
298 502
503static struct notifier_block ghes_notifier_nmi = {
504 .notifier_call = ghes_notify_nmi,
505};
506
299static int __devinit ghes_probe(struct platform_device *ghes_dev) 507static int __devinit ghes_probe(struct platform_device *ghes_dev)
300{ 508{
301 struct acpi_hest_generic *generic; 509 struct acpi_hest_generic *generic;
@@ -306,18 +514,27 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev)
306 if (!generic->enabled) 514 if (!generic->enabled)
307 return -ENODEV; 515 return -ENODEV;
308 516
309 if (generic->error_block_length < 517 switch (generic->notify.type) {
310 sizeof(struct acpi_hest_generic_status)) { 518 case ACPI_HEST_NOTIFY_POLLED:
311 pr_warning(FW_BUG GHES_PFX 519 case ACPI_HEST_NOTIFY_EXTERNAL:
312"Invalid error block length: %u for generic hardware error source: %d\n", 520 case ACPI_HEST_NOTIFY_SCI:
313 generic->error_block_length, 521 case ACPI_HEST_NOTIFY_NMI:
522 break;
523 case ACPI_HEST_NOTIFY_LOCAL:
524 pr_warning(GHES_PFX "Generic hardware error source: %d notified via local interrupt is not supported!\n",
314 generic->header.source_id); 525 generic->header.source_id);
315 goto err; 526 goto err;
527 default:
528 pr_warning(FW_WARN GHES_PFX "Unknown notification type: %u for generic hardware error source: %d\n",
529 generic->notify.type, generic->header.source_id);
530 goto err;
316 } 531 }
317 if (generic->records_to_preallocate == 0) { 532
318 pr_warning(FW_BUG GHES_PFX 533 rc = -EIO;
319"Invalid records to preallocate: %u for generic hardware error source: %d\n", 534 if (generic->error_block_length <
320 generic->records_to_preallocate, 535 sizeof(struct acpi_hest_generic_status)) {
536 pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
537 generic->error_block_length,
321 generic->header.source_id); 538 generic->header.source_id);
322 goto err; 539 goto err;
323 } 540 }
@@ -327,38 +544,43 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev)
327 ghes = NULL; 544 ghes = NULL;
328 goto err; 545 goto err;
329 } 546 }
330 if (generic->notify.type == ACPI_HEST_NOTIFY_SCI) { 547 switch (generic->notify.type) {
548 case ACPI_HEST_NOTIFY_POLLED:
549 ghes->timer.function = ghes_poll_func;
550 ghes->timer.data = (unsigned long)ghes;
551 init_timer_deferrable(&ghes->timer);
552 ghes_add_timer(ghes);
553 break;
554 case ACPI_HEST_NOTIFY_EXTERNAL:
555 /* External interrupt vector is GSI */
556 if (acpi_gsi_to_irq(generic->notify.vector, &ghes->irq)) {
557 pr_err(GHES_PFX "Failed to map GSI to IRQ for generic hardware error source: %d\n",
558 generic->header.source_id);
559 goto err;
560 }
561 if (request_irq(ghes->irq, ghes_irq_func,
562 0, "GHES IRQ", ghes)) {
563 pr_err(GHES_PFX "Failed to register IRQ for generic hardware error source: %d\n",
564 generic->header.source_id);
565 goto err;
566 }
567 break;
568 case ACPI_HEST_NOTIFY_SCI:
331 mutex_lock(&ghes_list_mutex); 569 mutex_lock(&ghes_list_mutex);
332 if (list_empty(&ghes_sci)) 570 if (list_empty(&ghes_sci))
333 register_acpi_hed_notifier(&ghes_notifier_sci); 571 register_acpi_hed_notifier(&ghes_notifier_sci);
334 list_add_rcu(&ghes->list, &ghes_sci); 572 list_add_rcu(&ghes->list, &ghes_sci);
335 mutex_unlock(&ghes_list_mutex); 573 mutex_unlock(&ghes_list_mutex);
336 } else { 574 break;
337 unsigned char *notify = NULL; 575 case ACPI_HEST_NOTIFY_NMI:
338 576 mutex_lock(&ghes_list_mutex);
339 switch (generic->notify.type) { 577 if (list_empty(&ghes_nmi))
340 case ACPI_HEST_NOTIFY_POLLED: 578 register_die_notifier(&ghes_notifier_nmi);
341 notify = "POLL"; 579 list_add_rcu(&ghes->list, &ghes_nmi);
342 break; 580 mutex_unlock(&ghes_list_mutex);
343 case ACPI_HEST_NOTIFY_EXTERNAL: 581 break;
344 case ACPI_HEST_NOTIFY_LOCAL: 582 default:
345 notify = "IRQ"; 583 BUG();
346 break;
347 case ACPI_HEST_NOTIFY_NMI:
348 notify = "NMI";
349 break;
350 }
351 if (notify) {
352 pr_warning(GHES_PFX
353"Generic hardware error source: %d notified via %s is not supported!\n",
354 generic->header.source_id, notify);
355 } else {
356 pr_warning(FW_WARN GHES_PFX
357"Unknown notification type: %u for generic hardware error source: %d\n",
358 generic->notify.type, generic->header.source_id);
359 }
360 rc = -ENODEV;
361 goto err;
362 } 584 }
363 platform_set_drvdata(ghes_dev, ghes); 585 platform_set_drvdata(ghes_dev, ghes);
364 586
@@ -379,7 +601,14 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev)
379 ghes = platform_get_drvdata(ghes_dev); 601 ghes = platform_get_drvdata(ghes_dev);
380 generic = ghes->generic; 602 generic = ghes->generic;
381 603
604 ghes->flags |= GHES_EXITING;
382 switch (generic->notify.type) { 605 switch (generic->notify.type) {
606 case ACPI_HEST_NOTIFY_POLLED:
607 del_timer_sync(&ghes->timer);
608 break;
609 case ACPI_HEST_NOTIFY_EXTERNAL:
610 free_irq(ghes->irq, ghes);
611 break;
383 case ACPI_HEST_NOTIFY_SCI: 612 case ACPI_HEST_NOTIFY_SCI:
384 mutex_lock(&ghes_list_mutex); 613 mutex_lock(&ghes_list_mutex);
385 list_del_rcu(&ghes->list); 614 list_del_rcu(&ghes->list);
@@ -387,12 +616,23 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev)
387 unregister_acpi_hed_notifier(&ghes_notifier_sci); 616 unregister_acpi_hed_notifier(&ghes_notifier_sci);
388 mutex_unlock(&ghes_list_mutex); 617 mutex_unlock(&ghes_list_mutex);
389 break; 618 break;
619 case ACPI_HEST_NOTIFY_NMI:
620 mutex_lock(&ghes_list_mutex);
621 list_del_rcu(&ghes->list);
622 if (list_empty(&ghes_nmi))
623 unregister_die_notifier(&ghes_notifier_nmi);
624 mutex_unlock(&ghes_list_mutex);
625 /*
626 * To synchronize with NMI handler, ghes can only be
627 * freed after NMI handler finishes.
628 */
629 synchronize_rcu();
630 break;
390 default: 631 default:
391 BUG(); 632 BUG();
392 break; 633 break;
393 } 634 }
394 635
395 synchronize_rcu();
396 ghes_fini(ghes); 636 ghes_fini(ghes);
397 kfree(ghes); 637 kfree(ghes);
398 638
@@ -412,6 +652,8 @@ static struct platform_driver ghes_platform_driver = {
412 652
413static int __init ghes_init(void) 653static int __init ghes_init(void)
414{ 654{
655 int rc;
656
415 if (acpi_disabled) 657 if (acpi_disabled)
416 return -ENODEV; 658 return -ENODEV;
417 659
@@ -420,12 +662,25 @@ static int __init ghes_init(void)
420 return -EINVAL; 662 return -EINVAL;
421 } 663 }
422 664
423 return platform_driver_register(&ghes_platform_driver); 665 rc = ghes_ioremap_init();
666 if (rc)
667 goto err;
668
669 rc = platform_driver_register(&ghes_platform_driver);
670 if (rc)
671 goto err_ioremap_exit;
672
673 return 0;
674err_ioremap_exit:
675 ghes_ioremap_exit();
676err:
677 return rc;
424} 678}
425 679
426static void __exit ghes_exit(void) 680static void __exit ghes_exit(void)
427{ 681{
428 platform_driver_unregister(&ghes_platform_driver); 682 platform_driver_unregister(&ghes_platform_driver);
683 ghes_ioremap_exit();
429} 684}
430 685
431module_init(ghes_init); 686module_init(ghes_init);
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 1a3508a7fe03..181bc2f7bb74 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable);
46 46
47/* HEST table parsing */ 47/* HEST table parsing */
48 48
49static struct acpi_table_hest *hest_tab; 49static struct acpi_table_hest *__read_mostly hest_tab;
50 50
51static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { 51static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = {
52 [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ 52 [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */
53 [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, 53 [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1,
54 [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), 54 [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi),
@@ -126,7 +126,7 @@ struct ghes_arr {
126 unsigned int count; 126 unsigned int count;
127}; 127};
128 128
129static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) 129static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
130{ 130{
131 int *count = data; 131 int *count = data;
132 132
@@ -135,17 +135,27 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data)
135 return 0; 135 return 0;
136} 136}
137 137
138static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) 138static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
139{ 139{
140 struct platform_device *ghes_dev; 140 struct platform_device *ghes_dev;
141 struct ghes_arr *ghes_arr = data; 141 struct ghes_arr *ghes_arr = data;
142 int rc; 142 int rc, i;
143 143
144 if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) 144 if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR)
145 return 0; 145 return 0;
146 146
147 if (!((struct acpi_hest_generic *)hest_hdr)->enabled) 147 if (!((struct acpi_hest_generic *)hest_hdr)->enabled)
148 return 0; 148 return 0;
149 for (i = 0; i < ghes_arr->count; i++) {
150 struct acpi_hest_header *hdr;
151 ghes_dev = ghes_arr->ghes_devs[i];
152 hdr = *(struct acpi_hest_header **)ghes_dev->dev.platform_data;
153 if (hdr->source_id == hest_hdr->source_id) {
154 pr_warning(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n",
155 hdr->source_id);
156 return -EIO;
157 }
158 }
149 ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); 159 ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id);
150 if (!ghes_dev) 160 if (!ghes_dev)
151 return -ENOMEM; 161 return -ENOMEM;
@@ -165,7 +175,7 @@ err:
165 return rc; 175 return rc;
166} 176}
167 177
168static int hest_ghes_dev_register(unsigned int ghes_count) 178static int __init hest_ghes_dev_register(unsigned int ghes_count)
169{ 179{
170 int rc, i; 180 int rc, i;
171 struct ghes_arr ghes_arr; 181 struct ghes_arr ghes_arr;
@@ -195,24 +205,24 @@ static int __init setup_hest_disable(char *str)
195 205
196__setup("hest_disable", setup_hest_disable); 206__setup("hest_disable", setup_hest_disable);
197 207
198static int __init hest_init(void) 208void __init acpi_hest_init(void)
199{ 209{
200 acpi_status status; 210 acpi_status status;
201 int rc = -ENODEV; 211 int rc = -ENODEV;
202 unsigned int ghes_count = 0; 212 unsigned int ghes_count = 0;
203 213
204 if (acpi_disabled)
205 goto err;
206
207 if (hest_disable) { 214 if (hest_disable) {
208 pr_info(HEST_PFX "HEST tabling parsing is disabled.\n"); 215 pr_info(HEST_PFX "Table parsing disabled.\n");
209 goto err; 216 return;
210 } 217 }
211 218
219 if (acpi_disabled)
220 goto err;
221
212 status = acpi_get_table(ACPI_SIG_HEST, 0, 222 status = acpi_get_table(ACPI_SIG_HEST, 0,
213 (struct acpi_table_header **)&hest_tab); 223 (struct acpi_table_header **)&hest_tab);
214 if (status == AE_NOT_FOUND) { 224 if (status == AE_NOT_FOUND) {
215 pr_info(HEST_PFX "Table is not found!\n"); 225 pr_info(HEST_PFX "Table not found.\n");
216 goto err; 226 goto err;
217 } else if (ACPI_FAILURE(status)) { 227 } else if (ACPI_FAILURE(status)) {
218 const char *msg = acpi_format_exception(status); 228 const char *msg = acpi_format_exception(status);
@@ -226,15 +236,11 @@ static int __init hest_init(void)
226 goto err; 236 goto err;
227 237
228 rc = hest_ghes_dev_register(ghes_count); 238 rc = hest_ghes_dev_register(ghes_count);
229 if (rc) 239 if (!rc) {
230 goto err; 240 pr_info(HEST_PFX "Table parsing has been initialized.\n");
231 241 return;
232 pr_info(HEST_PFX "HEST table parsing is initialized.\n"); 242 }
233 243
234 return 0;
235err: 244err:
236 hest_disable = 1; 245 hest_disable = 1;
237 return rc;
238} 246}
239
240subsys_initcall(hest_init);
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
index 542e53903891..7489b89c300f 100644
--- a/drivers/acpi/atomicio.c
+++ b/drivers/acpi/atomicio.c
@@ -280,9 +280,11 @@ static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
280 case 32: 280 case 32:
281 *val = readl(addr); 281 *val = readl(addr);
282 break; 282 break;
283#ifdef readq
283 case 64: 284 case 64:
284 *val = readq(addr); 285 *val = readq(addr);
285 break; 286 break;
287#endif
286 default: 288 default:
287 return -EINVAL; 289 return -EINVAL;
288 } 290 }
@@ -307,9 +309,11 @@ static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
307 case 32: 309 case 32:
308 writel(val, addr); 310 writel(val, addr);
309 break; 311 break;
312#ifdef writeq
310 case 64: 313 case 64:
311 writeq(val, addr); 314 writeq(val, addr);
312 break; 315 break;
316#endif
313 default: 317 default:
314 return -EINVAL; 318 return -EINVAL;
315 } 319 }
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 98417201e9ce..fcc13ac0aa18 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -33,6 +33,7 @@
33#include <linux/async.h> 33#include <linux/async.h>
34#include <linux/dmi.h> 34#include <linux/dmi.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/suspend.h>
36 37
37#ifdef CONFIG_ACPI_PROCFS_POWER 38#ifdef CONFIG_ACPI_PROCFS_POWER
38#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
@@ -42,10 +43,7 @@
42 43
43#include <acpi/acpi_bus.h> 44#include <acpi/acpi_bus.h>
44#include <acpi/acpi_drivers.h> 45#include <acpi/acpi_drivers.h>
45
46#ifdef CONFIG_ACPI_SYSFS_POWER
47#include <linux/power_supply.h> 46#include <linux/power_supply.h>
48#endif
49 47
50#define PREFIX "ACPI: " 48#define PREFIX "ACPI: "
51 49
@@ -98,14 +96,14 @@ enum {
98 * due to bad math. 96 * due to bad math.
99 */ 97 */
100 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, 98 ACPI_BATTERY_QUIRK_SIGNED16_CURRENT,
99 ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY,
101}; 100};
102 101
103struct acpi_battery { 102struct acpi_battery {
104 struct mutex lock; 103 struct mutex lock;
105#ifdef CONFIG_ACPI_SYSFS_POWER
106 struct power_supply bat; 104 struct power_supply bat;
107#endif
108 struct acpi_device *device; 105 struct acpi_device *device;
106 struct notifier_block pm_nb;
109 unsigned long update_time; 107 unsigned long update_time;
110 int rate_now; 108 int rate_now;
111 int capacity_now; 109 int capacity_now;
@@ -141,7 +139,6 @@ inline int acpi_battery_present(struct acpi_battery *battery)
141 return battery->device->status.battery_present; 139 return battery->device->status.battery_present;
142} 140}
143 141
144#ifdef CONFIG_ACPI_SYSFS_POWER
145static int acpi_battery_technology(struct acpi_battery *battery) 142static int acpi_battery_technology(struct acpi_battery *battery)
146{ 143{
147 if (!strcasecmp("NiCd", battery->type)) 144 if (!strcasecmp("NiCd", battery->type))
@@ -186,6 +183,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
186 enum power_supply_property psp, 183 enum power_supply_property psp,
187 union power_supply_propval *val) 184 union power_supply_propval *val)
188{ 185{
186 int ret = 0;
189 struct acpi_battery *battery = to_acpi_battery(psy); 187 struct acpi_battery *battery = to_acpi_battery(psy);
190 188
191 if (acpi_battery_present(battery)) { 189 if (acpi_battery_present(battery)) {
@@ -214,26 +212,44 @@ static int acpi_battery_get_property(struct power_supply *psy,
214 val->intval = battery->cycle_count; 212 val->intval = battery->cycle_count;
215 break; 213 break;
216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 214 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
217 val->intval = battery->design_voltage * 1000; 215 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
216 ret = -ENODEV;
217 else
218 val->intval = battery->design_voltage * 1000;
218 break; 219 break;
219 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 220 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
220 val->intval = battery->voltage_now * 1000; 221 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
222 ret = -ENODEV;
223 else
224 val->intval = battery->voltage_now * 1000;
221 break; 225 break;
222 case POWER_SUPPLY_PROP_CURRENT_NOW: 226 case POWER_SUPPLY_PROP_CURRENT_NOW:
223 case POWER_SUPPLY_PROP_POWER_NOW: 227 case POWER_SUPPLY_PROP_POWER_NOW:
224 val->intval = battery->rate_now * 1000; 228 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
229 ret = -ENODEV;
230 else
231 val->intval = battery->rate_now * 1000;
225 break; 232 break;
226 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 233 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
227 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 234 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
228 val->intval = battery->design_capacity * 1000; 235 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
236 ret = -ENODEV;
237 else
238 val->intval = battery->design_capacity * 1000;
229 break; 239 break;
230 case POWER_SUPPLY_PROP_CHARGE_FULL: 240 case POWER_SUPPLY_PROP_CHARGE_FULL:
231 case POWER_SUPPLY_PROP_ENERGY_FULL: 241 case POWER_SUPPLY_PROP_ENERGY_FULL:
232 val->intval = battery->full_charge_capacity * 1000; 242 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
243 ret = -ENODEV;
244 else
245 val->intval = battery->full_charge_capacity * 1000;
233 break; 246 break;
234 case POWER_SUPPLY_PROP_CHARGE_NOW: 247 case POWER_SUPPLY_PROP_CHARGE_NOW:
235 case POWER_SUPPLY_PROP_ENERGY_NOW: 248 case POWER_SUPPLY_PROP_ENERGY_NOW:
236 val->intval = battery->capacity_now * 1000; 249 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
250 ret = -ENODEV;
251 else
252 val->intval = battery->capacity_now * 1000;
237 break; 253 break;
238 case POWER_SUPPLY_PROP_MODEL_NAME: 254 case POWER_SUPPLY_PROP_MODEL_NAME:
239 val->strval = battery->model_number; 255 val->strval = battery->model_number;
@@ -245,9 +261,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
245 val->strval = battery->serial_number; 261 val->strval = battery->serial_number;
246 break; 262 break;
247 default: 263 default:
248 return -EINVAL; 264 ret = -EINVAL;
249 } 265 }
250 return 0; 266 return ret;
251} 267}
252 268
253static enum power_supply_property charge_battery_props[] = { 269static enum power_supply_property charge_battery_props[] = {
@@ -281,7 +297,6 @@ static enum power_supply_property energy_battery_props[] = {
281 POWER_SUPPLY_PROP_MANUFACTURER, 297 POWER_SUPPLY_PROP_MANUFACTURER,
282 POWER_SUPPLY_PROP_SERIAL_NUMBER, 298 POWER_SUPPLY_PROP_SERIAL_NUMBER,
283}; 299};
284#endif
285 300
286#ifdef CONFIG_ACPI_PROCFS_POWER 301#ifdef CONFIG_ACPI_PROCFS_POWER
287inline char *acpi_battery_units(struct acpi_battery *battery) 302inline char *acpi_battery_units(struct acpi_battery *battery)
@@ -412,6 +427,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
412 result = extract_package(battery, buffer.pointer, 427 result = extract_package(battery, buffer.pointer,
413 info_offsets, ARRAY_SIZE(info_offsets)); 428 info_offsets, ARRAY_SIZE(info_offsets));
414 kfree(buffer.pointer); 429 kfree(buffer.pointer);
430 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
431 battery->full_charge_capacity = battery->design_capacity;
415 return result; 432 return result;
416} 433}
417 434
@@ -448,6 +465,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
448 battery->rate_now != -1) 465 battery->rate_now != -1)
449 battery->rate_now = abs((s16)battery->rate_now); 466 battery->rate_now = abs((s16)battery->rate_now);
450 467
468 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
469 && battery->capacity_now >= 0 && battery->capacity_now <= 100)
470 battery->capacity_now = (battery->capacity_now *
471 battery->full_charge_capacity) / 100;
451 return result; 472 return result;
452} 473}
453 474
@@ -492,7 +513,6 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
492 return acpi_battery_set_alarm(battery); 513 return acpi_battery_set_alarm(battery);
493} 514}
494 515
495#ifdef CONFIG_ACPI_SYSFS_POWER
496static ssize_t acpi_battery_alarm_show(struct device *dev, 516static ssize_t acpi_battery_alarm_show(struct device *dev,
497 struct device_attribute *attr, 517 struct device_attribute *attr,
498 char *buf) 518 char *buf)
@@ -552,7 +572,6 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
552 power_supply_unregister(&battery->bat); 572 power_supply_unregister(&battery->bat);
553 battery->bat.dev = NULL; 573 battery->bat.dev = NULL;
554} 574}
555#endif
556 575
557static void acpi_battery_quirks(struct acpi_battery *battery) 576static void acpi_battery_quirks(struct acpi_battery *battery)
558{ 577{
@@ -561,6 +580,33 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
561 } 580 }
562} 581}
563 582
583/*
584 * According to the ACPI spec, some kinds of primary batteries can
585 * report percentage battery remaining capacity directly to OS.
586 * In this case, it reports the Last Full Charged Capacity == 100
587 * and BatteryPresentRate == 0xFFFFFFFF.
588 *
589 * Now we found some battery reports percentage remaining capacity
590 * even if it's rechargeable.
591 * https://bugzilla.kernel.org/show_bug.cgi?id=15979
592 *
593 * Handle this correctly so that they won't break userspace.
594 */
595static void acpi_battery_quirks2(struct acpi_battery *battery)
596{
597 if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
598 return ;
599
600 if (battery->full_charge_capacity == 100 &&
601 battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
602 battery->capacity_now >=0 && battery->capacity_now <= 100) {
603 set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
604 battery->full_charge_capacity = battery->design_capacity;
605 battery->capacity_now = (battery->capacity_now *
606 battery->full_charge_capacity) / 100;
607 }
608}
609
564static int acpi_battery_update(struct acpi_battery *battery) 610static int acpi_battery_update(struct acpi_battery *battery)
565{ 611{
566 int result, old_present = acpi_battery_present(battery); 612 int result, old_present = acpi_battery_present(battery);
@@ -568,9 +614,7 @@ static int acpi_battery_update(struct acpi_battery *battery)
568 if (result) 614 if (result)
569 return result; 615 return result;
570 if (!acpi_battery_present(battery)) { 616 if (!acpi_battery_present(battery)) {
571#ifdef CONFIG_ACPI_SYSFS_POWER
572 sysfs_remove_battery(battery); 617 sysfs_remove_battery(battery);
573#endif
574 battery->update_time = 0; 618 battery->update_time = 0;
575 return 0; 619 return 0;
576 } 620 }
@@ -582,11 +626,22 @@ static int acpi_battery_update(struct acpi_battery *battery)
582 acpi_battery_quirks(battery); 626 acpi_battery_quirks(battery);
583 acpi_battery_init_alarm(battery); 627 acpi_battery_init_alarm(battery);
584 } 628 }
585#ifdef CONFIG_ACPI_SYSFS_POWER
586 if (!battery->bat.dev) 629 if (!battery->bat.dev)
587 sysfs_add_battery(battery); 630 sysfs_add_battery(battery);
588#endif 631 result = acpi_battery_get_state(battery);
589 return acpi_battery_get_state(battery); 632 acpi_battery_quirks2(battery);
633 return result;
634}
635
636static void acpi_battery_refresh(struct acpi_battery *battery)
637{
638 if (!battery->bat.dev)
639 return;
640
641 acpi_battery_get_info(battery);
642 /* The battery may have changed its reporting units. */
643 sysfs_remove_battery(battery);
644 sysfs_add_battery(battery);
590} 645}
591 646
592/* -------------------------------------------------------------------------- 647/* --------------------------------------------------------------------------
@@ -826,6 +881,8 @@ static int acpi_battery_add_fs(struct acpi_device *device)
826 struct proc_dir_entry *entry = NULL; 881 struct proc_dir_entry *entry = NULL;
827 int i; 882 int i;
828 883
884 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded,"
885 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
829 if (!acpi_device_dir(device)) { 886 if (!acpi_device_dir(device)) {
830 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 887 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
831 acpi_battery_dir); 888 acpi_battery_dir);
@@ -867,26 +924,37 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
867static void acpi_battery_notify(struct acpi_device *device, u32 event) 924static void acpi_battery_notify(struct acpi_device *device, u32 event)
868{ 925{
869 struct acpi_battery *battery = acpi_driver_data(device); 926 struct acpi_battery *battery = acpi_driver_data(device);
870#ifdef CONFIG_ACPI_SYSFS_POWER
871 struct device *old; 927 struct device *old;
872#endif
873 928
874 if (!battery) 929 if (!battery)
875 return; 930 return;
876#ifdef CONFIG_ACPI_SYSFS_POWER
877 old = battery->bat.dev; 931 old = battery->bat.dev;
878#endif 932 if (event == ACPI_BATTERY_NOTIFY_INFO)
933 acpi_battery_refresh(battery);
879 acpi_battery_update(battery); 934 acpi_battery_update(battery);
880 acpi_bus_generate_proc_event(device, event, 935 acpi_bus_generate_proc_event(device, event,
881 acpi_battery_present(battery)); 936 acpi_battery_present(battery));
882 acpi_bus_generate_netlink_event(device->pnp.device_class, 937 acpi_bus_generate_netlink_event(device->pnp.device_class,
883 dev_name(&device->dev), event, 938 dev_name(&device->dev), event,
884 acpi_battery_present(battery)); 939 acpi_battery_present(battery));
885#ifdef CONFIG_ACPI_SYSFS_POWER
886 /* acpi_battery_update could remove power_supply object */ 940 /* acpi_battery_update could remove power_supply object */
887 if (old && battery->bat.dev) 941 if (old && battery->bat.dev)
888 power_supply_changed(&battery->bat); 942 power_supply_changed(&battery->bat);
889#endif 943}
944
945static int battery_notify(struct notifier_block *nb,
946 unsigned long mode, void *_unused)
947{
948 struct acpi_battery *battery = container_of(nb, struct acpi_battery,
949 pm_nb);
950 switch (mode) {
951 case PM_POST_SUSPEND:
952 sysfs_remove_battery(battery);
953 sysfs_add_battery(battery);
954 break;
955 }
956
957 return 0;
890} 958}
891 959
892static int acpi_battery_add(struct acpi_device *device) 960static int acpi_battery_add(struct acpi_device *device)
@@ -921,6 +989,10 @@ static int acpi_battery_add(struct acpi_device *device)
921#endif 989#endif
922 kfree(battery); 990 kfree(battery);
923 } 991 }
992
993 battery->pm_nb.notifier_call = battery_notify;
994 register_pm_notifier(&battery->pm_nb);
995
924 return result; 996 return result;
925} 997}
926 998
@@ -931,12 +1003,11 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
931 if (!device || !acpi_driver_data(device)) 1003 if (!device || !acpi_driver_data(device))
932 return -EINVAL; 1004 return -EINVAL;
933 battery = acpi_driver_data(device); 1005 battery = acpi_driver_data(device);
1006 unregister_pm_notifier(&battery->pm_nb);
934#ifdef CONFIG_ACPI_PROCFS_POWER 1007#ifdef CONFIG_ACPI_PROCFS_POWER
935 acpi_battery_remove_fs(device); 1008 acpi_battery_remove_fs(device);
936#endif 1009#endif
937#ifdef CONFIG_ACPI_SYSFS_POWER
938 sysfs_remove_battery(battery); 1010 sysfs_remove_battery(battery);
939#endif
940 mutex_destroy(&battery->lock); 1011 mutex_destroy(&battery->lock);
941 kfree(battery); 1012 kfree(battery);
942 return 0; 1013 return 0;
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 310e3b9749cb..d1e06c182cdb 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -40,6 +40,7 @@
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include <acpi/acpi_drivers.h> 41#include <acpi/acpi_drivers.h>
42#include <linux/dmi.h> 42#include <linux/dmi.h>
43#include <linux/suspend.h>
43 44
44#include "internal.h" 45#include "internal.h"
45 46
@@ -52,22 +53,6 @@ EXPORT_SYMBOL(acpi_root_dir);
52 53
53#define STRUCT_TO_INT(s) (*((int*)&s)) 54#define STRUCT_TO_INT(s) (*((int*)&s))
54 55
55static int set_power_nocheck(const struct dmi_system_id *id)
56{
57 printk(KERN_NOTICE PREFIX "%s detected - "
58 "disable power check in power transition\n", id->ident);
59 acpi_power_nocheck = 1;
60 return 0;
61}
62static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = {
63 {
64 set_power_nocheck, "HP Pavilion 05", {
65 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
66 DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"),
67 DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL},
68 {},
69};
70
71 56
72#ifdef CONFIG_X86 57#ifdef CONFIG_X86
73static int set_copy_dsdt(const struct dmi_system_id *id) 58static int set_copy_dsdt(const struct dmi_system_id *id)
@@ -196,33 +181,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data);
196 Power Management 181 Power Management
197 -------------------------------------------------------------------------- */ 182 -------------------------------------------------------------------------- */
198 183
199int acpi_bus_get_power(acpi_handle handle, int *state) 184static int __acpi_bus_get_power(struct acpi_device *device, int *state)
200{ 185{
201 int result = 0; 186 int result = 0;
202 acpi_status status = 0; 187 acpi_status status = 0;
203 struct acpi_device *device = NULL;
204 unsigned long long psc = 0; 188 unsigned long long psc = 0;
205 189
206 190 if (!device || !state)
207 result = acpi_bus_get_device(handle, &device); 191 return -EINVAL;
208 if (result)
209 return result;
210 192
211 *state = ACPI_STATE_UNKNOWN; 193 *state = ACPI_STATE_UNKNOWN;
212 194
213 if (!device->flags.power_manageable) { 195 if (device->flags.power_manageable) {
214 /* TBD: Non-recursive algorithm for walking up hierarchy */
215 if (device->parent)
216 *state = device->parent->power.state;
217 else
218 *state = ACPI_STATE_D0;
219 } else {
220 /* 196 /*
221 * Get the device's power state either directly (via _PSC) or 197 * Get the device's power state either directly (via _PSC) or
222 * indirectly (via power resources). 198 * indirectly (via power resources).
223 */ 199 */
224 if (device->power.flags.power_resources) { 200 if (device->power.flags.power_resources) {
225 result = acpi_power_get_inferred_state(device); 201 result = acpi_power_get_inferred_state(device, state);
226 if (result) 202 if (result)
227 return result; 203 return result;
228 } else if (device->power.flags.explicit_get) { 204 } else if (device->power.flags.explicit_get) {
@@ -230,59 +206,33 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
230 NULL, &psc); 206 NULL, &psc);
231 if (ACPI_FAILURE(status)) 207 if (ACPI_FAILURE(status))
232 return -ENODEV; 208 return -ENODEV;
233 device->power.state = (int)psc; 209 *state = (int)psc;
234 } 210 }
235 211 } else {
236 *state = device->power.state; 212 /* TBD: Non-recursive algorithm for walking up hierarchy. */
213 *state = device->parent ?
214 device->parent->power.state : ACPI_STATE_D0;
237 } 215 }
238 216
239 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", 217 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n",
240 device->pnp.bus_id, device->power.state)); 218 device->pnp.bus_id, *state));
241 219
242 return 0; 220 return 0;
243} 221}
244 222
245EXPORT_SYMBOL(acpi_bus_get_power);
246 223
247int acpi_bus_set_power(acpi_handle handle, int state) 224static int __acpi_bus_set_power(struct acpi_device *device, int state)
248{ 225{
249 int result = 0; 226 int result = 0;
250 acpi_status status = AE_OK; 227 acpi_status status = AE_OK;
251 struct acpi_device *device = NULL;
252 char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; 228 char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
253 229
254 230 if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
255 result = acpi_bus_get_device(handle, &device);
256 if (result)
257 return result;
258
259 if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
260 return -EINVAL; 231 return -EINVAL;
261 232
262 /* Make sure this is a valid target state */ 233 /* Make sure this is a valid target state */
263 234
264 if (!device->flags.power_manageable) { 235 if (state == device->power.state) {
265 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
266 kobject_name(&device->dev.kobj)));
267 return -ENODEV;
268 }
269 /*
270 * Get device's current power state
271 */
272 if (!acpi_power_nocheck) {
273 /*
274 * Maybe the incorrect power state is returned on the bogus
275 * bios, which is different with the real power state.
276 * For example: the bios returns D0 state and the real power
277 * state is D3. OS expects to set the device to D0 state. In
278 * such case if OS uses the power state returned by the BIOS,
279 * the device can't be transisted to the correct power state.
280 * So if the acpi_power_nocheck is set, it is unnecessary to
281 * get the power state by calling acpi_bus_get_power.
282 */
283 acpi_bus_get_power(device->handle, &device->power.state);
284 }
285 if ((state == device->power.state) && !device->flags.force_power_state) {
286 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", 236 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
287 state)); 237 state));
288 return 0; 238 return 0;
@@ -351,8 +301,75 @@ int acpi_bus_set_power(acpi_handle handle, int state)
351 return result; 301 return result;
352} 302}
353 303
304
305int acpi_bus_set_power(acpi_handle handle, int state)
306{
307 struct acpi_device *device;
308 int result;
309
310 result = acpi_bus_get_device(handle, &device);
311 if (result)
312 return result;
313
314 if (!device->flags.power_manageable) {
315 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
316 "Device [%s] is not power manageable\n",
317 dev_name(&device->dev)));
318 return -ENODEV;
319 }
320
321 return __acpi_bus_set_power(device, state);
322}
354EXPORT_SYMBOL(acpi_bus_set_power); 323EXPORT_SYMBOL(acpi_bus_set_power);
355 324
325
326int acpi_bus_init_power(struct acpi_device *device)
327{
328 int state;
329 int result;
330
331 if (!device)
332 return -EINVAL;
333
334 device->power.state = ACPI_STATE_UNKNOWN;
335
336 result = __acpi_bus_get_power(device, &state);
337 if (result)
338 return result;
339
340 if (device->power.flags.power_resources)
341 result = acpi_power_on_resources(device, state);
342
343 if (!result)
344 device->power.state = state;
345
346 return result;
347}
348
349
350int acpi_bus_update_power(acpi_handle handle, int *state_p)
351{
352 struct acpi_device *device;
353 int state;
354 int result;
355
356 result = acpi_bus_get_device(handle, &device);
357 if (result)
358 return result;
359
360 result = __acpi_bus_get_power(device, &state);
361 if (result)
362 return result;
363
364 result = __acpi_bus_set_power(device, state);
365 if (!result && state_p)
366 *state_p = state;
367
368 return result;
369}
370EXPORT_SYMBOL_GPL(acpi_bus_update_power);
371
372
356bool acpi_bus_power_manageable(acpi_handle handle) 373bool acpi_bus_power_manageable(acpi_handle handle)
357{ 374{
358 struct acpi_device *device; 375 struct acpi_device *device;
@@ -935,6 +952,12 @@ static int __init acpi_bus_init(void)
935 goto error1; 952 goto error1;
936 } 953 }
937 954
955 /*
956 * _PDC control method may load dynamic SSDT tables,
957 * and we need to install the table handler before that.
958 */
959 acpi_sysfs_init();
960
938 acpi_early_processor_set_pdc(); 961 acpi_early_processor_set_pdc();
939 962
940 /* 963 /*
@@ -984,8 +1007,7 @@ struct kobject *acpi_kobj;
984 1007
985static int __init acpi_init(void) 1008static int __init acpi_init(void)
986{ 1009{
987 int result = 0; 1010 int result;
988
989 1011
990 if (acpi_disabled) { 1012 if (acpi_disabled) {
991 printk(KERN_INFO PREFIX "Interpreter disabled.\n"); 1013 printk(KERN_INFO PREFIX "Interpreter disabled.\n");
@@ -1000,37 +1022,18 @@ static int __init acpi_init(void)
1000 1022
1001 init_acpi_device_notify(); 1023 init_acpi_device_notify();
1002 result = acpi_bus_init(); 1024 result = acpi_bus_init();
1003 1025 if (result) {
1004 if (!result) {
1005 pci_mmcfg_late_init();
1006 if (!(pm_flags & PM_APM))
1007 pm_flags |= PM_ACPI;
1008 else {
1009 printk(KERN_INFO PREFIX
1010 "APM is already active, exiting\n");
1011 disable_acpi();
1012 result = -ENODEV;
1013 }
1014 } else
1015 disable_acpi(); 1026 disable_acpi();
1016
1017 if (acpi_disabled)
1018 return result; 1027 return result;
1028 }
1019 1029
1020 /* 1030 pci_mmcfg_late_init();
1021 * If the laptop falls into the DMI check table, the power state check
1022 * will be disabled in the course of device power transition.
1023 */
1024 dmi_check_system(power_nocheck_dmi_table);
1025
1026 acpi_scan_init(); 1031 acpi_scan_init();
1027 acpi_ec_init(); 1032 acpi_ec_init();
1028 acpi_power_init();
1029 acpi_sysfs_init();
1030 acpi_debugfs_init(); 1033 acpi_debugfs_init();
1031 acpi_sleep_proc_init(); 1034 acpi_sleep_proc_init();
1032 acpi_wakeup_device_init(); 1035 acpi_wakeup_device_init();
1033 return result; 1036 return 0;
1034} 1037}
1035 1038
1036subsys_initcall(acpi_init); 1039subsys_initcall(acpi_init);
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 1575a9b51f1d..d27d072472f9 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,8 +78,6 @@ static int acpi_button_add(struct acpi_device *device);
78static int acpi_button_remove(struct acpi_device *device, int type); 78static int acpi_button_remove(struct acpi_device *device, int type);
79static int acpi_button_resume(struct acpi_device *device); 79static int acpi_button_resume(struct acpi_device *device);
80static void acpi_button_notify(struct acpi_device *device, u32 event); 80static void acpi_button_notify(struct acpi_device *device, u32 event);
81static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
82static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
83 81
84static struct acpi_driver acpi_button_driver = { 82static struct acpi_driver acpi_button_driver = {
85 .name = "button", 83 .name = "button",
@@ -98,22 +96,7 @@ struct acpi_button {
98 struct input_dev *input; 96 struct input_dev *input;
99 char phys[32]; /* for input device */ 97 char phys[32]; /* for input device */
100 unsigned long pushed; 98 unsigned long pushed;
101}; 99 bool wakeup_enabled;
102
103static const struct file_operations acpi_button_info_fops = {
104 .owner = THIS_MODULE,
105 .open = acpi_button_info_open_fs,
106 .read = seq_read,
107 .llseek = seq_lseek,
108 .release = single_release,
109};
110
111static const struct file_operations acpi_button_state_fops = {
112 .owner = THIS_MODULE,
113 .open = acpi_button_state_open_fs,
114 .read = seq_read,
115 .llseek = seq_lseek,
116 .release = single_release,
117}; 100};
118 101
119static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); 102static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
@@ -124,20 +107,7 @@ static struct acpi_device *lid_device;
124 -------------------------------------------------------------------------- */ 107 -------------------------------------------------------------------------- */
125 108
126static struct proc_dir_entry *acpi_button_dir; 109static struct proc_dir_entry *acpi_button_dir;
127 110static struct proc_dir_entry *acpi_lid_dir;
128static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
129{
130 struct acpi_device *device = seq->private;
131
132 seq_printf(seq, "type: %s\n",
133 acpi_device_name(device));
134 return 0;
135}
136
137static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
138{
139 return single_open(file, acpi_button_info_seq_show, PDE(inode)->data);
140}
141 111
142static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) 112static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
143{ 113{
@@ -157,77 +127,85 @@ static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
157 return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); 127 return single_open(file, acpi_button_state_seq_show, PDE(inode)->data);
158} 128}
159 129
160static struct proc_dir_entry *acpi_power_dir; 130static const struct file_operations acpi_button_state_fops = {
161static struct proc_dir_entry *acpi_sleep_dir; 131 .owner = THIS_MODULE,
162static struct proc_dir_entry *acpi_lid_dir; 132 .open = acpi_button_state_open_fs,
133 .read = seq_read,
134 .llseek = seq_lseek,
135 .release = single_release,
136};
163 137
164static int acpi_button_add_fs(struct acpi_device *device) 138static int acpi_button_add_fs(struct acpi_device *device)
165{ 139{
166 struct acpi_button *button = acpi_driver_data(device); 140 struct acpi_button *button = acpi_driver_data(device);
167 struct proc_dir_entry *entry = NULL; 141 struct proc_dir_entry *entry = NULL;
142 int ret = 0;
168 143
169 switch (button->type) { 144 /* procfs I/F for ACPI lid device only */
170 case ACPI_BUTTON_TYPE_POWER: 145 if (button->type != ACPI_BUTTON_TYPE_LID)
171 if (!acpi_power_dir) 146 return 0;
172 acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, 147
173 acpi_button_dir); 148 if (acpi_button_dir || acpi_lid_dir) {
174 entry = acpi_power_dir; 149 printk(KERN_ERR PREFIX "More than one Lid device found!\n");
175 break; 150 return -EEXIST;
176 case ACPI_BUTTON_TYPE_SLEEP:
177 if (!acpi_sleep_dir)
178 acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
179 acpi_button_dir);
180 entry = acpi_sleep_dir;
181 break;
182 case ACPI_BUTTON_TYPE_LID:
183 if (!acpi_lid_dir)
184 acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID,
185 acpi_button_dir);
186 entry = acpi_lid_dir;
187 break;
188 } 151 }
189 152
190 if (!entry) 153 /* create /proc/acpi/button */
154 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
155 if (!acpi_button_dir)
191 return -ENODEV; 156 return -ENODEV;
192 157
193 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); 158 /* create /proc/acpi/button/lid */
194 if (!acpi_device_dir(device)) 159 acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
195 return -ENODEV; 160 if (!acpi_lid_dir) {
161 ret = -ENODEV;
162 goto remove_button_dir;
163 }
196 164
197 /* 'info' [R] */ 165 /* create /proc/acpi/button/lid/LID/ */
198 entry = proc_create_data(ACPI_BUTTON_FILE_INFO, 166 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
199 S_IRUGO, acpi_device_dir(device), 167 if (!acpi_device_dir(device)) {
200 &acpi_button_info_fops, device); 168 ret = -ENODEV;
201 if (!entry) 169 goto remove_lid_dir;
202 return -ENODEV; 170 }
203 171
204 /* show lid state [R] */ 172 /* create /proc/acpi/button/lid/LID/state */
205 if (button->type == ACPI_BUTTON_TYPE_LID) { 173 entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
206 entry = proc_create_data(ACPI_BUTTON_FILE_STATE, 174 S_IRUGO, acpi_device_dir(device),
207 S_IRUGO, acpi_device_dir(device), 175 &acpi_button_state_fops, device);
208 &acpi_button_state_fops, device); 176 if (!entry) {
209 if (!entry) 177 ret = -ENODEV;
210 return -ENODEV; 178 goto remove_dev_dir;
211 } 179 }
212 180
213 return 0; 181done:
182 return ret;
183
184remove_dev_dir:
185 remove_proc_entry(acpi_device_bid(device),
186 acpi_lid_dir);
187 acpi_device_dir(device) = NULL;
188remove_lid_dir:
189 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
190remove_button_dir:
191 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
192 goto done;
214} 193}
215 194
216static int acpi_button_remove_fs(struct acpi_device *device) 195static int acpi_button_remove_fs(struct acpi_device *device)
217{ 196{
218 struct acpi_button *button = acpi_driver_data(device); 197 struct acpi_button *button = acpi_driver_data(device);
219 198
220 if (acpi_device_dir(device)) { 199 if (button->type != ACPI_BUTTON_TYPE_LID)
221 if (button->type == ACPI_BUTTON_TYPE_LID) 200 return 0;
222 remove_proc_entry(ACPI_BUTTON_FILE_STATE,
223 acpi_device_dir(device));
224 remove_proc_entry(ACPI_BUTTON_FILE_INFO,
225 acpi_device_dir(device));
226 201
227 remove_proc_entry(acpi_device_bid(device), 202 remove_proc_entry(ACPI_BUTTON_FILE_STATE,
228 acpi_device_dir(device)->parent); 203 acpi_device_dir(device));
229 acpi_device_dir(device) = NULL; 204 remove_proc_entry(acpi_device_bid(device),
230 } 205 acpi_lid_dir);
206 acpi_device_dir(device) = NULL;
207 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
208 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
231 209
232 return 0; 210 return 0;
233} 211}
@@ -279,6 +257,9 @@ static int acpi_lid_send_state(struct acpi_device *device)
279 input_report_switch(button->input, SW_LID, !state); 257 input_report_switch(button->input, SW_LID, !state);
280 input_sync(button->input); 258 input_sync(button->input);
281 259
260 if (state)
261 pm_wakeup_event(&device->dev, 0);
262
282 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); 263 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
283 if (ret == NOTIFY_DONE) 264 if (ret == NOTIFY_DONE)
284 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, 265 ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
@@ -314,6 +295,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
314 input_sync(input); 295 input_sync(input);
315 input_report_key(input, keycode, 0); 296 input_report_key(input, keycode, 0);
316 input_sync(input); 297 input_sync(input);
298
299 pm_wakeup_event(&device->dev, 0);
317 } 300 }
318 301
319 acpi_bus_generate_proc_event(device, event, ++button->pushed); 302 acpi_bus_generate_proc_event(device, event, ++button->pushed);
@@ -338,7 +321,8 @@ static int acpi_button_add(struct acpi_device *device)
338{ 321{
339 struct acpi_button *button; 322 struct acpi_button *button;
340 struct input_dev *input; 323 struct input_dev *input;
341 char *hid, *name, *class; 324 const char *hid = acpi_device_hid(device);
325 char *name, *class;
342 int error; 326 int error;
343 327
344 button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); 328 button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
@@ -353,7 +337,6 @@ static int acpi_button_add(struct acpi_device *device)
353 goto err_free_button; 337 goto err_free_button;
354 } 338 }
355 339
356 hid = acpi_device_hid(device);
357 name = acpi_device_name(device); 340 name = acpi_device_name(device);
358 class = acpi_device_class(device); 341 class = acpi_device_class(device);
359 342
@@ -425,8 +408,10 @@ static int acpi_button_add(struct acpi_device *device)
425 /* Button's GPE is run-wake GPE */ 408 /* Button's GPE is run-wake GPE */
426 acpi_enable_gpe(device->wakeup.gpe_device, 409 acpi_enable_gpe(device->wakeup.gpe_device,
427 device->wakeup.gpe_number); 410 device->wakeup.gpe_number);
428 device->wakeup.run_wake_count++; 411 if (!device_may_wakeup(&device->dev)) {
429 device->wakeup.state.enabled = 1; 412 device_set_wakeup_enable(&device->dev, true);
413 button->wakeup_enabled = true;
414 }
430 } 415 }
431 416
432 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); 417 printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
@@ -448,8 +433,8 @@ static int acpi_button_remove(struct acpi_device *device, int type)
448 if (device->wakeup.flags.valid) { 433 if (device->wakeup.flags.valid) {
449 acpi_disable_gpe(device->wakeup.gpe_device, 434 acpi_disable_gpe(device->wakeup.gpe_device,
450 device->wakeup.gpe_number); 435 device->wakeup.gpe_number);
451 device->wakeup.run_wake_count--; 436 if (button->wakeup_enabled)
452 device->wakeup.state.enabled = 0; 437 device_set_wakeup_enable(&device->dev, false);
453 } 438 }
454 439
455 acpi_button_remove_fs(device); 440 acpi_button_remove_fs(device);
@@ -460,32 +445,12 @@ static int acpi_button_remove(struct acpi_device *device, int type)
460 445
461static int __init acpi_button_init(void) 446static int __init acpi_button_init(void)
462{ 447{
463 int result; 448 return acpi_bus_register_driver(&acpi_button_driver);
464
465 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
466 if (!acpi_button_dir)
467 return -ENODEV;
468
469 result = acpi_bus_register_driver(&acpi_button_driver);
470 if (result < 0) {
471 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
472 return -ENODEV;
473 }
474
475 return 0;
476} 449}
477 450
478static void __exit acpi_button_exit(void) 451static void __exit acpi_button_exit(void)
479{ 452{
480 acpi_bus_unregister_driver(&acpi_button_driver); 453 acpi_bus_unregister_driver(&acpi_button_driver);
481
482 if (acpi_power_dir)
483 remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir);
484 if (acpi_sleep_dir)
485 remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir);
486 if (acpi_lid_dir)
487 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
488 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
489} 454}
490 455
491module_init(acpi_button_init); 456module_init(acpi_button_init);
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
new file mode 100644
index 000000000000..5d42c2414ae5
--- /dev/null
+++ b/drivers/acpi/custom_method.c
@@ -0,0 +1,100 @@
1/*
2 * debugfs.c - ACPI debugfs interface to userspace.
3 */
4
5#include <linux/init.h>
6#include <linux/module.h>
7#include <linux/kernel.h>
8#include <linux/uaccess.h>
9#include <linux/debugfs.h>
10#include <acpi/acpi_drivers.h>
11
12#include "internal.h"
13
14#define _COMPONENT ACPI_SYSTEM_COMPONENT
15ACPI_MODULE_NAME("custom_method");
16MODULE_LICENSE("GPL");
17
18static struct dentry *cm_dentry;
19
20/* /sys/kernel/debug/acpi/custom_method */
21
22static ssize_t cm_write(struct file *file, const char __user * user_buf,
23 size_t count, loff_t *ppos)
24{
25 static char *buf;
26 static u32 max_size;
27 static u32 uncopied_bytes;
28
29 struct acpi_table_header table;
30 acpi_status status;
31
32 if (!(*ppos)) {
33 /* parse the table header to get the table length */
34 if (count <= sizeof(struct acpi_table_header))
35 return -EINVAL;
36 if (copy_from_user(&table, user_buf,
37 sizeof(struct acpi_table_header)))
38 return -EFAULT;
39 uncopied_bytes = max_size = table.length;
40 buf = kzalloc(max_size, GFP_KERNEL);
41 if (!buf)
42 return -ENOMEM;
43 }
44
45 if (buf == NULL)
46 return -EINVAL;
47
48 if ((*ppos > max_size) ||
49 (*ppos + count > max_size) ||
50 (*ppos + count < count) ||
51 (count > uncopied_bytes))
52 return -EINVAL;
53
54 if (copy_from_user(buf + (*ppos), user_buf, count)) {
55 kfree(buf);
56 buf = NULL;
57 return -EFAULT;
58 }
59
60 uncopied_bytes -= count;
61 *ppos += count;
62
63 if (!uncopied_bytes) {
64 status = acpi_install_method(buf);
65 kfree(buf);
66 buf = NULL;
67 if (ACPI_FAILURE(status))
68 return -EINVAL;
69 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
70 }
71
72 return count;
73}
74
75static const struct file_operations cm_fops = {
76 .write = cm_write,
77 .llseek = default_llseek,
78};
79
80static int __init acpi_custom_method_init(void)
81{
82 if (acpi_debugfs_dir == NULL)
83 return -ENOENT;
84
85 cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
86 acpi_debugfs_dir, NULL, &cm_fops);
87 if (cm_dentry == NULL)
88 return -ENODEV;
89
90 return 0;
91}
92
93static void __exit acpi_custom_method_exit(void)
94{
95 if (cm_dentry)
96 debugfs_remove(cm_dentry);
97 }
98
99module_init(acpi_custom_method_init);
100module_exit(acpi_custom_method_exit);
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c
index 7de27d49c4b9..182a9fc36355 100644
--- a/drivers/acpi/debugfs.c
+++ b/drivers/acpi/debugfs.c
@@ -3,91 +3,16 @@
3 */ 3 */
4 4
5#include <linux/init.h> 5#include <linux/init.h>
6#include <linux/module.h>
7#include <linux/kernel.h>
8#include <linux/uaccess.h>
9#include <linux/debugfs.h> 6#include <linux/debugfs.h>
10#include <acpi/acpi_drivers.h> 7#include <acpi/acpi_drivers.h>
11 8
12#define _COMPONENT ACPI_SYSTEM_COMPONENT 9#define _COMPONENT ACPI_SYSTEM_COMPONENT
13ACPI_MODULE_NAME("debugfs"); 10ACPI_MODULE_NAME("debugfs");
14 11
12struct dentry *acpi_debugfs_dir;
13EXPORT_SYMBOL_GPL(acpi_debugfs_dir);
15 14
16/* /sys/modules/acpi/parameters/aml_debug_output */ 15void __init acpi_debugfs_init(void)
17
18module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
19 bool, 0644);
20MODULE_PARM_DESC(aml_debug_output,
21 "To enable/disable the ACPI Debug Object output.");
22
23/* /sys/kernel/debug/acpi/custom_method */
24
25static ssize_t cm_write(struct file *file, const char __user * user_buf,
26 size_t count, loff_t *ppos)
27{ 16{
28 static char *buf; 17 acpi_debugfs_dir = debugfs_create_dir("acpi", NULL);
29 static int uncopied_bytes;
30 struct acpi_table_header table;
31 acpi_status status;
32
33 if (!(*ppos)) {
34 /* parse the table header to get the table length */
35 if (count <= sizeof(struct acpi_table_header))
36 return -EINVAL;
37 if (copy_from_user(&table, user_buf,
38 sizeof(struct acpi_table_header)))
39 return -EFAULT;
40 uncopied_bytes = table.length;
41 buf = kzalloc(uncopied_bytes, GFP_KERNEL);
42 if (!buf)
43 return -ENOMEM;
44 }
45
46 if (uncopied_bytes < count) {
47 kfree(buf);
48 return -EINVAL;
49 }
50
51 if (copy_from_user(buf + (*ppos), user_buf, count)) {
52 kfree(buf);
53 return -EFAULT;
54 }
55
56 uncopied_bytes -= count;
57 *ppos += count;
58
59 if (!uncopied_bytes) {
60 status = acpi_install_method(buf);
61 kfree(buf);
62 if (ACPI_FAILURE(status))
63 return -EINVAL;
64 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
65 }
66
67 return count;
68}
69
70static const struct file_operations cm_fops = {
71 .write = cm_write,
72};
73
74int __init acpi_debugfs_init(void)
75{
76 struct dentry *acpi_dir, *cm_dentry;
77
78 acpi_dir = debugfs_create_dir("acpi", NULL);
79 if (!acpi_dir)
80 goto err;
81
82 cm_dentry = debugfs_create_file("custom_method", S_IWUGO,
83 acpi_dir, NULL, &cm_fops);
84 if (!cm_dentry)
85 goto err;
86
87 return 0;
88
89err:
90 if (acpi_dir)
91 debugfs_remove(acpi_dir);
92 return -EINVAL;
93} 18}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 3fe29e992be8..1864ad3cf895 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -725,6 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
725 complete_dock(ds); 725 complete_dock(ds);
726 dock_event(ds, event, DOCK_EVENT); 726 dock_event(ds, event, DOCK_EVENT);
727 dock_lock(ds, 1); 727 dock_lock(ds, 1);
728 acpi_update_all_gpes();
728 break; 729 break;
729 } 730 }
730 if (dock_present(ds) || dock_in_progress(ds)) 731 if (dock_present(ds) || dock_in_progress(ds))
@@ -929,7 +930,7 @@ static struct attribute_group dock_attribute_group = {
929 * allocated and initialize a new dock station device. Find all devices 930 * allocated and initialize a new dock station device. Find all devices
930 * that are on the dock station, and register for dock event notifications. 931 * that are on the dock station, and register for dock event notifications.
931 */ 932 */
932static int dock_add(acpi_handle handle) 933static int __init dock_add(acpi_handle handle)
933{ 934{
934 int ret, id; 935 int ret, id;
935 struct dock_station ds, *dock_station; 936 struct dock_station ds, *dock_station;
@@ -1023,7 +1024,7 @@ static int dock_remove(struct dock_station *ds)
1023 * 1024 *
1024 * This is called by acpi_walk_namespace to look for dock stations. 1025 * This is called by acpi_walk_namespace to look for dock stations.
1025 */ 1026 */
1026static acpi_status 1027static __init acpi_status
1027find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) 1028find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
1028{ 1029{
1029 if (is_dock(handle)) 1030 if (is_dock(handle))
@@ -1032,7 +1033,7 @@ find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
1032 return AE_OK; 1033 return AE_OK;
1033} 1034}
1034 1035
1035static acpi_status 1036static __init acpi_status
1036find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) 1037find_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
1037{ 1038{
1038 /* If bay is a dock, it's already handled */ 1039 /* If bay is a dock, it's already handled */
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f31291ba94d0..b19a18dd994f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -69,7 +69,6 @@ enum ec_command {
69 69
70#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ 70#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
71#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ 71#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
72#define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */
73#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ 72#define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */
74 73
75#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts 74#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
@@ -83,6 +82,11 @@ enum {
83 EC_FLAGS_BLOCKED, /* Transactions are blocked */ 82 EC_FLAGS_BLOCKED, /* Transactions are blocked */
84}; 83};
85 84
85/* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
86static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
87module_param(ec_delay, uint, 0644);
88MODULE_PARM_DESC(ec_delay, "Timeout(ms) waited until an EC command completes");
89
86/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 90/* If we find an EC via the ECDT, we need to keep a ptr to its context */
87/* External interfaces use first EC only, so remember */ 91/* External interfaces use first EC only, so remember */
88typedef int (*acpi_ec_query_func) (void *data); 92typedef int (*acpi_ec_query_func) (void *data);
@@ -210,7 +214,7 @@ static int ec_poll(struct acpi_ec *ec)
210 int repeat = 2; /* number of command restarts */ 214 int repeat = 2; /* number of command restarts */
211 while (repeat--) { 215 while (repeat--) {
212 unsigned long delay = jiffies + 216 unsigned long delay = jiffies +
213 msecs_to_jiffies(ACPI_EC_DELAY); 217 msecs_to_jiffies(ec_delay);
214 do { 218 do {
215 /* don't sleep with disabled interrupts */ 219 /* don't sleep with disabled interrupts */
216 if (EC_FLAGS_MSI || irqs_disabled()) { 220 if (EC_FLAGS_MSI || irqs_disabled()) {
@@ -265,7 +269,7 @@ static int ec_check_ibf0(struct acpi_ec *ec)
265 269
266static int ec_wait_ibf0(struct acpi_ec *ec) 270static int ec_wait_ibf0(struct acpi_ec *ec)
267{ 271{
268 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); 272 unsigned long delay = jiffies + msecs_to_jiffies(ec_delay);
269 /* interrupt wait manually if GPE mode is not active */ 273 /* interrupt wait manually if GPE mode is not active */
270 while (time_before(jiffies, delay)) 274 while (time_before(jiffies, delay))
271 if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), 275 if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
@@ -428,8 +432,7 @@ EXPORT_SYMBOL(ec_write);
428 432
429int ec_transaction(u8 command, 433int ec_transaction(u8 command,
430 const u8 * wdata, unsigned wdata_len, 434 const u8 * wdata, unsigned wdata_len,
431 u8 * rdata, unsigned rdata_len, 435 u8 * rdata, unsigned rdata_len)
432 int force_poll)
433{ 436{
434 struct transaction t = {.command = command, 437 struct transaction t = {.command = command,
435 .wdata = wdata, .rdata = rdata, 438 .wdata = wdata, .rdata = rdata,
@@ -587,8 +590,6 @@ static void acpi_ec_gpe_query(void *ec_cxt)
587 mutex_unlock(&ec->lock); 590 mutex_unlock(&ec->lock);
588} 591}
589 592
590static void acpi_ec_gpe_query(void *ec_cxt);
591
592static int ec_check_sci(struct acpi_ec *ec, u8 state) 593static int ec_check_sci(struct acpi_ec *ec, u8 state)
593{ 594{
594 if (state & ACPI_EC_FLAG_SCI) { 595 if (state & ACPI_EC_FLAG_SCI) {
@@ -601,7 +602,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
601 return 0; 602 return 0;
602} 603}
603 604
604static u32 acpi_ec_gpe_handler(void *data) 605static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
606 u32 gpe_number, void *data)
605{ 607{
606 struct acpi_ec *ec = data; 608 struct acpi_ec *ec = data;
607 609
@@ -613,7 +615,7 @@ static u32 acpi_ec_gpe_handler(void *data)
613 wake_up(&ec->wait); 615 wake_up(&ec->wait);
614 ec_check_sci(ec, acpi_ec_read_status(ec)); 616 ec_check_sci(ec, acpi_ec_read_status(ec));
615 } 617 }
616 return ACPI_INTERRUPT_HANDLED; 618 return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
617} 619}
618 620
619/* -------------------------------------------------------------------------- 621/* --------------------------------------------------------------------------
@@ -802,8 +804,6 @@ static int acpi_ec_add(struct acpi_device *device)
802 return -EINVAL; 804 return -EINVAL;
803 } 805 }
804 806
805 ec->handle = device->handle;
806
807 /* Find and register all query methods */ 807 /* Find and register all query methods */
808 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, 808 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
809 acpi_ec_register_query_methods, NULL, ec, NULL); 809 acpi_ec_register_query_methods, NULL, ec, NULL);
@@ -929,8 +929,22 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
929 ec_flag_msi, "MSI hardware", { 929 ec_flag_msi, "MSI hardware", {
930 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, 930 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL},
931 { 931 {
932 ec_flag_msi, "MSI hardware", {
933 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
934 {
935 ec_flag_msi, "Quanta hardware", {
936 DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
937 DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL},
938 {
939 ec_flag_msi, "Quanta hardware", {
940 DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
941 DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL},
942 {
932 ec_validate_ecdt, "ASUS hardware", { 943 ec_validate_ecdt, "ASUS hardware", {
933 DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, 944 DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
945 {
946 ec_validate_ecdt, "ASUS hardware", {
947 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL},
934 {}, 948 {},
935}; 949};
936 950
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
index 0e869b3f81ca..05b44201a614 100644
--- a/drivers/acpi/ec_sys.c
+++ b/drivers/acpi/ec_sys.c
@@ -24,10 +24,6 @@ MODULE_PARM_DESC(write_support, "Dangerous, reboot and removal of battery may "
24 24
25#define EC_SPACE_SIZE 256 25#define EC_SPACE_SIZE 256
26 26
27struct sysdev_class acpi_ec_sysdev_class = {
28 .name = "ec",
29};
30
31static struct dentry *acpi_ec_debugfs_dir; 27static struct dentry *acpi_ec_debugfs_dir;
32 28
33static int acpi_ec_open_io(struct inode *i, struct file *f) 29static int acpi_ec_open_io(struct inode *i, struct file *f)
@@ -101,6 +97,7 @@ static struct file_operations acpi_ec_io_ops = {
101 .open = acpi_ec_open_io, 97 .open = acpi_ec_open_io,
102 .read = acpi_ec_read_io, 98 .read = acpi_ec_read_io,
103 .write = acpi_ec_write_io, 99 .write = acpi_ec_write_io,
100 .llseek = default_llseek,
104}; 101};
105 102
106int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count) 103int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count)
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index d439314a75d8..85d908993809 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -110,6 +110,7 @@ static const struct file_operations acpi_system_event_ops = {
110 .read = acpi_system_read_event, 110 .read = acpi_system_read_event,
111 .release = acpi_system_close_event, 111 .release = acpi_system_close_event,
112 .poll = acpi_system_poll_event, 112 .poll = acpi_system_poll_event,
113 .llseek = default_llseek,
113}; 114};
114#endif /* CONFIG_ACPI_PROC_EVENT */ 115#endif /* CONFIG_ACPI_PROC_EVENT */
115 116
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index d94d2953c974..467479f07c1f 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -27,8 +27,6 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/proc_fs.h>
31#include <linux/seq_file.h>
32#include <asm/uaccess.h> 30#include <asm/uaccess.h>
33#include <linux/thermal.h> 31#include <linux/thermal.h>
34#include <acpi/acpi_bus.h> 32#include <acpi/acpi_bus.h>
@@ -88,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
88 if (!device) 86 if (!device)
89 return -EINVAL; 87 return -EINVAL;
90 88
91 result = acpi_bus_get_power(device->handle, &acpi_state); 89 result = acpi_bus_update_power(device->handle, &acpi_state);
92 if (result) 90 if (result)
93 return result; 91 return result;
94 92
@@ -119,129 +117,12 @@ static struct thermal_cooling_device_ops fan_cooling_ops = {
119}; 117};
120 118
121/* -------------------------------------------------------------------------- 119/* --------------------------------------------------------------------------
122 FS Interface (/proc)
123 -------------------------------------------------------------------------- */
124#ifdef CONFIG_ACPI_PROCFS
125
126static struct proc_dir_entry *acpi_fan_dir;
127
128static int acpi_fan_read_state(struct seq_file *seq, void *offset)
129{
130 struct acpi_device *device = seq->private;
131 int state = 0;
132
133
134 if (device) {
135 if (acpi_bus_get_power(device->handle, &state))
136 seq_printf(seq, "status: ERROR\n");
137 else
138 seq_printf(seq, "status: %s\n",
139 !state ? "on" : "off");
140 }
141 return 0;
142}
143
144static int acpi_fan_state_open_fs(struct inode *inode, struct file *file)
145{
146 return single_open(file, acpi_fan_read_state, PDE(inode)->data);
147}
148
149static ssize_t
150acpi_fan_write_state(struct file *file, const char __user * buffer,
151 size_t count, loff_t * ppos)
152{
153 int result = 0;
154 struct seq_file *m = file->private_data;
155 struct acpi_device *device = m->private;
156 char state_string[3] = { '\0' };
157
158 if (count > sizeof(state_string) - 1)
159 return -EINVAL;
160
161 if (copy_from_user(state_string, buffer, count))
162 return -EFAULT;
163
164 state_string[count] = '\0';
165 if ((state_string[0] < '0') || (state_string[0] > '3'))
166 return -EINVAL;
167 if (state_string[1] == '\n')
168 state_string[1] = '\0';
169 if (state_string[1] != '\0')
170 return -EINVAL;
171
172 result = acpi_bus_set_power(device->handle,
173 simple_strtoul(state_string, NULL, 0));
174 if (result)
175 return result;
176
177 return count;
178}
179
180static const struct file_operations acpi_fan_state_ops = {
181 .open = acpi_fan_state_open_fs,
182 .read = seq_read,
183 .write = acpi_fan_write_state,
184 .llseek = seq_lseek,
185 .release = single_release,
186 .owner = THIS_MODULE,
187};
188
189static int acpi_fan_add_fs(struct acpi_device *device)
190{
191 struct proc_dir_entry *entry = NULL;
192
193
194 if (!device)
195 return -EINVAL;
196
197 if (!acpi_device_dir(device)) {
198 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
199 acpi_fan_dir);
200 if (!acpi_device_dir(device))
201 return -ENODEV;
202 }
203
204 /* 'status' [R/W] */
205 entry = proc_create_data(ACPI_FAN_FILE_STATE,
206 S_IFREG | S_IRUGO | S_IWUSR,
207 acpi_device_dir(device),
208 &acpi_fan_state_ops,
209 device);
210 if (!entry)
211 return -ENODEV;
212 return 0;
213}
214
215static int acpi_fan_remove_fs(struct acpi_device *device)
216{
217
218 if (acpi_device_dir(device)) {
219 remove_proc_entry(ACPI_FAN_FILE_STATE, acpi_device_dir(device));
220 remove_proc_entry(acpi_device_bid(device), acpi_fan_dir);
221 acpi_device_dir(device) = NULL;
222 }
223
224 return 0;
225}
226#else
227static int acpi_fan_add_fs(struct acpi_device *device)
228{
229 return 0;
230}
231
232static int acpi_fan_remove_fs(struct acpi_device *device)
233{
234 return 0;
235}
236#endif
237/* --------------------------------------------------------------------------
238 Driver Interface 120 Driver Interface
239 -------------------------------------------------------------------------- */ 121 -------------------------------------------------------------------------- */
240 122
241static int acpi_fan_add(struct acpi_device *device) 123static int acpi_fan_add(struct acpi_device *device)
242{ 124{
243 int result = 0; 125 int result = 0;
244 int state = 0;
245 struct thermal_cooling_device *cdev; 126 struct thermal_cooling_device *cdev;
246 127
247 if (!device) 128 if (!device)
@@ -250,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device)
250 strcpy(acpi_device_name(device), "Fan"); 131 strcpy(acpi_device_name(device), "Fan");
251 strcpy(acpi_device_class(device), ACPI_FAN_CLASS); 132 strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
252 133
253 result = acpi_bus_get_power(device->handle, &state); 134 result = acpi_bus_update_power(device->handle, NULL);
254 if (result) { 135 if (result) {
255 printk(KERN_ERR PREFIX "Reading power state\n"); 136 printk(KERN_ERR PREFIX "Setting initial power state\n");
256 goto end; 137 goto end;
257 } 138 }
258 139
259 device->flags.force_power_state = 1;
260 acpi_bus_set_power(device->handle, state);
261 device->flags.force_power_state = 0;
262
263 cdev = thermal_cooling_device_register("Fan", device, 140 cdev = thermal_cooling_device_register("Fan", device,
264 &fan_cooling_ops); 141 &fan_cooling_ops);
265 if (IS_ERR(cdev)) { 142 if (IS_ERR(cdev)) {
@@ -284,10 +161,6 @@ static int acpi_fan_add(struct acpi_device *device)
284 dev_err(&device->dev, "Failed to create sysfs link " 161 dev_err(&device->dev, "Failed to create sysfs link "
285 "'device'\n"); 162 "'device'\n");
286 163
287 result = acpi_fan_add_fs(device);
288 if (result)
289 goto end;
290
291 printk(KERN_INFO PREFIX "%s [%s] (%s)\n", 164 printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
292 acpi_device_name(device), acpi_device_bid(device), 165 acpi_device_name(device), acpi_device_bid(device),
293 !device->power.state ? "on" : "off"); 166 !device->power.state ? "on" : "off");
@@ -303,7 +176,6 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
303 if (!device || !cdev) 176 if (!device || !cdev)
304 return -EINVAL; 177 return -EINVAL;
305 178
306 acpi_fan_remove_fs(device);
307 sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 179 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
308 sysfs_remove_link(&cdev->device.kobj, "device"); 180 sysfs_remove_link(&cdev->device.kobj, "device");
309 thermal_cooling_device_unregister(cdev); 181 thermal_cooling_device_unregister(cdev);
@@ -323,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
323 195
324static int acpi_fan_resume(struct acpi_device *device) 196static int acpi_fan_resume(struct acpi_device *device)
325{ 197{
326 int result = 0; 198 int result;
327 int power_state = 0;
328 199
329 if (!device) 200 if (!device)
330 return -EINVAL; 201 return -EINVAL;
331 202
332 result = acpi_bus_get_power(device->handle, &power_state); 203 result = acpi_bus_update_power(device->handle, NULL);
333 if (result) { 204 if (result)
334 printk(KERN_ERR PREFIX 205 printk(KERN_ERR PREFIX "Error updating fan power state\n");
335 "Error reading fan power state\n");
336 return result;
337 }
338
339 device->flags.force_power_state = 1;
340 acpi_bus_set_power(device->handle, power_state);
341 device->flags.force_power_state = 0;
342 206
343 return result; 207 return result;
344} 208}
@@ -347,19 +211,9 @@ static int __init acpi_fan_init(void)
347{ 211{
348 int result = 0; 212 int result = 0;
349 213
350#ifdef CONFIG_ACPI_PROCFS
351 acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
352 if (!acpi_fan_dir)
353 return -ENODEV;
354#endif
355
356 result = acpi_bus_register_driver(&acpi_fan_driver); 214 result = acpi_bus_register_driver(&acpi_fan_driver);
357 if (result < 0) { 215 if (result < 0)
358#ifdef CONFIG_ACPI_PROCFS
359 remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
360#endif
361 return -ENODEV; 216 return -ENODEV;
362 }
363 217
364 return 0; 218 return 0;
365} 219}
@@ -369,10 +223,6 @@ static void __exit acpi_fan_exit(void)
369 223
370 acpi_bus_unregister_driver(&acpi_fan_driver); 224 acpi_bus_unregister_driver(&acpi_fan_driver);
371 225
372#ifdef CONFIG_ACPI_PROCFS
373 remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir);
374#endif
375
376 return; 226 return;
377} 227}
378 228
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 78b0164c35b2..7c47ed55e528 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
167 "firmware_node"); 167 "firmware_node");
168 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, 168 ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
169 "physical_node"); 169 "physical_node");
170 if (acpi_dev->wakeup.flags.valid) { 170 if (acpi_dev->wakeup.flags.valid)
171 device_set_wakeup_capable(dev, true); 171 device_set_wakeup_capable(dev, true);
172 device_set_wakeup_enable(dev,
173 acpi_dev->wakeup.state.enabled);
174 }
175 } 172 }
176 173
177 return 0; 174 return 0;
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index a212bfeddf8c..ca75b9ce0489 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -21,8 +21,6 @@
21#ifndef _ACPI_INTERNAL_H_ 21#ifndef _ACPI_INTERNAL_H_
22#define _ACPI_INTERNAL_H_ 22#define _ACPI_INTERNAL_H_
23 23
24#include <linux/sysdev.h>
25
26#define PREFIX "ACPI: " 24#define PREFIX "ACPI: "
27 25
28int init_acpi_device_notify(void); 26int init_acpi_device_notify(void);
@@ -30,9 +28,10 @@ int acpi_scan_init(void);
30int acpi_sysfs_init(void); 28int acpi_sysfs_init(void);
31 29
32#ifdef CONFIG_DEBUG_FS 30#ifdef CONFIG_DEBUG_FS
31extern struct dentry *acpi_debugfs_dir;
33int acpi_debugfs_init(void); 32int acpi_debugfs_init(void);
34#else 33#else
35static inline int acpi_debugfs_init(void) { return 0; } 34static inline void acpi_debugfs_init(void) { return; }
36#endif 35#endif
37 36
38/* -------------------------------------------------------------------------- 37/* --------------------------------------------------------------------------
@@ -41,9 +40,10 @@ static inline int acpi_debugfs_init(void) { return 0; }
41int acpi_power_init(void); 40int acpi_power_init(void);
42int acpi_device_sleep_wake(struct acpi_device *dev, 41int acpi_device_sleep_wake(struct acpi_device *dev,
43 int enable, int sleep_state, int dev_state); 42 int enable, int sleep_state, int dev_state);
44int acpi_power_get_inferred_state(struct acpi_device *device); 43int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
44int acpi_power_on_resources(struct acpi_device *device, int state);
45int acpi_power_transition(struct acpi_device *device, int state); 45int acpi_power_transition(struct acpi_device *device, int state);
46extern int acpi_power_nocheck; 46int acpi_bus_init_power(struct acpi_device *device);
47 47
48int acpi_wakeup_device_init(void); 48int acpi_wakeup_device_init(void);
49void acpi_early_processor_set_pdc(void); 49void acpi_early_processor_set_pdc(void);
@@ -63,7 +63,6 @@ struct acpi_ec {
63 struct list_head list; 63 struct list_head list;
64 struct transaction *curr; 64 struct transaction *curr;
65 spinlock_t curr_lock; 65 spinlock_t curr_lock;
66 struct sys_device sysdev;
67}; 66};
68 67
69extern struct acpi_ec *first_ec; 68extern struct acpi_ec *first_ec;
@@ -82,8 +81,16 @@ extern int acpi_sleep_init(void);
82 81
83#ifdef CONFIG_ACPI_SLEEP 82#ifdef CONFIG_ACPI_SLEEP
84int acpi_sleep_proc_init(void); 83int acpi_sleep_proc_init(void);
84int suspend_nvs_alloc(void);
85void suspend_nvs_free(void);
86int suspend_nvs_save(void);
87void suspend_nvs_restore(void);
85#else 88#else
86static inline int acpi_sleep_proc_init(void) { return 0; } 89static inline int acpi_sleep_proc_init(void) { return 0; }
90static inline int suspend_nvs_alloc(void) { return 0; }
91static inline void suspend_nvs_free(void) {}
92static inline int suspend_nvs_save(void) { return 0; }
93static inline void suspend_nvs_restore(void) {}
87#endif 94#endif
88 95
89#endif /* _ACPI_INTERNAL_H_ */ 96#endif /* _ACPI_INTERNAL_H_ */
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 5718566e00f9..3b5c3189fd99 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -274,15 +274,21 @@ acpi_table_parse_srat(enum acpi_srat_type id,
274 274
275int __init acpi_numa_init(void) 275int __init acpi_numa_init(void)
276{ 276{
277 int ret = 0; 277 int cnt = 0;
278
279 /*
280 * Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
281 * SRAT cpu entries could have different order with that in MADT.
282 * So go over all cpu entries in SRAT to get apicid to node mapping.
283 */
278 284
279 /* SRAT: Static Resource Affinity Table */ 285 /* SRAT: Static Resource Affinity Table */
280 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { 286 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
281 acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, 287 acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
282 acpi_parse_x2apic_affinity, nr_cpu_ids); 288 acpi_parse_x2apic_affinity, 0);
283 acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, 289 acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
284 acpi_parse_processor_affinity, nr_cpu_ids); 290 acpi_parse_processor_affinity, 0);
285 ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, 291 cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
286 acpi_parse_memory_affinity, 292 acpi_parse_memory_affinity,
287 NR_NODE_MEMBLKS); 293 NR_NODE_MEMBLKS);
288 } 294 }
@@ -291,7 +297,10 @@ int __init acpi_numa_init(void)
291 acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); 297 acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
292 298
293 acpi_numa_arch_fixup(); 299 acpi_numa_arch_fixup();
294 return ret; 300
301 if (cnt <= 0)
302 return cnt ?: -ENOENT;
303 return 0;
295} 304}
296 305
297int acpi_get_pxm(acpi_handle h) 306int acpi_get_pxm(acpi_handle h)
diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c
new file mode 100644
index 000000000000..096787b43c96
--- /dev/null
+++ b/drivers/acpi/nvs.c
@@ -0,0 +1,161 @@
1/*
2 * nvs.c - Routines for saving and restoring ACPI NVS memory region
3 *
4 * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
5 *
6 * This file is released under the GPLv2.
7 */
8
9#include <linux/io.h>
10#include <linux/kernel.h>
11#include <linux/list.h>
12#include <linux/mm.h>
13#include <linux/slab.h>
14#include <linux/acpi.h>
15#include <linux/acpi_io.h>
16#include <acpi/acpiosxf.h>
17
18/*
19 * Platforms, like ACPI, may want us to save some memory used by them during
20 * suspend and to restore the contents of this memory during the subsequent
21 * resume. The code below implements a mechanism allowing us to do that.
22 */
23
24struct nvs_page {
25 unsigned long phys_start;
26 unsigned int size;
27 void *kaddr;
28 void *data;
29 bool unmap;
30 struct list_head node;
31};
32
33static LIST_HEAD(nvs_list);
34
35/**
36 * suspend_nvs_register - register platform NVS memory region to save
37 * @start - physical address of the region
38 * @size - size of the region
39 *
40 * The NVS region need not be page-aligned (both ends) and we arrange
41 * things so that the data from page-aligned addresses in this region will
42 * be copied into separate RAM pages.
43 */
44int suspend_nvs_register(unsigned long start, unsigned long size)
45{
46 struct nvs_page *entry, *next;
47
48 pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
49 start, size);
50
51 while (size > 0) {
52 unsigned int nr_bytes;
53
54 entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL);
55 if (!entry)
56 goto Error;
57
58 list_add_tail(&entry->node, &nvs_list);
59 entry->phys_start = start;
60 nr_bytes = PAGE_SIZE - (start & ~PAGE_MASK);
61 entry->size = (size < nr_bytes) ? size : nr_bytes;
62
63 start += entry->size;
64 size -= entry->size;
65 }
66 return 0;
67
68 Error:
69 list_for_each_entry_safe(entry, next, &nvs_list, node) {
70 list_del(&entry->node);
71 kfree(entry);
72 }
73 return -ENOMEM;
74}
75
76/**
77 * suspend_nvs_free - free data pages allocated for saving NVS regions
78 */
79void suspend_nvs_free(void)
80{
81 struct nvs_page *entry;
82
83 list_for_each_entry(entry, &nvs_list, node)
84 if (entry->data) {
85 free_page((unsigned long)entry->data);
86 entry->data = NULL;
87 if (entry->kaddr) {
88 if (entry->unmap) {
89 iounmap(entry->kaddr);
90 entry->unmap = false;
91 } else {
92 acpi_os_unmap_memory(entry->kaddr,
93 entry->size);
94 }
95 entry->kaddr = NULL;
96 }
97 }
98}
99
100/**
101 * suspend_nvs_alloc - allocate memory necessary for saving NVS regions
102 */
103int suspend_nvs_alloc(void)
104{
105 struct nvs_page *entry;
106
107 list_for_each_entry(entry, &nvs_list, node) {
108 entry->data = (void *)__get_free_page(GFP_KERNEL);
109 if (!entry->data) {
110 suspend_nvs_free();
111 return -ENOMEM;
112 }
113 }
114 return 0;
115}
116
117/**
118 * suspend_nvs_save - save NVS memory regions
119 */
120int suspend_nvs_save(void)
121{
122 struct nvs_page *entry;
123
124 printk(KERN_INFO "PM: Saving platform NVS memory\n");
125
126 list_for_each_entry(entry, &nvs_list, node)
127 if (entry->data) {
128 unsigned long phys = entry->phys_start;
129 unsigned int size = entry->size;
130
131 entry->kaddr = acpi_os_get_iomem(phys, size);
132 if (!entry->kaddr) {
133 entry->kaddr = acpi_os_ioremap(phys, size);
134 entry->unmap = !!entry->kaddr;
135 }
136 if (!entry->kaddr) {
137 suspend_nvs_free();
138 return -ENOMEM;
139 }
140 memcpy(entry->data, entry->kaddr, entry->size);
141 }
142
143 return 0;
144}
145
146/**
147 * suspend_nvs_restore - restore NVS memory regions
148 *
149 * This function is going to be called with interrupts disabled, so it
150 * cannot iounmap the virtual addresses used to access the NVS region.
151 */
152void suspend_nvs_restore(void)
153{
154 struct nvs_page *entry;
155
156 printk(KERN_INFO "PM: Restoring platform NVS memory\n");
157
158 list_for_each_entry(entry, &nvs_list, node)
159 if (entry->data)
160 memcpy(entry->kaddr, entry->data, entry->size);
161}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 65b25a303b86..372f9b70f7f4 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -38,6 +38,7 @@
38#include <linux/workqueue.h> 38#include <linux/workqueue.h>
39#include <linux/nmi.h> 39#include <linux/nmi.h>
40#include <linux/acpi.h> 40#include <linux/acpi.h>
41#include <linux/acpi_io.h>
41#include <linux/efi.h> 42#include <linux/efi.h>
42#include <linux/ioport.h> 43#include <linux/ioport.h>
43#include <linux/list.h> 44#include <linux/list.h>
@@ -75,7 +76,6 @@ EXPORT_SYMBOL(acpi_in_debugger);
75extern char line_buf[80]; 76extern char line_buf[80];
76#endif /*ENABLE_DEBUGGER */ 77#endif /*ENABLE_DEBUGGER */
77 78
78static unsigned int acpi_irq_irq;
79static acpi_osd_handler acpi_irq_handler; 79static acpi_osd_handler acpi_irq_handler;
80static void *acpi_irq_context; 80static void *acpi_irq_context;
81static struct workqueue_struct *kacpid_wq; 81static struct workqueue_struct *kacpid_wq;
@@ -95,8 +95,22 @@ struct acpi_res_list {
95static LIST_HEAD(resource_list_head); 95static LIST_HEAD(resource_list_head);
96static DEFINE_SPINLOCK(acpi_res_lock); 96static DEFINE_SPINLOCK(acpi_res_lock);
97 97
98#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ 98/*
99static char osi_additional_string[OSI_STRING_LENGTH_MAX]; 99 * This list of permanent mappings is for memory that may be accessed from
100 * interrupt context, where we can't do the ioremap().
101 */
102struct acpi_ioremap {
103 struct list_head list;
104 void __iomem *virt;
105 acpi_physical_address phys;
106 acpi_size size;
107 unsigned long refcount;
108};
109
110static LIST_HEAD(acpi_ioremaps);
111static DEFINE_MUTEX(acpi_ioremap_lock);
112
113static void __init acpi_osi_setup_late(void);
100 114
101/* 115/*
102 * The story of _OSI(Linux) 116 * The story of _OSI(Linux)
@@ -135,8 +149,21 @@ static struct osi_linux {
135 unsigned int enable:1; 149 unsigned int enable:1;
136 unsigned int dmi:1; 150 unsigned int dmi:1;
137 unsigned int cmdline:1; 151 unsigned int cmdline:1;
138 unsigned int known:1; 152} osi_linux = {0, 0, 0};
139} osi_linux = { 0, 0, 0, 0}; 153
154static u32 acpi_osi_handler(acpi_string interface, u32 supported)
155{
156 if (!strcmp("Linux", interface)) {
157
158 printk(KERN_NOTICE FW_BUG PREFIX
159 "BIOS _OSI(Linux) query %s%s\n",
160 osi_linux.enable ? "honored" : "ignored",
161 osi_linux.cmdline ? " via cmdline" :
162 osi_linux.dmi ? " via DMI" : "");
163 }
164
165 return supported;
166}
140 167
141static void __init acpi_request_region (struct acpi_generic_address *addr, 168static void __init acpi_request_region (struct acpi_generic_address *addr,
142 unsigned int length, char *desc) 169 unsigned int length, char *desc)
@@ -185,36 +212,6 @@ static int __init acpi_reserve_resources(void)
185} 212}
186device_initcall(acpi_reserve_resources); 213device_initcall(acpi_reserve_resources);
187 214
188acpi_status __init acpi_os_initialize(void)
189{
190 return AE_OK;
191}
192
193acpi_status acpi_os_initialize1(void)
194{
195 kacpid_wq = create_workqueue("kacpid");
196 kacpi_notify_wq = create_workqueue("kacpi_notify");
197 kacpi_hotplug_wq = create_workqueue("kacpi_hotplug");
198 BUG_ON(!kacpid_wq);
199 BUG_ON(!kacpi_notify_wq);
200 BUG_ON(!kacpi_hotplug_wq);
201 return AE_OK;
202}
203
204acpi_status acpi_os_terminate(void)
205{
206 if (acpi_irq_handler) {
207 acpi_os_remove_interrupt_handler(acpi_irq_irq,
208 acpi_irq_handler);
209 }
210
211 destroy_workqueue(kacpid_wq);
212 destroy_workqueue(kacpi_notify_wq);
213 destroy_workqueue(kacpi_hotplug_wq);
214
215 return AE_OK;
216}
217
218void acpi_os_printf(const char *fmt, ...) 215void acpi_os_printf(const char *fmt, ...)
219{ 216{
220 va_list args; 217 va_list args;
@@ -260,29 +257,151 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
260 } 257 }
261} 258}
262 259
260/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
261static struct acpi_ioremap *
262acpi_map_lookup(acpi_physical_address phys, acpi_size size)
263{
264 struct acpi_ioremap *map;
265
266 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
267 if (map->phys <= phys &&
268 phys + size <= map->phys + map->size)
269 return map;
270
271 return NULL;
272}
273
274/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
275static void __iomem *
276acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
277{
278 struct acpi_ioremap *map;
279
280 map = acpi_map_lookup(phys, size);
281 if (map)
282 return map->virt + (phys - map->phys);
283
284 return NULL;
285}
286
287void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
288{
289 struct acpi_ioremap *map;
290 void __iomem *virt = NULL;
291
292 mutex_lock(&acpi_ioremap_lock);
293 map = acpi_map_lookup(phys, size);
294 if (map) {
295 virt = map->virt + (phys - map->phys);
296 map->refcount++;
297 }
298 mutex_unlock(&acpi_ioremap_lock);
299 return virt;
300}
301EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
302
303/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
304static struct acpi_ioremap *
305acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
306{
307 struct acpi_ioremap *map;
308
309 list_for_each_entry_rcu(map, &acpi_ioremaps, list)
310 if (map->virt <= virt &&
311 virt + size <= map->virt + map->size)
312 return map;
313
314 return NULL;
315}
316
263void __iomem *__init_refok 317void __iomem *__init_refok
264acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 318acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
265{ 319{
320 struct acpi_ioremap *map;
321 void __iomem *virt;
322 acpi_physical_address pg_off;
323 acpi_size pg_sz;
324
266 if (phys > ULONG_MAX) { 325 if (phys > ULONG_MAX) {
267 printk(KERN_ERR PREFIX "Cannot map memory that high\n"); 326 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
268 return NULL; 327 return NULL;
269 } 328 }
270 if (acpi_gbl_permanent_mmap) 329
271 /* 330 if (!acpi_gbl_permanent_mmap)
272 * ioremap checks to ensure this is in reserved space
273 */
274 return ioremap((unsigned long)phys, size);
275 else
276 return __acpi_map_table((unsigned long)phys, size); 331 return __acpi_map_table((unsigned long)phys, size);
332
333 mutex_lock(&acpi_ioremap_lock);
334 /* Check if there's a suitable mapping already. */
335 map = acpi_map_lookup(phys, size);
336 if (map) {
337 map->refcount++;
338 goto out;
339 }
340
341 map = kzalloc(sizeof(*map), GFP_KERNEL);
342 if (!map) {
343 mutex_unlock(&acpi_ioremap_lock);
344 return NULL;
345 }
346
347 pg_off = round_down(phys, PAGE_SIZE);
348 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
349 virt = acpi_os_ioremap(pg_off, pg_sz);
350 if (!virt) {
351 mutex_unlock(&acpi_ioremap_lock);
352 kfree(map);
353 return NULL;
354 }
355
356 INIT_LIST_HEAD(&map->list);
357 map->virt = virt;
358 map->phys = pg_off;
359 map->size = pg_sz;
360 map->refcount = 1;
361
362 list_add_tail_rcu(&map->list, &acpi_ioremaps);
363
364 out:
365 mutex_unlock(&acpi_ioremap_lock);
366 return map->virt + (phys - map->phys);
277} 367}
278EXPORT_SYMBOL_GPL(acpi_os_map_memory); 368EXPORT_SYMBOL_GPL(acpi_os_map_memory);
279 369
370static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
371{
372 if (!--map->refcount)
373 list_del_rcu(&map->list);
374}
375
376static void acpi_os_map_cleanup(struct acpi_ioremap *map)
377{
378 if (!map->refcount) {
379 synchronize_rcu();
380 iounmap(map->virt);
381 kfree(map);
382 }
383}
384
280void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 385void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
281{ 386{
282 if (acpi_gbl_permanent_mmap) 387 struct acpi_ioremap *map;
283 iounmap(virt); 388
284 else 389 if (!acpi_gbl_permanent_mmap) {
285 __acpi_unmap_table(virt, size); 390 __acpi_unmap_table(virt, size);
391 return;
392 }
393
394 mutex_lock(&acpi_ioremap_lock);
395 map = acpi_map_lookup_virt(virt, size);
396 if (!map) {
397 mutex_unlock(&acpi_ioremap_lock);
398 WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
399 return;
400 }
401 acpi_os_drop_map_ref(map);
402 mutex_unlock(&acpi_ioremap_lock);
403
404 acpi_os_map_cleanup(map);
286} 405}
287EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); 406EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
288 407
@@ -292,6 +411,45 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
292 __acpi_unmap_table(virt, size); 411 __acpi_unmap_table(virt, size);
293} 412}
294 413
414static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
415{
416 void __iomem *virt;
417
418 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
419 return 0;
420
421 if (!addr->address || !addr->bit_width)
422 return -EINVAL;
423
424 virt = acpi_os_map_memory(addr->address, addr->bit_width / 8);
425 if (!virt)
426 return -EIO;
427
428 return 0;
429}
430
431static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
432{
433 struct acpi_ioremap *map;
434
435 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
436 return;
437
438 if (!addr->address || !addr->bit_width)
439 return;
440
441 mutex_lock(&acpi_ioremap_lock);
442 map = acpi_map_lookup(addr->address, addr->bit_width / 8);
443 if (!map) {
444 mutex_unlock(&acpi_ioremap_lock);
445 return;
446 }
447 acpi_os_drop_map_ref(map);
448 mutex_unlock(&acpi_ioremap_lock);
449
450 acpi_os_map_cleanup(map);
451}
452
295#ifdef ACPI_FUTURE_USAGE 453#ifdef ACPI_FUTURE_USAGE
296acpi_status 454acpi_status
297acpi_os_get_physical_address(void *virt, acpi_physical_address * phys) 455acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
@@ -373,11 +531,15 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
373 acpi_irq_stats_init(); 531 acpi_irq_stats_init();
374 532
375 /* 533 /*
376 * Ignore the GSI from the core, and use the value in our copy of the 534 * ACPI interrupts different from the SCI in our copy of the FADT are
377 * FADT. It may not be the same if an interrupt source override exists 535 * not supported.
378 * for the SCI.
379 */ 536 */
380 gsi = acpi_gbl_FADT.sci_interrupt; 537 if (gsi != acpi_gbl_FADT.sci_interrupt)
538 return AE_BAD_PARAMETER;
539
540 if (acpi_irq_handler)
541 return AE_ALREADY_ACQUIRED;
542
381 if (acpi_gsi_to_irq(gsi, &irq) < 0) { 543 if (acpi_gsi_to_irq(gsi, &irq) < 0) {
382 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", 544 printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n",
383 gsi); 545 gsi);
@@ -388,20 +550,20 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
388 acpi_irq_context = context; 550 acpi_irq_context = context;
389 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { 551 if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
390 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); 552 printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
553 acpi_irq_handler = NULL;
391 return AE_NOT_ACQUIRED; 554 return AE_NOT_ACQUIRED;
392 } 555 }
393 acpi_irq_irq = irq;
394 556
395 return AE_OK; 557 return AE_OK;
396} 558}
397 559
398acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) 560acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
399{ 561{
400 if (irq) { 562 if (irq != acpi_gbl_FADT.sci_interrupt)
401 free_irq(irq, acpi_irq); 563 return AE_BAD_PARAMETER;
402 acpi_irq_handler = NULL; 564
403 acpi_irq_irq = 0; 565 free_irq(irq, acpi_irq);
404 } 566 acpi_irq_handler = NULL;
405 567
406 return AE_OK; 568 return AE_OK;
407} 569}
@@ -493,10 +655,21 @@ EXPORT_SYMBOL(acpi_os_write_port);
493acpi_status 655acpi_status
494acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) 656acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
495{ 657{
496 u32 dummy;
497 void __iomem *virt_addr; 658 void __iomem *virt_addr;
659 unsigned int size = width / 8;
660 bool unmap = false;
661 u32 dummy;
662
663 rcu_read_lock();
664 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
665 if (!virt_addr) {
666 rcu_read_unlock();
667 virt_addr = acpi_os_ioremap(phys_addr, size);
668 if (!virt_addr)
669 return AE_BAD_ADDRESS;
670 unmap = true;
671 }
498 672
499 virt_addr = ioremap(phys_addr, width);
500 if (!value) 673 if (!value)
501 value = &dummy; 674 value = &dummy;
502 675
@@ -514,7 +687,10 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
514 BUG(); 687 BUG();
515 } 688 }
516 689
517 iounmap(virt_addr); 690 if (unmap)
691 iounmap(virt_addr);
692 else
693 rcu_read_unlock();
518 694
519 return AE_OK; 695 return AE_OK;
520} 696}
@@ -523,8 +699,18 @@ acpi_status
523acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) 699acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
524{ 700{
525 void __iomem *virt_addr; 701 void __iomem *virt_addr;
526 702 unsigned int size = width / 8;
527 virt_addr = ioremap(phys_addr, width); 703 bool unmap = false;
704
705 rcu_read_lock();
706 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
707 if (!virt_addr) {
708 rcu_read_unlock();
709 virt_addr = acpi_os_ioremap(phys_addr, size);
710 if (!virt_addr)
711 return AE_BAD_ADDRESS;
712 unmap = true;
713 }
528 714
529 switch (width) { 715 switch (width) {
530 case 8: 716 case 8:
@@ -540,16 +726,20 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
540 BUG(); 726 BUG();
541 } 727 }
542 728
543 iounmap(virt_addr); 729 if (unmap)
730 iounmap(virt_addr);
731 else
732 rcu_read_unlock();
544 733
545 return AE_OK; 734 return AE_OK;
546} 735}
547 736
548acpi_status 737acpi_status
549acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, 738acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
550 u32 *value, u32 width) 739 u64 *value, u32 width)
551{ 740{
552 int result, size; 741 int result, size;
742 u32 value32;
553 743
554 if (!value) 744 if (!value)
555 return AE_BAD_PARAMETER; 745 return AE_BAD_PARAMETER;
@@ -570,7 +760,8 @@ acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
570 760
571 result = raw_pci_read(pci_id->segment, pci_id->bus, 761 result = raw_pci_read(pci_id->segment, pci_id->bus,
572 PCI_DEVFN(pci_id->device, pci_id->function), 762 PCI_DEVFN(pci_id->device, pci_id->function),
573 reg, size, value); 763 reg, size, &value32);
764 *value = value32;
574 765
575 return (result ? AE_ERROR : AE_OK); 766 return (result ? AE_ERROR : AE_OK);
576} 767}
@@ -602,74 +793,6 @@ acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
602 return (result ? AE_ERROR : AE_OK); 793 return (result ? AE_ERROR : AE_OK);
603} 794}
604 795
605/* TODO: Change code to take advantage of driver model more */
606static void acpi_os_derive_pci_id_2(acpi_handle rhandle, /* upper bound */
607 acpi_handle chandle, /* current node */
608 struct acpi_pci_id **id,
609 int *is_bridge, u8 * bus_number)
610{
611 acpi_handle handle;
612 struct acpi_pci_id *pci_id = *id;
613 acpi_status status;
614 unsigned long long temp;
615 acpi_object_type type;
616
617 acpi_get_parent(chandle, &handle);
618 if (handle != rhandle) {
619 acpi_os_derive_pci_id_2(rhandle, handle, &pci_id, is_bridge,
620 bus_number);
621
622 status = acpi_get_type(handle, &type);
623 if ((ACPI_FAILURE(status)) || (type != ACPI_TYPE_DEVICE))
624 return;
625
626 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
627 &temp);
628 if (ACPI_SUCCESS(status)) {
629 u32 val;
630 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(temp));
631 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(temp));
632
633 if (*is_bridge)
634 pci_id->bus = *bus_number;
635
636 /* any nicer way to get bus number of bridge ? */
637 status =
638 acpi_os_read_pci_configuration(pci_id, 0x0e, &val,
639 8);
640 if (ACPI_SUCCESS(status)
641 && ((val & 0x7f) == 1 || (val & 0x7f) == 2)) {
642 status =
643 acpi_os_read_pci_configuration(pci_id, 0x18,
644 &val, 8);
645 if (!ACPI_SUCCESS(status)) {
646 /* Certainly broken... FIX ME */
647 return;
648 }
649 *is_bridge = 1;
650 pci_id->bus = val;
651 status =
652 acpi_os_read_pci_configuration(pci_id, 0x19,
653 &val, 8);
654 if (ACPI_SUCCESS(status)) {
655 *bus_number = val;
656 }
657 } else
658 *is_bridge = 0;
659 }
660 }
661}
662
663void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
664 acpi_handle chandle, /* current node */
665 struct acpi_pci_id **id)
666{
667 int is_bridge = 1;
668 u8 bus_number = (*id)->bus;
669
670 acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
671}
672
673static void acpi_os_execute_deferred(struct work_struct *work) 796static void acpi_os_execute_deferred(struct work_struct *work)
674{ 797{
675 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); 798 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
@@ -779,24 +902,6 @@ void acpi_os_wait_events_complete(void *context)
779 902
780EXPORT_SYMBOL(acpi_os_wait_events_complete); 903EXPORT_SYMBOL(acpi_os_wait_events_complete);
781 904
782/*
783 * Allocate the memory for a spinlock and initialize it.
784 */
785acpi_status acpi_os_create_lock(acpi_spinlock * handle)
786{
787 spin_lock_init(*handle);
788
789 return AE_OK;
790}
791
792/*
793 * Deallocate the memory for a spinlock.
794 */
795void acpi_os_delete_lock(acpi_spinlock handle)
796{
797 return;
798}
799
800acpi_status 905acpi_status
801acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) 906acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
802{ 907{
@@ -970,19 +1075,66 @@ static int __init acpi_os_name_setup(char *str)
970 1075
971__setup("acpi_os_name=", acpi_os_name_setup); 1076__setup("acpi_os_name=", acpi_os_name_setup);
972 1077
1078#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
1079#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */
1080
1081struct osi_setup_entry {
1082 char string[OSI_STRING_LENGTH_MAX];
1083 bool enable;
1084};
1085
1086static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX];
1087
1088void __init acpi_osi_setup(char *str)
1089{
1090 struct osi_setup_entry *osi;
1091 bool enable = true;
1092 int i;
1093
1094 if (!acpi_gbl_create_osi_method)
1095 return;
1096
1097 if (str == NULL || *str == '\0') {
1098 printk(KERN_INFO PREFIX "_OSI method disabled\n");
1099 acpi_gbl_create_osi_method = FALSE;
1100 return;
1101 }
1102
1103 if (*str == '!') {
1104 str++;
1105 enable = false;
1106 }
1107
1108 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
1109 osi = &osi_setup_entries[i];
1110 if (!strcmp(osi->string, str)) {
1111 osi->enable = enable;
1112 break;
1113 } else if (osi->string[0] == '\0') {
1114 osi->enable = enable;
1115 strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
1116 break;
1117 }
1118 }
1119}
1120
973static void __init set_osi_linux(unsigned int enable) 1121static void __init set_osi_linux(unsigned int enable)
974{ 1122{
975 if (osi_linux.enable != enable) { 1123 if (osi_linux.enable != enable)
976 osi_linux.enable = enable; 1124 osi_linux.enable = enable;
977 printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", 1125
978 enable ? "Add": "Delet"); 1126 if (osi_linux.enable)
979 } 1127 acpi_osi_setup("Linux");
1128 else
1129 acpi_osi_setup("!Linux");
1130
980 return; 1131 return;
981} 1132}
982 1133
983static void __init acpi_cmdline_osi_linux(unsigned int enable) 1134static void __init acpi_cmdline_osi_linux(unsigned int enable)
984{ 1135{
985 osi_linux.cmdline = 1; /* cmdline set the default */ 1136 osi_linux.cmdline = 1; /* cmdline set the default and override DMI */
1137 osi_linux.dmi = 0;
986 set_osi_linux(enable); 1138 set_osi_linux(enable);
987 1139
988 return; 1140 return;
@@ -990,15 +1142,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable)
990 1142
991void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) 1143void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
992{ 1144{
993 osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
994
995 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); 1145 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
996 1146
997 if (enable == -1) 1147 if (enable == -1)
998 return; 1148 return;
999 1149
1000 osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ 1150 osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
1001
1002 set_osi_linux(enable); 1151 set_osi_linux(enable);
1003 1152
1004 return; 1153 return;
@@ -1011,27 +1160,46 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1011 * string starting with '!' disables that string 1160 * string starting with '!' disables that string
1012 * otherwise string is added to list, augmenting built-in strings 1161 * otherwise string is added to list, augmenting built-in strings
1013 */ 1162 */
1014int __init acpi_osi_setup(char *str) 1163static void __init acpi_osi_setup_late(void)
1015{ 1164{
1016 if (str == NULL || *str == '\0') { 1165 struct osi_setup_entry *osi;
1017 printk(KERN_INFO PREFIX "_OSI method disabled\n"); 1166 char *str;
1018 acpi_gbl_create_osi_method = FALSE; 1167 int i;
1019 } else if (!strcmp("!Linux", str)) { 1168 acpi_status status;
1020 acpi_cmdline_osi_linux(0); /* !enable */ 1169
1021 } else if (*str == '!') { 1170 for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
1022 if (acpi_osi_invalidate(++str) == AE_OK) 1171 osi = &osi_setup_entries[i];
1023 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); 1172 str = osi->string;
1024 } else if (!strcmp("Linux", str)) { 1173
1025 acpi_cmdline_osi_linux(1); /* enable */ 1174 if (*str == '\0')
1026 } else if (*osi_additional_string == '\0') { 1175 break;
1027 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); 1176 if (osi->enable) {
1028 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); 1177 status = acpi_install_interface(str);
1178
1179 if (ACPI_SUCCESS(status))
1180 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
1181 } else {
1182 status = acpi_remove_interface(str);
1183
1184 if (ACPI_SUCCESS(status))
1185 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
1186 }
1029 } 1187 }
1188}
1189
1190static int __init osi_setup(char *str)
1191{
1192 if (str && !strcmp("Linux", str))
1193 acpi_cmdline_osi_linux(1);
1194 else if (str && !strcmp("!Linux", str))
1195 acpi_cmdline_osi_linux(0);
1196 else
1197 acpi_osi_setup(str);
1030 1198
1031 return 1; 1199 return 1;
1032} 1200}
1033 1201
1034__setup("acpi_osi=", acpi_osi_setup); 1202__setup("acpi_osi=", osi_setup);
1035 1203
1036/* enable serialization to combat AE_ALREADY_EXISTS errors */ 1204/* enable serialization to combat AE_ALREADY_EXISTS errors */
1037static int __init acpi_serialize_setup(char *str) 1205static int __init acpi_serialize_setup(char *str)
@@ -1089,8 +1257,7 @@ __setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
1089int acpi_check_resource_conflict(const struct resource *res) 1257int acpi_check_resource_conflict(const struct resource *res)
1090{ 1258{
1091 struct acpi_res_list *res_list_elem; 1259 struct acpi_res_list *res_list_elem;
1092 int ioport; 1260 int ioport = 0, clash = 0;
1093 int clash = 0;
1094 1261
1095 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) 1262 if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
1096 return 0; 1263 return 0;
@@ -1120,9 +1287,13 @@ int acpi_check_resource_conflict(const struct resource *res)
1120 if (clash) { 1287 if (clash) {
1121 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { 1288 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1122 printk(KERN_WARNING "ACPI: resource %s %pR" 1289 printk(KERN_WARNING "ACPI: resource %s %pR"
1123 " conflicts with ACPI region %s %pR\n", 1290 " conflicts with ACPI region %s "
1291 "[%s 0x%zx-0x%zx]\n",
1124 res->name, res, res_list_elem->name, 1292 res->name, res, res_list_elem->name,
1125 res_list_elem); 1293 (res_list_elem->resource_type ==
1294 ACPI_ADR_SPACE_SYSTEM_IO) ? "io" : "mem",
1295 (size_t) res_list_elem->start,
1296 (size_t) res_list_elem->end);
1126 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX) 1297 if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
1127 printk(KERN_NOTICE "ACPI: This conflict may" 1298 printk(KERN_NOTICE "ACPI: This conflict may"
1128 " cause random problems and system" 1299 " cause random problems and system"
@@ -1152,21 +1323,6 @@ int acpi_check_region(resource_size_t start, resource_size_t n,
1152} 1323}
1153EXPORT_SYMBOL(acpi_check_region); 1324EXPORT_SYMBOL(acpi_check_region);
1154 1325
1155int acpi_check_mem_region(resource_size_t start, resource_size_t n,
1156 const char *name)
1157{
1158 struct resource res = {
1159 .start = start,
1160 .end = start + n - 1,
1161 .name = name,
1162 .flags = IORESOURCE_MEM,
1163 };
1164
1165 return acpi_check_resource_conflict(&res);
1166
1167}
1168EXPORT_SYMBOL(acpi_check_mem_region);
1169
1170/* 1326/*
1171 * Let drivers know whether the resource checks are effective 1327 * Let drivers know whether the resource checks are effective
1172 */ 1328 */
@@ -1177,6 +1333,14 @@ int acpi_resources_are_enforced(void)
1177EXPORT_SYMBOL(acpi_resources_are_enforced); 1333EXPORT_SYMBOL(acpi_resources_are_enforced);
1178 1334
1179/* 1335/*
1336 * Deallocate the memory for a spinlock.
1337 */
1338void acpi_os_delete_lock(acpi_spinlock handle)
1339{
1340 ACPI_FREE(handle);
1341}
1342
1343/*
1180 * Acquire a spinlock. 1344 * Acquire a spinlock.
1181 * 1345 *
1182 * handle is a pointer to the spinlock_t. 1346 * handle is a pointer to the spinlock_t.
@@ -1282,38 +1446,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1282 return (AE_OK); 1446 return (AE_OK);
1283} 1447}
1284 1448
1285/******************************************************************************
1286 *
1287 * FUNCTION: acpi_os_validate_interface
1288 *
1289 * PARAMETERS: interface - Requested interface to be validated
1290 *
1291 * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise
1292 *
1293 * DESCRIPTION: Match an interface string to the interfaces supported by the
1294 * host. Strings originate from an AML call to the _OSI method.
1295 *
1296 *****************************************************************************/
1297
1298acpi_status
1299acpi_os_validate_interface (char *interface)
1300{
1301 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
1302 return AE_OK;
1303 if (!strcmp("Linux", interface)) {
1304
1305 printk(KERN_NOTICE PREFIX
1306 "BIOS _OSI(Linux) query %s%s\n",
1307 osi_linux.enable ? "honored" : "ignored",
1308 osi_linux.cmdline ? " via cmdline" :
1309 osi_linux.dmi ? " via DMI" : "");
1310
1311 if (osi_linux.enable)
1312 return AE_OK;
1313 }
1314 return AE_SUPPORT;
1315}
1316
1317static inline int acpi_res_list_add(struct acpi_res_list *res) 1449static inline int acpi_res_list_add(struct acpi_res_list *res)
1318{ 1450{
1319 struct acpi_res_list *res_list_elem; 1451 struct acpi_res_list *res_list_elem;
@@ -1462,5 +1594,46 @@ acpi_os_validate_address (
1462 } 1594 }
1463 return AE_OK; 1595 return AE_OK;
1464} 1596}
1465
1466#endif 1597#endif
1598
1599acpi_status __init acpi_os_initialize(void)
1600{
1601 acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1602 acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1603 acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
1604 acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
1605
1606 return AE_OK;
1607}
1608
1609acpi_status __init acpi_os_initialize1(void)
1610{
1611 kacpid_wq = alloc_workqueue("kacpid", 0, 1);
1612 kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
1613 kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
1614 BUG_ON(!kacpid_wq);
1615 BUG_ON(!kacpi_notify_wq);
1616 BUG_ON(!kacpi_hotplug_wq);
1617 acpi_install_interface_handler(acpi_osi_handler);
1618 acpi_osi_setup_late();
1619 return AE_OK;
1620}
1621
1622acpi_status acpi_os_terminate(void)
1623{
1624 if (acpi_irq_handler) {
1625 acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt,
1626 acpi_irq_handler);
1627 }
1628
1629 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
1630 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
1631 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
1632 acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
1633
1634 destroy_workqueue(kacpid_wq);
1635 destroy_workqueue(kacpi_notify_wq);
1636 destroy_workqueue(kacpi_hotplug_wq);
1637
1638 return AE_OK;
1639}
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index e4804fb05e23..f907cfbfa13c 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -32,7 +32,6 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/spinlock.h> 35#include <linux/spinlock.h>
37#include <linux/pm.h> 36#include <linux/pm.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 8d47a5846aeb..4a29763b8eb4 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -29,12 +29,11 @@
29 * for IRQ management (e.g. start()->_SRS). 29 * for IRQ management (e.g. start()->_SRS).
30 */ 30 */
31 31
32#include <linux/sysdev.h> 32#include <linux/syscore_ops.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/proc_fs.h>
38#include <linux/spinlock.h> 37#include <linux/spinlock.h>
39#include <linux/pm.h> 38#include <linux/pm.h>
40#include <linux/pci.h> 39#include <linux/pci.h>
@@ -758,14 +757,13 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link)
758 return 0; 757 return 0;
759} 758}
760 759
761static int irqrouter_resume(struct sys_device *dev) 760static void irqrouter_resume(void)
762{ 761{
763 struct acpi_pci_link *link; 762 struct acpi_pci_link *link;
764 763
765 list_for_each_entry(link, &acpi_link_list, list) { 764 list_for_each_entry(link, &acpi_link_list, list) {
766 acpi_pci_link_resume(link); 765 acpi_pci_link_resume(link);
767 } 766 }
768 return 0;
769} 767}
770 768
771static int acpi_pci_link_remove(struct acpi_device *device, int type) 769static int acpi_pci_link_remove(struct acpi_device *device, int type)
@@ -872,32 +870,19 @@ static int __init acpi_irq_balance_set(char *str)
872 870
873__setup("acpi_irq_balance", acpi_irq_balance_set); 871__setup("acpi_irq_balance", acpi_irq_balance_set);
874 872
875/* FIXME: we will remove this interface after all drivers call pci_disable_device */ 873static struct syscore_ops irqrouter_syscore_ops = {
876static struct sysdev_class irqrouter_sysdev_class = {
877 .name = "irqrouter",
878 .resume = irqrouter_resume, 874 .resume = irqrouter_resume,
879}; 875};
880 876
881static struct sys_device device_irqrouter = { 877static int __init irqrouter_init_ops(void)
882 .id = 0,
883 .cls = &irqrouter_sysdev_class,
884};
885
886static int __init irqrouter_init_sysfs(void)
887{ 878{
888 int error; 879 if (!acpi_disabled && !acpi_noirq)
880 register_syscore_ops(&irqrouter_syscore_ops);
889 881
890 if (acpi_disabled || acpi_noirq) 882 return 0;
891 return 0;
892
893 error = sysdev_class_register(&irqrouter_sysdev_class);
894 if (!error)
895 error = sysdev_register(&device_irqrouter);
896
897 return error;
898} 883}
899 884
900device_initcall(irqrouter_init_sysfs); 885device_initcall(irqrouter_init_ops);
901 886
902static int __init acpi_pci_link_init(void) 887static int __init acpi_pci_link_init(void)
903{ 888{
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 3ba8d1f44a73..d06078d660ad 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -27,16 +27,17 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/proc_fs.h>
31#include <linux/spinlock.h> 30#include <linux/spinlock.h>
32#include <linux/pm.h> 31#include <linux/pm.h>
33#include <linux/pm_runtime.h> 32#include <linux/pm_runtime.h>
34#include <linux/pci.h> 33#include <linux/pci.h>
35#include <linux/pci-acpi.h> 34#include <linux/pci-acpi.h>
35#include <linux/pci-aspm.h>
36#include <linux/acpi.h> 36#include <linux/acpi.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
39#include <acpi/acpi_drivers.h> 39#include <acpi/acpi_drivers.h>
40#include <acpi/apei.h>
40 41
41#define PREFIX "ACPI: " 42#define PREFIX "ACPI: "
42 43
@@ -48,6 +49,11 @@ static int acpi_pci_root_add(struct acpi_device *device);
48static int acpi_pci_root_remove(struct acpi_device *device, int type); 49static int acpi_pci_root_remove(struct acpi_device *device, int type);
49static int acpi_pci_root_start(struct acpi_device *device); 50static int acpi_pci_root_start(struct acpi_device *device);
50 51
52#define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \
53 | OSC_ACTIVE_STATE_PWR_SUPPORT \
54 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \
55 | OSC_MSI_SUPPORT)
56
51static const struct acpi_device_id root_device_ids[] = { 57static const struct acpi_device_id root_device_ids[] = {
52 {"PNP0A03", 0}, 58 {"PNP0A03", 0},
53 {"", 0}, 59 {"", 0},
@@ -559,7 +565,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
559 /* Indicate support for various _OSC capabilities. */ 565 /* Indicate support for various _OSC capabilities. */
560 if (pci_ext_cfg_avail(root->bus->self)) 566 if (pci_ext_cfg_avail(root->bus->self))
561 flags |= OSC_EXT_PCI_CONFIG_SUPPORT; 567 flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
562 if (pcie_aspm_enabled()) 568 if (pcie_aspm_support_enabled())
563 flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | 569 flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
564 OSC_CLOCK_PWR_CAPABILITY_SUPPORT; 570 OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
565 if (pci_msi_enabled()) 571 if (pci_msi_enabled())
@@ -567,6 +573,43 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
567 if (flags != base_flags) 573 if (flags != base_flags)
568 acpi_pci_osc_support(root, flags); 574 acpi_pci_osc_support(root, flags);
569 575
576 if (!pcie_ports_disabled
577 && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
578 flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
579 | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
580 | OSC_PCI_EXPRESS_PME_CONTROL;
581
582 if (pci_aer_available()) {
583 if (aer_acpi_firmware_first())
584 dev_dbg(root->bus->bridge,
585 "PCIe errors handled by BIOS.\n");
586 else
587 flags |= OSC_PCI_EXPRESS_AER_CONTROL;
588 }
589
590 dev_info(root->bus->bridge,
591 "Requesting ACPI _OSC control (0x%02x)\n", flags);
592
593 status = acpi_pci_osc_control_set(device->handle, &flags,
594 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
595 if (ACPI_SUCCESS(status)) {
596 dev_info(root->bus->bridge,
597 "ACPI _OSC control (0x%02x) granted\n", flags);
598 } else {
599 dev_info(root->bus->bridge,
600 "ACPI _OSC request failed (%s), "
601 "returned control mask: 0x%02x\n",
602 acpi_format_exception(status), flags);
603 pr_info("ACPI _OSC control for PCIe not granted, "
604 "disabling ASPM\n");
605 pcie_no_aspm();
606 }
607 } else {
608 dev_info(root->bus->bridge,
609 "Unable to request _OSC control "
610 "(_OSC support mask: 0x%02x)\n", flags);
611 }
612
570 pci_acpi_add_bus_pm_notifier(device, root->bus); 613 pci_acpi_add_bus_pm_notifier(device, root->bus);
571 if (device->wakeup.flags.run_wake) 614 if (device->wakeup.flags.run_wake)
572 device_set_run_wake(root->bus->bridge, true); 615 device_set_run_wake(root->bus->bridge, true);
@@ -601,6 +644,8 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
601 644
602static int __init acpi_pci_root_init(void) 645static int __init acpi_pci_root_init(void)
603{ 646{
647 acpi_hest_init();
648
604 if (acpi_pci_disabled) 649 if (acpi_pci_disabled)
605 return 0; 650 return 0;
606 651
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 844c155aeb0f..9ac2a9fa90ff 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -56,9 +56,6 @@ ACPI_MODULE_NAME("power");
56#define ACPI_POWER_RESOURCE_STATE_ON 0x01 56#define ACPI_POWER_RESOURCE_STATE_ON 0x01
57#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF 57#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
58 58
59int acpi_power_nocheck;
60module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
61
62static int acpi_power_add(struct acpi_device *device); 59static int acpi_power_add(struct acpi_device *device);
63static int acpi_power_remove(struct acpi_device *device, int type); 60static int acpi_power_remove(struct acpi_device *device, int type);
64static int acpi_power_resume(struct acpi_device *device); 61static int acpi_power_resume(struct acpi_device *device);
@@ -80,18 +77,13 @@ static struct acpi_driver acpi_power_driver = {
80 }, 77 },
81}; 78};
82 79
83struct acpi_power_reference {
84 struct list_head node;
85 struct acpi_device *device;
86};
87
88struct acpi_power_resource { 80struct acpi_power_resource {
89 struct acpi_device * device; 81 struct acpi_device * device;
90 acpi_bus_id name; 82 acpi_bus_id name;
91 u32 system_level; 83 u32 system_level;
92 u32 order; 84 u32 order;
85 unsigned int ref_count;
93 struct mutex resource_lock; 86 struct mutex resource_lock;
94 struct list_head reference;
95}; 87};
96 88
97static struct list_head acpi_power_resource_list; 89static struct list_head acpi_power_resource_list;
@@ -153,9 +145,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state)
153 145
154static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) 146static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
155{ 147{
156 int result = 0, state1; 148 int cur_state;
157 u32 i = 0; 149 int i = 0;
158
159 150
160 if (!list || !state) 151 if (!list || !state)
161 return -EINVAL; 152 return -EINVAL;
@@ -163,122 +154,149 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
163 /* The state of the list is 'on' IFF all resources are 'on'. */ 154 /* The state of the list is 'on' IFF all resources are 'on'. */
164 155
165 for (i = 0; i < list->count; i++) { 156 for (i = 0; i < list->count; i++) {
166 /* 157 struct acpi_power_resource *resource;
167 * The state of the power resource can be obtained by 158 acpi_handle handle = list->handles[i];
168 * using the ACPI handle. In such case it is unnecessary to 159 int result;
169 * get the Power resource first and then get its state again. 160
170 */ 161 result = acpi_power_get_context(handle, &resource);
171 result = acpi_power_get_state(list->handles[i], &state1);
172 if (result) 162 if (result)
173 return result; 163 return result;
174 164
175 *state = state1; 165 mutex_lock(&resource->resource_lock);
166
167 result = acpi_power_get_state(handle, &cur_state);
168
169 mutex_unlock(&resource->resource_lock);
176 170
177 if (*state != ACPI_POWER_RESOURCE_STATE_ON) 171 if (result)
172 return result;
173
174 if (cur_state != ACPI_POWER_RESOURCE_STATE_ON)
178 break; 175 break;
179 } 176 }
180 177
181 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", 178 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n",
182 *state ? "on" : "off")); 179 cur_state ? "on" : "off"));
183 180
184 return result; 181 *state = cur_state;
182
183 return 0;
185} 184}
186 185
187static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) 186static int __acpi_power_on(struct acpi_power_resource *resource)
188{ 187{
189 int result = 0;
190 int found = 0;
191 acpi_status status = AE_OK; 188 acpi_status status = AE_OK;
192 struct acpi_power_resource *resource = NULL;
193 struct list_head *node, *next;
194 struct acpi_power_reference *ref;
195 189
190 status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
191 if (ACPI_FAILURE(status))
192 return -ENODEV;
193
194 /* Update the power resource's _device_ power state */
195 resource->device->power.state = ACPI_STATE_D0;
196
197 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n",
198 resource->name));
199
200 return 0;
201}
202
203static int acpi_power_on(acpi_handle handle)
204{
205 int result = 0;
206 struct acpi_power_resource *resource = NULL;
196 207
197 result = acpi_power_get_context(handle, &resource); 208 result = acpi_power_get_context(handle, &resource);
198 if (result) 209 if (result)
199 return result; 210 return result;
200 211
201 mutex_lock(&resource->resource_lock); 212 mutex_lock(&resource->resource_lock);
202 list_for_each_safe(node, next, &resource->reference) {
203 ref = container_of(node, struct acpi_power_reference, node);
204 if (dev->handle == ref->device->handle) {
205 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n",
206 dev->pnp.bus_id, resource->name));
207 found = 1;
208 break;
209 }
210 }
211 213
212 if (!found) { 214 if (resource->ref_count++) {
213 ref = kmalloc(sizeof (struct acpi_power_reference), 215 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
214 irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); 216 "Power resource [%s] already on",
215 if (!ref) { 217 resource->name));
216 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n")); 218 } else {
217 mutex_unlock(&resource->resource_lock); 219 result = __acpi_power_on(resource);
218 return -ENOMEM; 220 if (result)
219 } 221 resource->ref_count--;
220 list_add_tail(&ref->node, &resource->reference);
221 ref->device = dev;
222 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n",
223 dev->pnp.bus_id, resource->name));
224 } 222 }
225 mutex_unlock(&resource->resource_lock);
226 223
227 status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); 224 mutex_unlock(&resource->resource_lock);
228 if (ACPI_FAILURE(status))
229 return -ENODEV;
230
231 /* Update the power resource's _device_ power state */
232 resource->device->power.state = ACPI_STATE_D0;
233 225
234 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", 226 return result;
235 resource->name));
236 return 0;
237} 227}
238 228
239static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) 229static int acpi_power_off(acpi_handle handle)
240{ 230{
241 int result = 0; 231 int result = 0;
242 acpi_status status = AE_OK; 232 acpi_status status = AE_OK;
243 struct acpi_power_resource *resource = NULL; 233 struct acpi_power_resource *resource = NULL;
244 struct list_head *node, *next;
245 struct acpi_power_reference *ref;
246 234
247 result = acpi_power_get_context(handle, &resource); 235 result = acpi_power_get_context(handle, &resource);
248 if (result) 236 if (result)
249 return result; 237 return result;
250 238
251 mutex_lock(&resource->resource_lock); 239 mutex_lock(&resource->resource_lock);
252 list_for_each_safe(node, next, &resource->reference) { 240
253 ref = container_of(node, struct acpi_power_reference, node); 241 if (!resource->ref_count) {
254 if (dev->handle == ref->device->handle) { 242 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
255 list_del(&ref->node); 243 "Power resource [%s] already off",
256 kfree(ref); 244 resource->name));
257 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n", 245 goto unlock;
258 dev->pnp.bus_id, resource->name));
259 break;
260 }
261 } 246 }
262 247
263 if (!list_empty(&resource->reference)) { 248 if (--resource->ref_count) {
264 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n", 249 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
265 resource->name)); 250 "Power resource [%s] still in use\n",
266 mutex_unlock(&resource->resource_lock); 251 resource->name));
267 return 0; 252 goto unlock;
268 } 253 }
269 mutex_unlock(&resource->resource_lock);
270 254
271 status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL); 255 status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
272 if (ACPI_FAILURE(status)) 256 if (ACPI_FAILURE(status)) {
273 return -ENODEV; 257 result = -ENODEV;
258 } else {
259 /* Update the power resource's _device_ power state */
260 resource->device->power.state = ACPI_STATE_D3;
274 261
275 /* Update the power resource's _device_ power state */ 262 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
276 resource->device->power.state = ACPI_STATE_D3; 263 "Power resource [%s] turned off\n",
264 resource->name));
265 }
277 266
278 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", 267 unlock:
279 resource->name)); 268 mutex_unlock(&resource->resource_lock);
280 269
281 return 0; 270 return result;
271}
272
273static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
274{
275 int i;
276
277 for (i = num_res - 1; i >= 0 ; i--)
278 acpi_power_off(list->handles[i]);
279}
280
281static void acpi_power_off_list(struct acpi_handle_list *list)
282{
283 __acpi_power_off_list(list, list->count);
284}
285
286static int acpi_power_on_list(struct acpi_handle_list *list)
287{
288 int result = 0;
289 int i;
290
291 for (i = 0; i < list->count; i++) {
292 result = acpi_power_on(list->handles[i]);
293 if (result) {
294 __acpi_power_off_list(list, i);
295 break;
296 }
297 }
298
299 return result;
282} 300}
283 301
284/** 302/**
@@ -364,7 +382,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
364 382
365 /* Open power resource */ 383 /* Open power resource */
366 for (i = 0; i < dev->wakeup.resources.count; i++) { 384 for (i = 0; i < dev->wakeup.resources.count; i++) {
367 int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); 385 int ret = acpi_power_on(dev->wakeup.resources.handles[i]);
368 if (ret) { 386 if (ret) {
369 printk(KERN_ERR PREFIX "Transition power state\n"); 387 printk(KERN_ERR PREFIX "Transition power state\n");
370 dev->wakeup.flags.valid = 0; 388 dev->wakeup.flags.valid = 0;
@@ -419,8 +437,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
419 437
420 /* Close power resource */ 438 /* Close power resource */
421 for (i = 0; i < dev->wakeup.resources.count; i++) { 439 for (i = 0; i < dev->wakeup.resources.count; i++) {
422 int ret = acpi_power_off_device( 440 int ret = acpi_power_off(dev->wakeup.resources.handles[i]);
423 dev->wakeup.resources.handles[i], dev);
424 if (ret) { 441 if (ret) {
425 printk(KERN_ERR PREFIX "Transition power state\n"); 442 printk(KERN_ERR PREFIX "Transition power state\n");
426 dev->wakeup.flags.valid = 0; 443 dev->wakeup.flags.valid = 0;
@@ -438,19 +455,16 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
438 Device Power Management 455 Device Power Management
439 -------------------------------------------------------------------------- */ 456 -------------------------------------------------------------------------- */
440 457
441int acpi_power_get_inferred_state(struct acpi_device *device) 458int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
442{ 459{
443 int result = 0; 460 int result = 0;
444 struct acpi_handle_list *list = NULL; 461 struct acpi_handle_list *list = NULL;
445 int list_state = 0; 462 int list_state = 0;
446 int i = 0; 463 int i = 0;
447 464
448 465 if (!device || !state)
449 if (!device)
450 return -EINVAL; 466 return -EINVAL;
451 467
452 device->power.state = ACPI_STATE_UNKNOWN;
453
454 /* 468 /*
455 * We know a device's inferred power state when all the resources 469 * We know a device's inferred power state when all the resources
456 * required for a given D-state are 'on'. 470 * required for a given D-state are 'on'.
@@ -465,66 +479,51 @@ int acpi_power_get_inferred_state(struct acpi_device *device)
465 return result; 479 return result;
466 480
467 if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { 481 if (list_state == ACPI_POWER_RESOURCE_STATE_ON) {
468 device->power.state = i; 482 *state = i;
469 return 0; 483 return 0;
470 } 484 }
471 } 485 }
472 486
473 device->power.state = ACPI_STATE_D3; 487 *state = ACPI_STATE_D3;
474
475 return 0; 488 return 0;
476} 489}
477 490
478int acpi_power_transition(struct acpi_device *device, int state) 491int acpi_power_on_resources(struct acpi_device *device, int state)
479{ 492{
480 int result = 0; 493 if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3)
481 struct acpi_handle_list *cl = NULL; /* Current Resources */ 494 return -EINVAL;
482 struct acpi_handle_list *tl = NULL; /* Target Resources */ 495
483 int i = 0; 496 return acpi_power_on_list(&device->power.states[state].resources);
497}
484 498
499int acpi_power_transition(struct acpi_device *device, int state)
500{
501 int result;
485 502
486 if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) 503 if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
487 return -EINVAL; 504 return -EINVAL;
488 505
506 if (device->power.state == state)
507 return 0;
508
489 if ((device->power.state < ACPI_STATE_D0) 509 if ((device->power.state < ACPI_STATE_D0)
490 || (device->power.state > ACPI_STATE_D3)) 510 || (device->power.state > ACPI_STATE_D3))
491 return -ENODEV; 511 return -ENODEV;
492 512
493 cl = &device->power.states[device->power.state].resources;
494 tl = &device->power.states[state].resources;
495
496 /* TBD: Resources must be ordered. */ 513 /* TBD: Resources must be ordered. */
497 514
498 /* 515 /*
499 * First we reference all power resources required in the target list 516 * First we reference all power resources required in the target list
500 * (e.g. so the device doesn't lose power while transitioning). 517 * (e.g. so the device doesn't lose power while transitioning). Then,
501 */ 518 * we dereference all power resources used in the current list.
502 for (i = 0; i < tl->count; i++) {
503 result = acpi_power_on(tl->handles[i], device);
504 if (result)
505 goto end;
506 }
507
508 if (device->power.state == state) {
509 goto end;
510 }
511
512 /*
513 * Then we dereference all power resources used in the current list.
514 */ 519 */
515 for (i = 0; i < cl->count; i++) { 520 result = acpi_power_on_list(&device->power.states[state].resources);
516 result = acpi_power_off_device(cl->handles[i], device); 521 if (!result)
517 if (result) 522 acpi_power_off_list(
518 goto end; 523 &device->power.states[device->power.state].resources);
519 }
520 524
521 end: 525 /* We shouldn't change the state unless the above operations succeed. */
522 if (result) 526 device->power.state = result ? ACPI_STATE_UNKNOWN : state;
523 device->power.state = ACPI_STATE_UNKNOWN;
524 else {
525 /* We shouldn't change the state till all above operations succeed */
526 device->power.state = state;
527 }
528 527
529 return result; 528 return result;
530} 529}
@@ -551,7 +550,6 @@ static int acpi_power_add(struct acpi_device *device)
551 550
552 resource->device = device; 551 resource->device = device;
553 mutex_init(&resource->resource_lock); 552 mutex_init(&resource->resource_lock);
554 INIT_LIST_HEAD(&resource->reference);
555 strcpy(resource->name, device->pnp.bus_id); 553 strcpy(resource->name, device->pnp.bus_id);
556 strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); 554 strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
557 strcpy(acpi_device_class(device), ACPI_POWER_CLASS); 555 strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
@@ -594,22 +592,14 @@ static int acpi_power_add(struct acpi_device *device)
594 592
595static int acpi_power_remove(struct acpi_device *device, int type) 593static int acpi_power_remove(struct acpi_device *device, int type)
596{ 594{
597 struct acpi_power_resource *resource = NULL; 595 struct acpi_power_resource *resource;
598 struct list_head *node, *next;
599 596
600 597 if (!device)
601 if (!device || !acpi_driver_data(device))
602 return -EINVAL; 598 return -EINVAL;
603 599
604 resource = acpi_driver_data(device); 600 resource = acpi_driver_data(device);
605 601 if (!resource)
606 mutex_lock(&resource->resource_lock); 602 return -EINVAL;
607 list_for_each_safe(node, next, &resource->reference) {
608 struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);
609 list_del(&ref->node);
610 kfree(ref);
611 }
612 mutex_unlock(&resource->resource_lock);
613 603
614 kfree(resource); 604 kfree(resource);
615 605
@@ -619,29 +609,28 @@ static int acpi_power_remove(struct acpi_device *device, int type)
619static int acpi_power_resume(struct acpi_device *device) 609static int acpi_power_resume(struct acpi_device *device)
620{ 610{
621 int result = 0, state; 611 int result = 0, state;
622 struct acpi_power_resource *resource = NULL; 612 struct acpi_power_resource *resource;
623 struct acpi_power_reference *ref;
624 613
625 if (!device || !acpi_driver_data(device)) 614 if (!device)
626 return -EINVAL; 615 return -EINVAL;
627 616
628 resource = acpi_driver_data(device); 617 resource = acpi_driver_data(device);
618 if (!resource)
619 return -EINVAL;
620
621 mutex_lock(&resource->resource_lock);
629 622
630 result = acpi_power_get_state(device->handle, &state); 623 result = acpi_power_get_state(device->handle, &state);
631 if (result) 624 if (result)
632 return result; 625 goto unlock;
633 626
634 mutex_lock(&resource->resource_lock); 627 if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
635 if (state == ACPI_POWER_RESOURCE_STATE_OFF && 628 result = __acpi_power_on(resource);
636 !list_empty(&resource->reference)) {
637 ref = container_of(resource->reference.next, struct acpi_power_reference, node);
638 mutex_unlock(&resource->resource_lock);
639 result = acpi_power_on(device->handle, ref->device);
640 return result;
641 }
642 629
630 unlock:
643 mutex_unlock(&resource->resource_lock); 631 mutex_unlock(&resource->resource_lock);
644 return 0; 632
633 return result;
645} 634}
646 635
647int __init acpi_power_init(void) 636int __init acpi_power_init(void)
diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c
deleted file mode 100644
index 66f67293341e..000000000000
--- a/drivers/acpi/power_meter.c
+++ /dev/null
@@ -1,1023 +0,0 @@
1/*
2 * A hwmon driver for ACPI 4.0 power meters
3 * Copyright (C) 2009 IBM
4 *
5 * Author: Darrick J. Wong <djwong@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/module.h>
23#include <linux/hwmon.h>
24#include <linux/hwmon-sysfs.h>
25#include <linux/jiffies.h>
26#include <linux/mutex.h>
27#include <linux/dmi.h>
28#include <linux/slab.h>
29#include <linux/kdev_t.h>
30#include <linux/sched.h>
31#include <linux/time.h>
32#include <acpi/acpi_drivers.h>
33#include <acpi/acpi_bus.h>
34
35#define ACPI_POWER_METER_NAME "power_meter"
36ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
37#define ACPI_POWER_METER_DEVICE_NAME "Power Meter"
38#define ACPI_POWER_METER_CLASS "pwr_meter_resource"
39
40#define NUM_SENSORS 17
41
42#define POWER_METER_CAN_MEASURE (1 << 0)
43#define POWER_METER_CAN_TRIP (1 << 1)
44#define POWER_METER_CAN_CAP (1 << 2)
45#define POWER_METER_CAN_NOTIFY (1 << 3)
46#define POWER_METER_IS_BATTERY (1 << 8)
47#define UNKNOWN_HYSTERESIS 0xFFFFFFFF
48
49#define METER_NOTIFY_CONFIG 0x80
50#define METER_NOTIFY_TRIP 0x81
51#define METER_NOTIFY_CAP 0x82
52#define METER_NOTIFY_CAPPING 0x83
53#define METER_NOTIFY_INTERVAL 0x84
54
55#define POWER_AVERAGE_NAME "power1_average"
56#define POWER_CAP_NAME "power1_cap"
57#define POWER_AVG_INTERVAL_NAME "power1_average_interval"
58#define POWER_ALARM_NAME "power1_alarm"
59
60static int cap_in_hardware;
61static int force_cap_on;
62
63static int can_cap_in_hardware(void)
64{
65 return force_cap_on || cap_in_hardware;
66}
67
68static const struct acpi_device_id power_meter_ids[] = {
69 {"ACPI000D", 0},
70 {"", 0},
71};
72MODULE_DEVICE_TABLE(acpi, power_meter_ids);
73
74struct acpi_power_meter_capabilities {
75 u64 flags;
76 u64 units;
77 u64 type;
78 u64 accuracy;
79 u64 sampling_time;
80 u64 min_avg_interval;
81 u64 max_avg_interval;
82 u64 hysteresis;
83 u64 configurable_cap;
84 u64 min_cap;
85 u64 max_cap;
86};
87
88struct acpi_power_meter_resource {
89 struct acpi_device *acpi_dev;
90 acpi_bus_id name;
91 struct mutex lock;
92 struct device *hwmon_dev;
93 struct acpi_power_meter_capabilities caps;
94 acpi_string model_number;
95 acpi_string serial_number;
96 acpi_string oem_info;
97 u64 power;
98 u64 cap;
99 u64 avg_interval;
100 int sensors_valid;
101 unsigned long sensors_last_updated;
102 struct sensor_device_attribute sensors[NUM_SENSORS];
103 int num_sensors;
104 int trip[2];
105 int num_domain_devices;
106 struct acpi_device **domain_devices;
107 struct kobject *holders_dir;
108};
109
110struct ro_sensor_template {
111 char *label;
112 ssize_t (*show)(struct device *dev,
113 struct device_attribute *devattr,
114 char *buf);
115 int index;
116};
117
118struct rw_sensor_template {
119 char *label;
120 ssize_t (*show)(struct device *dev,
121 struct device_attribute *devattr,
122 char *buf);
123 ssize_t (*set)(struct device *dev,
124 struct device_attribute *devattr,
125 const char *buf, size_t count);
126 int index;
127};
128
129/* Averaging interval */
130static int update_avg_interval(struct acpi_power_meter_resource *resource)
131{
132 unsigned long long data;
133 acpi_status status;
134
135 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI",
136 NULL, &data);
137 if (ACPI_FAILURE(status)) {
138 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI"));
139 return -ENODEV;
140 }
141
142 resource->avg_interval = data;
143 return 0;
144}
145
146static ssize_t show_avg_interval(struct device *dev,
147 struct device_attribute *devattr,
148 char *buf)
149{
150 struct acpi_device *acpi_dev = to_acpi_device(dev);
151 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
152
153 mutex_lock(&resource->lock);
154 update_avg_interval(resource);
155 mutex_unlock(&resource->lock);
156
157 return sprintf(buf, "%llu\n", resource->avg_interval);
158}
159
160static ssize_t set_avg_interval(struct device *dev,
161 struct device_attribute *devattr,
162 const char *buf, size_t count)
163{
164 struct acpi_device *acpi_dev = to_acpi_device(dev);
165 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
166 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
167 struct acpi_object_list args = { 1, &arg0 };
168 int res;
169 unsigned long temp;
170 unsigned long long data;
171 acpi_status status;
172
173 res = strict_strtoul(buf, 10, &temp);
174 if (res)
175 return res;
176
177 if (temp > resource->caps.max_avg_interval ||
178 temp < resource->caps.min_avg_interval)
179 return -EINVAL;
180 arg0.integer.value = temp;
181
182 mutex_lock(&resource->lock);
183 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI",
184 &args, &data);
185 if (!ACPI_FAILURE(status))
186 resource->avg_interval = temp;
187 mutex_unlock(&resource->lock);
188
189 if (ACPI_FAILURE(status)) {
190 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI"));
191 return -EINVAL;
192 }
193
194 /* _PAI returns 0 on success, nonzero otherwise */
195 if (data)
196 return -EINVAL;
197
198 return count;
199}
200
201/* Cap functions */
202static int update_cap(struct acpi_power_meter_resource *resource)
203{
204 unsigned long long data;
205 acpi_status status;
206
207 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL",
208 NULL, &data);
209 if (ACPI_FAILURE(status)) {
210 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL"));
211 return -ENODEV;
212 }
213
214 resource->cap = data;
215 return 0;
216}
217
218static ssize_t show_cap(struct device *dev,
219 struct device_attribute *devattr,
220 char *buf)
221{
222 struct acpi_device *acpi_dev = to_acpi_device(dev);
223 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
224
225 mutex_lock(&resource->lock);
226 update_cap(resource);
227 mutex_unlock(&resource->lock);
228
229 return sprintf(buf, "%llu\n", resource->cap * 1000);
230}
231
232static ssize_t set_cap(struct device *dev, struct device_attribute *devattr,
233 const char *buf, size_t count)
234{
235 struct acpi_device *acpi_dev = to_acpi_device(dev);
236 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
237 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
238 struct acpi_object_list args = { 1, &arg0 };
239 int res;
240 unsigned long temp;
241 unsigned long long data;
242 acpi_status status;
243
244 res = strict_strtoul(buf, 10, &temp);
245 if (res)
246 return res;
247
248 temp /= 1000;
249 if (temp > resource->caps.max_cap || temp < resource->caps.min_cap)
250 return -EINVAL;
251 arg0.integer.value = temp;
252
253 mutex_lock(&resource->lock);
254 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL",
255 &args, &data);
256 if (!ACPI_FAILURE(status))
257 resource->cap = temp;
258 mutex_unlock(&resource->lock);
259
260 if (ACPI_FAILURE(status)) {
261 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL"));
262 return -EINVAL;
263 }
264
265 /* _SHL returns 0 on success, nonzero otherwise */
266 if (data)
267 return -EINVAL;
268
269 return count;
270}
271
272/* Power meter trip points */
273static int set_acpi_trip(struct acpi_power_meter_resource *resource)
274{
275 union acpi_object arg_objs[] = {
276 {ACPI_TYPE_INTEGER},
277 {ACPI_TYPE_INTEGER}
278 };
279 struct acpi_object_list args = { 2, arg_objs };
280 unsigned long long data;
281 acpi_status status;
282
283 /* Both trip levels must be set */
284 if (resource->trip[0] < 0 || resource->trip[1] < 0)
285 return 0;
286
287 /* This driver stores min, max; ACPI wants max, min. */
288 arg_objs[0].integer.value = resource->trip[1];
289 arg_objs[1].integer.value = resource->trip[0];
290
291 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP",
292 &args, &data);
293 if (ACPI_FAILURE(status)) {
294 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP"));
295 return -EINVAL;
296 }
297
298 /* _PTP returns 0 on success, nonzero otherwise */
299 if (data)
300 return -EINVAL;
301
302 return 0;
303}
304
305static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
306 const char *buf, size_t count)
307{
308 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
309 struct acpi_device *acpi_dev = to_acpi_device(dev);
310 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
311 int res;
312 unsigned long temp;
313
314 res = strict_strtoul(buf, 10, &temp);
315 if (res)
316 return res;
317
318 temp /= 1000;
319 if (temp < 0)
320 return -EINVAL;
321
322 mutex_lock(&resource->lock);
323 resource->trip[attr->index - 7] = temp;
324 res = set_acpi_trip(resource);
325 mutex_unlock(&resource->lock);
326
327 if (res)
328 return res;
329
330 return count;
331}
332
333/* Power meter */
334static int update_meter(struct acpi_power_meter_resource *resource)
335{
336 unsigned long long data;
337 acpi_status status;
338 unsigned long local_jiffies = jiffies;
339
340 if (time_before(local_jiffies, resource->sensors_last_updated +
341 msecs_to_jiffies(resource->caps.sampling_time)) &&
342 resource->sensors_valid)
343 return 0;
344
345 status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM",
346 NULL, &data);
347 if (ACPI_FAILURE(status)) {
348 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM"));
349 return -ENODEV;
350 }
351
352 resource->power = data;
353 resource->sensors_valid = 1;
354 resource->sensors_last_updated = jiffies;
355 return 0;
356}
357
358static ssize_t show_power(struct device *dev,
359 struct device_attribute *devattr,
360 char *buf)
361{
362 struct acpi_device *acpi_dev = to_acpi_device(dev);
363 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
364
365 mutex_lock(&resource->lock);
366 update_meter(resource);
367 mutex_unlock(&resource->lock);
368
369 return sprintf(buf, "%llu\n", resource->power * 1000);
370}
371
372/* Miscellaneous */
373static ssize_t show_str(struct device *dev,
374 struct device_attribute *devattr,
375 char *buf)
376{
377 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
378 struct acpi_device *acpi_dev = to_acpi_device(dev);
379 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
380 acpi_string val;
381
382 switch (attr->index) {
383 case 0:
384 val = resource->model_number;
385 break;
386 case 1:
387 val = resource->serial_number;
388 break;
389 case 2:
390 val = resource->oem_info;
391 break;
392 default:
393 BUG();
394 }
395
396 return sprintf(buf, "%s\n", val);
397}
398
399static ssize_t show_val(struct device *dev,
400 struct device_attribute *devattr,
401 char *buf)
402{
403 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
404 struct acpi_device *acpi_dev = to_acpi_device(dev);
405 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
406 u64 val = 0;
407
408 switch (attr->index) {
409 case 0:
410 val = resource->caps.min_avg_interval;
411 break;
412 case 1:
413 val = resource->caps.max_avg_interval;
414 break;
415 case 2:
416 val = resource->caps.min_cap * 1000;
417 break;
418 case 3:
419 val = resource->caps.max_cap * 1000;
420 break;
421 case 4:
422 if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS)
423 return sprintf(buf, "unknown\n");
424
425 val = resource->caps.hysteresis * 1000;
426 break;
427 case 5:
428 if (resource->caps.flags & POWER_METER_IS_BATTERY)
429 val = 1;
430 else
431 val = 0;
432 break;
433 case 6:
434 if (resource->power > resource->cap)
435 val = 1;
436 else
437 val = 0;
438 break;
439 case 7:
440 case 8:
441 if (resource->trip[attr->index - 7] < 0)
442 return sprintf(buf, "unknown\n");
443
444 val = resource->trip[attr->index - 7] * 1000;
445 break;
446 default:
447 BUG();
448 }
449
450 return sprintf(buf, "%llu\n", val);
451}
452
453static ssize_t show_accuracy(struct device *dev,
454 struct device_attribute *devattr,
455 char *buf)
456{
457 struct acpi_device *acpi_dev = to_acpi_device(dev);
458 struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
459 unsigned int acc = resource->caps.accuracy;
460
461 return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000);
462}
463
464static ssize_t show_name(struct device *dev,
465 struct device_attribute *devattr,
466 char *buf)
467{
468 return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME);
469}
470
471/* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */
472static struct ro_sensor_template meter_ro_attrs[] = {
473{POWER_AVERAGE_NAME, show_power, 0},
474{"power1_accuracy", show_accuracy, 0},
475{"power1_average_interval_min", show_val, 0},
476{"power1_average_interval_max", show_val, 1},
477{"power1_is_battery", show_val, 5},
478{NULL, NULL, 0},
479};
480
481static struct rw_sensor_template meter_rw_attrs[] = {
482{POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0},
483{NULL, NULL, NULL, 0},
484};
485
486static struct ro_sensor_template misc_cap_attrs[] = {
487{"power1_cap_min", show_val, 2},
488{"power1_cap_max", show_val, 3},
489{"power1_cap_hyst", show_val, 4},
490{POWER_ALARM_NAME, show_val, 6},
491{NULL, NULL, 0},
492};
493
494static struct ro_sensor_template ro_cap_attrs[] = {
495{POWER_CAP_NAME, show_cap, 0},
496{NULL, NULL, 0},
497};
498
499static struct rw_sensor_template rw_cap_attrs[] = {
500{POWER_CAP_NAME, show_cap, set_cap, 0},
501{NULL, NULL, NULL, 0},
502};
503
504static struct rw_sensor_template trip_attrs[] = {
505{"power1_average_min", show_val, set_trip, 7},
506{"power1_average_max", show_val, set_trip, 8},
507{NULL, NULL, NULL, 0},
508};
509
510static struct ro_sensor_template misc_attrs[] = {
511{"name", show_name, 0},
512{"power1_model_number", show_str, 0},
513{"power1_oem_info", show_str, 2},
514{"power1_serial_number", show_str, 1},
515{NULL, NULL, 0},
516};
517
518/* Read power domain data */
519static void remove_domain_devices(struct acpi_power_meter_resource *resource)
520{
521 int i;
522
523 if (!resource->num_domain_devices)
524 return;
525
526 for (i = 0; i < resource->num_domain_devices; i++) {
527 struct acpi_device *obj = resource->domain_devices[i];
528 if (!obj)
529 continue;
530
531 sysfs_remove_link(resource->holders_dir,
532 kobject_name(&obj->dev.kobj));
533 put_device(&obj->dev);
534 }
535
536 kfree(resource->domain_devices);
537 kobject_put(resource->holders_dir);
538 resource->num_domain_devices = 0;
539}
540
541static int read_domain_devices(struct acpi_power_meter_resource *resource)
542{
543 int res = 0;
544 int i;
545 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
546 union acpi_object *pss;
547 acpi_status status;
548
549 status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL,
550 &buffer);
551 if (ACPI_FAILURE(status)) {
552 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD"));
553 return -ENODEV;
554 }
555
556 pss = buffer.pointer;
557 if (!pss ||
558 pss->type != ACPI_TYPE_PACKAGE) {
559 dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
560 "Invalid _PMD data\n");
561 res = -EFAULT;
562 goto end;
563 }
564
565 if (!pss->package.count)
566 goto end;
567
568 resource->domain_devices = kzalloc(sizeof(struct acpi_device *) *
569 pss->package.count, GFP_KERNEL);
570 if (!resource->domain_devices) {
571 res = -ENOMEM;
572 goto end;
573 }
574
575 resource->holders_dir = kobject_create_and_add("measures",
576 &resource->acpi_dev->dev.kobj);
577 if (!resource->holders_dir) {
578 res = -ENOMEM;
579 goto exit_free;
580 }
581
582 resource->num_domain_devices = pss->package.count;
583
584 for (i = 0; i < pss->package.count; i++) {
585 struct acpi_device *obj;
586 union acpi_object *element = &(pss->package.elements[i]);
587
588 /* Refuse non-references */
589 if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
590 continue;
591
592 /* Create a symlink to domain objects */
593 resource->domain_devices[i] = NULL;
594 status = acpi_bus_get_device(element->reference.handle,
595 &resource->domain_devices[i]);
596 if (ACPI_FAILURE(status))
597 continue;
598
599 obj = resource->domain_devices[i];
600 get_device(&obj->dev);
601
602 res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj,
603 kobject_name(&obj->dev.kobj));
604 if (res) {
605 put_device(&obj->dev);
606 resource->domain_devices[i] = NULL;
607 }
608 }
609
610 res = 0;
611 goto end;
612
613exit_free:
614 kfree(resource->domain_devices);
615end:
616 kfree(buffer.pointer);
617 return res;
618}
619
620/* Registration and deregistration */
621static int register_ro_attrs(struct acpi_power_meter_resource *resource,
622 struct ro_sensor_template *ro)
623{
624 struct device *dev = &resource->acpi_dev->dev;
625 struct sensor_device_attribute *sensors =
626 &resource->sensors[resource->num_sensors];
627 int res = 0;
628
629 while (ro->label) {
630 sensors->dev_attr.attr.name = ro->label;
631 sensors->dev_attr.attr.mode = S_IRUGO;
632 sensors->dev_attr.show = ro->show;
633 sensors->index = ro->index;
634
635 res = device_create_file(dev, &sensors->dev_attr);
636 if (res) {
637 sensors->dev_attr.attr.name = NULL;
638 goto error;
639 }
640 sensors++;
641 resource->num_sensors++;
642 ro++;
643 }
644
645error:
646 return res;
647}
648
649static int register_rw_attrs(struct acpi_power_meter_resource *resource,
650 struct rw_sensor_template *rw)
651{
652 struct device *dev = &resource->acpi_dev->dev;
653 struct sensor_device_attribute *sensors =
654 &resource->sensors[resource->num_sensors];
655 int res = 0;
656
657 while (rw->label) {
658 sensors->dev_attr.attr.name = rw->label;
659 sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
660 sensors->dev_attr.show = rw->show;
661 sensors->dev_attr.store = rw->set;
662 sensors->index = rw->index;
663
664 res = device_create_file(dev, &sensors->dev_attr);
665 if (res) {
666 sensors->dev_attr.attr.name = NULL;
667 goto error;
668 }
669 sensors++;
670 resource->num_sensors++;
671 rw++;
672 }
673
674error:
675 return res;
676}
677
678static void remove_attrs(struct acpi_power_meter_resource *resource)
679{
680 int i;
681
682 for (i = 0; i < resource->num_sensors; i++) {
683 if (!resource->sensors[i].dev_attr.attr.name)
684 continue;
685 device_remove_file(&resource->acpi_dev->dev,
686 &resource->sensors[i].dev_attr);
687 }
688
689 remove_domain_devices(resource);
690
691 resource->num_sensors = 0;
692}
693
694static int setup_attrs(struct acpi_power_meter_resource *resource)
695{
696 int res = 0;
697
698 res = read_domain_devices(resource);
699 if (res)
700 return res;
701
702 if (resource->caps.flags & POWER_METER_CAN_MEASURE) {
703 res = register_ro_attrs(resource, meter_ro_attrs);
704 if (res)
705 goto error;
706 res = register_rw_attrs(resource, meter_rw_attrs);
707 if (res)
708 goto error;
709 }
710
711 if (resource->caps.flags & POWER_METER_CAN_CAP) {
712 if (!can_cap_in_hardware()) {
713 dev_err(&resource->acpi_dev->dev,
714 "Ignoring unsafe software power cap!\n");
715 goto skip_unsafe_cap;
716 }
717
718 if (resource->caps.configurable_cap) {
719 res = register_rw_attrs(resource, rw_cap_attrs);
720 if (res)
721 goto error;
722 } else {
723 res = register_ro_attrs(resource, ro_cap_attrs);
724 if (res)
725 goto error;
726 }
727 res = register_ro_attrs(resource, misc_cap_attrs);
728 if (res)
729 goto error;
730 }
731skip_unsafe_cap:
732
733 if (resource->caps.flags & POWER_METER_CAN_TRIP) {
734 res = register_rw_attrs(resource, trip_attrs);
735 if (res)
736 goto error;
737 }
738
739 res = register_ro_attrs(resource, misc_attrs);
740 if (res)
741 goto error;
742
743 return res;
744error:
745 remove_attrs(resource);
746 return res;
747}
748
749static void free_capabilities(struct acpi_power_meter_resource *resource)
750{
751 acpi_string *str;
752 int i;
753
754 str = &resource->model_number;
755 for (i = 0; i < 3; i++, str++)
756 kfree(*str);
757}
758
759static int read_capabilities(struct acpi_power_meter_resource *resource)
760{
761 int res = 0;
762 int i;
763 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
764 struct acpi_buffer state = { 0, NULL };
765 struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" };
766 union acpi_object *pss;
767 acpi_string *str;
768 acpi_status status;
769
770 status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL,
771 &buffer);
772 if (ACPI_FAILURE(status)) {
773 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC"));
774 return -ENODEV;
775 }
776
777 pss = buffer.pointer;
778 if (!pss ||
779 pss->type != ACPI_TYPE_PACKAGE ||
780 pss->package.count != 14) {
781 dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
782 "Invalid _PMC data\n");
783 res = -EFAULT;
784 goto end;
785 }
786
787 /* Grab all the integer data at once */
788 state.length = sizeof(struct acpi_power_meter_capabilities);
789 state.pointer = &resource->caps;
790
791 status = acpi_extract_package(pss, &format, &state);
792 if (ACPI_FAILURE(status)) {
793 ACPI_EXCEPTION((AE_INFO, status, "Invalid data"));
794 res = -EFAULT;
795 goto end;
796 }
797
798 if (resource->caps.units) {
799 dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
800 "Unknown units %llu.\n",
801 resource->caps.units);
802 res = -EINVAL;
803 goto end;
804 }
805
806 /* Grab the string data */
807 str = &resource->model_number;
808
809 for (i = 11; i < 14; i++) {
810 union acpi_object *element = &(pss->package.elements[i]);
811
812 if (element->type != ACPI_TYPE_STRING) {
813 res = -EINVAL;
814 goto error;
815 }
816
817 *str = kzalloc(sizeof(u8) * (element->string.length + 1),
818 GFP_KERNEL);
819 if (!*str) {
820 res = -ENOMEM;
821 goto error;
822 }
823
824 strncpy(*str, element->string.pointer, element->string.length);
825 str++;
826 }
827
828 dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n");
829 goto end;
830error:
831 str = &resource->model_number;
832 for (i = 0; i < 3; i++, str++)
833 kfree(*str);
834end:
835 kfree(buffer.pointer);
836 return res;
837}
838
839/* Handle ACPI event notifications */
840static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
841{
842 struct acpi_power_meter_resource *resource;
843 int res;
844
845 if (!device || !acpi_driver_data(device))
846 return;
847
848 resource = acpi_driver_data(device);
849
850 mutex_lock(&resource->lock);
851 switch (event) {
852 case METER_NOTIFY_CONFIG:
853 free_capabilities(resource);
854 res = read_capabilities(resource);
855 if (res)
856 break;
857
858 remove_attrs(resource);
859 setup_attrs(resource);
860 break;
861 case METER_NOTIFY_TRIP:
862 sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
863 update_meter(resource);
864 break;
865 case METER_NOTIFY_CAP:
866 sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME);
867 update_cap(resource);
868 break;
869 case METER_NOTIFY_INTERVAL:
870 sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME);
871 update_avg_interval(resource);
872 break;
873 case METER_NOTIFY_CAPPING:
874 sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME);
875 dev_info(&device->dev, "Capping in progress.\n");
876 break;
877 default:
878 BUG();
879 }
880 mutex_unlock(&resource->lock);
881
882 acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS,
883 dev_name(&device->dev), event, 0);
884}
885
886static int acpi_power_meter_add(struct acpi_device *device)
887{
888 int res;
889 struct acpi_power_meter_resource *resource;
890
891 if (!device)
892 return -EINVAL;
893
894 resource = kzalloc(sizeof(struct acpi_power_meter_resource),
895 GFP_KERNEL);
896 if (!resource)
897 return -ENOMEM;
898
899 resource->sensors_valid = 0;
900 resource->acpi_dev = device;
901 mutex_init(&resource->lock);
902 strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME);
903 strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS);
904 device->driver_data = resource;
905
906 free_capabilities(resource);
907 res = read_capabilities(resource);
908 if (res)
909 goto exit_free;
910
911 resource->trip[0] = resource->trip[1] = -1;
912
913 res = setup_attrs(resource);
914 if (res)
915 goto exit_free;
916
917 resource->hwmon_dev = hwmon_device_register(&device->dev);
918 if (IS_ERR(resource->hwmon_dev)) {
919 res = PTR_ERR(resource->hwmon_dev);
920 goto exit_remove;
921 }
922
923 res = 0;
924 goto exit;
925
926exit_remove:
927 remove_attrs(resource);
928exit_free:
929 kfree(resource);
930exit:
931 return res;
932}
933
934static int acpi_power_meter_remove(struct acpi_device *device, int type)
935{
936 struct acpi_power_meter_resource *resource;
937
938 if (!device || !acpi_driver_data(device))
939 return -EINVAL;
940
941 resource = acpi_driver_data(device);
942 hwmon_device_unregister(resource->hwmon_dev);
943
944 free_capabilities(resource);
945 remove_attrs(resource);
946
947 kfree(resource);
948 return 0;
949}
950
951static int acpi_power_meter_resume(struct acpi_device *device)
952{
953 struct acpi_power_meter_resource *resource;
954
955 if (!device || !acpi_driver_data(device))
956 return -EINVAL;
957
958 resource = acpi_driver_data(device);
959 free_capabilities(resource);
960 read_capabilities(resource);
961
962 return 0;
963}
964
965static struct acpi_driver acpi_power_meter_driver = {
966 .name = "power_meter",
967 .class = ACPI_POWER_METER_CLASS,
968 .ids = power_meter_ids,
969 .ops = {
970 .add = acpi_power_meter_add,
971 .remove = acpi_power_meter_remove,
972 .resume = acpi_power_meter_resume,
973 .notify = acpi_power_meter_notify,
974 },
975};
976
977/* Module init/exit routines */
978static int __init enable_cap_knobs(const struct dmi_system_id *d)
979{
980 cap_in_hardware = 1;
981 return 0;
982}
983
984static struct dmi_system_id __initdata pm_dmi_table[] = {
985 {
986 enable_cap_knobs, "IBM Active Energy Manager",
987 {
988 DMI_MATCH(DMI_SYS_VENDOR, "IBM")
989 },
990 },
991 {}
992};
993
994static int __init acpi_power_meter_init(void)
995{
996 int result;
997
998 if (acpi_disabled)
999 return -ENODEV;
1000
1001 dmi_check_system(pm_dmi_table);
1002
1003 result = acpi_bus_register_driver(&acpi_power_meter_driver);
1004 if (result < 0)
1005 return -ENODEV;
1006
1007 return 0;
1008}
1009
1010static void __exit acpi_power_meter_exit(void)
1011{
1012 acpi_bus_unregister_driver(&acpi_power_meter_driver);
1013}
1014
1015MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
1016MODULE_DESCRIPTION("ACPI 4.0 power meter driver");
1017MODULE_LICENSE("GPL");
1018
1019module_param(force_cap_on, bool, 0644);
1020MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so.");
1021
1022module_init(acpi_power_meter_init);
1023module_exit(acpi_power_meter_exit);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index afad67769db6..f5f986991b52 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
311 dev->pnp.bus_id, 311 dev->pnp.bus_id,
312 (u32) dev->wakeup.sleep_state, 312 (u32) dev->wakeup.sleep_state,
313 dev->wakeup.flags.run_wake ? '*' : ' ', 313 dev->wakeup.flags.run_wake ? '*' : ' ',
314 dev->wakeup.state.enabled ? "enabled" : "disabled"); 314 (device_may_wakeup(&dev->dev)
315 || (ldev && device_may_wakeup(ldev))) ?
316 "enabled" : "disabled");
315 if (ldev) 317 if (ldev)
316 seq_printf(seq, "%s:%s", 318 seq_printf(seq, "%s:%s",
317 ldev->bus ? ldev->bus->name : "no-bus", 319 ldev->bus ? ldev->bus->name : "no-bus",
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
328{ 330{
329 struct device *dev = acpi_get_physical_device(adev->handle); 331 struct device *dev = acpi_get_physical_device(adev->handle);
330 332
331 if (dev && device_can_wakeup(dev)) 333 if (dev && device_can_wakeup(dev)) {
332 device_set_wakeup_enable(dev, adev->wakeup.state.enabled); 334 bool enable = !device_may_wakeup(dev);
335 device_set_wakeup_enable(dev, enable);
336 }
333} 337}
334 338
335static ssize_t 339static ssize_t
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file,
341 char strbuf[5]; 345 char strbuf[5];
342 char str[5] = ""; 346 char str[5] = "";
343 unsigned int len = count; 347 unsigned int len = count;
344 struct acpi_device *found_dev = NULL;
345 348
346 if (len > 4) 349 if (len > 4)
347 len = 4; 350 len = 4;
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file,
361 continue; 364 continue;
362 365
363 if (!strncmp(dev->pnp.bus_id, str, 4)) { 366 if (!strncmp(dev->pnp.bus_id, str, 4)) {
364 dev->wakeup.state.enabled = 367 if (device_can_wakeup(&dev->dev)) {
365 dev->wakeup.state.enabled ? 0 : 1; 368 bool enable = !device_may_wakeup(&dev->dev);
366 found_dev = dev; 369 device_set_wakeup_enable(&dev->dev, enable);
367 break; 370 } else {
368 }
369 }
370 if (found_dev) {
371 physical_device_enable_wakeup(found_dev);
372 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
373 struct acpi_device *dev = container_of(node,
374 struct
375 acpi_device,
376 wakeup_list);
377
378 if ((dev != found_dev) &&
379 (dev->wakeup.gpe_number ==
380 found_dev->wakeup.gpe_number)
381 && (dev->wakeup.gpe_device ==
382 found_dev->wakeup.gpe_device)) {
383 printk(KERN_WARNING
384 "ACPI: '%s' and '%s' have the same GPE, "
385 "can't disable/enable one separately\n",
386 dev->pnp.bus_id, found_dev->pnp.bus_id);
387 dev->wakeup.state.enabled =
388 found_dev->wakeup.state.enabled;
389 physical_device_enable_wakeup(dev); 371 physical_device_enable_wakeup(dev);
390 } 372 }
373 break;
391 } 374 }
392 } 375 }
393 mutex_unlock(&acpi_device_lock); 376 mutex_unlock(&acpi_device_lock);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index bec561c14beb..02d2a4c9084d 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -19,15 +19,15 @@
19#define _COMPONENT ACPI_PROCESSOR_COMPONENT 19#define _COMPONENT ACPI_PROCESSOR_COMPONENT
20ACPI_MODULE_NAME("processor_core"); 20ACPI_MODULE_NAME("processor_core");
21 21
22static int set_no_mwait(const struct dmi_system_id *id) 22static int __init set_no_mwait(const struct dmi_system_id *id)
23{ 23{
24 printk(KERN_NOTICE PREFIX "%s detected - " 24 printk(KERN_NOTICE PREFIX "%s detected - "
25 "disabling mwait for CPU C-states\n", id->ident); 25 "disabling mwait for CPU C-states\n", id->ident);
26 idle_nomwait = 1; 26 boot_option_idle_override = IDLE_NOMWAIT;
27 return 0; 27 return 0;
28} 28}
29 29
30static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = { 30static struct dmi_system_id __initdata processor_idle_dmi_table[] = {
31 { 31 {
32 set_no_mwait, "Extensa 5220", { 32 set_no_mwait, "Extensa 5220", {
33 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), 33 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
@@ -37,7 +37,6 @@ static struct dmi_system_id __cpuinitdata processor_idle_dmi_table[] = {
37 {}, 37 {},
38}; 38};
39 39
40#ifdef CONFIG_SMP
41static int map_lapic_id(struct acpi_subtable_header *entry, 40static int map_lapic_id(struct acpi_subtable_header *entry,
42 u32 acpi_id, int *apic_id) 41 u32 acpi_id, int *apic_id)
43{ 42{
@@ -165,7 +164,9 @@ exit:
165 164
166int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) 165int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
167{ 166{
167#ifdef CONFIG_SMP
168 int i; 168 int i;
169#endif
169 int apic_id = -1; 170 int apic_id = -1;
170 171
171 apic_id = map_mat_entry(handle, type, acpi_id); 172 apic_id = map_mat_entry(handle, type, acpi_id);
@@ -174,16 +175,21 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
174 if (apic_id == -1) 175 if (apic_id == -1)
175 return apic_id; 176 return apic_id;
176 177
178#ifdef CONFIG_SMP
177 for_each_possible_cpu(i) { 179 for_each_possible_cpu(i) {
178 if (cpu_physical_id(i) == apic_id) 180 if (cpu_physical_id(i) == apic_id)
179 return i; 181 return i;
180 } 182 }
183#else
184 /* In UP kernel, only processor 0 is valid */
185 if (apic_id == 0)
186 return apic_id;
187#endif
181 return -1; 188 return -1;
182} 189}
183EXPORT_SYMBOL_GPL(acpi_get_cpuid); 190EXPORT_SYMBOL_GPL(acpi_get_cpuid);
184#endif
185 191
186static bool processor_physically_present(acpi_handle handle) 192static bool __init processor_physically_present(acpi_handle handle)
187{ 193{
188 int cpuid, type; 194 int cpuid, type;
189 u32 acpi_id; 195 u32 acpi_id;
@@ -217,13 +223,13 @@ static bool processor_physically_present(acpi_handle handle)
217 type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0; 223 type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
218 cpuid = acpi_get_cpuid(handle, type, acpi_id); 224 cpuid = acpi_get_cpuid(handle, type, acpi_id);
219 225
220 if ((cpuid == -1) && (num_possible_cpus() > 1)) 226 if (cpuid == -1)
221 return false; 227 return false;
222 228
223 return true; 229 return true;
224} 230}
225 231
226static void acpi_set_pdc_bits(u32 *buf) 232static void __cpuinit acpi_set_pdc_bits(u32 *buf)
227{ 233{
228 buf[0] = ACPI_PDC_REVISION_ID; 234 buf[0] = ACPI_PDC_REVISION_ID;
229 buf[1] = 1; 235 buf[1] = 1;
@@ -235,7 +241,7 @@ static void acpi_set_pdc_bits(u32 *buf)
235 arch_acpi_set_pdc_bits(buf); 241 arch_acpi_set_pdc_bits(buf);
236} 242}
237 243
238static struct acpi_object_list *acpi_processor_alloc_pdc(void) 244static struct acpi_object_list *__cpuinit acpi_processor_alloc_pdc(void)
239{ 245{
240 struct acpi_object_list *obj_list; 246 struct acpi_object_list *obj_list;
241 union acpi_object *obj; 247 union acpi_object *obj;
@@ -278,12 +284,12 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void)
278 * _PDC is required for a BIOS-OS handshake for most of the newer 284 * _PDC is required for a BIOS-OS handshake for most of the newer
279 * ACPI processor features. 285 * ACPI processor features.
280 */ 286 */
281static int 287static int __cpuinit
282acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in) 288acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
283{ 289{
284 acpi_status status = AE_OK; 290 acpi_status status = AE_OK;
285 291
286 if (idle_nomwait) { 292 if (boot_option_idle_override == IDLE_NOMWAIT) {
287 /* 293 /*
288 * If mwait is disabled for CPU C-states, the C2C3_FFH access 294 * If mwait is disabled for CPU C-states, the C2C3_FFH access
289 * mode will be disabled in the parameter of _PDC object. 295 * mode will be disabled in the parameter of _PDC object.
@@ -306,7 +312,7 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
306 return status; 312 return status;
307} 313}
308 314
309void acpi_processor_set_pdc(acpi_handle handle) 315void __cpuinit acpi_processor_set_pdc(acpi_handle handle)
310{ 316{
311 struct acpi_object_list *obj_list; 317 struct acpi_object_list *obj_list;
312 318
@@ -323,9 +329,8 @@ void acpi_processor_set_pdc(acpi_handle handle)
323 kfree(obj_list->pointer); 329 kfree(obj_list->pointer);
324 kfree(obj_list); 330 kfree(obj_list);
325} 331}
326EXPORT_SYMBOL_GPL(acpi_processor_set_pdc);
327 332
328static acpi_status 333static acpi_status __init
329early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv) 334early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
330{ 335{
331 if (processor_physically_present(handle) == false) 336 if (processor_physically_present(handle) == false)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index 347eb21b2353..a4e0f1ba6040 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -40,8 +40,6 @@
40#include <linux/pm.h> 40#include <linux/pm.h>
41#include <linux/cpufreq.h> 41#include <linux/cpufreq.h>
42#include <linux/cpu.h> 42#include <linux/cpu.h>
43#include <linux/proc_fs.h>
44#include <linux/seq_file.h>
45#include <linux/dmi.h> 43#include <linux/dmi.h>
46#include <linux/moduleparam.h> 44#include <linux/moduleparam.h>
47#include <linux/cpuidle.h> 45#include <linux/cpuidle.h>
@@ -244,43 +242,6 @@ static int acpi_processor_errata(struct acpi_processor *pr)
244 return result; 242 return result;
245} 243}
246 244
247static struct proc_dir_entry *acpi_processor_dir = NULL;
248
249static int __cpuinit acpi_processor_add_fs(struct acpi_device *device)
250{
251 struct proc_dir_entry *entry = NULL;
252
253
254 if (!acpi_device_dir(device)) {
255 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
256 acpi_processor_dir);
257 if (!acpi_device_dir(device))
258 return -ENODEV;
259 }
260
261 /* 'throttling' [R/W] */
262 entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING,
263 S_IFREG | S_IRUGO | S_IWUSR,
264 acpi_device_dir(device),
265 &acpi_processor_throttling_fops,
266 acpi_driver_data(device));
267 if (!entry)
268 return -EIO;
269 return 0;
270}
271static int acpi_processor_remove_fs(struct acpi_device *device)
272{
273
274 if (acpi_device_dir(device)) {
275 remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING,
276 acpi_device_dir(device));
277 remove_proc_entry(acpi_device_bid(device), acpi_processor_dir);
278 acpi_device_dir(device) = NULL;
279 }
280
281 return 0;
282}
283
284/* -------------------------------------------------------------------------- 245/* --------------------------------------------------------------------------
285 Driver Interface 246 Driver Interface
286 -------------------------------------------------------------------------- */ 247 -------------------------------------------------------------------------- */
@@ -466,8 +427,13 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
466 if (action == CPU_ONLINE && pr) { 427 if (action == CPU_ONLINE && pr) {
467 acpi_processor_ppc_has_changed(pr, 0); 428 acpi_processor_ppc_has_changed(pr, 0);
468 acpi_processor_cst_has_changed(pr); 429 acpi_processor_cst_has_changed(pr);
430 acpi_processor_reevaluate_tstate(pr, action);
469 acpi_processor_tstate_has_changed(pr); 431 acpi_processor_tstate_has_changed(pr);
470 } 432 }
433 if (action == CPU_DEAD && pr) {
434 /* invalidate the flag.throttling after one CPU is offline */
435 acpi_processor_reevaluate_tstate(pr, action);
436 }
471 return NOTIFY_OK; 437 return NOTIFY_OK;
472} 438}
473 439
@@ -525,14 +491,10 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
525 491
526 per_cpu(processors, pr->id) = pr; 492 per_cpu(processors, pr->id) = pr;
527 493
528 result = acpi_processor_add_fs(device);
529 if (result)
530 goto err_free_cpumask;
531
532 sysdev = get_cpu_sysdev(pr->id); 494 sysdev = get_cpu_sysdev(pr->id);
533 if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { 495 if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) {
534 result = -EFAULT; 496 result = -EFAULT;
535 goto err_remove_fs; 497 goto err_free_cpumask;
536 } 498 }
537 499
538#ifdef CONFIG_CPU_FREQ 500#ifdef CONFIG_CPU_FREQ
@@ -578,8 +540,6 @@ err_thermal_unregister:
578 thermal_cooling_device_unregister(pr->cdev); 540 thermal_cooling_device_unregister(pr->cdev);
579err_power_exit: 541err_power_exit:
580 acpi_processor_power_exit(pr, device); 542 acpi_processor_power_exit(pr, device);
581err_remove_fs:
582 acpi_processor_remove_fs(device);
583err_free_cpumask: 543err_free_cpumask:
584 free_cpumask_var(pr->throttling.shared_cpu_map); 544 free_cpumask_var(pr->throttling.shared_cpu_map);
585 545
@@ -608,8 +568,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
608 568
609 sysfs_remove_link(&device->dev.kobj, "sysdev"); 569 sysfs_remove_link(&device->dev.kobj, "sysdev");
610 570
611 acpi_processor_remove_fs(device);
612
613 if (pr->cdev) { 571 if (pr->cdev) {
614 sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 572 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
615 sysfs_remove_link(&pr->cdev->device.kobj, "device"); 573 sysfs_remove_link(&pr->cdev->device.kobj, "device");
@@ -677,8 +635,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
677 return 0; 635 return 0;
678} 636}
679 637
680static void __ref acpi_processor_hotplug_notify(acpi_handle handle, 638static void acpi_processor_hotplug_notify(acpi_handle handle,
681 u32 event, void *data) 639 u32 event, void *data)
682{ 640{
683 struct acpi_processor *pr; 641 struct acpi_processor *pr;
684 struct acpi_device *device = NULL; 642 struct acpi_device *device = NULL;
@@ -842,10 +800,6 @@ static int __init acpi_processor_init(void)
842 800
843 memset(&errata, 0, sizeof(errata)); 801 memset(&errata, 0, sizeof(errata));
844 802
845 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
846 if (!acpi_processor_dir)
847 return -ENOMEM;
848
849 if (!cpuidle_register_driver(&acpi_idle_driver)) { 803 if (!cpuidle_register_driver(&acpi_idle_driver)) {
850 printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", 804 printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n",
851 acpi_idle_driver.name); 805 acpi_idle_driver.name);
@@ -871,8 +825,6 @@ static int __init acpi_processor_init(void)
871out_cpuidle: 825out_cpuidle:
872 cpuidle_unregister_driver(&acpi_idle_driver); 826 cpuidle_unregister_driver(&acpi_idle_driver);
873 827
874 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
875
876 return result; 828 return result;
877} 829}
878 830
@@ -891,14 +843,10 @@ static void __exit acpi_processor_exit(void)
891 843
892 cpuidle_unregister_driver(&acpi_idle_driver); 844 cpuidle_unregister_driver(&acpi_idle_driver);
893 845
894 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
895
896 return; 846 return;
897} 847}
898 848
899module_init(acpi_processor_init); 849module_init(acpi_processor_init);
900module_exit(acpi_processor_exit); 850module_exit(acpi_processor_exit);
901 851
902EXPORT_SYMBOL(acpi_processor_set_thermal_limit);
903
904MODULE_ALIAS("processor"); 852MODULE_ALIAS("processor");
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index f4428e82b352..431ab11c8c1b 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
64#define ACPI_PROCESSOR_CLASS "processor" 64#define ACPI_PROCESSOR_CLASS "processor"
65#define _COMPONENT ACPI_PROCESSOR_COMPONENT 65#define _COMPONENT ACPI_PROCESSOR_COMPONENT
66ACPI_MODULE_NAME("processor_idle"); 66ACPI_MODULE_NAME("processor_idle");
67#define ACPI_PROCESSOR_FILE_POWER "power"
68#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) 67#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
69#define C2_OVERHEAD 1 /* 1us */ 68#define C2_OVERHEAD 1 /* 1us */
70#define C3_OVERHEAD 1 /* 1us */ 69#define C3_OVERHEAD 1 /* 1us */
@@ -80,6 +79,13 @@ module_param(bm_check_disable, uint, 0000);
80static unsigned int latency_factor __read_mostly = 2; 79static unsigned int latency_factor __read_mostly = 2;
81module_param(latency_factor, uint, 0644); 80module_param(latency_factor, uint, 0644);
82 81
82static int disabled_by_idle_boot_param(void)
83{
84 return boot_option_idle_override == IDLE_POLL ||
85 boot_option_idle_override == IDLE_FORCE_MWAIT ||
86 boot_option_idle_override == IDLE_HALT;
87}
88
83/* 89/*
84 * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. 90 * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
85 * For now disable this. Probably a bug somewhere else. 91 * For now disable this. Probably a bug somewhere else.
@@ -155,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
155 if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) 161 if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
156 return; 162 return;
157 163
158 if (c1e_detected) 164 if (amd_e400_c1e_detected)
159 type = ACPI_STATE_C1; 165 type = ACPI_STATE_C1;
160 166
161 /* 167 /*
@@ -456,7 +462,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
456 continue; 462 continue;
457 } 463 }
458 if (cx.type == ACPI_STATE_C1 && 464 if (cx.type == ACPI_STATE_C1 &&
459 (idle_halt || idle_nomwait)) { 465 (boot_option_idle_override == IDLE_NOMWAIT)) {
460 /* 466 /*
461 * In most cases the C1 space_id obtained from 467 * In most cases the C1 space_id obtained from
462 * _CST object is FIXED_HARDWARE access mode. 468 * _CST object is FIXED_HARDWARE access mode.
@@ -747,7 +753,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
747 struct acpi_processor *pr; 753 struct acpi_processor *pr;
748 struct acpi_processor_cx *cx = cpuidle_get_statedata(state); 754 struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
749 755
750 pr = __get_cpu_var(processors); 756 pr = __this_cpu_read(processors);
751 757
752 if (unlikely(!pr)) 758 if (unlikely(!pr))
753 return 0; 759 return 0;
@@ -788,7 +794,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
788 s64 idle_time_ns; 794 s64 idle_time_ns;
789 s64 idle_time; 795 s64 idle_time;
790 796
791 pr = __get_cpu_var(processors); 797 pr = __this_cpu_read(processors);
792 798
793 if (unlikely(!pr)) 799 if (unlikely(!pr))
794 return 0; 800 return 0;
@@ -865,7 +871,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
865 s64 idle_time; 871 s64 idle_time;
866 872
867 873
868 pr = __get_cpu_var(processors); 874 pr = __this_cpu_read(processors);
869 875
870 if (unlikely(!pr)) 876 if (unlikely(!pr))
871 return 0; 877 return 0;
@@ -1013,12 +1019,10 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1013 strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN); 1019 strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
1014 state->exit_latency = cx->latency; 1020 state->exit_latency = cx->latency;
1015 state->target_residency = cx->latency * latency_factor; 1021 state->target_residency = cx->latency * latency_factor;
1016 state->power_usage = cx->power;
1017 1022
1018 state->flags = 0; 1023 state->flags = 0;
1019 switch (cx->type) { 1024 switch (cx->type) {
1020 case ACPI_STATE_C1: 1025 case ACPI_STATE_C1:
1021 state->flags |= CPUIDLE_FLAG_SHALLOW;
1022 if (cx->entry_method == ACPI_CSTATE_FFH) 1026 if (cx->entry_method == ACPI_CSTATE_FFH)
1023 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1027 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1024 1028
@@ -1027,16 +1031,13 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
1027 break; 1031 break;
1028 1032
1029 case ACPI_STATE_C2: 1033 case ACPI_STATE_C2:
1030 state->flags |= CPUIDLE_FLAG_BALANCED;
1031 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1034 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1032 state->enter = acpi_idle_enter_simple; 1035 state->enter = acpi_idle_enter_simple;
1033 dev->safe_state = state; 1036 dev->safe_state = state;
1034 break; 1037 break;
1035 1038
1036 case ACPI_STATE_C3: 1039 case ACPI_STATE_C3:
1037 state->flags |= CPUIDLE_FLAG_DEEP;
1038 state->flags |= CPUIDLE_FLAG_TIME_VALID; 1040 state->flags |= CPUIDLE_FLAG_TIME_VALID;
1039 state->flags |= CPUIDLE_FLAG_CHECK_BM;
1040 state->enter = pr->flags.bm_check ? 1041 state->enter = pr->flags.bm_check ?
1041 acpi_idle_enter_bm : 1042 acpi_idle_enter_bm :
1042 acpi_idle_enter_simple; 1043 acpi_idle_enter_simple;
@@ -1060,7 +1061,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1060{ 1061{
1061 int ret = 0; 1062 int ret = 0;
1062 1063
1063 if (boot_option_idle_override) 1064 if (disabled_by_idle_boot_param())
1064 return 0; 1065 return 0;
1065 1066
1066 if (!pr) 1067 if (!pr)
@@ -1091,19 +1092,10 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1091 acpi_status status = 0; 1092 acpi_status status = 0;
1092 static int first_run; 1093 static int first_run;
1093 1094
1094 if (boot_option_idle_override) 1095 if (disabled_by_idle_boot_param())
1095 return 0; 1096 return 0;
1096 1097
1097 if (!first_run) { 1098 if (!first_run) {
1098 if (idle_halt) {
1099 /*
1100 * When the boot option of "idle=halt" is added, halt
1101 * is used for CPU IDLE.
1102 * In such case C2/C3 is meaningless. So the max_cstate
1103 * is set to one.
1104 */
1105 max_cstate = 1;
1106 }
1107 dmi_check_system(processor_power_dmi_table); 1099 dmi_check_system(processor_power_dmi_table);
1108 max_cstate = acpi_processor_cstate_check(max_cstate); 1100 max_cstate = acpi_processor_cstate_check(max_cstate);
1109 if (max_cstate < ACPI_C_STATES_MAX) 1101 if (max_cstate < ACPI_C_STATES_MAX)
@@ -1144,7 +1136,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1144int acpi_processor_power_exit(struct acpi_processor *pr, 1136int acpi_processor_power_exit(struct acpi_processor *pr,
1145 struct acpi_device *device) 1137 struct acpi_device *device)
1146{ 1138{
1147 if (boot_option_idle_override) 1139 if (disabled_by_idle_boot_param())
1148 return 0; 1140 return 0;
1149 1141
1150 cpuidle_unregister_device(&pr->power.dev); 1142 cpuidle_unregister_device(&pr->power.dev);
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 3a73a93596e8..85b32376dad7 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -49,10 +49,6 @@ ACPI_MODULE_NAME("processor_perflib");
49 49
50static DEFINE_MUTEX(performance_mutex); 50static DEFINE_MUTEX(performance_mutex);
51 51
52/* Use cpufreq debug layer for _PPC changes. */
53#define cpufreq_printk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
54 "cpufreq-core", msg)
55
56/* 52/*
57 * _PPC support is implemented as a CPUfreq policy notifier: 53 * _PPC support is implemented as a CPUfreq policy notifier:
58 * This means each time a CPUfreq driver registered also with 54 * This means each time a CPUfreq driver registered also with
@@ -145,7 +141,7 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
145 return -ENODEV; 141 return -ENODEV;
146 } 142 }
147 143
148 cpufreq_printk("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, 144 pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
149 (int)ppc, ppc ? "" : "not"); 145 (int)ppc, ppc ? "" : "not");
150 146
151 pr->performance_platform_limit = (int)ppc; 147 pr->performance_platform_limit = (int)ppc;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 953b25fb9869..79cb65332894 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -44,47 +44,6 @@
44#define _COMPONENT ACPI_PROCESSOR_COMPONENT 44#define _COMPONENT ACPI_PROCESSOR_COMPONENT
45ACPI_MODULE_NAME("processor_thermal"); 45ACPI_MODULE_NAME("processor_thermal");
46 46
47/* --------------------------------------------------------------------------
48 Limit Interface
49 -------------------------------------------------------------------------- */
50static int acpi_processor_apply_limit(struct acpi_processor *pr)
51{
52 int result = 0;
53 u16 px = 0;
54 u16 tx = 0;
55
56
57 if (!pr)
58 return -EINVAL;
59
60 if (!pr->flags.limit)
61 return -ENODEV;
62
63 if (pr->flags.throttling) {
64 if (pr->limit.user.tx > tx)
65 tx = pr->limit.user.tx;
66 if (pr->limit.thermal.tx > tx)
67 tx = pr->limit.thermal.tx;
68
69 result = acpi_processor_set_throttling(pr, tx, false);
70 if (result)
71 goto end;
72 }
73
74 pr->limit.state.px = px;
75 pr->limit.state.tx = tx;
76
77 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
78 "Processor [%d] limit set to (P%d:T%d)\n", pr->id,
79 pr->limit.state.px, pr->limit.state.tx));
80
81 end:
82 if (result)
83 printk(KERN_ERR PREFIX "Unable to set limit\n");
84
85 return result;
86}
87
88#ifdef CONFIG_CPU_FREQ 47#ifdef CONFIG_CPU_FREQ
89 48
90/* If a passive cooling situation is detected, primarily CPUfreq is used, as it 49/* If a passive cooling situation is detected, primarily CPUfreq is used, as it
@@ -107,36 +66,6 @@ static int cpu_has_cpufreq(unsigned int cpu)
107 return 1; 66 return 1;
108} 67}
109 68
110static int acpi_thermal_cpufreq_increase(unsigned int cpu)
111{
112 if (!cpu_has_cpufreq(cpu))
113 return -ENODEV;
114
115 if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) <
116 CPUFREQ_THERMAL_MAX_STEP) {
117 per_cpu(cpufreq_thermal_reduction_pctg, cpu)++;
118 cpufreq_update_policy(cpu);
119 return 0;
120 }
121
122 return -ERANGE;
123}
124
125static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
126{
127 if (!cpu_has_cpufreq(cpu))
128 return -ENODEV;
129
130 if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) >
131 (CPUFREQ_THERMAL_MIN_STEP + 1))
132 per_cpu(cpufreq_thermal_reduction_pctg, cpu)--;
133 else
134 per_cpu(cpufreq_thermal_reduction_pctg, cpu) = 0;
135 cpufreq_update_policy(cpu);
136 /* We reached max freq again and can leave passive mode */
137 return !per_cpu(cpufreq_thermal_reduction_pctg, cpu);
138}
139
140static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, 69static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
141 unsigned long event, void *data) 70 unsigned long event, void *data)
142{ 71{
@@ -227,124 +156,8 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state)
227 return 0; 156 return 0;
228} 157}
229 158
230static int acpi_thermal_cpufreq_increase(unsigned int cpu)
231{
232 return -ENODEV;
233}
234static int acpi_thermal_cpufreq_decrease(unsigned int cpu)
235{
236 return -ENODEV;
237}
238
239#endif 159#endif
240 160
241int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
242{
243 int result = 0;
244 struct acpi_processor *pr = NULL;
245 struct acpi_device *device = NULL;
246 int tx = 0, max_tx_px = 0;
247
248
249 if ((type < ACPI_PROCESSOR_LIMIT_NONE)
250 || (type > ACPI_PROCESSOR_LIMIT_DECREMENT))
251 return -EINVAL;
252
253 result = acpi_bus_get_device(handle, &device);
254 if (result)
255 return result;
256
257 pr = acpi_driver_data(device);
258 if (!pr)
259 return -ENODEV;
260
261 /* Thermal limits are always relative to the current Px/Tx state. */
262 if (pr->flags.throttling)
263 pr->limit.thermal.tx = pr->throttling.state;
264
265 /*
266 * Our default policy is to only use throttling at the lowest
267 * performance state.
268 */
269
270 tx = pr->limit.thermal.tx;
271
272 switch (type) {
273
274 case ACPI_PROCESSOR_LIMIT_NONE:
275 do {
276 result = acpi_thermal_cpufreq_decrease(pr->id);
277 } while (!result);
278 tx = 0;
279 break;
280
281 case ACPI_PROCESSOR_LIMIT_INCREMENT:
282 /* if going up: P-states first, T-states later */
283
284 result = acpi_thermal_cpufreq_increase(pr->id);
285 if (!result)
286 goto end;
287 else if (result == -ERANGE)
288 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
289 "At maximum performance state\n"));
290
291 if (pr->flags.throttling) {
292 if (tx == (pr->throttling.state_count - 1))
293 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
294 "At maximum throttling state\n"));
295 else
296 tx++;
297 }
298 break;
299
300 case ACPI_PROCESSOR_LIMIT_DECREMENT:
301 /* if going down: T-states first, P-states later */
302
303 if (pr->flags.throttling) {
304 if (tx == 0) {
305 max_tx_px = 1;
306 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
307 "At minimum throttling state\n"));
308 } else {
309 tx--;
310 goto end;
311 }
312 }
313
314 result = acpi_thermal_cpufreq_decrease(pr->id);
315 if (result) {
316 /*
317 * We only could get -ERANGE, 1 or 0.
318 * In the first two cases we reached max freq again.
319 */
320 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
321 "At minimum performance state\n"));
322 max_tx_px = 1;
323 } else
324 max_tx_px = 0;
325
326 break;
327 }
328
329 end:
330 if (pr->flags.throttling) {
331 pr->limit.thermal.px = 0;
332 pr->limit.thermal.tx = tx;
333
334 result = acpi_processor_apply_limit(pr);
335 if (result)
336 printk(KERN_ERR PREFIX "Unable to set thermal limit\n");
337
338 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n",
339 pr->limit.thermal.px, pr->limit.thermal.tx));
340 } else
341 result = 0;
342 if (max_tx_px)
343 return 1;
344 else
345 return result;
346}
347
348int acpi_processor_get_limit_info(struct acpi_processor *pr) 161int acpi_processor_get_limit_info(struct acpi_processor *pr)
349{ 162{
350 163
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 730863855ed5..605a2954ef17 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -32,8 +32,6 @@
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/cpufreq.h> 34#include <linux/cpufreq.h>
35#include <linux/proc_fs.h>
36#include <linux/seq_file.h>
37 35
38#include <asm/io.h> 36#include <asm/io.h>
39#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -368,6 +366,58 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
368} 366}
369 367
370/* 368/*
369 * This function is used to reevaluate whether the T-state is valid
370 * after one CPU is onlined/offlined.
371 * It is noted that it won't reevaluate the following properties for
372 * the T-state.
373 * 1. Control method.
374 * 2. the number of supported T-state
375 * 3. TSD domain
376 */
377void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
378 unsigned long action)
379{
380 int result = 0;
381
382 if (action == CPU_DEAD) {
383 /* When one CPU is offline, the T-state throttling
384 * will be invalidated.
385 */
386 pr->flags.throttling = 0;
387 return;
388 }
389 /* the following is to recheck whether the T-state is valid for
390 * the online CPU
391 */
392 if (!pr->throttling.state_count) {
393 /* If the number of T-state is invalid, it is
394 * invalidated.
395 */
396 pr->flags.throttling = 0;
397 return;
398 }
399 pr->flags.throttling = 1;
400
401 /* Disable throttling (if enabled). We'll let subsequent
402 * policy (e.g.thermal) decide to lower performance if it
403 * so chooses, but for now we'll crank up the speed.
404 */
405
406 result = acpi_processor_get_throttling(pr);
407 if (result)
408 goto end;
409
410 if (pr->throttling.state) {
411 result = acpi_processor_set_throttling(pr, 0, false);
412 if (result)
413 goto end;
414 }
415
416end:
417 if (result)
418 pr->flags.throttling = 0;
419}
420/*
371 * _PTC - Processor Throttling Control (and status) register location 421 * _PTC - Processor Throttling Control (and status) register location
372 */ 422 */
373static int acpi_processor_get_throttling_control(struct acpi_processor *pr) 423static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
@@ -660,20 +710,14 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
660} 710}
661 711
662#ifdef CONFIG_X86 712#ifdef CONFIG_X86
663static int acpi_throttling_rdmsr(struct acpi_processor *pr, 713static int acpi_throttling_rdmsr(u64 *value)
664 u64 *value)
665{ 714{
666 struct cpuinfo_x86 *c;
667 u64 msr_high, msr_low; 715 u64 msr_high, msr_low;
668 unsigned int cpu;
669 u64 msr = 0; 716 u64 msr = 0;
670 int ret = -1; 717 int ret = -1;
671 718
672 cpu = pr->id; 719 if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
673 c = &cpu_data(cpu); 720 !this_cpu_has(X86_FEATURE_ACPI)) {
674
675 if ((c->x86_vendor != X86_VENDOR_INTEL) ||
676 !cpu_has(c, X86_FEATURE_ACPI)) {
677 printk(KERN_ERR PREFIX 721 printk(KERN_ERR PREFIX
678 "HARDWARE addr space,NOT supported yet\n"); 722 "HARDWARE addr space,NOT supported yet\n");
679 } else { 723 } else {
@@ -688,18 +732,13 @@ static int acpi_throttling_rdmsr(struct acpi_processor *pr,
688 return ret; 732 return ret;
689} 733}
690 734
691static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) 735static int acpi_throttling_wrmsr(u64 value)
692{ 736{
693 struct cpuinfo_x86 *c;
694 unsigned int cpu;
695 int ret = -1; 737 int ret = -1;
696 u64 msr; 738 u64 msr;
697 739
698 cpu = pr->id; 740 if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
699 c = &cpu_data(cpu); 741 !this_cpu_has(X86_FEATURE_ACPI)) {
700
701 if ((c->x86_vendor != X86_VENDOR_INTEL) ||
702 !cpu_has(c, X86_FEATURE_ACPI)) {
703 printk(KERN_ERR PREFIX 742 printk(KERN_ERR PREFIX
704 "HARDWARE addr space,NOT supported yet\n"); 743 "HARDWARE addr space,NOT supported yet\n");
705 } else { 744 } else {
@@ -711,15 +750,14 @@ static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value)
711 return ret; 750 return ret;
712} 751}
713#else 752#else
714static int acpi_throttling_rdmsr(struct acpi_processor *pr, 753static int acpi_throttling_rdmsr(u64 *value)
715 u64 *value)
716{ 754{
717 printk(KERN_ERR PREFIX 755 printk(KERN_ERR PREFIX
718 "HARDWARE addr space,NOT supported yet\n"); 756 "HARDWARE addr space,NOT supported yet\n");
719 return -1; 757 return -1;
720} 758}
721 759
722static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value) 760static int acpi_throttling_wrmsr(u64 value)
723{ 761{
724 printk(KERN_ERR PREFIX 762 printk(KERN_ERR PREFIX
725 "HARDWARE addr space,NOT supported yet\n"); 763 "HARDWARE addr space,NOT supported yet\n");
@@ -751,7 +789,7 @@ static int acpi_read_throttling_status(struct acpi_processor *pr,
751 ret = 0; 789 ret = 0;
752 break; 790 break;
753 case ACPI_ADR_SPACE_FIXED_HARDWARE: 791 case ACPI_ADR_SPACE_FIXED_HARDWARE:
754 ret = acpi_throttling_rdmsr(pr, value); 792 ret = acpi_throttling_rdmsr(value);
755 break; 793 break;
756 default: 794 default:
757 printk(KERN_ERR PREFIX "Unknown addr space %d\n", 795 printk(KERN_ERR PREFIX "Unknown addr space %d\n",
@@ -784,7 +822,7 @@ static int acpi_write_throttling_state(struct acpi_processor *pr,
784 ret = 0; 822 ret = 0;
785 break; 823 break;
786 case ACPI_ADR_SPACE_FIXED_HARDWARE: 824 case ACPI_ADR_SPACE_FIXED_HARDWARE:
787 ret = acpi_throttling_wrmsr(pr, value); 825 ret = acpi_throttling_wrmsr(value);
788 break; 826 break;
789 default: 827 default:
790 printk(KERN_ERR PREFIX "Unknown addr space %d\n", 828 printk(KERN_ERR PREFIX "Unknown addr space %d\n",
@@ -874,7 +912,11 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
874 */ 912 */
875 cpumask_copy(saved_mask, &current->cpus_allowed); 913 cpumask_copy(saved_mask, &current->cpus_allowed);
876 /* FIXME: use work_on_cpu() */ 914 /* FIXME: use work_on_cpu() */
877 set_cpus_allowed_ptr(current, cpumask_of(pr->id)); 915 if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
916 /* Can't migrate to the target pr->id CPU. Exit */
917 free_cpumask_var(saved_mask);
918 return -ENODEV;
919 }
878 ret = pr->throttling.acpi_processor_get_throttling(pr); 920 ret = pr->throttling.acpi_processor_get_throttling(pr);
879 /* restore the previous state */ 921 /* restore the previous state */
880 set_cpus_allowed_ptr(current, saved_mask); 922 set_cpus_allowed_ptr(current, saved_mask);
@@ -1049,6 +1091,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1049 return -ENOMEM; 1091 return -ENOMEM;
1050 } 1092 }
1051 1093
1094 if (cpu_is_offline(pr->id)) {
1095 /*
1096 * the cpu pointed by pr->id is offline. Unnecessary to change
1097 * the throttling state any more.
1098 */
1099 return -ENODEV;
1100 }
1101
1052 cpumask_copy(saved_mask, &current->cpus_allowed); 1102 cpumask_copy(saved_mask, &current->cpus_allowed);
1053 t_state.target_state = state; 1103 t_state.target_state = state;
1054 p_throttling = &(pr->throttling); 1104 p_throttling = &(pr->throttling);
@@ -1072,7 +1122,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1072 */ 1122 */
1073 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { 1123 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
1074 /* FIXME: use work_on_cpu() */ 1124 /* FIXME: use work_on_cpu() */
1075 set_cpus_allowed_ptr(current, cpumask_of(pr->id)); 1125 if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
1126 /* Can't migrate to the pr->id CPU. Exit */
1127 ret = -ENODEV;
1128 goto exit;
1129 }
1076 ret = p_throttling->acpi_processor_set_throttling(pr, 1130 ret = p_throttling->acpi_processor_set_throttling(pr,
1077 t_state.target_state, force); 1131 t_state.target_state, force);
1078 } else { 1132 } else {
@@ -1098,13 +1152,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1098 */ 1152 */
1099 if (!match_pr->flags.throttling) { 1153 if (!match_pr->flags.throttling) {
1100 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1154 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1101 "Throttling Controll is unsupported " 1155 "Throttling Control is unsupported "
1102 "on CPU %d\n", i)); 1156 "on CPU %d\n", i));
1103 continue; 1157 continue;
1104 } 1158 }
1105 t_state.cpu = i; 1159 t_state.cpu = i;
1106 /* FIXME: use work_on_cpu() */ 1160 /* FIXME: use work_on_cpu() */
1107 set_cpus_allowed_ptr(current, cpumask_of(i)); 1161 if (set_cpus_allowed_ptr(current, cpumask_of(i)))
1162 continue;
1108 ret = match_pr->throttling. 1163 ret = match_pr->throttling.
1109 acpi_processor_set_throttling( 1164 acpi_processor_set_throttling(
1110 match_pr, t_state.target_state, force); 1165 match_pr, t_state.target_state, force);
@@ -1124,6 +1179,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1124 /* restore the previous state */ 1179 /* restore the previous state */
1125 /* FIXME: use work_on_cpu() */ 1180 /* FIXME: use work_on_cpu() */
1126 set_cpus_allowed_ptr(current, saved_mask); 1181 set_cpus_allowed_ptr(current, saved_mask);
1182exit:
1127 free_cpumask_var(online_throttling_cpus); 1183 free_cpumask_var(online_throttling_cpus);
1128 free_cpumask_var(saved_mask); 1184 free_cpumask_var(saved_mask);
1129 return ret; 1185 return ret;
@@ -1214,111 +1270,3 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
1214 return result; 1270 return result;
1215} 1271}
1216 1272
1217/* proc interface */
1218static int acpi_processor_throttling_seq_show(struct seq_file *seq,
1219 void *offset)
1220{
1221 struct acpi_processor *pr = seq->private;
1222 int i = 0;
1223 int result = 0;
1224
1225 if (!pr)
1226 goto end;
1227
1228 if (!(pr->throttling.state_count > 0)) {
1229 seq_puts(seq, "<not supported>\n");
1230 goto end;
1231 }
1232
1233 result = acpi_processor_get_throttling(pr);
1234
1235 if (result) {
1236 seq_puts(seq,
1237 "Could not determine current throttling state.\n");
1238 goto end;
1239 }
1240
1241 seq_printf(seq, "state count: %d\n"
1242 "active state: T%d\n"
1243 "state available: T%d to T%d\n",
1244 pr->throttling.state_count, pr->throttling.state,
1245 pr->throttling_platform_limit,
1246 pr->throttling.state_count - 1);
1247
1248 seq_puts(seq, "states:\n");
1249 if (pr->throttling.acpi_processor_get_throttling ==
1250 acpi_processor_get_throttling_fadt) {
1251 for (i = 0; i < pr->throttling.state_count; i++)
1252 seq_printf(seq, " %cT%d: %02d%%\n",
1253 (i == pr->throttling.state ? '*' : ' '), i,
1254 (pr->throttling.states[i].performance ? pr->
1255 throttling.states[i].performance / 10 : 0));
1256 } else {
1257 for (i = 0; i < pr->throttling.state_count; i++)
1258 seq_printf(seq, " %cT%d: %02d%%\n",
1259 (i == pr->throttling.state ? '*' : ' '), i,
1260 (int)pr->throttling.states_tss[i].
1261 freqpercentage);
1262 }
1263
1264 end:
1265 return 0;
1266}
1267
1268static int acpi_processor_throttling_open_fs(struct inode *inode,
1269 struct file *file)
1270{
1271 return single_open(file, acpi_processor_throttling_seq_show,
1272 PDE(inode)->data);
1273}
1274
1275static ssize_t acpi_processor_write_throttling(struct file *file,
1276 const char __user * buffer,
1277 size_t count, loff_t * data)
1278{
1279 int result = 0;
1280 struct seq_file *m = file->private_data;
1281 struct acpi_processor *pr = m->private;
1282 char state_string[5] = "";
1283 char *charp = NULL;
1284 size_t state_val = 0;
1285 char tmpbuf[5] = "";
1286
1287 if (!pr || (count > sizeof(state_string) - 1))
1288 return -EINVAL;
1289
1290 if (copy_from_user(state_string, buffer, count))
1291 return -EFAULT;
1292
1293 state_string[count] = '\0';
1294 if ((count > 0) && (state_string[count-1] == '\n'))
1295 state_string[count-1] = '\0';
1296
1297 charp = state_string;
1298 if ((state_string[0] == 't') || (state_string[0] == 'T'))
1299 charp++;
1300
1301 state_val = simple_strtoul(charp, NULL, 0);
1302 if (state_val >= pr->throttling.state_count)
1303 return -EINVAL;
1304
1305 snprintf(tmpbuf, 5, "%zu", state_val);
1306
1307 if (strcmp(tmpbuf, charp) != 0)
1308 return -EINVAL;
1309
1310 result = acpi_processor_set_throttling(pr, state_val, false);
1311 if (result)
1312 return result;
1313
1314 return count;
1315}
1316
1317const struct file_operations acpi_processor_throttling_fops = {
1318 .owner = THIS_MODULE,
1319 .open = acpi_processor_throttling_open_fs,
1320 .read = seq_read,
1321 .write = acpi_processor_write_throttling,
1322 .llseek = seq_lseek,
1323 .release = single_release,
1324};
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index 93f91142d7ad..a6c77e8b37bd 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -15,9 +15,15 @@ void acpi_reboot(void)
15 15
16 rr = &acpi_gbl_FADT.reset_register; 16 rr = &acpi_gbl_FADT.reset_register;
17 17
18 /* Is the reset register supported? */ 18 /* ACPI reset register was only introduced with v2 of the FADT */
19 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || 19
20 rr->bit_width != 8 || rr->bit_offset != 0) 20 if (acpi_gbl_FADT.header.revision < 2)
21 return;
22
23 /* Is the reset register supported? The spec says we should be
24 * checking the bit width and bit offset, but Windows ignores
25 * these fields */
26 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER))
21 return; 27 return;
22 28
23 reset_value = acpi_gbl_FADT.reset_value; 29 reset_value = acpi_gbl_FADT.reset_value;
@@ -45,6 +51,4 @@ void acpi_reboot(void)
45 acpi_reset(); 51 acpi_reset();
46 break; 52 break;
47 } 53 }
48 /* Wait ten seconds */
49 acpi_os_stall(10000000);
50} 54}
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 4ff76e8174eb..51ae3794ec7f 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -40,10 +40,7 @@
40#include <linux/timer.h> 40#include <linux/timer.h>
41#include <linux/jiffies.h> 41#include <linux/jiffies.h>
42#include <linux/delay.h> 42#include <linux/delay.h>
43
44#ifdef CONFIG_ACPI_SYSFS_POWER
45#include <linux/power_supply.h> 43#include <linux/power_supply.h>
46#endif
47 44
48#include "sbshc.h" 45#include "sbshc.h"
49 46
@@ -85,9 +82,7 @@ static const struct acpi_device_id sbs_device_ids[] = {
85MODULE_DEVICE_TABLE(acpi, sbs_device_ids); 82MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
86 83
87struct acpi_battery { 84struct acpi_battery {
88#ifdef CONFIG_ACPI_SYSFS_POWER
89 struct power_supply bat; 85 struct power_supply bat;
90#endif
91 struct acpi_sbs *sbs; 86 struct acpi_sbs *sbs;
92#ifdef CONFIG_ACPI_PROCFS_POWER 87#ifdef CONFIG_ACPI_PROCFS_POWER
93 struct proc_dir_entry *proc_entry; 88 struct proc_dir_entry *proc_entry;
@@ -120,9 +115,7 @@ struct acpi_battery {
120#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 115#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
121 116
122struct acpi_sbs { 117struct acpi_sbs {
123#ifdef CONFIG_ACPI_SYSFS_POWER
124 struct power_supply charger; 118 struct power_supply charger;
125#endif
126 struct acpi_device *device; 119 struct acpi_device *device;
127 struct acpi_smb_hc *hc; 120 struct acpi_smb_hc *hc;
128 struct mutex lock; 121 struct mutex lock;
@@ -166,7 +159,6 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)
166 acpi_battery_ipscale(battery); 159 acpi_battery_ipscale(battery);
167} 160}
168 161
169#ifdef CONFIG_ACPI_SYSFS_POWER
170static int sbs_get_ac_property(struct power_supply *psy, 162static int sbs_get_ac_property(struct power_supply *psy,
171 enum power_supply_property psp, 163 enum power_supply_property psp,
172 union power_supply_propval *val) 164 union power_supply_propval *val)
@@ -313,7 +305,6 @@ static enum power_supply_property sbs_energy_battery_props[] = {
313 POWER_SUPPLY_PROP_MANUFACTURER, 305 POWER_SUPPLY_PROP_MANUFACTURER,
314}; 306};
315 307
316#endif
317 308
318/* -------------------------------------------------------------------------- 309/* --------------------------------------------------------------------------
319 Smart Battery System Management 310 Smart Battery System Management
@@ -449,7 +440,6 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
449 return result; 440 return result;
450} 441}
451 442
452#ifdef CONFIG_ACPI_SYSFS_POWER
453static ssize_t acpi_battery_alarm_show(struct device *dev, 443static ssize_t acpi_battery_alarm_show(struct device *dev,
454 struct device_attribute *attr, 444 struct device_attribute *attr,
455 char *buf) 445 char *buf)
@@ -479,7 +469,6 @@ static struct device_attribute alarm_attr = {
479 .show = acpi_battery_alarm_show, 469 .show = acpi_battery_alarm_show,
480 .store = acpi_battery_alarm_store, 470 .store = acpi_battery_alarm_store,
481}; 471};
482#endif
483 472
484/* -------------------------------------------------------------------------- 473/* --------------------------------------------------------------------------
485 FS Interface (/proc/acpi) 474 FS Interface (/proc/acpi)
@@ -495,6 +484,8 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir,
495 const struct file_operations *state_fops, 484 const struct file_operations *state_fops,
496 const struct file_operations *alarm_fops, void *data) 485 const struct file_operations *alarm_fops, void *data)
497{ 486{
487 printk(KERN_WARNING PREFIX "Deprecated procfs I/F for SBS is loaded,"
488 " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
498 if (!*dir) { 489 if (!*dir) {
499 *dir = proc_mkdir(dir_name, parent_dir); 490 *dir = proc_mkdir(dir_name, parent_dir);
500 if (!*dir) { 491 if (!*dir) {
@@ -798,7 +789,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
798 &acpi_battery_state_fops, &acpi_battery_alarm_fops, 789 &acpi_battery_state_fops, &acpi_battery_alarm_fops,
799 battery); 790 battery);
800#endif 791#endif
801#ifdef CONFIG_ACPI_SYSFS_POWER
802 battery->bat.name = battery->name; 792 battery->bat.name = battery->name;
803 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; 793 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
804 if (!acpi_battery_mode(battery)) { 794 if (!acpi_battery_mode(battery)) {
@@ -819,7 +809,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
819 goto end; 809 goto end;
820 battery->have_sysfs_alarm = 1; 810 battery->have_sysfs_alarm = 1;
821 end: 811 end:
822#endif
823 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", 812 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
824 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 813 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
825 battery->name, battery->present ? "present" : "absent"); 814 battery->name, battery->present ? "present" : "absent");
@@ -828,17 +817,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
828 817
829static void acpi_battery_remove(struct acpi_sbs *sbs, int id) 818static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
830{ 819{
831#if defined(CONFIG_ACPI_SYSFS_POWER) || defined(CONFIG_ACPI_PROCFS_POWER)
832 struct acpi_battery *battery = &sbs->battery[id]; 820 struct acpi_battery *battery = &sbs->battery[id];
833#endif
834 821
835#ifdef CONFIG_ACPI_SYSFS_POWER
836 if (battery->bat.dev) { 822 if (battery->bat.dev) {
837 if (battery->have_sysfs_alarm) 823 if (battery->have_sysfs_alarm)
838 device_remove_file(battery->bat.dev, &alarm_attr); 824 device_remove_file(battery->bat.dev, &alarm_attr);
839 power_supply_unregister(&battery->bat); 825 power_supply_unregister(&battery->bat);
840 } 826 }
841#endif
842#ifdef CONFIG_ACPI_PROCFS_POWER 827#ifdef CONFIG_ACPI_PROCFS_POWER
843 if (battery->proc_entry) 828 if (battery->proc_entry)
844 acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); 829 acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
@@ -859,14 +844,12 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
859 if (result) 844 if (result)
860 goto end; 845 goto end;
861#endif 846#endif
862#ifdef CONFIG_ACPI_SYSFS_POWER
863 sbs->charger.name = "sbs-charger"; 847 sbs->charger.name = "sbs-charger";
864 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; 848 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
865 sbs->charger.properties = sbs_ac_props; 849 sbs->charger.properties = sbs_ac_props;
866 sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); 850 sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
867 sbs->charger.get_property = sbs_get_ac_property; 851 sbs->charger.get_property = sbs_get_ac_property;
868 power_supply_register(&sbs->device->dev, &sbs->charger); 852 power_supply_register(&sbs->device->dev, &sbs->charger);
869#endif
870 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", 853 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
871 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 854 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
872 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); 855 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
@@ -876,10 +859,8 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
876 859
877static void acpi_charger_remove(struct acpi_sbs *sbs) 860static void acpi_charger_remove(struct acpi_sbs *sbs)
878{ 861{
879#ifdef CONFIG_ACPI_SYSFS_POWER
880 if (sbs->charger.dev) 862 if (sbs->charger.dev)
881 power_supply_unregister(&sbs->charger); 863 power_supply_unregister(&sbs->charger);
882#endif
883#ifdef CONFIG_ACPI_PROCFS_POWER 864#ifdef CONFIG_ACPI_PROCFS_POWER
884 if (sbs->charger_entry) 865 if (sbs->charger_entry)
885 acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); 866 acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
@@ -900,9 +881,7 @@ static void acpi_sbs_callback(void *context)
900 ACPI_SBS_NOTIFY_STATUS, 881 ACPI_SBS_NOTIFY_STATUS,
901 sbs->charger_present); 882 sbs->charger_present);
902#endif 883#endif
903#ifdef CONFIG_ACPI_SYSFS_POWER
904 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); 884 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
905#endif
906 } 885 }
907 if (sbs->manager_present) { 886 if (sbs->manager_present) {
908 for (id = 0; id < MAX_SBS_BAT; ++id) { 887 for (id = 0; id < MAX_SBS_BAT; ++id) {
@@ -919,9 +898,7 @@ static void acpi_sbs_callback(void *context)
919 ACPI_SBS_NOTIFY_STATUS, 898 ACPI_SBS_NOTIFY_STATUS,
920 bat->present); 899 bat->present);
921#endif 900#endif
922#ifdef CONFIG_ACPI_SYSFS_POWER
923 kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); 901 kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
924#endif
925 } 902 }
926 } 903 }
927} 904}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b23825ecfa37..449c556274c0 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -26,6 +26,8 @@ extern struct acpi_device *acpi_root;
26 26
27#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent) 27#define ACPI_IS_ROOT_DEVICE(device) (!(device)->parent)
28 28
29static const char *dummy_hid = "device";
30
29static LIST_HEAD(acpi_device_list); 31static LIST_HEAD(acpi_device_list);
30static LIST_HEAD(acpi_bus_id_list); 32static LIST_HEAD(acpi_bus_id_list);
31DEFINE_MUTEX(acpi_device_lock); 33DEFINE_MUTEX(acpi_device_lock);
@@ -49,6 +51,9 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
49 int count; 51 int count;
50 struct acpi_hardware_id *id; 52 struct acpi_hardware_id *id;
51 53
54 if (list_empty(&acpi_dev->pnp.ids))
55 return 0;
56
52 len = snprintf(modalias, size, "acpi:"); 57 len = snprintf(modalias, size, "acpi:");
53 size -= len; 58 size -= len;
54 59
@@ -202,13 +207,15 @@ static int acpi_device_setup_files(struct acpi_device *dev)
202 goto end; 207 goto end;
203 } 208 }
204 209
205 result = device_create_file(&dev->dev, &dev_attr_hid); 210 if (!list_empty(&dev->pnp.ids)) {
206 if (result) 211 result = device_create_file(&dev->dev, &dev_attr_hid);
207 goto end; 212 if (result)
213 goto end;
208 214
209 result = device_create_file(&dev->dev, &dev_attr_modalias); 215 result = device_create_file(&dev->dev, &dev_attr_modalias);
210 if (result) 216 if (result)
211 goto end; 217 goto end;
218 }
212 219
213 /* 220 /*
214 * If device has _EJ0, 'eject' file is created that is used to trigger 221 * If device has _EJ0, 'eject' file is created that is used to trigger
@@ -316,6 +323,9 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
316 struct acpi_device *acpi_dev = to_acpi_device(dev); 323 struct acpi_device *acpi_dev = to_acpi_device(dev);
317 int len; 324 int len;
318 325
326 if (list_empty(&acpi_dev->pnp.ids))
327 return 0;
328
319 if (add_uevent_var(env, "MODALIAS=")) 329 if (add_uevent_var(env, "MODALIAS="))
320 return -ENOMEM; 330 return -ENOMEM;
321 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1], 331 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
@@ -695,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device)
695} 705}
696 706
697static acpi_status 707static acpi_status
698acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, 708acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
699 union acpi_object *package) 709 struct acpi_device_wakeup *wakeup)
700{ 710{
701 int i = 0; 711 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
712 union acpi_object *package = NULL;
702 union acpi_object *element = NULL; 713 union acpi_object *element = NULL;
714 acpi_status status;
715 int i = 0;
703 716
704 if (!device || !package || (package->package.count < 2)) 717 if (!wakeup)
705 return AE_BAD_PARAMETER; 718 return AE_BAD_PARAMETER;
706 719
720 /* _PRW */
721 status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer);
722 if (ACPI_FAILURE(status)) {
723 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
724 return status;
725 }
726
727 package = (union acpi_object *)buffer.pointer;
728
729 if (!package || (package->package.count < 2)) {
730 status = AE_BAD_DATA;
731 goto out;
732 }
733
707 element = &(package->package.elements[0]); 734 element = &(package->package.elements[0]);
708 if (!element) 735 if (!element) {
709 return AE_BAD_PARAMETER; 736 status = AE_BAD_DATA;
737 goto out;
738 }
710 if (element->type == ACPI_TYPE_PACKAGE) { 739 if (element->type == ACPI_TYPE_PACKAGE) {
711 if ((element->package.count < 2) || 740 if ((element->package.count < 2) ||
712 (element->package.elements[0].type != 741 (element->package.elements[0].type !=
713 ACPI_TYPE_LOCAL_REFERENCE) 742 ACPI_TYPE_LOCAL_REFERENCE)
714 || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) 743 || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) {
715 return AE_BAD_DATA; 744 status = AE_BAD_DATA;
716 device->wakeup.gpe_device = 745 goto out;
746 }
747 wakeup->gpe_device =
717 element->package.elements[0].reference.handle; 748 element->package.elements[0].reference.handle;
718 device->wakeup.gpe_number = 749 wakeup->gpe_number =
719 (u32) element->package.elements[1].integer.value; 750 (u32) element->package.elements[1].integer.value;
720 } else if (element->type == ACPI_TYPE_INTEGER) { 751 } else if (element->type == ACPI_TYPE_INTEGER) {
721 device->wakeup.gpe_number = element->integer.value; 752 wakeup->gpe_device = NULL;
722 } else 753 wakeup->gpe_number = element->integer.value;
723 return AE_BAD_DATA; 754 } else {
755 status = AE_BAD_DATA;
756 goto out;
757 }
724 758
725 element = &(package->package.elements[1]); 759 element = &(package->package.elements[1]);
726 if (element->type != ACPI_TYPE_INTEGER) { 760 if (element->type != ACPI_TYPE_INTEGER) {
727 return AE_BAD_DATA; 761 status = AE_BAD_DATA;
762 goto out;
728 } 763 }
729 device->wakeup.sleep_state = element->integer.value; 764 wakeup->sleep_state = element->integer.value;
730 765
731 if ((package->package.count - 2) > ACPI_MAX_HANDLES) { 766 if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
732 return AE_NO_MEMORY; 767 status = AE_NO_MEMORY;
768 goto out;
733 } 769 }
734 device->wakeup.resources.count = package->package.count - 2; 770 wakeup->resources.count = package->package.count - 2;
735 for (i = 0; i < device->wakeup.resources.count; i++) { 771 for (i = 0; i < wakeup->resources.count; i++) {
736 element = &(package->package.elements[i + 2]); 772 element = &(package->package.elements[i + 2]);
737 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) 773 if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
738 return AE_BAD_DATA; 774 status = AE_BAD_DATA;
775 goto out;
776 }
739 777
740 device->wakeup.resources.handles[i] = element->reference.handle; 778 wakeup->resources.handles[i] = element->reference.handle;
741 } 779 }
742 780
743 acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); 781 acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
744 782
745 return AE_OK; 783 out:
784 kfree(buffer.pointer);
785
786 return status;
746} 787}
747 788
748static void acpi_bus_set_run_wake_flags(struct acpi_device *device) 789static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
@@ -756,13 +797,12 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
756 acpi_status status; 797 acpi_status status;
757 acpi_event_status event_status; 798 acpi_event_status event_status;
758 799
759 device->wakeup.run_wake_count = 0;
760 device->wakeup.flags.notifier_present = 0; 800 device->wakeup.flags.notifier_present = 0;
761 801
762 /* Power button, Lid switch always enable wakeup */ 802 /* Power button, Lid switch always enable wakeup */
763 if (!acpi_match_device_ids(device, button_device_ids)) { 803 if (!acpi_match_device_ids(device, button_device_ids)) {
764 device->wakeup.flags.run_wake = 1; 804 device->wakeup.flags.run_wake = 1;
765 device->wakeup.flags.always_enabled = 1; 805 device_set_wakeup_capable(&device->dev, true);
766 return; 806 return;
767 } 807 }
768 808
@@ -774,29 +814,24 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
774 !!(event_status & ACPI_EVENT_FLAG_HANDLE); 814 !!(event_status & ACPI_EVENT_FLAG_HANDLE);
775} 815}
776 816
777static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) 817static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
778{ 818{
819 acpi_handle temp;
779 acpi_status status = 0; 820 acpi_status status = 0;
780 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
781 union acpi_object *package = NULL;
782 int psw_error; 821 int psw_error;
783 822
784 /* _PRW */ 823 /* Presence of _PRW indicates wake capable */
785 status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); 824 status = acpi_get_handle(device->handle, "_PRW", &temp);
786 if (ACPI_FAILURE(status)) { 825 if (ACPI_FAILURE(status))
787 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); 826 return;
788 goto end;
789 }
790 827
791 package = (union acpi_object *)buffer.pointer; 828 status = acpi_bus_extract_wakeup_device_power_package(device->handle,
792 status = acpi_bus_extract_wakeup_device_power_package(device, package); 829 &device->wakeup);
793 if (ACPI_FAILURE(status)) { 830 if (ACPI_FAILURE(status)) {
794 ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); 831 ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
795 goto end; 832 return;
796 } 833 }
797 834
798 kfree(buffer.pointer);
799
800 device->wakeup.flags.valid = 1; 835 device->wakeup.flags.valid = 1;
801 device->wakeup.prepare_count = 0; 836 device->wakeup.prepare_count = 0;
802 acpi_bus_set_run_wake_flags(device); 837 acpi_bus_set_run_wake_flags(device);
@@ -810,13 +845,10 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
810 if (psw_error) 845 if (psw_error)
811 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 846 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
812 "error in _DSW or _PSW evaluation\n")); 847 "error in _DSW or _PSW evaluation\n"));
813
814end:
815 if (ACPI_FAILURE(status))
816 device->flags.wake_capable = 0;
817 return 0;
818} 848}
819 849
850static void acpi_bus_add_power_resource(acpi_handle handle);
851
820static int acpi_bus_get_power_flags(struct acpi_device *device) 852static int acpi_bus_get_power_flags(struct acpi_device *device)
821{ 853{
822 acpi_status status = 0; 854 acpi_status status = 0;
@@ -845,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
845 acpi_evaluate_reference(device->handle, object_name, NULL, 877 acpi_evaluate_reference(device->handle, object_name, NULL,
846 &ps->resources); 878 &ps->resources);
847 if (ps->resources.count) { 879 if (ps->resources.count) {
880 int j;
881
848 device->power.flags.power_resources = 1; 882 device->power.flags.power_resources = 1;
849 ps->flags.valid = 1; 883 ps->flags.valid = 1;
884 for (j = 0; j < ps->resources.count; j++)
885 acpi_bus_add_power_resource(ps->resources.handles[j]);
850 } 886 }
851 887
852 /* Evaluate "_PSx" to see if we can do explicit sets */ 888 /* Evaluate "_PSx" to see if we can do explicit sets */
@@ -871,10 +907,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
871 device->power.states[ACPI_STATE_D3].flags.valid = 1; 907 device->power.states[ACPI_STATE_D3].flags.valid = 1;
872 device->power.states[ACPI_STATE_D3].power = 0; 908 device->power.states[ACPI_STATE_D3].power = 0;
873 909
874 /* TBD: System wake support and resource requirements. */ 910 acpi_bus_init_power(device);
875
876 device->power.state = ACPI_STATE_UNKNOWN;
877 acpi_bus_get_power(device->handle, &(device->power.state));
878 911
879 return 0; 912 return 0;
880} 913}
@@ -910,6 +943,10 @@ static int acpi_bus_get_flags(struct acpi_device *device)
910 if (ACPI_SUCCESS(status)) 943 if (ACPI_SUCCESS(status))
911 device->flags.lockable = 1; 944 device->flags.lockable = 1;
912 945
946 /* Power resources cannot be power manageable. */
947 if (device->device_type == ACPI_BUS_TYPE_POWER)
948 return 0;
949
913 /* Presence of _PS0|_PR0 indicates 'power manageable' */ 950 /* Presence of _PS0|_PR0 indicates 'power manageable' */
914 status = acpi_get_handle(device->handle, "_PS0", &temp); 951 status = acpi_get_handle(device->handle, "_PS0", &temp);
915 if (ACPI_FAILURE(status)) 952 if (ACPI_FAILURE(status))
@@ -917,11 +954,6 @@ static int acpi_bus_get_flags(struct acpi_device *device)
917 if (ACPI_SUCCESS(status)) 954 if (ACPI_SUCCESS(status))
918 device->flags.power_manageable = 1; 955 device->flags.power_manageable = 1;
919 956
920 /* Presence of _PRW indicates wake capable */
921 status = acpi_get_handle(device->handle, "_PRW", &temp);
922 if (ACPI_SUCCESS(status))
923 device->flags.wake_capable = 1;
924
925 /* TBD: Performance management */ 957 /* TBD: Performance management */
926 958
927 return 0; 959 return 0;
@@ -1010,10 +1042,13 @@ static int acpi_dock_match(struct acpi_device *device)
1010 return acpi_get_handle(device->handle, "_DCK", &tmp); 1042 return acpi_get_handle(device->handle, "_DCK", &tmp);
1011} 1043}
1012 1044
1013char *acpi_device_hid(struct acpi_device *device) 1045const char *acpi_device_hid(struct acpi_device *device)
1014{ 1046{
1015 struct acpi_hardware_id *hid; 1047 struct acpi_hardware_id *hid;
1016 1048
1049 if (list_empty(&device->pnp.ids))
1050 return dummy_hid;
1051
1017 hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list); 1052 hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
1018 return hid->id; 1053 return hid->id;
1019} 1054}
@@ -1142,16 +1177,6 @@ static void acpi_device_set_id(struct acpi_device *device)
1142 acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF); 1177 acpi_add_id(device, ACPI_BUTTON_HID_SLEEPF);
1143 break; 1178 break;
1144 } 1179 }
1145
1146 /*
1147 * We build acpi_devices for some objects that don't have _HID or _CID,
1148 * e.g., PCI bridges and slots. Drivers can't bind to these objects,
1149 * but we do use them indirectly by traversing the acpi_device tree.
1150 * This generic ID isn't useful for driver binding, but it provides
1151 * the useful property that "every acpi_device has an ID."
1152 */
1153 if (list_empty(&device->pnp.ids))
1154 acpi_add_id(device, "device");
1155} 1180}
1156 1181
1157static int acpi_device_set_context(struct acpi_device *device) 1182static int acpi_device_set_context(struct acpi_device *device)
@@ -1255,11 +1280,7 @@ static int acpi_add_single_object(struct acpi_device **child,
1255 * Wakeup device management 1280 * Wakeup device management
1256 *----------------------- 1281 *-----------------------
1257 */ 1282 */
1258 if (device->flags.wake_capable) { 1283 acpi_bus_get_wakeup_device_flags(device);
1259 result = acpi_bus_get_wakeup_device_flags(device);
1260 if (result)
1261 goto end;
1262 }
1263 1284
1264 /* 1285 /*
1265 * Performance Management 1286 * Performance Management
@@ -1303,6 +1324,20 @@ end:
1303#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ 1324#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
1304 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) 1325 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING)
1305 1326
1327static void acpi_bus_add_power_resource(acpi_handle handle)
1328{
1329 struct acpi_bus_ops ops = {
1330 .acpi_op_add = 1,
1331 .acpi_op_start = 1,
1332 };
1333 struct acpi_device *device = NULL;
1334
1335 acpi_bus_get_device(handle, &device);
1336 if (!device)
1337 acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER,
1338 ACPI_STA_DEFAULT, &ops);
1339}
1340
1306static int acpi_bus_type_and_status(acpi_handle handle, int *type, 1341static int acpi_bus_type_and_status(acpi_handle handle, int *type,
1307 unsigned long long *sta) 1342 unsigned long long *sta)
1308{ 1343{
@@ -1357,8 +1392,16 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
1357 return AE_OK; 1392 return AE_OK;
1358 1393
1359 if (!(sta & ACPI_STA_DEVICE_PRESENT) && 1394 if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
1360 !(sta & ACPI_STA_DEVICE_FUNCTIONING)) 1395 !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
1396 struct acpi_device_wakeup wakeup;
1397 acpi_handle temp;
1398
1399 status = acpi_get_handle(handle, "_PRW", &temp);
1400 if (ACPI_SUCCESS(status))
1401 acpi_bus_extract_wakeup_device_power_package(handle,
1402 &wakeup);
1361 return AE_CTRL_DEPTH; 1403 return AE_CTRL_DEPTH;
1404 }
1362 1405
1363 /* 1406 /*
1364 * We may already have an acpi_device from a previous enumeration. If 1407 * We may already have an acpi_device from a previous enumeration. If
@@ -1431,6 +1474,7 @@ EXPORT_SYMBOL(acpi_bus_add);
1431int acpi_bus_start(struct acpi_device *device) 1474int acpi_bus_start(struct acpi_device *device)
1432{ 1475{
1433 struct acpi_bus_ops ops; 1476 struct acpi_bus_ops ops;
1477 int result;
1434 1478
1435 if (!device) 1479 if (!device)
1436 return -EINVAL; 1480 return -EINVAL;
@@ -1438,7 +1482,11 @@ int acpi_bus_start(struct acpi_device *device)
1438 memset(&ops, 0, sizeof(ops)); 1482 memset(&ops, 0, sizeof(ops));
1439 ops.acpi_op_start = 1; 1483 ops.acpi_op_start = 1;
1440 1484
1441 return acpi_bus_scan(device->handle, &ops, NULL); 1485 result = acpi_bus_scan(device->handle, &ops, NULL);
1486
1487 acpi_update_all_gpes();
1488
1489 return result;
1442} 1490}
1443EXPORT_SYMBOL(acpi_bus_start); 1491EXPORT_SYMBOL(acpi_bus_start);
1444 1492
@@ -1542,6 +1590,8 @@ int __init acpi_scan_init(void)
1542 printk(KERN_ERR PREFIX "Could not register bus type\n"); 1590 printk(KERN_ERR PREFIX "Could not register bus type\n");
1543 } 1591 }
1544 1592
1593 acpi_power_init();
1594
1545 /* 1595 /*
1546 * Enumerate devices in the ACPI namespace. 1596 * Enumerate devices in the ACPI namespace.
1547 */ 1597 */
@@ -1552,6 +1602,8 @@ int __init acpi_scan_init(void)
1552 1602
1553 if (result) 1603 if (result)
1554 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1604 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
1605 else
1606 acpi_update_all_gpes();
1555 1607
1556 return result; 1608 return result;
1557} 1609}
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 4754ff6e70e6..6c949602cbd1 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -16,6 +16,7 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/suspend.h> 17#include <linux/suspend.h>
18#include <linux/reboot.h> 18#include <linux/reboot.h>
19#include <linux/acpi.h>
19 20
20#include <asm/io.h> 21#include <asm/io.h>
21 22
@@ -25,7 +26,7 @@
25#include "internal.h" 26#include "internal.h"
26#include "sleep.h" 27#include "sleep.h"
27 28
28u8 sleep_states[ACPI_S_STATE_COUNT]; 29static u8 sleep_states[ACPI_S_STATE_COUNT];
29 30
30static void acpi_sleep_tts_switch(u32 acpi_state) 31static void acpi_sleep_tts_switch(u32 acpi_state)
31{ 32{
@@ -124,8 +125,7 @@ static int acpi_pm_freeze(void)
124static int acpi_pm_pre_suspend(void) 125static int acpi_pm_pre_suspend(void)
125{ 126{
126 acpi_pm_freeze(); 127 acpi_pm_freeze();
127 suspend_nvs_save(); 128 return suspend_nvs_save();
128 return 0;
129} 129}
130 130
131/** 131/**
@@ -151,7 +151,7 @@ static int acpi_pm_prepare(void)
151{ 151{
152 int error = __acpi_pm_prepare(); 152 int error = __acpi_pm_prepare();
153 if (!error) 153 if (!error)
154 acpi_pm_pre_suspend(); 154 error = acpi_pm_pre_suspend();
155 155
156 return error; 156 return error;
157} 157}
@@ -167,6 +167,7 @@ static void acpi_pm_finish(void)
167 u32 acpi_state = acpi_target_sleep_state; 167 u32 acpi_state = acpi_target_sleep_state;
168 168
169 acpi_ec_unblock_transactions(); 169 acpi_ec_unblock_transactions();
170 suspend_nvs_free();
170 171
171 if (acpi_state == ACPI_STATE_S0) 172 if (acpi_state == ACPI_STATE_S0)
172 return; 173 return;
@@ -187,7 +188,6 @@ static void acpi_pm_finish(void)
187 */ 188 */
188static void acpi_pm_end(void) 189static void acpi_pm_end(void)
189{ 190{
190 suspend_nvs_free();
191 /* 191 /*
192 * This is necessary in case acpi_pm_finish() is not called during a 192 * This is necessary in case acpi_pm_finish() is not called during a
193 * failing transition to a sleep state. 193 * failing transition to a sleep state.
@@ -200,8 +200,6 @@ static void acpi_pm_end(void)
200#endif /* CONFIG_ACPI_SLEEP */ 200#endif /* CONFIG_ACPI_SLEEP */
201 201
202#ifdef CONFIG_SUSPEND 202#ifdef CONFIG_SUSPEND
203extern void do_suspend_lowlevel(void);
204
205static u32 acpi_suspend_states[] = { 203static u32 acpi_suspend_states[] = {
206 [PM_SUSPEND_ON] = ACPI_STATE_S0, 204 [PM_SUSPEND_ON] = ACPI_STATE_S0,
207 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, 205 [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
@@ -244,20 +242,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
244static int acpi_suspend_enter(suspend_state_t pm_state) 242static int acpi_suspend_enter(suspend_state_t pm_state)
245{ 243{
246 acpi_status status = AE_OK; 244 acpi_status status = AE_OK;
247 unsigned long flags = 0;
248 u32 acpi_state = acpi_target_sleep_state; 245 u32 acpi_state = acpi_target_sleep_state;
246 int error;
249 247
250 ACPI_FLUSH_CPU_CACHE(); 248 ACPI_FLUSH_CPU_CACHE();
251 249
252 /* Do arch specific saving of state. */
253 if (acpi_state == ACPI_STATE_S3) {
254 int error = acpi_save_state_mem();
255
256 if (error)
257 return error;
258 }
259
260 local_irq_save(flags);
261 switch (acpi_state) { 250 switch (acpi_state) {
262 case ACPI_STATE_S1: 251 case ACPI_STATE_S1:
263 barrier(); 252 barrier();
@@ -265,7 +254,10 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
265 break; 254 break;
266 255
267 case ACPI_STATE_S3: 256 case ACPI_STATE_S3:
268 do_suspend_lowlevel(); 257 error = acpi_suspend_lowlevel();
258 if (error)
259 return error;
260 pr_info(PREFIX "Low-level resume complete\n");
269 break; 261 break;
270 } 262 }
271 263
@@ -291,13 +283,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
291 /* Allow EC transactions to happen. */ 283 /* Allow EC transactions to happen. */
292 acpi_ec_unblock_transactions_early(); 284 acpi_ec_unblock_transactions_early();
293 285
294 local_irq_restore(flags);
295 printk(KERN_DEBUG "Back to C!\n");
296
297 /* restore processor state */
298 if (acpi_state == ACPI_STATE_S3)
299 acpi_restore_state_mem();
300
301 suspend_nvs_restore(); 286 suspend_nvs_restore();
302 287
303 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 288 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -319,7 +304,7 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state)
319 } 304 }
320} 305}
321 306
322static struct platform_suspend_ops acpi_suspend_ops = { 307static const struct platform_suspend_ops acpi_suspend_ops = {
323 .valid = acpi_suspend_state_valid, 308 .valid = acpi_suspend_state_valid,
324 .begin = acpi_suspend_begin, 309 .begin = acpi_suspend_begin,
325 .prepare_late = acpi_pm_prepare, 310 .prepare_late = acpi_pm_prepare,
@@ -347,7 +332,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
347 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has 332 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
348 * been requested. 333 * been requested.
349 */ 334 */
350static struct platform_suspend_ops acpi_suspend_ops_old = { 335static const struct platform_suspend_ops acpi_suspend_ops_old = {
351 .valid = acpi_suspend_state_valid, 336 .valid = acpi_suspend_state_valid,
352 .begin = acpi_suspend_begin_old, 337 .begin = acpi_suspend_begin_old,
353 .prepare_late = acpi_pm_pre_suspend, 338 .prepare_late = acpi_pm_pre_suspend,
@@ -419,6 +404,30 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
419 DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"), 404 DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
420 }, 405 },
421 }, 406 },
407 {
408 .callback = init_nvs_nosave,
409 .ident = "Sony Vaio VPCEB1Z1E",
410 .matches = {
411 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
412 DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
413 },
414 },
415 {
416 .callback = init_nvs_nosave,
417 .ident = "Sony Vaio VGN-NW130D",
418 .matches = {
419 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
420 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
421 },
422 },
423 {
424 .callback = init_nvs_nosave,
425 .ident = "Averatec AV1020-ED2",
426 .matches = {
427 DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
428 DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
429 },
430 },
422 {}, 431 {},
423}; 432};
424#endif /* CONFIG_SUSPEND */ 433#endif /* CONFIG_SUSPEND */
@@ -449,16 +458,13 @@ static int acpi_hibernation_begin(void)
449static int acpi_hibernation_enter(void) 458static int acpi_hibernation_enter(void)
450{ 459{
451 acpi_status status = AE_OK; 460 acpi_status status = AE_OK;
452 unsigned long flags = 0;
453 461
454 ACPI_FLUSH_CPU_CACHE(); 462 ACPI_FLUSH_CPU_CACHE();
455 463
456 local_irq_save(flags);
457 /* This shouldn't return. If it returns, we have a problem */ 464 /* This shouldn't return. If it returns, we have a problem */
458 status = acpi_enter_sleep_state(ACPI_STATE_S4); 465 status = acpi_enter_sleep_state(ACPI_STATE_S4);
459 /* Reprogram control registers and execute _BFS */ 466 /* Reprogram control registers and execute _BFS */
460 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 467 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
461 local_irq_restore(flags);
462 468
463 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 469 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
464} 470}
@@ -490,7 +496,7 @@ static void acpi_pm_thaw(void)
490 acpi_enable_all_runtime_gpes(); 496 acpi_enable_all_runtime_gpes();
491} 497}
492 498
493static struct platform_hibernation_ops acpi_hibernation_ops = { 499static const struct platform_hibernation_ops acpi_hibernation_ops = {
494 .begin = acpi_hibernation_begin, 500 .begin = acpi_hibernation_begin,
495 .end = acpi_pm_end, 501 .end = acpi_pm_end,
496 .pre_snapshot = acpi_pm_prepare, 502 .pre_snapshot = acpi_pm_prepare,
@@ -533,7 +539,7 @@ static int acpi_hibernation_begin_old(void)
533 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has 539 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
534 * been requested. 540 * been requested.
535 */ 541 */
536static struct platform_hibernation_ops acpi_hibernation_ops_old = { 542static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
537 .begin = acpi_hibernation_begin_old, 543 .begin = acpi_hibernation_begin_old,
538 .end = acpi_pm_end, 544 .end = acpi_pm_end,
539 .pre_snapshot = acpi_pm_pre_suspend, 545 .pre_snapshot = acpi_pm_pre_suspend,
@@ -562,7 +568,7 @@ int acpi_suspend(u32 acpi_state)
562 return -EINVAL; 568 return -EINVAL;
563} 569}
564 570
565#ifdef CONFIG_PM_SLEEP 571#ifdef CONFIG_PM
566/** 572/**
567 * acpi_pm_device_sleep_state - return preferred power state of ACPI device 573 * acpi_pm_device_sleep_state - return preferred power state of ACPI device
568 * in the system sleep state given by %acpi_target_sleep_state 574 * in the system sleep state given by %acpi_target_sleep_state
@@ -624,7 +630,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
624 * can wake the system. _S0W may be valid, too. 630 * can wake the system. _S0W may be valid, too.
625 */ 631 */
626 if (acpi_target_sleep_state == ACPI_STATE_S0 || 632 if (acpi_target_sleep_state == ACPI_STATE_S0 ||
627 (device_may_wakeup(dev) && adev->wakeup.state.enabled && 633 (device_may_wakeup(dev) &&
628 adev->wakeup.sleep_state <= acpi_target_sleep_state)) { 634 adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
629 acpi_status status; 635 acpi_status status;
630 636
@@ -632,7 +638,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
632 status = acpi_evaluate_integer(handle, acpi_method, NULL, 638 status = acpi_evaluate_integer(handle, acpi_method, NULL,
633 &d_max); 639 &d_max);
634 if (ACPI_FAILURE(status)) { 640 if (ACPI_FAILURE(status)) {
635 d_max = d_min; 641 if (acpi_target_sleep_state != ACPI_STATE_S0 ||
642 status != AE_NOT_FOUND)
643 d_max = d_min;
636 } else if (d_max < d_min) { 644 } else if (d_max < d_min) {
637 /* Warn the user of the broken DSDT */ 645 /* Warn the user of the broken DSDT */
638 printk(KERN_WARNING "ACPI: Wrong value from %s\n", 646 printk(KERN_WARNING "ACPI: Wrong value from %s\n",
@@ -646,7 +654,9 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p)
646 *d_min_p = d_min; 654 *d_min_p = d_min;
647 return d_max; 655 return d_max;
648} 656}
657#endif /* CONFIG_PM */
649 658
659#ifdef CONFIG_PM_SLEEP
650/** 660/**
651 * acpi_pm_device_sleep_wake - enable or disable the system wake-up 661 * acpi_pm_device_sleep_wake - enable or disable the system wake-up
652 * capability of given device 662 * capability of given device
@@ -677,7 +687,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
677 687
678 return error; 688 return error;
679} 689}
680#endif 690#endif /* CONFIG_PM_SLEEP */
681 691
682static void acpi_power_off_prepare(void) 692static void acpi_power_off_prepare(void)
683{ 693{
@@ -702,7 +712,7 @@ static void acpi_power_off(void)
702 * paths through the BIOS, so disable _GTS and _BFS by default, 712 * paths through the BIOS, so disable _GTS and _BFS by default,
703 * but do speak up and offer the option to enable them. 713 * but do speak up and offer the option to enable them.
704 */ 714 */
705void __init acpi_gts_bfs_check(void) 715static void __init acpi_gts_bfs_check(void)
706{ 716{
707 acpi_handle dummy; 717 acpi_handle dummy;
708 718
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
index d8821805c3bc..74d59c8f4678 100644
--- a/drivers/acpi/sleep.h
+++ b/drivers/acpi/sleep.h
@@ -1,5 +1,4 @@
1 1
2extern u8 sleep_states[];
3extern int acpi_suspend(u32 state); 2extern int acpi_suspend(u32 state);
4 3
5extern void acpi_enable_wakeup_devices(u8 sleep_state); 4extern void acpi_enable_wakeup_devices(u8 sleep_state);
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index f8588f81048a..77255f250dbb 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -220,6 +220,14 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
220 NULL, 0644); 220 NULL, 0644);
221#endif /* CONFIG_ACPI_DEBUG */ 221#endif /* CONFIG_ACPI_DEBUG */
222 222
223
224/* /sys/modules/acpi/parameters/aml_debug_output */
225
226module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
227 bool, 0644);
228MODULE_PARM_DESC(aml_debug_output,
229 "To enable/disable the ACPI Debug Object output.");
230
223/* /sys/module/acpi/parameters/acpica_version */ 231/* /sys/module/acpi/parameters/acpica_version */
224static int param_get_acpica_version(char *buffer, struct kernel_param *kp) 232static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
225{ 233{
@@ -438,7 +446,7 @@ static void delete_gpe_attr_array(void)
438 return; 446 return;
439} 447}
440 448
441void acpi_os_gpe_count(u32 gpe_number) 449static void gpe_count(u32 gpe_number)
442{ 450{
443 acpi_gpe_count++; 451 acpi_gpe_count++;
444 452
@@ -454,7 +462,7 @@ void acpi_os_gpe_count(u32 gpe_number)
454 return; 462 return;
455} 463}
456 464
457void acpi_os_fixed_event_count(u32 event_number) 465static void fixed_event_count(u32 event_number)
458{ 466{
459 if (!all_counters) 467 if (!all_counters)
460 return; 468 return;
@@ -468,6 +476,16 @@ void acpi_os_fixed_event_count(u32 event_number)
468 return; 476 return;
469} 477}
470 478
479static void acpi_gbl_event_handler(u32 event_type, acpi_handle device,
480 u32 event_number, void *context)
481{
482 if (event_type == ACPI_EVENT_TYPE_GPE)
483 gpe_count(event_number);
484
485 if (event_type == ACPI_EVENT_TYPE_FIXED)
486 fixed_event_count(event_number);
487}
488
471static int get_status(u32 index, acpi_event_status *status, 489static int get_status(u32 index, acpi_event_status *status,
472 acpi_handle *handle) 490 acpi_handle *handle)
473{ 491{
@@ -601,6 +619,7 @@ end:
601 619
602void acpi_irq_stats_init(void) 620void acpi_irq_stats_init(void)
603{ 621{
622 acpi_status status;
604 int i; 623 int i;
605 624
606 if (all_counters) 625 if (all_counters)
@@ -619,6 +638,10 @@ void acpi_irq_stats_init(void)
619 if (all_counters == NULL) 638 if (all_counters == NULL)
620 goto fail; 639 goto fail;
621 640
641 status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL);
642 if (ACPI_FAILURE(status))
643 goto fail;
644
622 counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), 645 counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters),
623 GFP_KERNEL); 646 GFP_KERNEL);
624 if (counter_attrs == NULL) 647 if (counter_attrs == NULL)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 2f8f17131d9f..2607e17b520f 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,12 +37,6 @@
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/types.h> 39#include <linux/types.h>
40
41#ifdef CONFIG_ACPI_PROCFS
42#include <linux/proc_fs.h>
43#include <linux/seq_file.h>
44#endif
45
46#include <linux/jiffies.h> 40#include <linux/jiffies.h>
47#include <linux/kmod.h> 41#include <linux/kmod.h>
48#include <linux/reboot.h> 42#include <linux/reboot.h>
@@ -195,61 +189,6 @@ struct acpi_thermal {
195 struct mutex lock; 189 struct mutex lock;
196}; 190};
197 191
198#ifdef CONFIG_ACPI_PROCFS
199static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
200static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
201static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
202static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
203static ssize_t acpi_thermal_write_cooling_mode(struct file *,
204 const char __user *, size_t,
205 loff_t *);
206static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
207static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
208 size_t, loff_t *);
209
210static const struct file_operations acpi_thermal_state_fops = {
211 .owner = THIS_MODULE,
212 .open = acpi_thermal_state_open_fs,
213 .read = seq_read,
214 .llseek = seq_lseek,
215 .release = single_release,
216};
217
218static const struct file_operations acpi_thermal_temp_fops = {
219 .owner = THIS_MODULE,
220 .open = acpi_thermal_temp_open_fs,
221 .read = seq_read,
222 .llseek = seq_lseek,
223 .release = single_release,
224};
225
226static const struct file_operations acpi_thermal_trip_fops = {
227 .owner = THIS_MODULE,
228 .open = acpi_thermal_trip_open_fs,
229 .read = seq_read,
230 .llseek = seq_lseek,
231 .release = single_release,
232};
233
234static const struct file_operations acpi_thermal_cooling_fops = {
235 .owner = THIS_MODULE,
236 .open = acpi_thermal_cooling_open_fs,
237 .read = seq_read,
238 .write = acpi_thermal_write_cooling_mode,
239 .llseek = seq_lseek,
240 .release = single_release,
241};
242
243static const struct file_operations acpi_thermal_polling_fops = {
244 .owner = THIS_MODULE,
245 .open = acpi_thermal_polling_open_fs,
246 .read = seq_read,
247 .write = acpi_thermal_write_polling,
248 .llseek = seq_lseek,
249 .release = single_release,
250};
251#endif /* CONFIG_ACPI_PROCFS*/
252
253/* -------------------------------------------------------------------------- 192/* --------------------------------------------------------------------------
254 Thermal Zone Management 193 Thermal Zone Management
255 -------------------------------------------------------------------------- */ 194 -------------------------------------------------------------------------- */
@@ -958,358 +897,6 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
958 897
959 898
960/* -------------------------------------------------------------------------- 899/* --------------------------------------------------------------------------
961 FS Interface (/proc)
962 -------------------------------------------------------------------------- */
963#ifdef CONFIG_ACPI_PROCFS
964static struct proc_dir_entry *acpi_thermal_dir;
965
966static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
967{
968 struct acpi_thermal *tz = seq->private;
969
970
971 if (!tz)
972 goto end;
973
974 seq_puts(seq, "state: ");
975
976 if (!tz->state.critical && !tz->state.hot && !tz->state.passive
977 && !tz->state.active)
978 seq_puts(seq, "ok\n");
979 else {
980 if (tz->state.critical)
981 seq_puts(seq, "critical ");
982 if (tz->state.hot)
983 seq_puts(seq, "hot ");
984 if (tz->state.passive)
985 seq_puts(seq, "passive ");
986 if (tz->state.active)
987 seq_printf(seq, "active[%d]", tz->state.active_index);
988 seq_puts(seq, "\n");
989 }
990
991 end:
992 return 0;
993}
994
995static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
996{
997 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
998}
999
1000static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
1001{
1002 int result = 0;
1003 struct acpi_thermal *tz = seq->private;
1004
1005
1006 if (!tz)
1007 goto end;
1008
1009 result = acpi_thermal_get_temperature(tz);
1010 if (result)
1011 goto end;
1012
1013 seq_printf(seq, "temperature: %ld C\n",
1014 KELVIN_TO_CELSIUS(tz->temperature));
1015
1016 end:
1017 return 0;
1018}
1019
1020static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
1021{
1022 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
1023}
1024
1025static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
1026{
1027 struct acpi_thermal *tz = seq->private;
1028 struct acpi_device *device;
1029 acpi_status status;
1030
1031 int i = 0;
1032 int j = 0;
1033
1034
1035 if (!tz)
1036 goto end;
1037
1038 if (tz->trips.critical.flags.valid)
1039 seq_printf(seq, "critical (S5): %ld C%s",
1040 KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
1041 nocrt ? " <disabled>\n" : "\n");
1042
1043 if (tz->trips.hot.flags.valid)
1044 seq_printf(seq, "hot (S4): %ld C%s",
1045 KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
1046 nocrt ? " <disabled>\n" : "\n");
1047
1048 if (tz->trips.passive.flags.valid) {
1049 seq_printf(seq,
1050 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
1051 KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
1052 tz->trips.passive.tc1, tz->trips.passive.tc2,
1053 tz->trips.passive.tsp);
1054 for (j = 0; j < tz->trips.passive.devices.count; j++) {
1055 status = acpi_bus_get_device(tz->trips.passive.devices.
1056 handles[j], &device);
1057 seq_printf(seq, "%4.4s ", status ? "" :
1058 acpi_device_bid(device));
1059 }
1060 seq_puts(seq, "\n");
1061 } else {
1062 seq_printf(seq, "passive (forced):");
1063 if (tz->thermal_zone->forced_passive)
1064 seq_printf(seq, " %i C\n",
1065 tz->thermal_zone->forced_passive / 1000);
1066 else
1067 seq_printf(seq, "<not set>\n");
1068 }
1069
1070 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1071 if (!(tz->trips.active[i].flags.valid))
1072 break;
1073 seq_printf(seq, "active[%d]: %ld C: devices=",
1074 i,
1075 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
1076 for (j = 0; j < tz->trips.active[i].devices.count; j++){
1077 status = acpi_bus_get_device(tz->trips.active[i].
1078 devices.handles[j],
1079 &device);
1080 seq_printf(seq, "%4.4s ", status ? "" :
1081 acpi_device_bid(device));
1082 }
1083 seq_puts(seq, "\n");
1084 }
1085
1086 end:
1087 return 0;
1088}
1089
1090static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
1091{
1092 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
1093}
1094
1095static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
1096{
1097 struct acpi_thermal *tz = seq->private;
1098
1099
1100 if (!tz)
1101 goto end;
1102
1103 if (!tz->flags.cooling_mode)
1104 seq_puts(seq, "<setting not supported>\n");
1105 else
1106 seq_puts(seq, "0 - Active; 1 - Passive\n");
1107
1108 end:
1109 return 0;
1110}
1111
1112static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
1113{
1114 return single_open(file, acpi_thermal_cooling_seq_show,
1115 PDE(inode)->data);
1116}
1117
1118static ssize_t
1119acpi_thermal_write_cooling_mode(struct file *file,
1120 const char __user * buffer,
1121 size_t count, loff_t * ppos)
1122{
1123 struct seq_file *m = file->private_data;
1124 struct acpi_thermal *tz = m->private;
1125 int result = 0;
1126 char mode_string[12] = { '\0' };
1127
1128
1129 if (!tz || (count > sizeof(mode_string) - 1))
1130 return -EINVAL;
1131
1132 if (!tz->flags.cooling_mode)
1133 return -ENODEV;
1134
1135 if (copy_from_user(mode_string, buffer, count))
1136 return -EFAULT;
1137
1138 mode_string[count] = '\0';
1139
1140 result = acpi_thermal_set_cooling_mode(tz,
1141 simple_strtoul(mode_string, NULL,
1142 0));
1143 if (result)
1144 return result;
1145
1146 acpi_thermal_check(tz);
1147
1148 return count;
1149}
1150
1151static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1152{
1153 struct acpi_thermal *tz = seq->private;
1154
1155
1156 if (!tz)
1157 goto end;
1158
1159 if (!tz->thermal_zone->polling_delay) {
1160 seq_puts(seq, "<polling disabled>\n");
1161 goto end;
1162 }
1163
1164 seq_printf(seq, "polling frequency: %d seconds\n",
1165 (tz->thermal_zone->polling_delay / 1000));
1166
1167 end:
1168 return 0;
1169}
1170
1171static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
1172{
1173 return single_open(file, acpi_thermal_polling_seq_show,
1174 PDE(inode)->data);
1175}
1176
1177static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
1178{
1179 if (!tz)
1180 return -EINVAL;
1181
1182 /* Convert value to deci-seconds */
1183 tz->polling_frequency = seconds * 10;
1184
1185 tz->thermal_zone->polling_delay = seconds * 1000;
1186
1187 if (tz->tz_enabled)
1188 thermal_zone_device_update(tz->thermal_zone);
1189
1190 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1191 "Polling frequency set to %lu seconds\n",
1192 tz->polling_frequency/10));
1193
1194 return 0;
1195}
1196
1197static ssize_t
1198acpi_thermal_write_polling(struct file *file,
1199 const char __user * buffer,
1200 size_t count, loff_t * ppos)
1201{
1202 struct seq_file *m = file->private_data;
1203 struct acpi_thermal *tz = m->private;
1204 int result = 0;
1205 char polling_string[12] = { '\0' };
1206 int seconds = 0;
1207
1208
1209 if (!tz || (count > sizeof(polling_string) - 1))
1210 return -EINVAL;
1211
1212 if (copy_from_user(polling_string, buffer, count))
1213 return -EFAULT;
1214
1215 polling_string[count] = '\0';
1216
1217 seconds = simple_strtoul(polling_string, NULL, 0);
1218
1219 result = acpi_thermal_set_polling(tz, seconds);
1220 if (result)
1221 return result;
1222
1223 acpi_thermal_check(tz);
1224
1225 return count;
1226}
1227
1228static int acpi_thermal_add_fs(struct acpi_device *device)
1229{
1230 struct proc_dir_entry *entry = NULL;
1231
1232
1233 if (!acpi_device_dir(device)) {
1234 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1235 acpi_thermal_dir);
1236 if (!acpi_device_dir(device))
1237 return -ENODEV;
1238 }
1239
1240 /* 'state' [R] */
1241 entry = proc_create_data(ACPI_THERMAL_FILE_STATE,
1242 S_IRUGO, acpi_device_dir(device),
1243 &acpi_thermal_state_fops,
1244 acpi_driver_data(device));
1245 if (!entry)
1246 return -ENODEV;
1247
1248 /* 'temperature' [R] */
1249 entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE,
1250 S_IRUGO, acpi_device_dir(device),
1251 &acpi_thermal_temp_fops,
1252 acpi_driver_data(device));
1253 if (!entry)
1254 return -ENODEV;
1255
1256 /* 'trip_points' [R] */
1257 entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS,
1258 S_IRUGO,
1259 acpi_device_dir(device),
1260 &acpi_thermal_trip_fops,
1261 acpi_driver_data(device));
1262 if (!entry)
1263 return -ENODEV;
1264
1265 /* 'cooling_mode' [R/W] */
1266 entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE,
1267 S_IFREG | S_IRUGO | S_IWUSR,
1268 acpi_device_dir(device),
1269 &acpi_thermal_cooling_fops,
1270 acpi_driver_data(device));
1271 if (!entry)
1272 return -ENODEV;
1273
1274 /* 'polling_frequency' [R/W] */
1275 entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ,
1276 S_IFREG | S_IRUGO | S_IWUSR,
1277 acpi_device_dir(device),
1278 &acpi_thermal_polling_fops,
1279 acpi_driver_data(device));
1280 if (!entry)
1281 return -ENODEV;
1282 return 0;
1283}
1284
1285static int acpi_thermal_remove_fs(struct acpi_device *device)
1286{
1287
1288 if (acpi_device_dir(device)) {
1289 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1290 acpi_device_dir(device));
1291 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1292 acpi_device_dir(device));
1293 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1294 acpi_device_dir(device));
1295 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1296 acpi_device_dir(device));
1297 remove_proc_entry(ACPI_THERMAL_FILE_STATE,
1298 acpi_device_dir(device));
1299 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
1300 acpi_device_dir(device) = NULL;
1301 }
1302
1303 return 0;
1304}
1305#else
1306static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; }
1307static inline int acpi_thermal_remove_fs(struct acpi_device *device)
1308{
1309 return 0;
1310}
1311#endif /* CONFIG_ACPI_PROCFS */
1312/* --------------------------------------------------------------------------
1313 Driver Interface 900 Driver Interface
1314 -------------------------------------------------------------------------- */ 901 -------------------------------------------------------------------------- */
1315 902
@@ -1428,17 +1015,11 @@ static int acpi_thermal_add(struct acpi_device *device)
1428 if (result) 1015 if (result)
1429 goto free_memory; 1016 goto free_memory;
1430 1017
1431 result = acpi_thermal_add_fs(device);
1432 if (result)
1433 goto unregister_thermal_zone;
1434
1435 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", 1018 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
1436 acpi_device_name(device), acpi_device_bid(device), 1019 acpi_device_name(device), acpi_device_bid(device),
1437 KELVIN_TO_CELSIUS(tz->temperature)); 1020 KELVIN_TO_CELSIUS(tz->temperature));
1438 goto end; 1021 goto end;
1439 1022
1440unregister_thermal_zone:
1441 thermal_zone_device_unregister(tz->thermal_zone);
1442free_memory: 1023free_memory:
1443 kfree(tz); 1024 kfree(tz);
1444end: 1025end:
@@ -1454,7 +1035,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1454 1035
1455 tz = acpi_driver_data(device); 1036 tz = acpi_driver_data(device);
1456 1037
1457 acpi_thermal_remove_fs(device);
1458 acpi_thermal_unregister_thermal_zone(tz); 1038 acpi_thermal_unregister_thermal_zone(tz);
1459 mutex_destroy(&tz->lock); 1039 mutex_destroy(&tz->lock);
1460 kfree(tz); 1040 kfree(tz);
@@ -1479,8 +1059,9 @@ static int acpi_thermal_resume(struct acpi_device *device)
1479 break; 1059 break;
1480 tz->trips.active[i].flags.enabled = 1; 1060 tz->trips.active[i].flags.enabled = 1;
1481 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1061 for (j = 0; j < tz->trips.active[i].devices.count; j++) {
1482 result = acpi_bus_get_power(tz->trips.active[i].devices. 1062 result = acpi_bus_update_power(
1483 handles[j], &power_state); 1063 tz->trips.active[i].devices.handles[j],
1064 &power_state);
1484 if (result || (power_state != ACPI_STATE_D0)) { 1065 if (result || (power_state != ACPI_STATE_D0)) {
1485 tz->trips.active[i].flags.enabled = 0; 1066 tz->trips.active[i].flags.enabled = 0;
1486 break; 1067 break;
@@ -1580,19 +1161,9 @@ static int __init acpi_thermal_init(void)
1580 return -ENODEV; 1161 return -ENODEV;
1581 } 1162 }
1582 1163
1583#ifdef CONFIG_ACPI_PROCFS
1584 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
1585 if (!acpi_thermal_dir)
1586 return -ENODEV;
1587#endif
1588
1589 result = acpi_bus_register_driver(&acpi_thermal_driver); 1164 result = acpi_bus_register_driver(&acpi_thermal_driver);
1590 if (result < 0) { 1165 if (result < 0)
1591#ifdef CONFIG_ACPI_PROCFS
1592 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1593#endif
1594 return -ENODEV; 1166 return -ENODEV;
1595 }
1596 1167
1597 return 0; 1168 return 0;
1598} 1169}
@@ -1602,10 +1173,6 @@ static void __exit acpi_thermal_exit(void)
1602 1173
1603 acpi_bus_unregister_driver(&acpi_thermal_driver); 1174 acpi_bus_unregister_driver(&acpi_thermal_driver);
1604 1175
1605#ifdef CONFIG_ACPI_PROCFS
1606 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1607#endif
1608
1609 return; 1176 return;
1610} 1177}
1611 1178
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 67dec0c675aa..db39e9e607d8 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -30,12 +30,9 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/list.h> 31#include <linux/list.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/proc_fs.h>
34#include <linux/seq_file.h>
35#include <linux/input.h> 33#include <linux/input.h>
36#include <linux/backlight.h> 34#include <linux/backlight.h>
37#include <linux/thermal.h> 35#include <linux/thermal.h>
38#include <linux/video_output.h>
39#include <linux/sort.h> 36#include <linux/sort.h>
40#include <linux/pci.h> 37#include <linux/pci.h>
41#include <linux/pci_ids.h> 38#include <linux/pci_ids.h>
@@ -83,6 +80,13 @@ module_param(brightness_switch_enabled, bool, 0644);
83static int allow_duplicates; 80static int allow_duplicates;
84module_param(allow_duplicates, bool, 0644); 81module_param(allow_duplicates, bool, 0644);
85 82
83/*
84 * Some BIOSes claim they use minimum backlight at boot,
85 * and this may bring dimming screen after boot
86 */
87static int use_bios_initial_backlight = 1;
88module_param(use_bios_initial_backlight, bool, 0644);
89
86static int register_count = 0; 90static int register_count = 0;
87static int acpi_video_bus_add(struct acpi_device *device); 91static int acpi_video_bus_add(struct acpi_device *device);
88static int acpi_video_bus_remove(struct acpi_device *device, int type); 92static int acpi_video_bus_remove(struct acpi_device *device, int type);
@@ -152,9 +156,6 @@ struct acpi_video_bus {
152 struct acpi_video_bus_flags flags; 156 struct acpi_video_bus_flags flags;
153 struct list_head video_device_list; 157 struct list_head video_device_list;
154 struct mutex device_list_lock; /* protects video_device_list */ 158 struct mutex device_list_lock; /* protects video_device_list */
155#ifdef CONFIG_ACPI_PROCFS
156 struct proc_dir_entry *dir;
157#endif
158 struct input_dev *input; 159 struct input_dev *input;
159 char phys[32]; /* for input device */ 160 char phys[32]; /* for input device */
160 struct notifier_block pm_nb; 161 struct notifier_block pm_nb;
@@ -177,9 +178,6 @@ struct acpi_video_device_cap {
177 u8 _BQC:1; /* Get current brightness level */ 178 u8 _BQC:1; /* Get current brightness level */
178 u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ 179 u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */
179 u8 _DDC:1; /*Return the EDID for this device */ 180 u8 _DDC:1; /*Return the EDID for this device */
180 u8 _DCS:1; /*Return status of output device */
181 u8 _DGS:1; /*Query graphics state */
182 u8 _DSS:1; /*Device state set */
183}; 181};
184 182
185struct acpi_video_brightness_flags { 183struct acpi_video_brightness_flags {
@@ -207,110 +205,7 @@ struct acpi_video_device {
207 struct acpi_video_device_brightness *brightness; 205 struct acpi_video_device_brightness *brightness;
208 struct backlight_device *backlight; 206 struct backlight_device *backlight;
209 struct thermal_cooling_device *cooling_dev; 207 struct thermal_cooling_device *cooling_dev;
210 struct output_device *output_dev;
211};
212
213#ifdef CONFIG_ACPI_PROCFS
214/* bus */
215static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
216static const struct file_operations acpi_video_bus_info_fops = {
217 .owner = THIS_MODULE,
218 .open = acpi_video_bus_info_open_fs,
219 .read = seq_read,
220 .llseek = seq_lseek,
221 .release = single_release,
222};
223
224static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
225static const struct file_operations acpi_video_bus_ROM_fops = {
226 .owner = THIS_MODULE,
227 .open = acpi_video_bus_ROM_open_fs,
228 .read = seq_read,
229 .llseek = seq_lseek,
230 .release = single_release,
231};
232
233static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
234 struct file *file);
235static const struct file_operations acpi_video_bus_POST_info_fops = {
236 .owner = THIS_MODULE,
237 .open = acpi_video_bus_POST_info_open_fs,
238 .read = seq_read,
239 .llseek = seq_lseek,
240 .release = single_release,
241};
242
243static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
244static ssize_t acpi_video_bus_write_POST(struct file *file,
245 const char __user *buffer, size_t count, loff_t *data);
246static const struct file_operations acpi_video_bus_POST_fops = {
247 .owner = THIS_MODULE,
248 .open = acpi_video_bus_POST_open_fs,
249 .read = seq_read,
250 .write = acpi_video_bus_write_POST,
251 .llseek = seq_lseek,
252 .release = single_release,
253};
254
255static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
256static ssize_t acpi_video_bus_write_DOS(struct file *file,
257 const char __user *buffer, size_t count, loff_t *data);
258static const struct file_operations acpi_video_bus_DOS_fops = {
259 .owner = THIS_MODULE,
260 .open = acpi_video_bus_DOS_open_fs,
261 .read = seq_read,
262 .write = acpi_video_bus_write_DOS,
263 .llseek = seq_lseek,
264 .release = single_release,
265};
266
267/* device */
268static int acpi_video_device_info_open_fs(struct inode *inode,
269 struct file *file);
270static const struct file_operations acpi_video_device_info_fops = {
271 .owner = THIS_MODULE,
272 .open = acpi_video_device_info_open_fs,
273 .read = seq_read,
274 .llseek = seq_lseek,
275 .release = single_release,
276};
277
278static int acpi_video_device_state_open_fs(struct inode *inode,
279 struct file *file);
280static ssize_t acpi_video_device_write_state(struct file *file,
281 const char __user *buffer, size_t count, loff_t *data);
282static const struct file_operations acpi_video_device_state_fops = {
283 .owner = THIS_MODULE,
284 .open = acpi_video_device_state_open_fs,
285 .read = seq_read,
286 .write = acpi_video_device_write_state,
287 .llseek = seq_lseek,
288 .release = single_release,
289};
290
291static int acpi_video_device_brightness_open_fs(struct inode *inode,
292 struct file *file);
293static ssize_t acpi_video_device_write_brightness(struct file *file,
294 const char __user *buffer, size_t count, loff_t *data);
295static const struct file_operations acpi_video_device_brightness_fops = {
296 .owner = THIS_MODULE,
297 .open = acpi_video_device_brightness_open_fs,
298 .read = seq_read,
299 .write = acpi_video_device_write_brightness,
300 .llseek = seq_lseek,
301 .release = single_release,
302};
303
304static int acpi_video_device_EDID_open_fs(struct inode *inode,
305 struct file *file);
306static const struct file_operations acpi_video_device_EDID_fops = {
307 .owner = THIS_MODULE,
308 .open = acpi_video_device_EDID_open_fs,
309 .read = seq_read,
310 .llseek = seq_lseek,
311 .release = single_release,
312}; 208};
313#endif /* CONFIG_ACPI_PROCFS */
314 209
315static const char device_decode[][30] = { 210static const char device_decode[][30] = {
316 "motherboard VGA device", 211 "motherboard VGA device",
@@ -333,10 +228,6 @@ static int acpi_video_get_next_level(struct acpi_video_device *device,
333 u32 level_current, u32 event); 228 u32 level_current, u32 event);
334static int acpi_video_switch_brightness(struct acpi_video_device *device, 229static int acpi_video_switch_brightness(struct acpi_video_device *device,
335 int event); 230 int event);
336static int acpi_video_device_get_state(struct acpi_video_device *device,
337 unsigned long long *state);
338static int acpi_video_output_get(struct output_device *od);
339static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
340 231
341/*backlight device sysfs support*/ 232/*backlight device sysfs support*/
342static int acpi_video_get_brightness(struct backlight_device *bd) 233static int acpi_video_get_brightness(struct backlight_device *bd)
@@ -367,35 +258,11 @@ static int acpi_video_set_brightness(struct backlight_device *bd)
367 vd->brightness->levels[request_level]); 258 vd->brightness->levels[request_level]);
368} 259}
369 260
370static struct backlight_ops acpi_backlight_ops = { 261static const struct backlight_ops acpi_backlight_ops = {
371 .get_brightness = acpi_video_get_brightness, 262 .get_brightness = acpi_video_get_brightness,
372 .update_status = acpi_video_set_brightness, 263 .update_status = acpi_video_set_brightness,
373}; 264};
374 265
375/*video output device sysfs support*/
376static int acpi_video_output_get(struct output_device *od)
377{
378 unsigned long long state;
379 struct acpi_video_device *vd =
380 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
381 acpi_video_device_get_state(vd, &state);
382 return (int)state;
383}
384
385static int acpi_video_output_set(struct output_device *od)
386{
387 unsigned long state = od->request_state;
388 struct acpi_video_device *vd=
389 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
390 return acpi_video_device_set_state(vd, state);
391}
392
393static struct output_properties acpi_output_properties = {
394 .set_state = acpi_video_output_set,
395 .get_status = acpi_video_output_get,
396};
397
398
399/* thermal cooling device callbacks */ 266/* thermal cooling device callbacks */
400static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned 267static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned
401 long *state) 268 long *state)
@@ -451,34 +318,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = {
451 Video Management 318 Video Management
452 -------------------------------------------------------------------------- */ 319 -------------------------------------------------------------------------- */
453 320
454/* device */
455
456static int
457acpi_video_device_get_state(struct acpi_video_device *device,
458 unsigned long long *state)
459{
460 int status;
461
462 status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state);
463
464 return status;
465}
466
467static int
468acpi_video_device_set_state(struct acpi_video_device *device, int state)
469{
470 int status;
471 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
472 struct acpi_object_list args = { 1, &arg0 };
473 unsigned long long ret;
474
475
476 arg0.integer.value = state;
477 status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret);
478
479 return status;
480}
481
482static int 321static int
483acpi_video_device_lcd_query_levels(struct acpi_video_device *device, 322acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
484 union acpi_object **levels) 323 union acpi_object **levels)
@@ -873,9 +712,11 @@ acpi_video_init_brightness(struct acpi_video_device *device)
873 * when invoked for the first time, i.e. level_old is invalid. 712 * when invoked for the first time, i.e. level_old is invalid.
874 * set the backlight to max_level in this case 713 * set the backlight to max_level in this case
875 */ 714 */
876 for (i = 2; i < br->count; i++) 715 if (use_bios_initial_backlight) {
877 if (level_old == br->levels[i]) 716 for (i = 2; i < br->count; i++)
878 level = level_old; 717 if (level_old == br->levels[i])
718 level = level_old;
719 }
879 goto set_level; 720 goto set_level;
880 } 721 }
881 722
@@ -938,18 +779,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
938 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 779 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
939 device->cap._DDC = 1; 780 device->cap._DDC = 1;
940 } 781 }
941 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) {
942 device->cap._DCS = 1;
943 }
944 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) {
945 device->cap._DGS = 1;
946 }
947 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) {
948 device->cap._DSS = 1;
949 }
950 782
951 if (acpi_video_backlight_support()) { 783 if (acpi_video_backlight_support()) {
952 struct backlight_properties props; 784 struct backlight_properties props;
785 struct pci_dev *pdev;
786 acpi_handle acpi_parent;
787 struct device *parent = NULL;
953 int result; 788 int result;
954 static int count = 0; 789 static int count = 0;
955 char *name; 790 char *name;
@@ -962,9 +797,20 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
962 return; 797 return;
963 count++; 798 count++;
964 799
800 acpi_get_parent(device->dev->handle, &acpi_parent);
801
802 pdev = acpi_get_pci_dev(acpi_parent);
803 if (pdev) {
804 parent = &pdev->dev;
805 pci_dev_put(pdev);
806 }
807
965 memset(&props, 0, sizeof(struct backlight_properties)); 808 memset(&props, 0, sizeof(struct backlight_properties));
809 props.type = BACKLIGHT_FIRMWARE;
966 props.max_brightness = device->brightness->count - 3; 810 props.max_brightness = device->brightness->count - 3;
967 device->backlight = backlight_device_register(name, NULL, device, 811 device->backlight = backlight_device_register(name,
812 parent,
813 device,
968 &acpi_backlight_ops, 814 &acpi_backlight_ops,
969 &props); 815 &props);
970 kfree(name); 816 kfree(name);
@@ -978,11 +824,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
978 device->backlight->props.brightness = 824 device->backlight->props.brightness =
979 acpi_video_get_brightness(device->backlight); 825 acpi_video_get_brightness(device->backlight);
980 826
981 result = sysfs_create_link(&device->backlight->dev.kobj,
982 &device->dev->dev.kobj, "device");
983 if (result)
984 printk(KERN_ERR PREFIX "Create sysfs link\n");
985
986 device->cooling_dev = thermal_cooling_device_register("LCD", 827 device->cooling_dev = thermal_cooling_device_register("LCD",
987 device->dev, &video_cooling_ops); 828 device->dev, &video_cooling_ops);
988 if (IS_ERR(device->cooling_dev)) { 829 if (IS_ERR(device->cooling_dev)) {
@@ -1011,21 +852,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
1011 printk(KERN_ERR PREFIX "Create sysfs link\n"); 852 printk(KERN_ERR PREFIX "Create sysfs link\n");
1012 853
1013 } 854 }
1014
1015 if (acpi_video_display_switch_support()) {
1016
1017 if (device->cap._DCS && device->cap._DSS) {
1018 static int count;
1019 char *name;
1020 name = kasprintf(GFP_KERNEL, "acpi_video%d", count);
1021 if (!name)
1022 return;
1023 count++;
1024 device->output_dev = video_output_register(name,
1025 NULL, device, &acpi_output_properties);
1026 kfree(name);
1027 }
1028 }
1029} 855}
1030 856
1031/* 857/*
@@ -1111,646 +937,6 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
1111} 937}
1112 938
1113/* -------------------------------------------------------------------------- 939/* --------------------------------------------------------------------------
1114 FS Interface (/proc)
1115 -------------------------------------------------------------------------- */
1116#ifdef CONFIG_ACPI_PROCFS
1117
1118static struct proc_dir_entry *acpi_video_dir;
1119
1120/* video devices */
1121
1122static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
1123{
1124 struct acpi_video_device *dev = seq->private;
1125
1126
1127 if (!dev)
1128 goto end;
1129
1130 seq_printf(seq, "device_id: 0x%04x\n", (u32) dev->device_id);
1131 seq_printf(seq, "type: ");
1132 if (dev->flags.crt)
1133 seq_printf(seq, "CRT\n");
1134 else if (dev->flags.lcd)
1135 seq_printf(seq, "LCD\n");
1136 else if (dev->flags.tvout)
1137 seq_printf(seq, "TVOUT\n");
1138 else if (dev->flags.dvi)
1139 seq_printf(seq, "DVI\n");
1140 else
1141 seq_printf(seq, "UNKNOWN\n");
1142
1143 seq_printf(seq, "known by bios: %s\n", dev->flags.bios ? "yes" : "no");
1144
1145 end:
1146 return 0;
1147}
1148
1149static int
1150acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
1151{
1152 return single_open(file, acpi_video_device_info_seq_show,
1153 PDE(inode)->data);
1154}
1155
1156static int
1157acpi_video_device_query(struct acpi_video_device *device,
1158 unsigned long long *state)
1159{
1160 int status;
1161
1162 status = acpi_evaluate_integer(device->dev->handle, "_DGS",
1163 NULL, state);
1164
1165 return status;
1166}
1167
1168static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
1169{
1170 int status;
1171 struct acpi_video_device *dev = seq->private;
1172 unsigned long long state;
1173
1174
1175 if (!dev)
1176 goto end;
1177
1178 status = acpi_video_device_get_state(dev, &state);
1179 seq_printf(seq, "state: ");
1180 if (ACPI_SUCCESS(status))
1181 seq_printf(seq, "0x%02llx\n", state);
1182 else
1183 seq_printf(seq, "<not supported>\n");
1184
1185 status = acpi_video_device_query(dev, &state);
1186 seq_printf(seq, "query: ");
1187 if (ACPI_SUCCESS(status))
1188 seq_printf(seq, "0x%02llx\n", state);
1189 else
1190 seq_printf(seq, "<not supported>\n");
1191
1192 end:
1193 return 0;
1194}
1195
1196static int
1197acpi_video_device_state_open_fs(struct inode *inode, struct file *file)
1198{
1199 return single_open(file, acpi_video_device_state_seq_show,
1200 PDE(inode)->data);
1201}
1202
1203static ssize_t
1204acpi_video_device_write_state(struct file *file,
1205 const char __user * buffer,
1206 size_t count, loff_t * data)
1207{
1208 int status;
1209 struct seq_file *m = file->private_data;
1210 struct acpi_video_device *dev = m->private;
1211 char str[12] = { 0 };
1212 u32 state = 0;
1213
1214
1215 if (!dev || count >= sizeof(str))
1216 return -EINVAL;
1217
1218 if (copy_from_user(str, buffer, count))
1219 return -EFAULT;
1220
1221 str[count] = 0;
1222 state = simple_strtoul(str, NULL, 0);
1223 state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));
1224
1225 status = acpi_video_device_set_state(dev, state);
1226
1227 if (status)
1228 return -EFAULT;
1229
1230 return count;
1231}
1232
1233static int
1234acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
1235{
1236 struct acpi_video_device *dev = seq->private;
1237 int i;
1238
1239
1240 if (!dev || !dev->brightness) {
1241 seq_printf(seq, "<not supported>\n");
1242 return 0;
1243 }
1244
1245 seq_printf(seq, "levels: ");
1246 for (i = 2; i < dev->brightness->count; i++)
1247 seq_printf(seq, " %d", dev->brightness->levels[i]);
1248 seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr);
1249
1250 return 0;
1251}
1252
1253static int
1254acpi_video_device_brightness_open_fs(struct inode *inode, struct file *file)
1255{
1256 return single_open(file, acpi_video_device_brightness_seq_show,
1257 PDE(inode)->data);
1258}
1259
1260static ssize_t
1261acpi_video_device_write_brightness(struct file *file,
1262 const char __user * buffer,
1263 size_t count, loff_t * data)
1264{
1265 struct seq_file *m = file->private_data;
1266 struct acpi_video_device *dev = m->private;
1267 char str[5] = { 0 };
1268 unsigned int level = 0;
1269 int i;
1270
1271
1272 if (!dev || !dev->brightness || count >= sizeof(str))
1273 return -EINVAL;
1274
1275 if (copy_from_user(str, buffer, count))
1276 return -EFAULT;
1277
1278 str[count] = 0;
1279 level = simple_strtoul(str, NULL, 0);
1280
1281 if (level > 100)
1282 return -EFAULT;
1283
1284 /* validate through the list of available levels */
1285 for (i = 2; i < dev->brightness->count; i++)
1286 if (level == dev->brightness->levels[i]) {
1287 if (!acpi_video_device_lcd_set_level(dev, level))
1288 return count;
1289 break;
1290 }
1291
1292 return -EINVAL;
1293}
1294
1295static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
1296{
1297 struct acpi_video_device *dev = seq->private;
1298 int status;
1299 int i;
1300 union acpi_object *edid = NULL;
1301
1302
1303 if (!dev)
1304 goto out;
1305
1306 status = acpi_video_device_EDID(dev, &edid, 128);
1307 if (ACPI_FAILURE(status)) {
1308 status = acpi_video_device_EDID(dev, &edid, 256);
1309 }
1310
1311 if (ACPI_FAILURE(status)) {
1312 goto out;
1313 }
1314
1315 if (edid && edid->type == ACPI_TYPE_BUFFER) {
1316 for (i = 0; i < edid->buffer.length; i++)
1317 seq_putc(seq, edid->buffer.pointer[i]);
1318 }
1319
1320 out:
1321 if (!edid)
1322 seq_printf(seq, "<not supported>\n");
1323 else
1324 kfree(edid);
1325
1326 return 0;
1327}
1328
1329static int
1330acpi_video_device_EDID_open_fs(struct inode *inode, struct file *file)
1331{
1332 return single_open(file, acpi_video_device_EDID_seq_show,
1333 PDE(inode)->data);
1334}
1335
1336static int acpi_video_device_add_fs(struct acpi_device *device)
1337{
1338 struct proc_dir_entry *entry, *device_dir;
1339 struct acpi_video_device *vid_dev;
1340
1341 vid_dev = acpi_driver_data(device);
1342 if (!vid_dev)
1343 return -ENODEV;
1344
1345 device_dir = proc_mkdir(acpi_device_bid(device),
1346 vid_dev->video->dir);
1347 if (!device_dir)
1348 return -ENOMEM;
1349
1350 /* 'info' [R] */
1351 entry = proc_create_data("info", S_IRUGO, device_dir,
1352 &acpi_video_device_info_fops, acpi_driver_data(device));
1353 if (!entry)
1354 goto err_remove_dir;
1355
1356 /* 'state' [R/W] */
1357 entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
1358 device_dir,
1359 &acpi_video_device_state_fops,
1360 acpi_driver_data(device));
1361 if (!entry)
1362 goto err_remove_info;
1363
1364 /* 'brightness' [R/W] */
1365 entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
1366 device_dir,
1367 &acpi_video_device_brightness_fops,
1368 acpi_driver_data(device));
1369 if (!entry)
1370 goto err_remove_state;
1371
1372 /* 'EDID' [R] */
1373 entry = proc_create_data("EDID", S_IRUGO, device_dir,
1374 &acpi_video_device_EDID_fops,
1375 acpi_driver_data(device));
1376 if (!entry)
1377 goto err_remove_brightness;
1378
1379 acpi_device_dir(device) = device_dir;
1380
1381 return 0;
1382
1383 err_remove_brightness:
1384 remove_proc_entry("brightness", device_dir);
1385 err_remove_state:
1386 remove_proc_entry("state", device_dir);
1387 err_remove_info:
1388 remove_proc_entry("info", device_dir);
1389 err_remove_dir:
1390 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1391 return -ENOMEM;
1392}
1393
1394static int acpi_video_device_remove_fs(struct acpi_device *device)
1395{
1396 struct acpi_video_device *vid_dev;
1397 struct proc_dir_entry *device_dir;
1398
1399 vid_dev = acpi_driver_data(device);
1400 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
1401 return -ENODEV;
1402
1403 device_dir = acpi_device_dir(device);
1404 if (device_dir) {
1405 remove_proc_entry("info", device_dir);
1406 remove_proc_entry("state", device_dir);
1407 remove_proc_entry("brightness", device_dir);
1408 remove_proc_entry("EDID", device_dir);
1409 remove_proc_entry(acpi_device_bid(device), vid_dev->video->dir);
1410 acpi_device_dir(device) = NULL;
1411 }
1412
1413 return 0;
1414}
1415
1416/* video bus */
1417static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
1418{
1419 struct acpi_video_bus *video = seq->private;
1420
1421
1422 if (!video)
1423 goto end;
1424
1425 seq_printf(seq, "Switching heads: %s\n",
1426 video->flags.multihead ? "yes" : "no");
1427 seq_printf(seq, "Video ROM: %s\n",
1428 video->flags.rom ? "yes" : "no");
1429 seq_printf(seq, "Device to be POSTed on boot: %s\n",
1430 video->flags.post ? "yes" : "no");
1431
1432 end:
1433 return 0;
1434}
1435
1436static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
1437{
1438 return single_open(file, acpi_video_bus_info_seq_show,
1439 PDE(inode)->data);
1440}
1441
1442static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
1443{
1444 struct acpi_video_bus *video = seq->private;
1445
1446
1447 if (!video)
1448 goto end;
1449
1450 printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
1451 seq_printf(seq, "<TODO>\n");
1452
1453 end:
1454 return 0;
1455}
1456
1457static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
1458{
1459 return single_open(file, acpi_video_bus_ROM_seq_show, PDE(inode)->data);
1460}
1461
1462static int
1463acpi_video_bus_POST_options(struct acpi_video_bus *video,
1464 unsigned long long *options)
1465{
1466 int status;
1467
1468 status = acpi_evaluate_integer(video->device->handle, "_VPO",
1469 NULL, options);
1470 *options &= 3;
1471
1472 return status;
1473}
1474
1475static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
1476{
1477 struct acpi_video_bus *video = seq->private;
1478 unsigned long long options;
1479 int status;
1480
1481
1482 if (!video)
1483 goto end;
1484
1485 status = acpi_video_bus_POST_options(video, &options);
1486 if (ACPI_SUCCESS(status)) {
1487 if (!(options & 1)) {
1488 printk(KERN_WARNING PREFIX
1489 "The motherboard VGA device is not listed as a possible POST device.\n");
1490 printk(KERN_WARNING PREFIX
1491 "This indicates a BIOS bug. Please contact the manufacturer.\n");
1492 }
1493 printk(KERN_WARNING "%llx\n", options);
1494 seq_printf(seq, "can POST: <integrated video>");
1495 if (options & 2)
1496 seq_printf(seq, " <PCI video>");
1497 if (options & 4)
1498 seq_printf(seq, " <AGP video>");
1499 seq_putc(seq, '\n');
1500 } else
1501 seq_printf(seq, "<not supported>\n");
1502 end:
1503 return 0;
1504}
1505
1506static int
1507acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1508{
1509 return single_open(file, acpi_video_bus_POST_info_seq_show,
1510 PDE(inode)->data);
1511}
1512
1513static int
1514acpi_video_bus_get_POST(struct acpi_video_bus *video, unsigned long long *id)
1515{
1516 int status;
1517
1518 status = acpi_evaluate_integer(video->device->handle, "_GPD", NULL, id);
1519
1520 return status;
1521}
1522
1523static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1524{
1525 struct acpi_video_bus *video = seq->private;
1526 int status;
1527 unsigned long long id;
1528
1529
1530 if (!video)
1531 goto end;
1532
1533 status = acpi_video_bus_get_POST(video, &id);
1534 if (!ACPI_SUCCESS(status)) {
1535 seq_printf(seq, "<not supported>\n");
1536 goto end;
1537 }
1538 seq_printf(seq, "device POSTed is <%s>\n", device_decode[id & 3]);
1539
1540 end:
1541 return 0;
1542}
1543
1544static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1545{
1546 struct acpi_video_bus *video = seq->private;
1547
1548
1549 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
1550
1551 return 0;
1552}
1553
1554static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file)
1555{
1556 return single_open(file, acpi_video_bus_POST_seq_show,
1557 PDE(inode)->data);
1558}
1559
1560static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file)
1561{
1562 return single_open(file, acpi_video_bus_DOS_seq_show, PDE(inode)->data);
1563}
1564
1565static int
1566acpi_video_bus_set_POST(struct acpi_video_bus *video, unsigned long option)
1567{
1568 int status;
1569 unsigned long long tmp;
1570 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
1571 struct acpi_object_list args = { 1, &arg0 };
1572
1573
1574 arg0.integer.value = option;
1575
1576 status = acpi_evaluate_integer(video->device->handle, "_SPD",
1577 &args, &tmp);
1578 if (ACPI_SUCCESS(status))
1579 status = tmp ? (-EINVAL) : (AE_OK);
1580
1581 return status;
1582}
1583
1584static ssize_t
1585acpi_video_bus_write_POST(struct file *file,
1586 const char __user * buffer,
1587 size_t count, loff_t * data)
1588{
1589 int status;
1590 struct seq_file *m = file->private_data;
1591 struct acpi_video_bus *video = m->private;
1592 char str[12] = { 0 };
1593 unsigned long long opt, options;
1594
1595
1596 if (!video || count >= sizeof(str))
1597 return -EINVAL;
1598
1599 status = acpi_video_bus_POST_options(video, &options);
1600 if (!ACPI_SUCCESS(status))
1601 return -EINVAL;
1602
1603 if (copy_from_user(str, buffer, count))
1604 return -EFAULT;
1605
1606 str[count] = 0;
1607 opt = strtoul(str, NULL, 0);
1608 if (opt > 3)
1609 return -EFAULT;
1610
1611 /* just in case an OEM 'forgot' the motherboard... */
1612 options |= 1;
1613
1614 if (options & (1ul << opt)) {
1615 status = acpi_video_bus_set_POST(video, opt);
1616 if (!ACPI_SUCCESS(status))
1617 return -EFAULT;
1618
1619 }
1620
1621 return count;
1622}
1623
1624static ssize_t
1625acpi_video_bus_write_DOS(struct file *file,
1626 const char __user * buffer,
1627 size_t count, loff_t * data)
1628{
1629 int status;
1630 struct seq_file *m = file->private_data;
1631 struct acpi_video_bus *video = m->private;
1632 char str[12] = { 0 };
1633 unsigned long opt;
1634
1635
1636 if (!video || count >= sizeof(str))
1637 return -EINVAL;
1638
1639 if (copy_from_user(str, buffer, count))
1640 return -EFAULT;
1641
1642 str[count] = 0;
1643 opt = strtoul(str, NULL, 0);
1644 if (opt > 7)
1645 return -EFAULT;
1646
1647 status = acpi_video_bus_DOS(video, opt & 0x3, (opt & 0x4) >> 2);
1648
1649 if (!ACPI_SUCCESS(status))
1650 return -EFAULT;
1651
1652 return count;
1653}
1654
1655static int acpi_video_bus_add_fs(struct acpi_device *device)
1656{
1657 struct acpi_video_bus *video = acpi_driver_data(device);
1658 struct proc_dir_entry *device_dir;
1659 struct proc_dir_entry *entry;
1660
1661 device_dir = proc_mkdir(acpi_device_bid(device), acpi_video_dir);
1662 if (!device_dir)
1663 return -ENOMEM;
1664
1665 /* 'info' [R] */
1666 entry = proc_create_data("info", S_IRUGO, device_dir,
1667 &acpi_video_bus_info_fops,
1668 acpi_driver_data(device));
1669 if (!entry)
1670 goto err_remove_dir;
1671
1672 /* 'ROM' [R] */
1673 entry = proc_create_data("ROM", S_IRUGO, device_dir,
1674 &acpi_video_bus_ROM_fops,
1675 acpi_driver_data(device));
1676 if (!entry)
1677 goto err_remove_info;
1678
1679 /* 'POST_info' [R] */
1680 entry = proc_create_data("POST_info", S_IRUGO, device_dir,
1681 &acpi_video_bus_POST_info_fops,
1682 acpi_driver_data(device));
1683 if (!entry)
1684 goto err_remove_rom;
1685
1686 /* 'POST' [R/W] */
1687 entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
1688 device_dir,
1689 &acpi_video_bus_POST_fops,
1690 acpi_driver_data(device));
1691 if (!entry)
1692 goto err_remove_post_info;
1693
1694 /* 'DOS' [R/W] */
1695 entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
1696 device_dir,
1697 &acpi_video_bus_DOS_fops,
1698 acpi_driver_data(device));
1699 if (!entry)
1700 goto err_remove_post;
1701
1702 video->dir = acpi_device_dir(device) = device_dir;
1703 return 0;
1704
1705 err_remove_post:
1706 remove_proc_entry("POST", device_dir);
1707 err_remove_post_info:
1708 remove_proc_entry("POST_info", device_dir);
1709 err_remove_rom:
1710 remove_proc_entry("ROM", device_dir);
1711 err_remove_info:
1712 remove_proc_entry("info", device_dir);
1713 err_remove_dir:
1714 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1715 return -ENOMEM;
1716}
1717
1718static int acpi_video_bus_remove_fs(struct acpi_device *device)
1719{
1720 struct proc_dir_entry *device_dir = acpi_device_dir(device);
1721
1722 if (device_dir) {
1723 remove_proc_entry("info", device_dir);
1724 remove_proc_entry("ROM", device_dir);
1725 remove_proc_entry("POST_info", device_dir);
1726 remove_proc_entry("POST", device_dir);
1727 remove_proc_entry("DOS", device_dir);
1728 remove_proc_entry(acpi_device_bid(device), acpi_video_dir);
1729 acpi_device_dir(device) = NULL;
1730 }
1731
1732 return 0;
1733}
1734#else
1735static inline int acpi_video_device_add_fs(struct acpi_device *device)
1736{
1737 return 0;
1738}
1739static inline int acpi_video_device_remove_fs(struct acpi_device *device)
1740{
1741 return 0;
1742}
1743static inline int acpi_video_bus_add_fs(struct acpi_device *device)
1744{
1745 return 0;
1746}
1747static inline int acpi_video_bus_remove_fs(struct acpi_device *device)
1748{
1749 return 0;
1750}
1751#endif /* CONFIG_ACPI_PROCFS */
1752
1753/* --------------------------------------------------------------------------
1754 Driver Interface 940 Driver Interface
1755 -------------------------------------------------------------------------- */ 941 -------------------------------------------------------------------------- */
1756 942
@@ -1877,8 +1063,6 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1877 list_add_tail(&data->entry, &video->video_device_list); 1063 list_add_tail(&data->entry, &video->video_device_list);
1878 mutex_unlock(&video->device_list_lock); 1064 mutex_unlock(&video->device_list_lock);
1879 1065
1880 acpi_video_device_add_fs(device);
1881
1882 return 0; 1066 return 0;
1883 } 1067 }
1884 1068
@@ -2109,6 +1293,9 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
2109 if (!video_device) 1293 if (!video_device)
2110 continue; 1294 continue;
2111 1295
1296 if (!video_device->cap._DDC)
1297 continue;
1298
2112 if (type) { 1299 if (type) {
2113 switch (type) { 1300 switch (type) {
2114 case ACPI_VIDEO_DISPLAY_CRT: 1301 case ACPI_VIDEO_DISPLAY_CRT:
@@ -2167,7 +1354,7 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
2167 status = acpi_video_bus_get_one_device(dev, video); 1354 status = acpi_video_bus_get_one_device(dev, video);
2168 if (ACPI_FAILURE(status)) { 1355 if (ACPI_FAILURE(status)) {
2169 printk(KERN_WARNING PREFIX 1356 printk(KERN_WARNING PREFIX
2170 "Cant attach device\n"); 1357 "Can't attach device\n");
2171 continue; 1358 continue;
2172 } 1359 }
2173 } 1360 }
@@ -2181,17 +1368,14 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
2181 if (!device || !device->video) 1368 if (!device || !device->video)
2182 return -ENOENT; 1369 return -ENOENT;
2183 1370
2184 acpi_video_device_remove_fs(device->dev);
2185
2186 status = acpi_remove_notify_handler(device->dev->handle, 1371 status = acpi_remove_notify_handler(device->dev->handle,
2187 ACPI_DEVICE_NOTIFY, 1372 ACPI_DEVICE_NOTIFY,
2188 acpi_video_device_notify); 1373 acpi_video_device_notify);
2189 if (ACPI_FAILURE(status)) { 1374 if (ACPI_FAILURE(status)) {
2190 printk(KERN_WARNING PREFIX 1375 printk(KERN_WARNING PREFIX
2191 "Cant remove video notify handler\n"); 1376 "Can't remove video notify handler\n");
2192 } 1377 }
2193 if (device->backlight) { 1378 if (device->backlight) {
2194 sysfs_remove_link(&device->backlight->dev.kobj, "device");
2195 backlight_device_unregister(device->backlight); 1379 backlight_device_unregister(device->backlight);
2196 device->backlight = NULL; 1380 device->backlight = NULL;
2197 } 1381 }
@@ -2203,7 +1387,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
2203 thermal_cooling_device_unregister(device->cooling_dev); 1387 thermal_cooling_device_unregister(device->cooling_dev);
2204 device->cooling_dev = NULL; 1388 device->cooling_dev = NULL;
2205 } 1389 }
2206 video_output_unregister(device->output_dev);
2207 1390
2208 return 0; 1391 return 0;
2209} 1392}
@@ -2338,7 +1521,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
2338 acpi_bus_generate_proc_event(device, event, 0); 1521 acpi_bus_generate_proc_event(device, event, 0);
2339 keycode = KEY_BRIGHTNESSDOWN; 1522 keycode = KEY_BRIGHTNESSDOWN;
2340 break; 1523 break;
2341 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ 1524 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */
2342 if (brightness_switch_enabled) 1525 if (brightness_switch_enabled)
2343 acpi_video_switch_brightness(video_device, event); 1526 acpi_video_switch_brightness(video_device, event);
2344 acpi_bus_generate_proc_event(device, event, 0); 1527 acpi_bus_generate_proc_event(device, event, 0);
@@ -2466,10 +1649,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2466 if (error) 1649 if (error)
2467 goto err_free_video; 1650 goto err_free_video;
2468 1651
2469 error = acpi_video_bus_add_fs(device);
2470 if (error)
2471 goto err_free_video;
2472
2473 mutex_init(&video->device_list_lock); 1652 mutex_init(&video->device_list_lock);
2474 INIT_LIST_HEAD(&video->video_device_list); 1653 INIT_LIST_HEAD(&video->video_device_list);
2475 1654
@@ -2522,7 +1701,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
2522 acpi_video_bus_stop_devices(video); 1701 acpi_video_bus_stop_devices(video);
2523 acpi_video_bus_put_devices(video); 1702 acpi_video_bus_put_devices(video);
2524 kfree(video->attached_array); 1703 kfree(video->attached_array);
2525 acpi_video_bus_remove_fs(device);
2526 err_free_video: 1704 err_free_video:
2527 kfree(video); 1705 kfree(video);
2528 device->driver_data = NULL; 1706 device->driver_data = NULL;
@@ -2544,7 +1722,6 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
2544 1722
2545 acpi_video_bus_stop_devices(video); 1723 acpi_video_bus_stop_devices(video);
2546 acpi_video_bus_put_devices(video); 1724 acpi_video_bus_put_devices(video);
2547 acpi_video_bus_remove_fs(device);
2548 1725
2549 input_unregister_device(video->input); 1726 input_unregister_device(video->input);
2550 kfree(video->attached_array); 1727 kfree(video->attached_array);
@@ -2584,17 +1761,9 @@ int acpi_video_register(void)
2584 return 0; 1761 return 0;
2585 } 1762 }
2586 1763
2587#ifdef CONFIG_ACPI_PROCFS
2588 acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
2589 if (!acpi_video_dir)
2590 return -ENODEV;
2591#endif
2592
2593 result = acpi_bus_register_driver(&acpi_video_bus); 1764 result = acpi_bus_register_driver(&acpi_video_bus);
2594 if (result < 0) { 1765 if (result < 0)
2595 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2596 return -ENODEV; 1766 return -ENODEV;
2597 }
2598 1767
2599 /* 1768 /*
2600 * When the acpi_video_bus is loaded successfully, increase 1769 * When the acpi_video_bus is loaded successfully, increase
@@ -2617,10 +1786,6 @@ void acpi_video_unregister(void)
2617 } 1786 }
2618 acpi_bus_unregister_driver(&acpi_video_bus); 1787 acpi_bus_unregister_driver(&acpi_video_bus);
2619 1788
2620#ifdef CONFIG_ACPI_PROCFS
2621 remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir);
2622#endif
2623
2624 register_count = 0; 1789 register_count = 0;
2625 1790
2626 return; 1791 return;
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index b83676126598..5af3479714f6 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -17,15 +17,14 @@
17 * capabilities the graphics cards plugged in support. The check for general 17 * capabilities the graphics cards plugged in support. The check for general
18 * video capabilities will be triggered by the first caller of 18 * video capabilities will be triggered by the first caller of
19 * acpi_video_get_capabilities(NULL); which will happen when the first 19 * acpi_video_get_capabilities(NULL); which will happen when the first
20 * backlight (or display output) switching supporting driver calls: 20 * backlight switching supporting driver calls:
21 * acpi_video_backlight_support(); 21 * acpi_video_backlight_support();
22 * 22 *
23 * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) 23 * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
24 * are available, video.ko should be used to handle the device. 24 * are available, video.ko should be used to handle the device.
25 * 25 *
26 * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, 26 * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi,
27 * sony_acpi,... can take care about backlight brightness and display output 27 * sony_acpi,... can take care about backlight brightness.
28 * switching.
29 * 28 *
30 * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) 29 * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
31 * this file will not be compiled, acpi_video_get_capabilities() and 30 * this file will not be compiled, acpi_video_get_capabilities() and
@@ -161,8 +160,6 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle)
161 * 160 *
162 * if (dmi_name_in_vendors("XY")) { 161 * if (dmi_name_in_vendors("XY")) {
163 * acpi_video_support |= 162 * acpi_video_support |=
164 * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR;
165 * acpi_video_support |=
166 * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; 163 * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR;
167 *} 164 *}
168 */ 165 */
@@ -212,33 +209,8 @@ int acpi_video_backlight_support(void)
212EXPORT_SYMBOL(acpi_video_backlight_support); 209EXPORT_SYMBOL(acpi_video_backlight_support);
213 210
214/* 211/*
215 * Returns true if video.ko can do display output switching. 212 * Use acpi_backlight=vendor/video to force that backlight switching
216 * This does not work well/at all with binary graphics drivers 213 * is processed by vendor specific acpi drivers or video.ko driver.
217 * which disable system io ranges and do it on their own.
218 */
219int acpi_video_display_switch_support(void)
220{
221 if (!acpi_video_caps_checked)
222 acpi_video_get_capabilities(NULL);
223
224 if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR)
225 return 0;
226 else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO)
227 return 1;
228
229 if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR)
230 return 0;
231 else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO)
232 return 1;
233
234 return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING;
235}
236EXPORT_SYMBOL(acpi_video_display_switch_support);
237
238/*
239 * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video
240 * To force that backlight or display output switching is processed by vendor
241 * specific acpi drivers or video.ko driver.
242 */ 214 */
243static int __init acpi_backlight(char *str) 215static int __init acpi_backlight(char *str)
244{ 216{
@@ -255,19 +227,3 @@ static int __init acpi_backlight(char *str)
255 return 1; 227 return 1;
256} 228}
257__setup("acpi_backlight=", acpi_backlight); 229__setup("acpi_backlight=", acpi_backlight);
258
259static int __init acpi_display_output(char *str)
260{
261 if (str == NULL || *str == '\0')
262 return 1;
263 else {
264 if (!strcmp("vendor", str))
265 acpi_video_support |=
266 ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR;
267 if (!strcmp("video", str))
268 acpi_video_support |=
269 ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
270 }
271 return 1;
272}
273__setup("acpi_display_output=", acpi_display_output);
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index f62a50c3ed34..7bfbe40bc43b 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -37,15 +37,16 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
37 container_of(node, struct acpi_device, wakeup_list); 37 container_of(node, struct acpi_device, wakeup_list);
38 38
39 if (!dev->wakeup.flags.valid 39 if (!dev->wakeup.flags.valid
40 || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) 40 || sleep_state > (u32) dev->wakeup.sleep_state
41 || sleep_state > (u32) dev->wakeup.sleep_state) 41 || !(device_may_wakeup(&dev->dev)
42 || dev->wakeup.prepare_count))
42 continue; 43 continue;
43 44
44 if (dev->wakeup.state.enabled) 45 if (device_may_wakeup(&dev->dev))
45 acpi_enable_wakeup_device_power(dev, sleep_state); 46 acpi_enable_wakeup_device_power(dev, sleep_state);
46 47
47 /* The wake-up power should have been enabled already. */ 48 /* The wake-up power should have been enabled already. */
48 acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, 49 acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
49 ACPI_GPE_ENABLE); 50 ACPI_GPE_ENABLE);
50 } 51 }
51} 52}
@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
63 container_of(node, struct acpi_device, wakeup_list); 64 container_of(node, struct acpi_device, wakeup_list);
64 65
65 if (!dev->wakeup.flags.valid 66 if (!dev->wakeup.flags.valid
66 || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) 67 || sleep_state > (u32) dev->wakeup.sleep_state
67 || (sleep_state > (u32) dev->wakeup.sleep_state)) 68 || !(device_may_wakeup(&dev->dev)
69 || dev->wakeup.prepare_count))
68 continue; 70 continue;
69 71
70 acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, 72 acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
71 ACPI_GPE_DISABLE); 73 ACPI_GPE_DISABLE);
72 74
73 if (dev->wakeup.state.enabled) 75 if (device_may_wakeup(&dev->dev))
74 acpi_disable_wakeup_device_power(dev); 76 acpi_disable_wakeup_device_power(dev);
75 } 77 }
76} 78}
@@ -84,8 +86,12 @@ int __init acpi_wakeup_device_init(void)
84 struct acpi_device *dev = container_of(node, 86 struct acpi_device *dev = container_of(node,
85 struct acpi_device, 87 struct acpi_device,
86 wakeup_list); 88 wakeup_list);
87 if (dev->wakeup.flags.always_enabled) 89 if (device_can_wakeup(&dev->dev)) {
88 dev->wakeup.state.enabled = 1; 90 /* Button GPEs are supposed to be always enabled. */
91 acpi_enable_gpe(dev->wakeup.gpe_device,
92 dev->wakeup.gpe_number);
93 device_set_wakeup_enable(&dev->dev, true);
94 }
89 } 95 }
90 mutex_unlock(&acpi_device_lock); 96 mutex_unlock(&acpi_device_lock);
91 return 0; 97 return 0;