diff options
Diffstat (limited to 'drivers')
113 files changed, 3989 insertions, 2477 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 8a851d0f4384..431f8b439553 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -11,9 +11,9 @@ menuconfig ACPI | |||
11 | select PNP | 11 | select PNP |
12 | select CPU_IDLE | 12 | select CPU_IDLE |
13 | default y | 13 | default y |
14 | ---help--- | 14 | help |
15 | Advanced Configuration and Power Interface (ACPI) support for | 15 | Advanced Configuration and Power Interface (ACPI) support for |
16 | Linux requires an ACPI compliant platform (hardware/firmware), | 16 | Linux requires an ACPI-compliant platform (hardware/firmware), |
17 | and assumes the presence of OS-directed configuration and power | 17 | and assumes the presence of OS-directed configuration and power |
18 | management (OSPM) software. This option will enlarge your | 18 | management (OSPM) software. This option will enlarge your |
19 | kernel by about 70K. | 19 | kernel by about 70K. |
@@ -23,20 +23,19 @@ menuconfig ACPI | |||
23 | the Plug-and-Play BIOS specification (PnP BIOS), the | 23 | the Plug-and-Play BIOS specification (PnP BIOS), the |
24 | MultiProcessor Specification (MPS), and the Advanced Power | 24 | MultiProcessor Specification (MPS), and the Advanced Power |
25 | Management (APM) specification. If both ACPI and APM support | 25 | Management (APM) specification. If both ACPI and APM support |
26 | are configured, whichever is loaded first shall be used. | 26 | are configured, ACPI is used. |
27 | 27 | ||
28 | The ACPI SourceForge project contains the latest source code, | 28 | The project home page for the Linux ACPI subsystem is here: |
29 | documentation, tools, mailing list subscription, and other | 29 | <http://www.lesswatts.org/projects/acpi/> |
30 | information. This project is available at: | ||
31 | <http://sourceforge.net/projects/acpi> | ||
32 | 30 | ||
33 | Linux support for ACPI is based on Intel Corporation's ACPI | 31 | Linux support for ACPI is based on Intel Corporation's ACPI |
34 | Component Architecture (ACPI CA). For more information see: | 32 | Component Architecture (ACPI CA). For more information on the |
35 | <http://developer.intel.com/technology/iapc/acpi> | 33 | ACPI CA, see: |
34 | <http://acpica.org/> | ||
36 | 35 | ||
37 | ACPI is an open industry specification co-developed by Compaq, | 36 | ACPI is an open industry specification co-developed by |
38 | Intel, Microsoft, Phoenix, and Toshiba. The specification is | 37 | Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba. |
39 | available at: | 38 | The specification is available at: |
40 | <http://www.acpi.info> | 39 | <http://www.acpi.info> |
41 | 40 | ||
42 | if ACPI | 41 | if ACPI |
@@ -49,14 +48,14 @@ config ACPI_SLEEP | |||
49 | config ACPI_PROCFS | 48 | config ACPI_PROCFS |
50 | bool "Deprecated /proc/acpi files" | 49 | bool "Deprecated /proc/acpi files" |
51 | depends on PROC_FS | 50 | depends on PROC_FS |
52 | ---help--- | 51 | help |
53 | For backwards compatibility, this option allows | 52 | For backwards compatibility, this option allows |
54 | deprecated /proc/acpi/ files to exist, even when | 53 | deprecated /proc/acpi/ files to exist, even when |
55 | they have been replaced by functions in /sys. | 54 | they have been replaced by functions in /sys. |
56 | The deprecated files (and their replacements) include: | 55 | The deprecated files (and their replacements) include: |
57 | 56 | ||
58 | /proc/acpi/sleep (/sys/power/state) | 57 | /proc/acpi/sleep (/sys/power/state) |
59 | /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version) | 58 | /proc/acpi/info (/sys/module/acpi/parameters/acpica_version) |
60 | /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) | 59 | /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) |
61 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) | 60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) |
62 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) | 61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) |
@@ -66,11 +65,12 @@ config ACPI_PROCFS | |||
66 | and functions which do not yet exist in /sys. | 65 | and functions which do not yet exist in /sys. |
67 | 66 | ||
68 | Say N to delete /proc/acpi/ files that have moved to /sys/ | 67 | Say N to delete /proc/acpi/ files that have moved to /sys/ |
68 | |||
69 | config ACPI_PROCFS_POWER | 69 | config ACPI_PROCFS_POWER |
70 | bool "Deprecated power /proc/acpi directories" | 70 | bool "Deprecated power /proc/acpi directories" |
71 | depends on PROC_FS | 71 | depends on PROC_FS |
72 | default y | 72 | default y |
73 | ---help--- | 73 | help |
74 | For backwards compatibility, this option allows | 74 | For backwards compatibility, this option allows |
75 | deprecated power /proc/acpi/ directories to exist, even when | 75 | deprecated power /proc/acpi/ directories to exist, even when |
76 | they have been replaced by functions in /sys. | 76 | they have been replaced by functions in /sys. |
@@ -86,19 +86,19 @@ config ACPI_SYSFS_POWER | |||
86 | bool "Future power /sys interface" | 86 | bool "Future power /sys interface" |
87 | select POWER_SUPPLY | 87 | select POWER_SUPPLY |
88 | default y | 88 | default y |
89 | ---help--- | 89 | help |
90 | Say N to disable power /sys interface | 90 | Say N to disable power /sys interface |
91 | 91 | ||
92 | config ACPI_PROC_EVENT | 92 | config ACPI_PROC_EVENT |
93 | bool "Deprecated /proc/acpi/event support" | 93 | bool "Deprecated /proc/acpi/event support" |
94 | depends on PROC_FS | 94 | depends on PROC_FS |
95 | default y | 95 | default y |
96 | ---help--- | 96 | help |
97 | A user-space daemon, acpi, typically read /proc/acpi/event | 97 | A user-space daemon, acpid, typically reads /proc/acpi/event |
98 | and handled all ACPI sub-system generated events. | 98 | and handles all ACPI-generated events. |
99 | 99 | ||
100 | These events are now delivered to user-space via | 100 | These events are now delivered to user-space either |
101 | either the input layer, or as netlink events. | 101 | via the input layer or as netlink events. |
102 | 102 | ||
103 | This build option enables the old code for legacy | 103 | This build option enables the old code for legacy |
104 | user-space implementation. After some time, this will | 104 | user-space implementation. After some time, this will |
@@ -112,10 +112,13 @@ config ACPI_AC | |||
112 | depends on X86 | 112 | depends on X86 |
113 | default y | 113 | default y |
114 | help | 114 | help |
115 | This driver adds support for the AC Adapter object, which indicates | 115 | This driver supports the AC Adapter object, which indicates |
116 | whether a system is on AC, or not. If you have a system that can | 116 | whether a system is on AC or not. If you have a system that can |
117 | switch between A/C and battery, say Y. | 117 | switch between A/C and battery, say Y. |
118 | 118 | ||
119 | To compile this driver as a module, choose M here: | ||
120 | the module will be called ac. | ||
121 | |||
119 | config ACPI_BATTERY | 122 | config ACPI_BATTERY |
120 | tristate "Battery" | 123 | tristate "Battery" |
121 | depends on X86 | 124 | depends on X86 |
@@ -125,15 +128,21 @@ config ACPI_BATTERY | |||
125 | /proc/acpi/battery. If you have a mobile system with a battery, | 128 | /proc/acpi/battery. If you have a mobile system with a battery, |
126 | say Y. | 129 | say Y. |
127 | 130 | ||
131 | To compile this driver as a module, choose M here: | ||
132 | the module will be called battery. | ||
133 | |||
128 | config ACPI_BUTTON | 134 | config ACPI_BUTTON |
129 | tristate "Button" | 135 | tristate "Button" |
130 | depends on INPUT | 136 | depends on INPUT |
131 | default y | 137 | default y |
132 | help | 138 | help |
133 | This driver handles events on the power, sleep and lid buttons. | 139 | This driver handles events on the power, sleep, and lid buttons. |
134 | A daemon reads /proc/acpi/event and perform user-defined actions | 140 | A daemon reads /proc/acpi/event and perform user-defined actions |
135 | such as shutting down the system. This is necessary for | 141 | such as shutting down the system. This is necessary for |
136 | software controlled poweroff. | 142 | software-controlled poweroff. |
143 | |||
144 | To compile this driver as a module, choose M here: | ||
145 | the module will be called button. | ||
137 | 146 | ||
138 | config ACPI_VIDEO | 147 | config ACPI_VIDEO |
139 | tristate "Video" | 148 | tristate "Video" |
@@ -141,38 +150,45 @@ config ACPI_VIDEO | |||
141 | depends on INPUT | 150 | depends on INPUT |
142 | select THERMAL | 151 | select THERMAL |
143 | help | 152 | help |
144 | This driver implement the ACPI Extensions For Display Adapters | 153 | This driver implements the ACPI Extensions For Display Adapters |
145 | for integrated graphics devices on motherboard, as specified in | 154 | for integrated graphics devices on motherboard, as specified in |
146 | ACPI 2.0 Specification, Appendix B, allowing to perform some basic | 155 | ACPI 2.0 Specification, Appendix B. This supports basic operations |
147 | control like defining the video POST device, retrieving EDID information | 156 | such as defining the video POST device, retrieving EDID information, |
148 | or to setup a video output, etc. | 157 | and setting up a video output. |
149 | Note that this is an ref. implementation only. It may or may not work | 158 | |
150 | for your integrated video device. | 159 | To compile this driver as a module, choose M here: |
160 | the module will be called video. | ||
151 | 161 | ||
152 | config ACPI_FAN | 162 | config ACPI_FAN |
153 | tristate "Fan" | 163 | tristate "Fan" |
154 | select THERMAL | 164 | select THERMAL |
155 | default y | 165 | default y |
156 | help | 166 | help |
157 | This driver adds support for ACPI fan devices, allowing user-mode | 167 | This driver supports ACPI fan devices, allowing user-mode |
158 | applications to perform basic fan control (on, off, status). | 168 | applications to perform basic fan control (on, off, status). |
159 | 169 | ||
170 | To compile this driver as a module, choose M here: | ||
171 | the module will be called fan. | ||
172 | |||
160 | config ACPI_DOCK | 173 | config ACPI_DOCK |
161 | bool "Dock" | 174 | bool "Dock" |
162 | depends on EXPERIMENTAL | 175 | depends on EXPERIMENTAL |
163 | help | 176 | help |
164 | This driver adds support for ACPI controlled docking stations and removable | 177 | This driver supports ACPI-controlled docking stations and removable |
165 | drive bays such as the IBM ultrabay or the Dell Module Bay. | 178 | drive bays such as the IBM Ultrabay and the Dell Module Bay. |
166 | 179 | ||
167 | config ACPI_PROCESSOR | 180 | config ACPI_PROCESSOR |
168 | tristate "Processor" | 181 | tristate "Processor" |
169 | select THERMAL | 182 | select THERMAL |
170 | default y | 183 | default y |
171 | help | 184 | help |
172 | This driver installs ACPI as the idle handler for Linux, and uses | 185 | This driver installs ACPI as the idle handler for Linux and uses |
173 | ACPI C2 and C3 processor states to save power, on systems that | 186 | ACPI C2 and C3 processor states to save power on systems that |
174 | support it. It is required by several flavors of cpufreq | 187 | support it. It is required by several flavors of cpufreq |
175 | Performance-state drivers. | 188 | performance-state drivers. |
189 | |||
190 | To compile this driver as a module, choose M here: | ||
191 | the module will be called processor. | ||
176 | 192 | ||
177 | config ACPI_HOTPLUG_CPU | 193 | config ACPI_HOTPLUG_CPU |
178 | bool | 194 | bool |
@@ -186,11 +202,14 @@ config ACPI_THERMAL | |||
186 | select THERMAL | 202 | select THERMAL |
187 | default y | 203 | default y |
188 | help | 204 | help |
189 | This driver adds support for ACPI thermal zones. Most mobile and | 205 | This driver supports ACPI thermal zones. Most mobile and |
190 | some desktop systems support ACPI thermal zones. It is HIGHLY | 206 | some desktop systems support ACPI thermal zones. It is HIGHLY |
191 | recommended that this option be enabled, as your processor(s) | 207 | recommended that this option be enabled, as your processor(s) |
192 | may be damaged without it. | 208 | may be damaged without it. |
193 | 209 | ||
210 | To compile this driver as a module, choose M here: | ||
211 | the module will be called thermal. | ||
212 | |||
194 | config ACPI_NUMA | 213 | config ACPI_NUMA |
195 | bool "NUMA support" | 214 | bool "NUMA support" |
196 | depends on NUMA | 215 | depends on NUMA |
@@ -218,7 +237,7 @@ config ACPI_BLACKLIST_YEAR | |||
218 | int "Disable ACPI for systems before Jan 1st this year" if X86_32 | 237 | int "Disable ACPI for systems before Jan 1st this year" if X86_32 |
219 | default 0 | 238 | default 0 |
220 | help | 239 | help |
221 | enter a 4-digit year, eg. 2001 to disable ACPI by default | 240 | Enter a 4-digit year, e.g., 2001, to disable ACPI by default |
222 | on platforms with DMI BIOS date before January 1st that year. | 241 | on platforms with DMI BIOS date before January 1st that year. |
223 | "acpi=force" can be used to override this mechanism. | 242 | "acpi=force" can be used to override this mechanism. |
224 | 243 | ||
@@ -249,10 +268,13 @@ config ACPI_PCI_SLOT | |||
249 | tristate "PCI slot detection driver" | 268 | tristate "PCI slot detection driver" |
250 | default n | 269 | default n |
251 | help | 270 | help |
252 | This driver will attempt to discover all PCI slots in your system, | 271 | This driver creates entries in /sys/bus/pci/slots/ for all PCI |
253 | and creates entries in /sys/bus/pci/slots/. This feature can | 272 | slots in the system. This can help correlate PCI bus addresses, |
254 | help you correlate PCI bus addresses with the physical geography | 273 | i.e., segment/bus/device/function tuples, with physical slots in |
255 | of your slots. If you are unsure, say N. | 274 | the system. If you are unsure, say N. |
275 | |||
276 | To compile this driver as a module, choose M here: | ||
277 | the module will be called pci_slot. | ||
256 | 278 | ||
257 | config X86_PM_TIMER | 279 | config X86_PM_TIMER |
258 | bool "Power Management Timer Support" if EMBEDDED | 280 | bool "Power Management Timer Support" if EMBEDDED |
@@ -271,43 +293,43 @@ config X86_PM_TIMER | |||
271 | systems require this timer. | 293 | systems require this timer. |
272 | 294 | ||
273 | config ACPI_CONTAINER | 295 | config ACPI_CONTAINER |
274 | tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)" | 296 | tristate "Container and Module Devices (EXPERIMENTAL)" |
275 | depends on EXPERIMENTAL | 297 | depends on EXPERIMENTAL |
276 | default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO) | 298 | default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO) |
277 | ---help--- | 299 | help |
278 | This allows _physical_ insertion and removal of CPUs and memory. | 300 | This driver supports ACPI Container and Module devices (IDs |
279 | This can be useful, for example, on NUMA machines that support | 301 | ACPI0004, PNP0A05, and PNP0A06). |
280 | ACPI based physical hotplug of nodes, or non-NUMA machines that | ||
281 | support physical cpu/memory hot-plug. | ||
282 | 302 | ||
283 | If one selects "m", this driver can be loaded with | 303 | This helps support hotplug of nodes, CPUs, and memory. |
284 | "modprobe container". | 304 | |
305 | To compile this driver as a module, choose M here: | ||
306 | the module will be called container. | ||
285 | 307 | ||
286 | config ACPI_HOTPLUG_MEMORY | 308 | config ACPI_HOTPLUG_MEMORY |
287 | tristate "Memory Hotplug" | 309 | tristate "Memory Hotplug" |
288 | depends on MEMORY_HOTPLUG | 310 | depends on MEMORY_HOTPLUG |
289 | default n | 311 | default n |
290 | help | 312 | help |
291 | This driver adds supports for ACPI Memory Hotplug. This driver | 313 | This driver supports ACPI memory hotplug. The driver |
292 | provides support for fielding notifications on ACPI memory | 314 | fields notifications on ACPI memory devices (PNP0C80), |
293 | devices (PNP0C80) which represent memory ranges that may be | 315 | which represent memory ranges that may be onlined or |
294 | onlined or offlined during runtime. | 316 | offlined during runtime. |
295 | 317 | ||
296 | Enabling this driver assumes that your platform hardware | 318 | If your hardware and firmware do not support adding or |
297 | and firmware have support for hot-plugging physical memory. If | 319 | removing memory devices at runtime, you need not enable |
298 | your system does not support physically adding or ripping out | 320 | this driver. |
299 | memory DIMMs at some platform defined granularity (individually | ||
300 | or as a bank) at runtime, then you need not enable this driver. | ||
301 | 321 | ||
302 | If one selects "m," this driver can be loaded using the following | 322 | To compile this driver as a module, choose M here: |
303 | command: | 323 | the module will be called acpi_memhotplug. |
304 | $>modprobe acpi_memhotplug | ||
305 | 324 | ||
306 | config ACPI_SBS | 325 | config ACPI_SBS |
307 | tristate "Smart Battery System" | 326 | tristate "Smart Battery System" |
308 | depends on X86 | 327 | depends on X86 |
309 | help | 328 | help |
310 | This driver adds support for the Smart Battery System, another | 329 | This driver supports the Smart Battery System, another |
311 | type of access to battery information, found on some laptops. | 330 | type of access to battery information, found on some laptops. |
312 | 331 | ||
332 | To compile this driver as a module, choose M here: | ||
333 | the modules will be called sbs and sbshc. | ||
334 | |||
313 | endif # ACPI | 335 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index b130ea0d0759..03a985be3fe3 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -14,48 +14,50 @@ obj-$(CONFIG_X86) += blacklist.o | |||
14 | # | 14 | # |
15 | # ACPI Core Subsystem (Interpreter) | 15 | # ACPI Core Subsystem (Interpreter) |
16 | # | 16 | # |
17 | obj-y += osl.o utils.o reboot.o\ | 17 | obj-y += acpi.o \ |
18 | acpica/ | 18 | acpica/ |
19 | 19 | ||
20 | # All the builtin files are in the "acpi." module_param namespace. | ||
21 | acpi-y += osl.o utils.o reboot.o | ||
22 | |||
20 | # sleep related files | 23 | # sleep related files |
21 | obj-y += wakeup.o | 24 | acpi-y += wakeup.o |
22 | obj-y += sleep.o | 25 | acpi-y += sleep.o |
23 | obj-$(CONFIG_ACPI_SLEEP) += proc.o | 26 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o |
24 | 27 | ||
25 | 28 | ||
26 | # | 29 | # |
27 | # ACPI Bus and Device Drivers | 30 | # ACPI Bus and Device Drivers |
28 | # | 31 | # |
29 | processor-objs += processor_core.o processor_throttling.o \ | 32 | acpi-y += bus.o glue.o |
30 | processor_idle.o processor_thermal.o | 33 | acpi-y += scan.o |
31 | ifdef CONFIG_CPU_FREQ | 34 | acpi-y += ec.o |
32 | processor-objs += processor_perflib.o | 35 | acpi-$(CONFIG_ACPI_DOCK) += dock.o |
36 | acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | ||
37 | acpi-y += power.o | ||
38 | acpi-y += system.o event.o | ||
39 | acpi-$(CONFIG_ACPI_DEBUG) += debug.o | ||
40 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | ||
41 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | ||
42 | ifdef CONFIG_ACPI_VIDEO | ||
43 | acpi-y += video_detect.o | ||
33 | endif | 44 | endif |
34 | 45 | ||
35 | obj-y += bus.o glue.o | 46 | # These are (potentially) separate modules |
36 | obj-y += scan.o | ||
37 | # Keep EC driver first. Initialization of others depend on it. | ||
38 | obj-y += ec.o | ||
39 | obj-$(CONFIG_ACPI_AC) += ac.o | 47 | obj-$(CONFIG_ACPI_AC) += ac.o |
40 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | ||
41 | obj-$(CONFIG_ACPI_BUTTON) += button.o | 48 | obj-$(CONFIG_ACPI_BUTTON) += button.o |
42 | obj-$(CONFIG_ACPI_FAN) += fan.o | 49 | obj-$(CONFIG_ACPI_FAN) += fan.o |
43 | obj-$(CONFIG_ACPI_DOCK) += dock.o | ||
44 | obj-$(CONFIG_ACPI_VIDEO) += video.o | 50 | obj-$(CONFIG_ACPI_VIDEO) += video.o |
45 | ifdef CONFIG_ACPI_VIDEO | ||
46 | obj-y += video_detect.o | ||
47 | endif | ||
48 | |||
49 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | ||
50 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o | 51 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o |
51 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o | 52 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o |
52 | obj-$(CONFIG_ACPI_CONTAINER) += container.o | 53 | obj-$(CONFIG_ACPI_CONTAINER) += container.o |
53 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o | 54 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o |
54 | obj-y += power.o | 55 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o |
55 | obj-y += system.o event.o | 56 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
56 | obj-$(CONFIG_ACPI_DEBUG) += debug.o | ||
57 | obj-$(CONFIG_ACPI_NUMA) += numa.o | ||
58 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o | ||
59 | obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | ||
60 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 57 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
61 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 58 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
59 | |||
60 | # processor has its own "processor." module_param namespace | ||
61 | processor-y := processor_core.o processor_throttling.o | ||
62 | processor-y += processor_idle.o processor_thermal.o | ||
63 | processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | ||
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 3f23298ee3fd..17e50824a6f1 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -18,7 +18,7 @@ obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | |||
18 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ | 18 | excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ |
19 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o | 19 | exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o |
20 | 20 | ||
21 | obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o | 21 | obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o |
22 | 22 | ||
23 | obj-$(ACPI_FUTURE_USAGE) += hwtimer.o | 23 | obj-$(ACPI_FUTURE_USAGE) += hwtimer.o |
24 | 24 | ||
@@ -41,4 +41,4 @@ obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | |||
41 | 41 | ||
42 | obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 42 | obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
43 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 43 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
44 | utstate.o utmutex.o utobject.o utresrc.o | 44 | utstate.o utmutex.o utobject.o utresrc.o utlock.o |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ddb40f5c68fc..16e5210ae936 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -148,9 +148,12 @@ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; | |||
148 | ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; | 148 | ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; |
149 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; | 149 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; |
150 | 150 | ||
151 | /* These addresses are calculated from FADT address values */ | 151 | /* These addresses are calculated from the FADT Event Block addresses */ |
152 | 152 | ||
153 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status; | ||
153 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; | 154 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; |
155 | |||
156 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status; | ||
154 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; | 157 | ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; |
155 | 158 | ||
156 | /* | 159 | /* |
@@ -162,6 +165,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; | |||
162 | ACPI_EXTERN u8 acpi_gbl_integer_byte_width; | 165 | ACPI_EXTERN u8 acpi_gbl_integer_byte_width; |
163 | ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; | 166 | ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; |
164 | 167 | ||
168 | /* Reader/Writer lock is used for namespace walk and dynamic table unload */ | ||
169 | |||
170 | ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock; | ||
171 | |||
165 | /***************************************************************************** | 172 | /***************************************************************************** |
166 | * | 173 | * |
167 | * Mutual exlusion within ACPICA subsystem | 174 | * Mutual exlusion within ACPICA subsystem |
@@ -245,6 +252,7 @@ ACPI_EXTERN u8 acpi_gbl_step_to_next_call; | |||
245 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; | 252 | ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; |
246 | ACPI_EXTERN u8 acpi_gbl_events_initialized; | 253 | ACPI_EXTERN u8 acpi_gbl_events_initialized; |
247 | ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; | 254 | ACPI_EXTERN u8 acpi_gbl_system_awake_and_running; |
255 | ACPI_EXTERN u8 acpi_gbl_osi_data; | ||
248 | 256 | ||
249 | #ifndef DEFINE_ACPI_GLOBALS | 257 | #ifndef DEFINE_ACPI_GLOBALS |
250 | 258 | ||
@@ -371,7 +379,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer; | |||
371 | ACPI_EXTERN char *acpi_gbl_db_filename; | 379 | ACPI_EXTERN char *acpi_gbl_db_filename; |
372 | ACPI_EXTERN u32 acpi_gbl_db_debug_level; | 380 | ACPI_EXTERN u32 acpi_gbl_db_debug_level; |
373 | ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; | 381 | ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; |
374 | ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr; | ||
375 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; | 382 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; |
376 | 383 | ||
377 | /* | 384 | /* |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 58c69dc49ab4..4afa3d8e0efb 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -64,14 +64,22 @@ u32 acpi_hw_get_mode(void); | |||
64 | */ | 64 | */ |
65 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); | 65 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); |
66 | 66 | ||
67 | acpi_status | 67 | acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control); |
68 | acpi_hw_register_read(u32 register_id, u32 * return_value); | 68 | |
69 | acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value); | ||
69 | 70 | ||
70 | acpi_status acpi_hw_register_write(u32 register_id, u32 value); | 71 | acpi_status acpi_hw_register_write(u32 register_id, u32 value); |
71 | 72 | ||
72 | acpi_status acpi_hw_clear_acpi_status(void); | 73 | acpi_status acpi_hw_clear_acpi_status(void); |
73 | 74 | ||
74 | /* | 75 | /* |
76 | * hwvalid - Port I/O with validation | ||
77 | */ | ||
78 | acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width); | ||
79 | |||
80 | acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); | ||
81 | |||
82 | /* | ||
75 | * hwgpe - GPE support | 83 | * hwgpe - GPE support |
76 | */ | 84 | */ |
77 | acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 85 | acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 492d02761bb7..772ee5c4ccca 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -108,6 +108,14 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = { | |||
108 | #endif | 108 | #endif |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | /* Lock structure for reader/writer interfaces */ | ||
112 | |||
113 | struct acpi_rw_lock { | ||
114 | acpi_mutex writer_mutex; | ||
115 | acpi_mutex reader_mutex; | ||
116 | u32 num_readers; | ||
117 | }; | ||
118 | |||
111 | /* | 119 | /* |
112 | * Predefined handles for spinlocks used within the subsystem. | 120 | * Predefined handles for spinlocks used within the subsystem. |
113 | * These spinlocks are created by acpi_ut_mutex_initialize | 121 | * These spinlocks are created by acpi_ut_mutex_initialize |
@@ -772,7 +780,19 @@ struct acpi_bit_register_info { | |||
772 | * must be preserved. | 780 | * must be preserved. |
773 | */ | 781 | */ |
774 | #define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */ | 782 | #define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */ |
775 | #define ACPI_PM1_CONTROL_PRESERVED_BITS 0x0200 /* Bit 9 (whatever) */ | 783 | |
784 | /* Write-only bits must be zeroed by software */ | ||
785 | |||
786 | #define ACPI_PM1_CONTROL_WRITEONLY_BITS 0x2004 /* Bits 13, 2 */ | ||
787 | |||
788 | /* For control registers, both ignored and reserved bits must be preserved */ | ||
789 | |||
790 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */ | ||
791 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ | ||
792 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ | ||
793 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) | ||
794 | |||
795 | #define ACPI_PM2_CONTROL_PRESERVED_BITS 0xFFFFFFFE /* All except bit 0 */ | ||
776 | 796 | ||
777 | /* | 797 | /* |
778 | * Register IDs | 798 | * Register IDs |
@@ -781,12 +801,10 @@ struct acpi_bit_register_info { | |||
781 | #define ACPI_REGISTER_PM1_STATUS 0x01 | 801 | #define ACPI_REGISTER_PM1_STATUS 0x01 |
782 | #define ACPI_REGISTER_PM1_ENABLE 0x02 | 802 | #define ACPI_REGISTER_PM1_ENABLE 0x02 |
783 | #define ACPI_REGISTER_PM1_CONTROL 0x03 | 803 | #define ACPI_REGISTER_PM1_CONTROL 0x03 |
784 | #define ACPI_REGISTER_PM1A_CONTROL 0x04 | 804 | #define ACPI_REGISTER_PM2_CONTROL 0x04 |
785 | #define ACPI_REGISTER_PM1B_CONTROL 0x05 | 805 | #define ACPI_REGISTER_PM_TIMER 0x05 |
786 | #define ACPI_REGISTER_PM2_CONTROL 0x06 | 806 | #define ACPI_REGISTER_PROCESSOR_BLOCK 0x06 |
787 | #define ACPI_REGISTER_PM_TIMER 0x07 | 807 | #define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x07 |
788 | #define ACPI_REGISTER_PROCESSOR_BLOCK 0x08 | ||
789 | #define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09 | ||
790 | 808 | ||
791 | /* Masks used to access the bit_registers */ | 809 | /* Masks used to access the bit_registers */ |
792 | 810 | ||
@@ -818,7 +836,7 @@ struct acpi_bit_register_info { | |||
818 | #define ACPI_BITMASK_SCI_ENABLE 0x0001 | 836 | #define ACPI_BITMASK_SCI_ENABLE 0x0001 |
819 | #define ACPI_BITMASK_BUS_MASTER_RLD 0x0002 | 837 | #define ACPI_BITMASK_BUS_MASTER_RLD 0x0002 |
820 | #define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004 | 838 | #define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004 |
821 | #define ACPI_BITMASK_SLEEP_TYPE_X 0x1C00 | 839 | #define ACPI_BITMASK_SLEEP_TYPE 0x1C00 |
822 | #define ACPI_BITMASK_SLEEP_ENABLE 0x2000 | 840 | #define ACPI_BITMASK_SLEEP_ENABLE 0x2000 |
823 | 841 | ||
824 | #define ACPI_BITMASK_ARB_DISABLE 0x0001 | 842 | #define ACPI_BITMASK_ARB_DISABLE 0x0001 |
@@ -844,11 +862,35 @@ struct acpi_bit_register_info { | |||
844 | #define ACPI_BITPOSITION_SCI_ENABLE 0x00 | 862 | #define ACPI_BITPOSITION_SCI_ENABLE 0x00 |
845 | #define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01 | 863 | #define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01 |
846 | #define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02 | 864 | #define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02 |
847 | #define ACPI_BITPOSITION_SLEEP_TYPE_X 0x0A | 865 | #define ACPI_BITPOSITION_SLEEP_TYPE 0x0A |
848 | #define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D | 866 | #define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D |
849 | 867 | ||
850 | #define ACPI_BITPOSITION_ARB_DISABLE 0x00 | 868 | #define ACPI_BITPOSITION_ARB_DISABLE 0x00 |
851 | 869 | ||
870 | /* Structs and definitions for _OSI support and I/O port validation */ | ||
871 | |||
872 | #define ACPI_OSI_WIN_2000 0x01 | ||
873 | #define ACPI_OSI_WIN_XP 0x02 | ||
874 | #define ACPI_OSI_WIN_XP_SP1 0x03 | ||
875 | #define ACPI_OSI_WINSRV_2003 0x04 | ||
876 | #define ACPI_OSI_WIN_XP_SP2 0x05 | ||
877 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 | ||
878 | #define ACPI_OSI_WIN_VISTA 0x07 | ||
879 | |||
880 | #define ACPI_ALWAYS_ILLEGAL 0x00 | ||
881 | |||
882 | struct acpi_interface_info { | ||
883 | char *name; | ||
884 | u8 value; | ||
885 | }; | ||
886 | |||
887 | struct acpi_port_info { | ||
888 | char *name; | ||
889 | u16 start; | ||
890 | u16 end; | ||
891 | u8 osi_dependency; | ||
892 | }; | ||
893 | |||
852 | /***************************************************************************** | 894 | /***************************************************************************** |
853 | * | 895 | * |
854 | * Resource descriptors | 896 | * Resource descriptors |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 9c127e8e2d6d..91ac7d7b4402 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -292,10 +292,6 @@ | |||
292 | #define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type) | 292 | #define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type) |
293 | #define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t) | 293 | #define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t) |
294 | 294 | ||
295 | /* Macro to test the object type */ | ||
296 | |||
297 | #define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type) | ||
298 | |||
299 | /* | 295 | /* |
300 | * Macros for the master AML opcode table | 296 | * Macros for the master AML opcode table |
301 | */ | 297 | */ |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index eb6f038b03d9..544dcf834922 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -97,7 +97,6 @@ | |||
97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 | 97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 |
98 | #define AOPOBJ_SETUP_COMPLETE 0x10 | 98 | #define AOPOBJ_SETUP_COMPLETE 0x10 |
99 | #define AOPOBJ_SINGLE_DATUM 0x20 | 99 | #define AOPOBJ_SINGLE_DATUM 0x20 |
100 | #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ | ||
101 | 100 | ||
102 | /****************************************************************************** | 101 | /****************************************************************************** |
103 | * | 102 | * |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 16a9ca9a66e4..63f656ae3604 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -52,41 +52,44 @@ | |||
52 | * 1) PTYPE1 packages do not contain sub-packages. | 52 | * 1) PTYPE1 packages do not contain sub-packages. |
53 | * | 53 | * |
54 | * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types: | 54 | * ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types: |
55 | * object type | 55 | * object type |
56 | * count | 56 | * count |
57 | * object type | 57 | * object type |
58 | * count | 58 | * count |
59 | * | 59 | * |
60 | * ACPI_PTYPE1_VAR: Variable length: | 60 | * ACPI_PTYPE1_VAR: Variable length: |
61 | * object type (Int/Buf/Ref) | 61 | * object type (Int/Buf/Ref) |
62 | * | 62 | * |
63 | * ACPI_PTYPE1_OPTION: Package has some required and some optional elements: | 63 | * ACPI_PTYPE1_OPTION: Package has some required and some optional elements |
64 | * Used for _PRW | 64 | * (Used for _PRW) |
65 | * | 65 | * |
66 | * | 66 | * |
67 | * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the | 67 | * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the |
68 | * different types describe the contents of each of the sub-packages. | 68 | * different types describe the contents of each of the sub-packages. |
69 | * | 69 | * |
70 | * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: | 70 | * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: |
71 | * object type | 71 | * object type |
72 | * count | 72 | * count |
73 | * object type | 73 | * object type |
74 | * count | 74 | * count |
75 | * (Used for _ALR,_MLS,_PSS,_TRT,_TSS) | ||
75 | * | 76 | * |
76 | * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element: | 77 | * ACPI_PTYPE2_COUNT: Each subpackage has a count as first element: |
77 | * object type | 78 | * object type |
79 | * (Used for _CSD,_PSD,_TSD) | ||
78 | * | 80 | * |
79 | * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types: | 81 | * ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types: |
80 | * object type | 82 | * object type |
81 | * count | 83 | * count |
82 | * object type | 84 | * object type |
83 | * count | 85 | * count |
86 | * (Used for _CST) | ||
84 | * | 87 | * |
85 | * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length: | 88 | * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length |
86 | * Used for _PRT | 89 | * (Used for _PRT) |
87 | * | 90 | * |
88 | * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length | 91 | * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length |
89 | * Used for _HPX | 92 | * (Used for _HPX) |
90 | * | 93 | * |
91 | *****************************************************************************/ | 94 | *****************************************************************************/ |
92 | 95 | ||
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 7ce6e33c7f78..01c76b8ea7ba 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h | |||
@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count); | |||
49 | /* | 49 | /* |
50 | * tbfadt - FADT parse/convert/validate | 50 | * tbfadt - FADT parse/convert/validate |
51 | */ | 51 | */ |
52 | void acpi_tb_parse_fadt(u32 table_index, u8 flags); | 52 | void acpi_tb_parse_fadt(u32 table_index); |
53 | 53 | ||
54 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); | 54 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length); |
55 | 55 | ||
@@ -79,7 +79,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc); | |||
79 | 79 | ||
80 | void acpi_tb_terminate(void); | 80 | void acpi_tb_terminate(void); |
81 | 81 | ||
82 | void acpi_tb_delete_namespace_by_owner(u32 table_index); | 82 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index); |
83 | 83 | ||
84 | acpi_status acpi_tb_allocate_owner_id(u32 table_index); | 84 | acpi_status acpi_tb_allocate_owner_id(u32 table_index); |
85 | 85 | ||
@@ -109,9 +109,8 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length); | |||
109 | 109 | ||
110 | void | 110 | void |
111 | acpi_tb_install_table(acpi_physical_address address, | 111 | acpi_tb_install_table(acpi_physical_address address, |
112 | u8 flags, char *signature, u32 table_index); | 112 | char *signature, u32 table_index); |
113 | 113 | ||
114 | acpi_status | 114 | acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address); |
115 | acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); | ||
116 | 115 | ||
117 | #endif /* __ACTABLES_H__ */ | 116 | #endif /* __ACTABLES_H__ */ |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 80d8813484fe..897810ba0ccc 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -346,6 +346,21 @@ acpi_status | |||
346 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); | 346 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); |
347 | 347 | ||
348 | /* | 348 | /* |
349 | * utlock - reader/writer locks | ||
350 | */ | ||
351 | acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock); | ||
352 | |||
353 | void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock); | ||
354 | |||
355 | acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock); | ||
356 | |||
357 | acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock); | ||
358 | |||
359 | acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock); | ||
360 | |||
361 | void acpi_ut_release_write_lock(struct acpi_rw_lock *lock); | ||
362 | |||
363 | /* | ||
349 | * utobject - internal object create/delete/cache routines | 364 | * utobject - internal object create/delete/cache routines |
350 | */ | 365 | */ |
351 | union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char | 366 | union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char |
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index eb144b13d8fa..3aae13f30c5e 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c | |||
@@ -180,11 +180,23 @@ acpi_ds_initialize_objects(u32 table_index, | |||
180 | 180 | ||
181 | /* Walk entire namespace from the supplied root */ | 181 | /* Walk entire namespace from the supplied root */ |
182 | 182 | ||
183 | status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, | 183 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
184 | acpi_ds_init_one_object, &info, NULL); | 184 | if (ACPI_FAILURE(status)) { |
185 | return_ACPI_STATUS(status); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * We don't use acpi_walk_namespace since we do not want to acquire | ||
190 | * the namespace reader lock. | ||
191 | */ | ||
192 | status = | ||
193 | acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX, | ||
194 | ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object, | ||
195 | &info, NULL); | ||
185 | if (ACPI_FAILURE(status)) { | 196 | if (ACPI_FAILURE(status)) { |
186 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); | 197 | ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); |
187 | } | 198 | } |
199 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
188 | 200 | ||
189 | status = acpi_get_table_by_index(table_index, &table); | 201 | status = acpi_get_table_by_index(table_index, &table); |
190 | if (ACPI_FAILURE(status)) { | 202 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index da0f5468184c..22b1a3ce2c94 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c | |||
@@ -713,6 +713,6 @@ acpi_ds_method_data_get_type(u16 opcode, | |||
713 | 713 | ||
714 | /* Get the object type */ | 714 | /* Get the object type */ |
715 | 715 | ||
716 | return_VALUE(ACPI_GET_OBJECT_TYPE(object)); | 716 | return_VALUE(object->type); |
717 | } | 717 | } |
718 | #endif | 718 | #endif |
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 15c628e6aa00..dab3f48f0b42 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -565,7 +565,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state, | |||
565 | 565 | ||
566 | /* Re-type the object according to its argument */ | 566 | /* Re-type the object according to its argument */ |
567 | 567 | ||
568 | node->type = ACPI_GET_OBJECT_TYPE(obj_desc); | 568 | node->type = obj_desc->common.type; |
569 | 569 | ||
570 | /* Attach obj to node */ | 570 | /* Attach obj to node */ |
571 | 571 | ||
@@ -619,7 +619,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
619 | 619 | ||
620 | /* Perform per-object initialization */ | 620 | /* Perform per-object initialization */ |
621 | 621 | ||
622 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 622 | switch (obj_desc->common.type) { |
623 | case ACPI_TYPE_BUFFER: | 623 | case ACPI_TYPE_BUFFER: |
624 | 624 | ||
625 | /* | 625 | /* |
@@ -803,7 +803,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
803 | default: | 803 | default: |
804 | 804 | ||
805 | ACPI_ERROR((AE_INFO, "Unimplemented data type: %X", | 805 | ACPI_ERROR((AE_INFO, "Unimplemented data type: %X", |
806 | ACPI_GET_OBJECT_TYPE(obj_desc))); | 806 | obj_desc->common.type)); |
807 | 807 | ||
808 | status = AE_AML_OPERAND_TYPE; | 808 | status = AE_AML_OPERAND_TYPE; |
809 | break; | 809 | break; |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 0c3b4dd60e8a..b4c87b5053e6 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -397,30 +397,6 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) | |||
397 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | 397 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), |
398 | extra_desc->extra.aml_length, | 398 | extra_desc->extra.aml_length, |
399 | extra_desc->extra.aml_start); | 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); | 400 | return_ACPI_STATUS(status); |
425 | } | 401 | } |
426 | 402 | ||
@@ -484,7 +460,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, | |||
484 | 460 | ||
485 | /* Host object must be a Buffer */ | 461 | /* Host object must be a Buffer */ |
486 | 462 | ||
487 | if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) { | 463 | if (buffer_desc->common.type != ACPI_TYPE_BUFFER) { |
488 | ACPI_ERROR((AE_INFO, | 464 | ACPI_ERROR((AE_INFO, |
489 | "Target of Create Field is not a Buffer object - %s", | 465 | "Target of Create Field is not a Buffer object - %s", |
490 | acpi_ut_get_object_type_name(buffer_desc))); | 466 | acpi_ut_get_object_type_name(buffer_desc))); |
@@ -1365,10 +1341,8 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
1365 | if ((ACPI_GET_DESCRIPTOR_TYPE | 1341 | if ((ACPI_GET_DESCRIPTOR_TYPE |
1366 | (walk_state->results->results.obj_desc[0]) == | 1342 | (walk_state->results->results.obj_desc[0]) == |
1367 | ACPI_DESC_TYPE_OPERAND) | 1343 | ACPI_DESC_TYPE_OPERAND) |
1368 | && | 1344 | && ((walk_state->results->results.obj_desc[0])-> |
1369 | (ACPI_GET_OBJECT_TYPE | 1345 | common.type == ACPI_TYPE_LOCAL_REFERENCE) |
1370 | (walk_state->results->results.obj_desc[0]) == | ||
1371 | ACPI_TYPE_LOCAL_REFERENCE) | ||
1372 | && ((walk_state->results->results.obj_desc[0])-> | 1346 | && ((walk_state->results->results.obj_desc[0])-> |
1373 | reference.class != ACPI_REFCLASS_INDEX)) { | 1347 | reference.class != ACPI_REFCLASS_INDEX)) { |
1374 | status = | 1348 | status = |
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index dabc23a46176..dfa104102926 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -816,7 +816,7 @@ acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) | |||
816 | goto push_result; | 816 | goto push_result; |
817 | } | 817 | } |
818 | 818 | ||
819 | type = ACPI_GET_OBJECT_TYPE(*operand); | 819 | type = (*operand)->common.type; |
820 | 820 | ||
821 | status = acpi_ex_resolve_to_value(operand, walk_state); | 821 | status = acpi_ex_resolve_to_value(operand, walk_state); |
822 | if (ACPI_FAILURE(status)) { | 822 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 350e6656bc89..f0280856dc0e 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -138,11 +138,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, | |||
138 | goto cleanup; | 138 | goto cleanup; |
139 | } | 139 | } |
140 | 140 | ||
141 | if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) { | 141 | if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) { |
142 | ACPI_ERROR((AE_INFO, | 142 | ACPI_ERROR((AE_INFO, |
143 | "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X", | 143 | "Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X", |
144 | obj_desc, walk_state, | 144 | obj_desc, walk_state, obj_desc->common.type)); |
145 | ACPI_GET_OBJECT_TYPE(obj_desc))); | ||
146 | 145 | ||
147 | status = AE_AML_OPERAND_TYPE; | 146 | status = AE_AML_OPERAND_TYPE; |
148 | goto cleanup; | 147 | goto cleanup; |
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index 803edd9e3f6a..cd55c774e882 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -183,7 +183,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void) | |||
183 | * | 183 | * |
184 | * RETURN: Status | 184 | * RETURN: Status |
185 | * | 185 | * |
186 | * DESCRIPTION: Install the fixed event handlers and enable the fixed events. | 186 | * DESCRIPTION: Install the fixed event handlers and disable all fixed events. |
187 | * | 187 | * |
188 | ******************************************************************************/ | 188 | ******************************************************************************/ |
189 | 189 | ||
@@ -200,12 +200,13 @@ static acpi_status acpi_ev_fixed_event_initialize(void) | |||
200 | acpi_gbl_fixed_event_handlers[i].handler = NULL; | 200 | acpi_gbl_fixed_event_handlers[i].handler = NULL; |
201 | acpi_gbl_fixed_event_handlers[i].context = NULL; | 201 | acpi_gbl_fixed_event_handlers[i].context = NULL; |
202 | 202 | ||
203 | /* Enable the fixed event */ | 203 | /* Disable the fixed event */ |
204 | 204 | ||
205 | if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { | 205 | if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) { |
206 | status = | 206 | status = |
207 | acpi_set_register(acpi_gbl_fixed_event_info[i]. | 207 | acpi_write_bit_register(acpi_gbl_fixed_event_info |
208 | enable_register_id, 0); | 208 | [i].enable_register_id, |
209 | ACPI_DISABLE_EVENT); | ||
209 | if (ACPI_FAILURE(status)) { | 210 | if (ACPI_FAILURE(status)) { |
210 | return (status); | 211 | return (status); |
211 | } | 212 | } |
@@ -288,16 +289,17 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event) | |||
288 | 289 | ||
289 | /* Clear the status bit */ | 290 | /* Clear the status bit */ |
290 | 291 | ||
291 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. | 292 | (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
292 | status_register_id, 1); | 293 | status_register_id, ACPI_CLEAR_STATUS); |
293 | 294 | ||
294 | /* | 295 | /* |
295 | * Make sure we've got a handler. If not, report an error. The event is | 296 | * Make sure we've got a handler. If not, report an error. The event is |
296 | * disabled to prevent further interrupts. | 297 | * disabled to prevent further interrupts. |
297 | */ | 298 | */ |
298 | if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { | 299 | if (NULL == acpi_gbl_fixed_event_handlers[event].handler) { |
299 | (void)acpi_set_register(acpi_gbl_fixed_event_info[event]. | 300 | (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
300 | enable_register_id, 0); | 301 | enable_register_id, |
302 | ACPI_DISABLE_EVENT); | ||
301 | 303 | ||
302 | ACPI_ERROR((AE_INFO, | 304 | ACPI_ERROR((AE_INFO, |
303 | "No installed handler for fixed event [%08X]", | 305 | "No installed handler for fixed event [%08X]", |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index f345ced36477..b9d8ee69ca6c 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -88,10 +88,10 @@ acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type) | |||
88 | 88 | ||
89 | status = acpi_ev_disable_gpe(gpe_event_info); | 89 | status = acpi_ev_disable_gpe(gpe_event_info); |
90 | 90 | ||
91 | /* Type was validated above */ | 91 | /* Clear the type bits and insert the new Type */ |
92 | 92 | ||
93 | gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */ | 93 | gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; |
94 | gpe_event_info->flags |= type; /* Insert type */ | 94 | gpe_event_info->flags |= type; |
95 | return_ACPI_STATUS(status); | 95 | return_ACPI_STATUS(status); |
96 | } | 96 | } |
97 | 97 | ||
@@ -122,6 +122,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info, | |||
122 | if (!gpe_register_info) { | 122 | if (!gpe_register_info) { |
123 | return_ACPI_STATUS(AE_NOT_EXIST); | 123 | return_ACPI_STATUS(AE_NOT_EXIST); |
124 | } | 124 | } |
125 | |||
125 | register_bit = (u8) | 126 | register_bit = (u8) |
126 | (1 << | 127 | (1 << |
127 | (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); | 128 | (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 484cc0565d5b..7b3463639422 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -104,9 +104,9 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) | |||
104 | 104 | ||
105 | while (gpe_block) { | 105 | while (gpe_block) { |
106 | if ((&gpe_block->event_info[0] <= gpe_event_info) && | 106 | if ((&gpe_block->event_info[0] <= gpe_event_info) && |
107 | (&gpe_block-> | 107 | (&gpe_block->event_info[((acpi_size) |
108 | event_info[((acpi_size) gpe_block-> | 108 | gpe_block-> |
109 | register_count) * 8] > | 109 | register_count) * 8] > |
110 | gpe_event_info)) { | 110 | gpe_event_info)) { |
111 | return (TRUE); | 111 | return (TRUE); |
112 | } | 112 | } |
@@ -210,10 +210,9 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
210 | /* Now look at the individual GPEs in this byte register */ | 210 | /* Now look at the individual GPEs in this byte register */ |
211 | 211 | ||
212 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { | 212 | for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { |
213 | gpe_event_info = | 213 | gpe_event_info = &gpe_block->event_info[((acpi_size) i * |
214 | &gpe_block-> | 214 | ACPI_GPE_REGISTER_WIDTH) |
215 | event_info[((acpi_size) i * | 215 | + j]; |
216 | ACPI_GPE_REGISTER_WIDTH) + j]; | ||
217 | 216 | ||
218 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 217 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
219 | ACPI_GPE_DISPATCH_HANDLER) { | 218 | ACPI_GPE_DISPATCH_HANDLER) { |
@@ -293,8 +292,8 @@ acpi_ev_save_method_info(acpi_handle obj_handle, | |||
293 | /* Unknown method type, just ignore it! */ | 292 | /* Unknown method type, just ignore it! */ |
294 | 293 | ||
295 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, | 294 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, |
296 | "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)", | 295 | "Ignoring unknown GPE method type: %s " |
297 | name)); | 296 | "(name not of form _Lxx or _Exx)", name)); |
298 | return_ACPI_STATUS(AE_OK); | 297 | return_ACPI_STATUS(AE_OK); |
299 | } | 298 | } |
300 | 299 | ||
@@ -306,17 +305,16 @@ acpi_ev_save_method_info(acpi_handle obj_handle, | |||
306 | /* Conversion failed; invalid method, just ignore it */ | 305 | /* Conversion failed; invalid method, just ignore it */ |
307 | 306 | ||
308 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, | 307 | ACPI_DEBUG_PRINT((ACPI_DB_LOAD, |
309 | "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)", | 308 | "Could not extract GPE number from name: %s " |
310 | name)); | 309 | "(name is not of form _Lxx or _Exx)", name)); |
311 | return_ACPI_STATUS(AE_OK); | 310 | return_ACPI_STATUS(AE_OK); |
312 | } | 311 | } |
313 | 312 | ||
314 | /* Ensure that we have a valid GPE number for this GPE block */ | 313 | /* Ensure that we have a valid GPE number for this GPE block */ |
315 | 314 | ||
316 | if ((gpe_number < gpe_block->block_base_number) || | 315 | if ((gpe_number < gpe_block->block_base_number) || |
317 | (gpe_number >= | 316 | (gpe_number >= (gpe_block->block_base_number + |
318 | (gpe_block->block_base_number + | 317 | (gpe_block->register_count * 8)))) { |
319 | (gpe_block->register_count * 8)))) { | ||
320 | /* | 318 | /* |
321 | * Not valid for this GPE block, just ignore it. However, it may be | 319 | * Not valid for this GPE block, just ignore it. However, it may be |
322 | * valid for a different GPE block, since GPE0 and GPE1 methods both | 320 | * valid for a different GPE block, since GPE0 and GPE1 methods both |
@@ -408,7 +406,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | |||
408 | */ | 406 | */ |
409 | obj_desc = pkg_desc->package.elements[0]; | 407 | obj_desc = pkg_desc->package.elements[0]; |
410 | 408 | ||
411 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 409 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { |
412 | 410 | ||
413 | /* Use FADT-defined GPE device (from definition of _PRW) */ | 411 | /* Use FADT-defined GPE device (from definition of _PRW) */ |
414 | 412 | ||
@@ -417,15 +415,15 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | |||
417 | /* Integer is the GPE number in the FADT described GPE blocks */ | 415 | /* Integer is the GPE number in the FADT described GPE blocks */ |
418 | 416 | ||
419 | gpe_number = (u32) obj_desc->integer.value; | 417 | gpe_number = (u32) obj_desc->integer.value; |
420 | } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { | 418 | } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { |
421 | 419 | ||
422 | /* Package contains a GPE reference and GPE number within a GPE block */ | 420 | /* Package contains a GPE reference and GPE number within a GPE block */ |
423 | 421 | ||
424 | if ((obj_desc->package.count < 2) || | 422 | if ((obj_desc->package.count < 2) || |
425 | (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) != | 423 | ((obj_desc->package.elements[0])->common.type != |
426 | ACPI_TYPE_LOCAL_REFERENCE) | 424 | ACPI_TYPE_LOCAL_REFERENCE) || |
427 | || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) != | 425 | ((obj_desc->package.elements[1])->common.type != |
428 | ACPI_TYPE_INTEGER)) { | 426 | ACPI_TYPE_INTEGER)) { |
429 | goto cleanup; | 427 | goto cleanup; |
430 | } | 428 | } |
431 | 429 | ||
@@ -450,11 +448,11 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | |||
450 | */ | 448 | */ |
451 | if ((gpe_device == target_gpe_device) && | 449 | if ((gpe_device == target_gpe_device) && |
452 | (gpe_number >= gpe_block->block_base_number) && | 450 | (gpe_number >= gpe_block->block_base_number) && |
453 | (gpe_number < | 451 | (gpe_number < gpe_block->block_base_number + |
454 | gpe_block->block_base_number + (gpe_block->register_count * 8))) { | 452 | (gpe_block->register_count * 8))) { |
455 | gpe_event_info = | 453 | gpe_event_info = &gpe_block->event_info[gpe_number - |
456 | &gpe_block->event_info[gpe_number - | 454 | gpe_block-> |
457 | gpe_block->block_base_number]; | 455 | block_base_number]; |
458 | 456 | ||
459 | /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */ | 457 | /* Mark GPE for WAKE-ONLY but WAKE_DISABLED */ |
460 | 458 | ||
@@ -1033,8 +1031,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
1033 | * 1) are "runtime" or "run/wake" GPEs, and | 1031 | * 1) are "runtime" or "run/wake" GPEs, and |
1034 | * 2) have a corresponding _Lxx or _Exx method | 1032 | * 2) have a corresponding _Lxx or _Exx method |
1035 | * | 1033 | * |
1036 | * Any other GPEs within this block must be enabled via the acpi_enable_gpe() | 1034 | * Any other GPEs within this block must be enabled via the |
1037 | * external interface. | 1035 | * acpi_enable_gpe() external interface. |
1038 | */ | 1036 | */ |
1039 | wake_gpe_count = 0; | 1037 | wake_gpe_count = 0; |
1040 | gpe_enabled_count = 0; | 1038 | gpe_enabled_count = 0; |
@@ -1044,14 +1042,13 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, | |||
1044 | 1042 | ||
1045 | /* Get the info block for this particular GPE */ | 1043 | /* Get the info block for this particular GPE */ |
1046 | 1044 | ||
1047 | gpe_event_info = | 1045 | gpe_event_info = &gpe_block->event_info[((acpi_size) i * |
1048 | &gpe_block-> | 1046 | ACPI_GPE_REGISTER_WIDTH) |
1049 | event_info[((acpi_size) i * | 1047 | + j]; |
1050 | ACPI_GPE_REGISTER_WIDTH) + j]; | ||
1051 | 1048 | ||
1052 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 1049 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
1053 | ACPI_GPE_DISPATCH_METHOD) | 1050 | ACPI_GPE_DISPATCH_METHOD) && |
1054 | && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) { | 1051 | (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) { |
1055 | gpe_enabled_count++; | 1052 | gpe_enabled_count++; |
1056 | } | 1053 | } |
1057 | 1054 | ||
@@ -1105,8 +1102,8 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1105 | /* | 1102 | /* |
1106 | * Initialize the GPE Block(s) defined in the FADT | 1103 | * Initialize the GPE Block(s) defined in the FADT |
1107 | * | 1104 | * |
1108 | * Why the GPE register block lengths are divided by 2: From the ACPI Spec, | 1105 | * Why the GPE register block lengths are divided by 2: From the ACPI |
1109 | * section "General-Purpose Event Registers", we have: | 1106 | * Spec, section "General-Purpose Event Registers", we have: |
1110 | * | 1107 | * |
1111 | * "Each register block contains two registers of equal length | 1108 | * "Each register block contains two registers of equal length |
1112 | * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the | 1109 | * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the |
@@ -1163,7 +1160,8 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
1163 | if ((register_count0) && | 1160 | if ((register_count0) && |
1164 | (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) { | 1161 | (gpe_number_max >= acpi_gbl_FADT.gpe1_base)) { |
1165 | ACPI_ERROR((AE_INFO, | 1162 | ACPI_ERROR((AE_INFO, |
1166 | "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1", | 1163 | "GPE0 block (GPE 0 to %d) overlaps the GPE1 block " |
1164 | "(GPE %d to %d) - Ignoring GPE1", | ||
1167 | gpe_number_max, acpi_gbl_FADT.gpe1_base, | 1165 | gpe_number_max, acpi_gbl_FADT.gpe1_base, |
1168 | acpi_gbl_FADT.gpe1_base + | 1166 | acpi_gbl_FADT.gpe1_base + |
1169 | ((register_count1 * | 1167 | ((register_count1 * |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 5f893057bcc6..ce224e1eaa89 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -163,10 +163,10 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
163 | * 2) Global device notify handler | 163 | * 2) Global device notify handler |
164 | * 3) Per-device notify handler | 164 | * 3) Per-device notify handler |
165 | */ | 165 | */ |
166 | if ((acpi_gbl_system_notify.handler | 166 | if ((acpi_gbl_system_notify.handler && |
167 | && (notify_value <= ACPI_MAX_SYS_NOTIFY)) | 167 | (notify_value <= ACPI_MAX_SYS_NOTIFY)) || |
168 | || (acpi_gbl_device_notify.handler | 168 | (acpi_gbl_device_notify.handler && |
169 | && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) { | 169 | (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) { |
170 | notify_info = acpi_ut_create_generic_state(); | 170 | notify_info = acpi_ut_create_generic_state(); |
171 | if (!notify_info) { | 171 | if (!notify_info) { |
172 | return (AE_NO_MEMORY); | 172 | return (AE_NO_MEMORY); |
@@ -174,7 +174,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
174 | 174 | ||
175 | if (!handler_obj) { | 175 | if (!handler_obj) { |
176 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 176 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
177 | "Executing system notify handler for Notify (%4.4s, %X) node %p\n", | 177 | "Executing system notify handler for Notify (%4.4s, %X) " |
178 | "node %p\n", | ||
178 | acpi_ut_get_node_name(node), | 179 | acpi_ut_get_node_name(node), |
179 | notify_value, node)); | 180 | notify_value, node)); |
180 | } | 181 | } |
@@ -534,8 +535,9 @@ acpi_status acpi_ev_release_global_lock(void) | |||
534 | */ | 535 | */ |
535 | if (pending) { | 536 | if (pending) { |
536 | status = | 537 | status = |
537 | acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE, | 538 | acpi_write_bit_register |
538 | 1); | 539 | (ACPI_BITREG_GLOBAL_LOCK_RELEASE, |
540 | ACPI_ENABLE_EVENT); | ||
539 | } | 541 | } |
540 | 542 | ||
541 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 543 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 665c0887ab4d..538d63264555 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -691,7 +691,7 @@ acpi_ev_install_handler(acpi_handle obj_handle, | |||
691 | 691 | ||
692 | /* Devices are handled different than regions */ | 692 | /* Devices are handled different than regions */ |
693 | 693 | ||
694 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) { | 694 | if (obj_desc->common.type == ACPI_TYPE_DEVICE) { |
695 | 695 | ||
696 | /* Check if this Device already has a handler for this address space */ | 696 | /* Check if this Device already has a handler for this address space */ |
697 | 697 | ||
@@ -703,7 +703,8 @@ acpi_ev_install_handler(acpi_handle obj_handle, | |||
703 | if (next_handler_obj->address_space.space_id == | 703 | if (next_handler_obj->address_space.space_id == |
704 | handler_obj->address_space.space_id) { | 704 | handler_obj->address_space.space_id) { |
705 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | 705 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, |
706 | "Found handler for region [%s] in device %p(%p) handler %p\n", | 706 | "Found handler for region [%s] in device %p(%p) " |
707 | "handler %p\n", | ||
707 | acpi_ut_get_region_name | 708 | acpi_ut_get_region_name |
708 | (handler_obj->address_space. | 709 | (handler_obj->address_space. |
709 | space_id), obj_desc, | 710 | space_id), obj_desc, |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index f3f1fb45c3dc..284a7becbe96 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -241,7 +241,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
241 | status = AE_OK; | 241 | status = AE_OK; |
242 | } else { | 242 | } else { |
243 | ACPI_EXCEPTION((AE_INFO, status, | 243 | ACPI_EXCEPTION((AE_INFO, status, |
244 | "Could not install PciConfig handler for Root Bridge %4.4s", | 244 | "Could not install PciConfig handler " |
245 | "for Root Bridge %4.4s", | ||
245 | acpi_ut_get_node_name | 246 | acpi_ut_get_node_name |
246 | (pci_root_node))); | 247 | (pci_root_node))); |
247 | } | 248 | } |
@@ -293,9 +294,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
293 | * Get the PCI device and function numbers from the _ADR object contained | 294 | * Get the PCI device and function numbers from the _ADR object contained |
294 | * in the parent's scope. | 295 | * in the parent's scope. |
295 | */ | 296 | */ |
296 | status = | 297 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, |
297 | acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node, | 298 | pci_device_node, &pci_value); |
298 | &pci_value); | ||
299 | 299 | ||
300 | /* | 300 | /* |
301 | * The default is zero, and since the allocation above zeroed the data, | 301 | * The default is zero, and since the allocation above zeroed the data, |
@@ -308,18 +308,16 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
308 | 308 | ||
309 | /* The PCI segment number comes from the _SEG method */ | 309 | /* The PCI segment number comes from the _SEG method */ |
310 | 310 | ||
311 | status = | 311 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, |
312 | acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node, | 312 | pci_root_node, &pci_value); |
313 | &pci_value); | ||
314 | if (ACPI_SUCCESS(status)) { | 313 | if (ACPI_SUCCESS(status)) { |
315 | pci_id->segment = ACPI_LOWORD(pci_value); | 314 | pci_id->segment = ACPI_LOWORD(pci_value); |
316 | } | 315 | } |
317 | 316 | ||
318 | /* The PCI bus number comes from the _BBN method */ | 317 | /* The PCI bus number comes from the _BBN method */ |
319 | 318 | ||
320 | status = | 319 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, |
321 | acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node, | 320 | pci_root_node, &pci_value); |
322 | &pci_value); | ||
323 | if (ACPI_SUCCESS(status)) { | 321 | if (ACPI_SUCCESS(status)) { |
324 | pci_id->bus = ACPI_LOWORD(pci_value); | 322 | pci_id->bus = ACPI_LOWORD(pci_value); |
325 | } | 323 | } |
@@ -632,8 +630,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
632 | acpi_ns_locked); | 630 | acpi_ns_locked); |
633 | 631 | ||
634 | /* | 632 | /* |
635 | * Tell all users that this region is usable by running the _REG | 633 | * Tell all users that this region is usable by |
636 | * method | 634 | * running the _REG method |
637 | */ | 635 | */ |
638 | if (acpi_ns_locked) { | 636 | if (acpi_ns_locked) { |
639 | status = | 637 | status = |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 3aca9010a11e..10b8543dd466 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -631,7 +631,8 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
631 | 631 | ||
632 | /* Setup up dispatch flags to indicate handler (vs. method) */ | 632 | /* Setup up dispatch flags to indicate handler (vs. method) */ |
633 | 633 | ||
634 | gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */ | 634 | gpe_event_info->flags &= |
635 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | ||
635 | gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER); | 636 | gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER); |
636 | 637 | ||
637 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 638 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 35485e4b60a6..d0a080747ec3 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -172,8 +172,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags) | |||
172 | * register bit) | 172 | * register bit) |
173 | */ | 173 | */ |
174 | status = | 174 | status = |
175 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | 175 | acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
176 | enable_register_id, 1); | 176 | enable_register_id, ACPI_ENABLE_EVENT); |
177 | if (ACPI_FAILURE(status)) { | 177 | if (ACPI_FAILURE(status)) { |
178 | return_ACPI_STATUS(status); | 178 | return_ACPI_STATUS(status); |
179 | } | 179 | } |
@@ -181,8 +181,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags) | |||
181 | /* Make sure that the hardware responded */ | 181 | /* Make sure that the hardware responded */ |
182 | 182 | ||
183 | status = | 183 | status = |
184 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 184 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
185 | enable_register_id, &value); | 185 | enable_register_id, &value); |
186 | if (ACPI_FAILURE(status)) { | 186 | if (ACPI_FAILURE(status)) { |
187 | return_ACPI_STATUS(status); | 187 | return_ACPI_STATUS(status); |
188 | } | 188 | } |
@@ -354,15 +354,15 @@ acpi_status acpi_disable_event(u32 event, u32 flags) | |||
354 | * register bit) | 354 | * register bit) |
355 | */ | 355 | */ |
356 | status = | 356 | status = |
357 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | 357 | acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
358 | enable_register_id, 0); | 358 | enable_register_id, ACPI_DISABLE_EVENT); |
359 | if (ACPI_FAILURE(status)) { | 359 | if (ACPI_FAILURE(status)) { |
360 | return_ACPI_STATUS(status); | 360 | return_ACPI_STATUS(status); |
361 | } | 361 | } |
362 | 362 | ||
363 | status = | 363 | status = |
364 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 364 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
365 | enable_register_id, &value); | 365 | enable_register_id, &value); |
366 | if (ACPI_FAILURE(status)) { | 366 | if (ACPI_FAILURE(status)) { |
367 | return_ACPI_STATUS(status); | 367 | return_ACPI_STATUS(status); |
368 | } | 368 | } |
@@ -407,8 +407,8 @@ acpi_status acpi_clear_event(u32 event) | |||
407 | * register bit) | 407 | * register bit) |
408 | */ | 408 | */ |
409 | status = | 409 | status = |
410 | acpi_set_register(acpi_gbl_fixed_event_info[event]. | 410 | acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
411 | status_register_id, 1); | 411 | status_register_id, ACPI_CLEAR_STATUS); |
412 | 412 | ||
413 | return_ACPI_STATUS(status); | 413 | return_ACPI_STATUS(status); |
414 | } | 414 | } |
@@ -495,7 +495,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
495 | /* Get the status of the requested fixed event */ | 495 | /* Get the status of the requested fixed event */ |
496 | 496 | ||
497 | status = | 497 | status = |
498 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 498 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
499 | enable_register_id, &value); | 499 | enable_register_id, &value); |
500 | if (ACPI_FAILURE(status)) | 500 | if (ACPI_FAILURE(status)) |
501 | return_ACPI_STATUS(status); | 501 | return_ACPI_STATUS(status); |
@@ -503,7 +503,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
503 | *event_status = value; | 503 | *event_status = value; |
504 | 504 | ||
505 | status = | 505 | status = |
506 | acpi_get_register(acpi_gbl_fixed_event_info[event]. | 506 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
507 | status_register_id, &value); | 507 | status_register_id, &value); |
508 | if (ACPI_FAILURE(status)) | 508 | if (ACPI_FAILURE(status)) |
509 | return_ACPI_STATUS(status); | 509 | return_ACPI_STATUS(status); |
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 479e7a3721be..7c3d2d356ffb 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -193,7 +193,8 @@ acpi_remove_address_space_handler(acpi_handle device, | |||
193 | /* Matched space_id, first dereference this in the Regions */ | 193 | /* Matched space_id, first dereference this in the Regions */ |
194 | 194 | ||
195 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | 195 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, |
196 | "Removing address handler %p(%p) for region %s on Device %p(%p)\n", | 196 | "Removing address handler %p(%p) for region %s " |
197 | "on Device %p(%p)\n", | ||
197 | handler_obj, handler, | 198 | handler_obj, handler, |
198 | acpi_ut_get_region_name(space_id), | 199 | acpi_ut_get_region_name(space_id), |
199 | node, obj_desc)); | 200 | node, obj_desc)); |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 932bbc26aa04..3deb20a126b2 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -291,7 +291,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
291 | 291 | ||
292 | /* Source Object can be either an op_region or a Buffer/Field */ | 292 | /* Source Object can be either an op_region or a Buffer/Field */ |
293 | 293 | ||
294 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 294 | switch (obj_desc->common.type) { |
295 | case ACPI_TYPE_REGION: | 295 | case ACPI_TYPE_REGION: |
296 | 296 | ||
297 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 297 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
@@ -501,7 +501,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
501 | */ | 501 | */ |
502 | if ((!ddb_handle) || | 502 | if ((!ddb_handle) || |
503 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || | 503 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || |
504 | (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) { | 504 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { |
505 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 505 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
506 | } | 506 | } |
507 | 507 | ||
@@ -520,13 +520,14 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
520 | } | 520 | } |
521 | } | 521 | } |
522 | 522 | ||
523 | /* | 523 | /* Delete the portion of the namespace owned by this table */ |
524 | * Delete the entire namespace under this table Node | 524 | |
525 | * (Offset contains the table_id) | 525 | status = acpi_tb_delete_namespace_by_owner(table_index); |
526 | */ | 526 | if (ACPI_FAILURE(status)) { |
527 | acpi_tb_delete_namespace_by_owner(table_index); | 527 | return_ACPI_STATUS(status); |
528 | (void)acpi_tb_release_owner_id(table_index); | 528 | } |
529 | 529 | ||
530 | (void)acpi_tb_release_owner_id(table_index); | ||
530 | acpi_tb_set_table_loaded_flag(table_index, FALSE); | 531 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
531 | 532 | ||
532 | /* Table unloaded, remove a reference to the ddb_handle object */ | 533 | /* Table unloaded, remove a reference to the ddb_handle object */ |
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index 0be10188316e..37d0d39e60a6 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c | |||
@@ -82,7 +82,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
82 | 82 | ||
83 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc); | 83 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc); |
84 | 84 | ||
85 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 85 | switch (obj_desc->common.type) { |
86 | case ACPI_TYPE_INTEGER: | 86 | case ACPI_TYPE_INTEGER: |
87 | 87 | ||
88 | /* No conversion necessary */ | 88 | /* No conversion necessary */ |
@@ -116,7 +116,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, | |||
116 | 116 | ||
117 | /* String conversion is different than Buffer conversion */ | 117 | /* String conversion is different than Buffer conversion */ |
118 | 118 | ||
119 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 119 | switch (obj_desc->common.type) { |
120 | case ACPI_TYPE_STRING: | 120 | case ACPI_TYPE_STRING: |
121 | 121 | ||
122 | /* | 122 | /* |
@@ -206,7 +206,7 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc, | |||
206 | 206 | ||
207 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc); | 207 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc); |
208 | 208 | ||
209 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 209 | switch (obj_desc->common.type) { |
210 | case ACPI_TYPE_BUFFER: | 210 | case ACPI_TYPE_BUFFER: |
211 | 211 | ||
212 | /* No conversion necessary */ | 212 | /* No conversion necessary */ |
@@ -409,7 +409,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, | |||
409 | 409 | ||
410 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc); | 410 | ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc); |
411 | 411 | ||
412 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 412 | switch (obj_desc->common.type) { |
413 | case ACPI_TYPE_STRING: | 413 | case ACPI_TYPE_STRING: |
414 | 414 | ||
415 | /* No conversion necessary */ | 415 | /* No conversion necessary */ |
@@ -605,8 +605,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, | |||
605 | default: | 605 | default: |
606 | /* No conversion allowed for these types */ | 606 | /* No conversion allowed for these types */ |
607 | 607 | ||
608 | if (destination_type != | 608 | if (destination_type != source_desc->common.type) { |
609 | ACPI_GET_OBJECT_TYPE(source_desc)) { | ||
610 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 609 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
611 | "Explicit operator, will store (%s) over existing type (%s)\n", | 610 | "Explicit operator, will store (%s) over existing type (%s)\n", |
612 | acpi_ut_get_object_type_name | 611 | acpi_ut_get_object_type_name |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index aa313574b0df..89d141fdae0b 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -350,6 +350,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
350 | break; | 350 | break; |
351 | 351 | ||
352 | case ACPI_EXD_TYPE: | 352 | case ACPI_EXD_TYPE: |
353 | |||
353 | acpi_ex_out_string("Type", | 354 | acpi_ex_out_string("Type", |
354 | acpi_ut_get_object_type_name | 355 | acpi_ut_get_object_type_name |
355 | (obj_desc)); | 356 | (obj_desc)); |
@@ -422,6 +423,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
422 | break; | 423 | break; |
423 | 424 | ||
424 | default: | 425 | default: |
426 | |||
425 | acpi_os_printf("**** Invalid table opcode [%X] ****\n", | 427 | acpi_os_printf("**** Invalid table opcode [%X] ****\n", |
426 | info->opcode); | 428 | info->opcode); |
427 | return; | 429 | return; |
@@ -492,7 +494,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
492 | 494 | ||
493 | /* Decode object type */ | 495 | /* Decode object type */ |
494 | 496 | ||
495 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 497 | switch (obj_desc->common.type) { |
496 | case ACPI_TYPE_LOCAL_REFERENCE: | 498 | case ACPI_TYPE_LOCAL_REFERENCE: |
497 | 499 | ||
498 | acpi_os_printf("Reference: [%s] ", | 500 | acpi_os_printf("Reference: [%s] ", |
@@ -527,44 +529,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
527 | type)); | 529 | type)); |
528 | break; | 530 | break; |
529 | 531 | ||
530 | case ACPI_REFCLASS_ARG: | 532 | case ACPI_REFCLASS_NAME: |
531 | |||
532 | acpi_os_printf("%X", obj_desc->reference.value); | ||
533 | |||
534 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | ||
535 | |||
536 | /* Value is an Integer */ | ||
537 | |||
538 | acpi_os_printf(" value is [%8.8X%8.8x]", | ||
539 | ACPI_FORMAT_UINT64(obj_desc-> | ||
540 | integer. | ||
541 | value)); | ||
542 | } | ||
543 | 533 | ||
544 | acpi_os_printf("\n"); | 534 | acpi_os_printf("- [%4.4s]\n", |
535 | obj_desc->reference.node->name.ascii); | ||
545 | break; | 536 | break; |
546 | 537 | ||
538 | case ACPI_REFCLASS_ARG: | ||
547 | case ACPI_REFCLASS_LOCAL: | 539 | case ACPI_REFCLASS_LOCAL: |
548 | 540 | ||
549 | acpi_os_printf("%X", obj_desc->reference.value); | 541 | acpi_os_printf("%X\n", obj_desc->reference.value); |
550 | |||
551 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | ||
552 | |||
553 | /* Value is an Integer */ | ||
554 | |||
555 | acpi_os_printf(" value is [%8.8X%8.8x]", | ||
556 | ACPI_FORMAT_UINT64(obj_desc-> | ||
557 | integer. | ||
558 | value)); | ||
559 | } | ||
560 | |||
561 | acpi_os_printf("\n"); | ||
562 | break; | ||
563 | |||
564 | case ACPI_REFCLASS_NAME: | ||
565 | |||
566 | acpi_os_printf("- [%4.4s]\n", | ||
567 | obj_desc->reference.node->name.ascii); | ||
568 | break; | 542 | break; |
569 | 543 | ||
570 | default: /* Unknown reference class */ | 544 | default: /* Unknown reference class */ |
@@ -661,8 +635,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
661 | case ACPI_TYPE_LOCAL_REGION_FIELD: | 635 | case ACPI_TYPE_LOCAL_REGION_FIELD: |
662 | 636 | ||
663 | acpi_os_printf | 637 | acpi_os_printf |
664 | ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n", | 638 | ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at " |
665 | obj_desc->field.bit_length, | 639 | "byte=%X bit=%X of below:\n", obj_desc->field.bit_length, |
666 | obj_desc->field.access_byte_width, | 640 | obj_desc->field.access_byte_width, |
667 | obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, | 641 | obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK, |
668 | obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK, | 642 | obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK, |
@@ -686,9 +660,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
686 | 660 | ||
687 | if (!obj_desc->buffer_field.buffer_obj) { | 661 | if (!obj_desc->buffer_field.buffer_obj) { |
688 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n")); | 662 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n")); |
689 | } else | 663 | } else if ((obj_desc->buffer_field.buffer_obj)->common.type != |
690 | if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj) | 664 | ACPI_TYPE_BUFFER) { |
691 | != ACPI_TYPE_BUFFER) { | ||
692 | acpi_os_printf("*not a Buffer*\n"); | 665 | acpi_os_printf("*not a Buffer*\n"); |
693 | } else { | 666 | } else { |
694 | acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj, | 667 | acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj, |
@@ -737,8 +710,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) | |||
737 | default: | 710 | default: |
738 | /* Unknown Type */ | 711 | /* Unknown Type */ |
739 | 712 | ||
740 | acpi_os_printf("Unknown Type %X\n", | 713 | acpi_os_printf("Unknown Type %X\n", obj_desc->common.type); |
741 | ACPI_GET_OBJECT_TYPE(obj_desc)); | ||
742 | break; | 714 | break; |
743 | } | 715 | } |
744 | 716 | ||
@@ -939,7 +911,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, | |||
939 | 911 | ||
940 | /* Packages may only contain a few object types */ | 912 | /* Packages may only contain a few object types */ |
941 | 913 | ||
942 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 914 | switch (obj_desc->common.type) { |
943 | case ACPI_TYPE_INTEGER: | 915 | case ACPI_TYPE_INTEGER: |
944 | 916 | ||
945 | acpi_os_printf("[Integer] = %8.8X%8.8X\n", | 917 | acpi_os_printf("[Integer] = %8.8X%8.8X\n", |
@@ -990,8 +962,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, | |||
990 | 962 | ||
991 | default: | 963 | default: |
992 | 964 | ||
993 | acpi_os_printf("[Unknown Type] %X\n", | 965 | acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type); |
994 | ACPI_GET_OBJECT_TYPE(obj_desc)); | ||
995 | break; | 966 | break; |
996 | } | 967 | } |
997 | } | 968 | } |
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index a352d0233857..546dcdd86785 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -84,7 +84,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
84 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 84 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
85 | } | 85 | } |
86 | 86 | ||
87 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) { | 87 | if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) { |
88 | /* | 88 | /* |
89 | * If the buffer_field arguments have not been previously evaluated, | 89 | * If the buffer_field arguments have not been previously evaluated, |
90 | * evaluate them now and save the results. | 90 | * evaluate them now and save the results. |
@@ -95,9 +95,8 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
95 | return_ACPI_STATUS(status); | 95 | return_ACPI_STATUS(status); |
96 | } | 96 | } |
97 | } | 97 | } |
98 | } else | 98 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
99 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) | 99 | (obj_desc->field.region_obj->region.space_id == |
100 | && (obj_desc->field.region_obj->region.space_id == | ||
101 | ACPI_ADR_SPACE_SMBUS)) { | 100 | ACPI_ADR_SPACE_SMBUS)) { |
102 | /* | 101 | /* |
103 | * This is an SMBus read. We must create a buffer to hold the data | 102 | * This is an SMBus read. We must create a buffer to hold the data |
@@ -163,7 +162,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
163 | 162 | ||
164 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 163 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
165 | "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n", | 164 | "FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n", |
166 | obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer, | 165 | obj_desc, obj_desc->common.type, buffer, |
167 | (u32) length)); | 166 | (u32) length)); |
168 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 167 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
169 | "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n", | 168 | "FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n", |
@@ -222,7 +221,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
222 | return_ACPI_STATUS(AE_AML_NO_OPERAND); | 221 | return_ACPI_STATUS(AE_AML_NO_OPERAND); |
223 | } | 222 | } |
224 | 223 | ||
225 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) { | 224 | if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) { |
226 | /* | 225 | /* |
227 | * If the buffer_field arguments have not been previously evaluated, | 226 | * If the buffer_field arguments have not been previously evaluated, |
228 | * evaluate them now and save the results. | 227 | * evaluate them now and save the results. |
@@ -233,9 +232,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
233 | return_ACPI_STATUS(status); | 232 | return_ACPI_STATUS(status); |
234 | } | 233 | } |
235 | } | 234 | } |
236 | } else | 235 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
237 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD) | 236 | (obj_desc->field.region_obj->region.space_id == |
238 | && (obj_desc->field.region_obj->region.space_id == | ||
239 | ACPI_ADR_SPACE_SMBUS)) { | 237 | ACPI_ADR_SPACE_SMBUS)) { |
240 | /* | 238 | /* |
241 | * This is an SMBus write. We will bypass the entire field mechanism | 239 | * This is an SMBus write. We will bypass the entire field mechanism |
@@ -243,7 +241,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
243 | * | 241 | * |
244 | * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). | 242 | * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). |
245 | */ | 243 | */ |
246 | if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) { | 244 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { |
247 | ACPI_ERROR((AE_INFO, | 245 | ACPI_ERROR((AE_INFO, |
248 | "SMBus write requires Buffer, found type %s", | 246 | "SMBus write requires Buffer, found type %s", |
249 | acpi_ut_get_object_type_name(source_desc))); | 247 | acpi_ut_get_object_type_name(source_desc))); |
@@ -291,7 +289,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
291 | 289 | ||
292 | /* Get a pointer to the data to be written */ | 290 | /* Get a pointer to the data to be written */ |
293 | 291 | ||
294 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { | 292 | switch (source_desc->common.type) { |
295 | case ACPI_TYPE_INTEGER: | 293 | case ACPI_TYPE_INTEGER: |
296 | buffer = &source_desc->integer.value; | 294 | buffer = &source_desc->integer.value; |
297 | length = sizeof(source_desc->integer.value); | 295 | length = sizeof(source_desc->integer.value); |
@@ -314,15 +312,14 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
314 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 312 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
315 | "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", | 313 | "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", |
316 | source_desc, | 314 | source_desc, |
317 | acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE | 315 | acpi_ut_get_type_name(source_desc->common.type), |
318 | (source_desc)), | 316 | source_desc->common.type, buffer, length)); |
319 | ACPI_GET_OBJECT_TYPE(source_desc), buffer, length)); | ||
320 | 317 | ||
321 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 318 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
322 | "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n", | 319 | "FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n", |
323 | obj_desc, | 320 | obj_desc, |
324 | acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)), | 321 | acpi_ut_get_type_name(obj_desc->common.type), |
325 | ACPI_GET_OBJECT_TYPE(obj_desc), | 322 | obj_desc->common.type, |
326 | obj_desc->common_field.bit_length, | 323 | obj_desc->common_field.bit_length, |
327 | obj_desc->common_field.start_field_bit_offset, | 324 | obj_desc->common_field.start_field_bit_offset, |
328 | obj_desc->common_field.base_byte_offset)); | 325 | obj_desc->common_field.base_byte_offset)); |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index ef58ac4e687b..99cee61e655d 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -94,9 +94,9 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
94 | 94 | ||
95 | /* We must have a valid region */ | 95 | /* We must have a valid region */ |
96 | 96 | ||
97 | if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) { | 97 | if (rgn_desc->common.type != ACPI_TYPE_REGION) { |
98 | ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)", | 98 | ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)", |
99 | ACPI_GET_OBJECT_TYPE(rgn_desc), | 99 | rgn_desc->common.type, |
100 | acpi_ut_get_object_type_name(rgn_desc))); | 100 | acpi_ut_get_object_type_name(rgn_desc))); |
101 | 101 | ||
102 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 102 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
@@ -113,12 +113,6 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Exit if Address/Length have been disallowed by the host OS */ | ||
117 | |||
118 | if (rgn_desc->common.flags & AOPOBJ_INVALID) { | ||
119 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | ||
120 | } | ||
121 | |||
122 | /* | 116 | /* |
123 | * Exit now for SMBus address space, it has a non-linear address space | 117 | * Exit now for SMBus address space, it has a non-linear address space |
124 | * and the request cannot be directly validated | 118 | * and the request cannot be directly validated |
@@ -390,7 +384,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, | |||
390 | * index_field - Write to an Index Register, then read/write from/to a | 384 | * index_field - Write to an Index Register, then read/write from/to a |
391 | * Data Register | 385 | * Data Register |
392 | */ | 386 | */ |
393 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 387 | switch (obj_desc->common.type) { |
394 | case ACPI_TYPE_BUFFER_FIELD: | 388 | case ACPI_TYPE_BUFFER_FIELD: |
395 | /* | 389 | /* |
396 | * If the buffer_field arguments have not been previously evaluated, | 390 | * If the buffer_field arguments have not been previously evaluated, |
@@ -527,7 +521,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, | |||
527 | default: | 521 | default: |
528 | 522 | ||
529 | ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X", | 523 | ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X", |
530 | ACPI_GET_OBJECT_TYPE(obj_desc))); | 524 | obj_desc->common.type)); |
531 | status = AE_AML_INTERNAL; | 525 | status = AE_AML_INTERNAL; |
532 | break; | 526 | break; |
533 | } | 527 | } |
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 6b0747ac683b..998eac329937 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c | |||
@@ -80,7 +80,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, | |||
80 | switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { | 80 | switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { |
81 | case ACPI_DESC_TYPE_OPERAND: | 81 | case ACPI_DESC_TYPE_OPERAND: |
82 | 82 | ||
83 | if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) { | 83 | if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) { |
84 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 84 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
85 | } | 85 | } |
86 | 86 | ||
@@ -260,7 +260,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
260 | * guaranteed to be either Integer/String/Buffer by the operand | 260 | * guaranteed to be either Integer/String/Buffer by the operand |
261 | * resolution mechanism. | 261 | * resolution mechanism. |
262 | */ | 262 | */ |
263 | switch (ACPI_GET_OBJECT_TYPE(operand0)) { | 263 | switch (operand0->common.type) { |
264 | case ACPI_TYPE_INTEGER: | 264 | case ACPI_TYPE_INTEGER: |
265 | status = | 265 | status = |
266 | acpi_ex_convert_to_integer(operand1, &local_operand1, 16); | 266 | acpi_ex_convert_to_integer(operand1, &local_operand1, 16); |
@@ -277,7 +277,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
277 | 277 | ||
278 | default: | 278 | default: |
279 | ACPI_ERROR((AE_INFO, "Invalid object type: %X", | 279 | ACPI_ERROR((AE_INFO, "Invalid object type: %X", |
280 | ACPI_GET_OBJECT_TYPE(operand0))); | 280 | operand0->common.type)); |
281 | status = AE_AML_INTERNAL; | 281 | status = AE_AML_INTERNAL; |
282 | } | 282 | } |
283 | 283 | ||
@@ -298,7 +298,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
298 | * 2) Two Strings concatenated to produce a new String | 298 | * 2) Two Strings concatenated to produce a new String |
299 | * 3) Two Buffers concatenated to produce a new Buffer | 299 | * 3) Two Buffers concatenated to produce a new Buffer |
300 | */ | 300 | */ |
301 | switch (ACPI_GET_OBJECT_TYPE(operand0)) { | 301 | switch (operand0->common.type) { |
302 | case ACPI_TYPE_INTEGER: | 302 | case ACPI_TYPE_INTEGER: |
303 | 303 | ||
304 | /* Result of two Integers is a Buffer */ | 304 | /* Result of two Integers is a Buffer */ |
@@ -379,7 +379,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
379 | /* Invalid object type, should not happen here */ | 379 | /* Invalid object type, should not happen here */ |
380 | 380 | ||
381 | ACPI_ERROR((AE_INFO, "Invalid object type: %X", | 381 | ACPI_ERROR((AE_INFO, "Invalid object type: %X", |
382 | ACPI_GET_OBJECT_TYPE(operand0))); | 382 | operand0->common.type)); |
383 | status = AE_AML_INTERNAL; | 383 | status = AE_AML_INTERNAL; |
384 | goto cleanup; | 384 | goto cleanup; |
385 | } | 385 | } |
@@ -581,7 +581,7 @@ acpi_ex_do_logical_op(u16 opcode, | |||
581 | * guaranteed to be either Integer/String/Buffer by the operand | 581 | * guaranteed to be either Integer/String/Buffer by the operand |
582 | * resolution mechanism. | 582 | * resolution mechanism. |
583 | */ | 583 | */ |
584 | switch (ACPI_GET_OBJECT_TYPE(operand0)) { | 584 | switch (operand0->common.type) { |
585 | case ACPI_TYPE_INTEGER: | 585 | case ACPI_TYPE_INTEGER: |
586 | status = | 586 | status = |
587 | acpi_ex_convert_to_integer(operand1, &local_operand1, 16); | 587 | acpi_ex_convert_to_integer(operand1, &local_operand1, 16); |
@@ -608,7 +608,7 @@ acpi_ex_do_logical_op(u16 opcode, | |||
608 | /* | 608 | /* |
609 | * Two cases: 1) Both Integers, 2) Both Strings or Buffers | 609 | * Two cases: 1) Both Integers, 2) Both Strings or Buffers |
610 | */ | 610 | */ |
611 | if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) { | 611 | if (operand0->common.type == ACPI_TYPE_INTEGER) { |
612 | /* | 612 | /* |
613 | * 1) Both operands are of type integer | 613 | * 1) Both operands are of type integer |
614 | * Note: local_operand1 may have changed above | 614 | * Note: local_operand1 may have changed above |
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index b530480cc7d5..9635d21e568d 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c | |||
@@ -807,11 +807,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
807 | acpi_namespace_node *) | 807 | acpi_namespace_node *) |
808 | operand[0]); | 808 | operand[0]); |
809 | if (temp_desc | 809 | if (temp_desc |
810 | && | 810 | && ((temp_desc->common.type == ACPI_TYPE_STRING) |
811 | ((ACPI_GET_OBJECT_TYPE(temp_desc) == | 811 | || (temp_desc->common.type == |
812 | ACPI_TYPE_STRING) | 812 | ACPI_TYPE_LOCAL_REFERENCE))) { |
813 | || (ACPI_GET_OBJECT_TYPE(temp_desc) == | ||
814 | ACPI_TYPE_LOCAL_REFERENCE))) { | ||
815 | operand[0] = temp_desc; | 813 | operand[0] = temp_desc; |
816 | acpi_ut_add_reference(temp_desc); | 814 | acpi_ut_add_reference(temp_desc); |
817 | } else { | 815 | } else { |
@@ -819,7 +817,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
819 | goto cleanup; | 817 | goto cleanup; |
820 | } | 818 | } |
821 | } else { | 819 | } else { |
822 | switch (ACPI_GET_OBJECT_TYPE(operand[0])) { | 820 | switch ((operand[0])->common.type) { |
823 | case ACPI_TYPE_LOCAL_REFERENCE: | 821 | case ACPI_TYPE_LOCAL_REFERENCE: |
824 | /* | 822 | /* |
825 | * This is a deref_of (local_x | arg_x) | 823 | * This is a deref_of (local_x | arg_x) |
@@ -877,8 +875,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
877 | 875 | ||
878 | if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) != | 876 | if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) != |
879 | ACPI_DESC_TYPE_NAMED) { | 877 | ACPI_DESC_TYPE_NAMED) { |
880 | if (ACPI_GET_OBJECT_TYPE(operand[0]) == | 878 | if ((operand[0])->common.type == ACPI_TYPE_STRING) { |
881 | ACPI_TYPE_STRING) { | ||
882 | /* | 879 | /* |
883 | * This is a deref_of (String). The string is a reference | 880 | * This is a deref_of (String). The string is a reference |
884 | * to a named ACPI object. | 881 | * to a named ACPI object. |
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 0b4f513ca885..85d95c92dfd3 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c | |||
@@ -399,7 +399,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
399 | * At this point, the Source operand is a String, Buffer, or Package. | 399 | * At this point, the Source operand is a String, Buffer, or Package. |
400 | * Verify that the index is within range. | 400 | * Verify that the index is within range. |
401 | */ | 401 | */ |
402 | switch (ACPI_GET_OBJECT_TYPE(operand[0])) { | 402 | switch ((operand[0])->common.type) { |
403 | case ACPI_TYPE_STRING: | 403 | case ACPI_TYPE_STRING: |
404 | 404 | ||
405 | if (index >= operand[0]->string.length) { | 405 | if (index >= operand[0]->string.length) { |
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index c6520bbf882b..253f9e122584 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c | |||
@@ -161,9 +161,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) | |||
161 | * Create the return object. The Source operand is guaranteed to be | 161 | * Create the return object. The Source operand is guaranteed to be |
162 | * either a String or a Buffer, so just use its type. | 162 | * either a String or a Buffer, so just use its type. |
163 | */ | 163 | */ |
164 | return_desc = | 164 | return_desc = acpi_ut_create_internal_object((operand[0])-> |
165 | acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE | 165 | common.type); |
166 | (operand[0])); | ||
167 | if (!return_desc) { | 166 | if (!return_desc) { |
168 | status = AE_NO_MEMORY; | 167 | status = AE_NO_MEMORY; |
169 | goto cleanup; | 168 | goto cleanup; |
@@ -191,7 +190,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) | |||
191 | 190 | ||
192 | /* Strings always have a sub-pointer, not so for buffers */ | 191 | /* Strings always have a sub-pointer, not so for buffers */ |
193 | 192 | ||
194 | switch (ACPI_GET_OBJECT_TYPE(operand[0])) { | 193 | switch ((operand[0])->common.type) { |
195 | case ACPI_TYPE_STRING: | 194 | case ACPI_TYPE_STRING: |
196 | 195 | ||
197 | /* Always allocate a new buffer for the String */ | 196 | /* Always allocate a new buffer for the String */ |
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index a226f74d4a5c..52fec07064f0 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c | |||
@@ -279,7 +279,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, | |||
279 | return_UINT32(0); | 279 | return_UINT32(0); |
280 | } | 280 | } |
281 | 281 | ||
282 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) { | 282 | if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) { |
283 | /* | 283 | /* |
284 | * buffer_field access can be on any byte boundary, so the | 284 | * buffer_field access can be on any byte boundary, so the |
285 | * byte_alignment is always 1 byte -- regardless of any byte_alignment | 285 | * byte_alignment is always 1 byte -- regardless of any byte_alignment |
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 76ec8ff903b8..3a54b737d2da 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c | |||
@@ -294,14 +294,14 @@ acpi_ex_system_io_space_handler(u32 function, | |||
294 | switch (function) { | 294 | switch (function) { |
295 | case ACPI_READ: | 295 | case ACPI_READ: |
296 | 296 | ||
297 | status = acpi_os_read_port((acpi_io_address) address, | 297 | status = acpi_hw_read_port((acpi_io_address) address, |
298 | &value32, bit_width); | 298 | &value32, bit_width); |
299 | *value = value32; | 299 | *value = value32; |
300 | break; | 300 | break; |
301 | 301 | ||
302 | case ACPI_WRITE: | 302 | case ACPI_WRITE: |
303 | 303 | ||
304 | status = acpi_os_write_port((acpi_io_address) address, | 304 | status = acpi_hw_write_port((acpi_io_address) address, |
305 | (u32) * value, bit_width); | 305 | (u32) * value, bit_width); |
306 | break; | 306 | break; |
307 | 307 | ||
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index a063a74006f6..607958ff467c 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c | |||
@@ -136,7 +136,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
136 | switch (entry_type) { | 136 | switch (entry_type) { |
137 | case ACPI_TYPE_PACKAGE: | 137 | case ACPI_TYPE_PACKAGE: |
138 | 138 | ||
139 | if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) { | 139 | if (source_desc->common.type != ACPI_TYPE_PACKAGE) { |
140 | ACPI_ERROR((AE_INFO, "Object not a Package, type %s", | 140 | ACPI_ERROR((AE_INFO, "Object not a Package, type %s", |
141 | acpi_ut_get_object_type_name(source_desc))); | 141 | acpi_ut_get_object_type_name(source_desc))); |
142 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 142 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
@@ -154,7 +154,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
154 | 154 | ||
155 | case ACPI_TYPE_BUFFER: | 155 | case ACPI_TYPE_BUFFER: |
156 | 156 | ||
157 | if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) { | 157 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { |
158 | ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s", | 158 | ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s", |
159 | acpi_ut_get_object_type_name(source_desc))); | 159 | acpi_ut_get_object_type_name(source_desc))); |
160 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 160 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
@@ -172,7 +172,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
172 | 172 | ||
173 | case ACPI_TYPE_STRING: | 173 | case ACPI_TYPE_STRING: |
174 | 174 | ||
175 | if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) { | 175 | if (source_desc->common.type != ACPI_TYPE_STRING) { |
176 | ACPI_ERROR((AE_INFO, "Object not a String, type %s", | 176 | ACPI_ERROR((AE_INFO, "Object not a String, type %s", |
177 | acpi_ut_get_object_type_name(source_desc))); | 177 | acpi_ut_get_object_type_name(source_desc))); |
178 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 178 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
@@ -186,7 +186,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, | |||
186 | 186 | ||
187 | case ACPI_TYPE_INTEGER: | 187 | case ACPI_TYPE_INTEGER: |
188 | 188 | ||
189 | if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) { | 189 | if (source_desc->common.type != ACPI_TYPE_INTEGER) { |
190 | ACPI_ERROR((AE_INFO, "Object not a Integer, type %s", | 190 | ACPI_ERROR((AE_INFO, "Object not a Integer, type %s", |
191 | acpi_ut_get_object_type_name(source_desc))); | 191 | acpi_ut_get_object_type_name(source_desc))); |
192 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 192 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index f6105a6d6126..c93b54ce7f78 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c | |||
@@ -149,7 +149,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
149 | 149 | ||
150 | /* This is a union acpi_operand_object */ | 150 | /* This is a union acpi_operand_object */ |
151 | 151 | ||
152 | switch (ACPI_GET_OBJECT_TYPE(stack_desc)) { | 152 | switch (stack_desc->common.type) { |
153 | case ACPI_TYPE_LOCAL_REFERENCE: | 153 | case ACPI_TYPE_LOCAL_REFERENCE: |
154 | 154 | ||
155 | ref_type = stack_desc->reference.class; | 155 | ref_type = stack_desc->reference.class; |
@@ -297,8 +297,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, | |||
297 | 297 | ||
298 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 298 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
299 | "FieldRead SourceDesc=%p Type=%X\n", | 299 | "FieldRead SourceDesc=%p Type=%X\n", |
300 | stack_desc, | 300 | stack_desc, stack_desc->common.type)); |
301 | ACPI_GET_OBJECT_TYPE(stack_desc))); | ||
302 | 301 | ||
303 | status = | 302 | status = |
304 | acpi_ex_read_data_from_field(walk_state, stack_desc, | 303 | acpi_ex_read_data_from_field(walk_state, stack_desc, |
@@ -386,7 +385,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
386 | * specification of the object_type and size_of operators). This means | 385 | * specification of the object_type and size_of operators). This means |
387 | * traversing the list of possibly many nested references. | 386 | * traversing the list of possibly many nested references. |
388 | */ | 387 | */ |
389 | while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) { | 388 | while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) { |
390 | switch (obj_desc->reference.class) { | 389 | switch (obj_desc->reference.class) { |
391 | case ACPI_REFCLASS_REFOF: | 390 | case ACPI_REFCLASS_REFOF: |
392 | case ACPI_REFCLASS_NAME: | 391 | case ACPI_REFCLASS_NAME: |
@@ -518,7 +517,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
518 | * Now we are guaranteed to have an object that has not been created | 517 | * Now we are guaranteed to have an object that has not been created |
519 | * via the ref_of or Index operators. | 518 | * via the ref_of or Index operators. |
520 | */ | 519 | */ |
521 | type = ACPI_GET_OBJECT_TYPE(obj_desc); | 520 | type = obj_desc->common.type; |
522 | 521 | ||
523 | exit: | 522 | exit: |
524 | /* Convert internal types to external types */ | 523 | /* Convert internal types to external types */ |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 3c3802764bfb..5c729a9e9131 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -212,7 +212,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
212 | 212 | ||
213 | /* ACPI internal object */ | 213 | /* ACPI internal object */ |
214 | 214 | ||
215 | object_type = ACPI_GET_OBJECT_TYPE(obj_desc); | 215 | object_type = obj_desc->common.type; |
216 | 216 | ||
217 | /* Check for bad acpi_object_type */ | 217 | /* Check for bad acpi_object_type */ |
218 | 218 | ||
@@ -287,8 +287,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
287 | 287 | ||
288 | if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == | 288 | if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == |
289 | ACPI_DESC_TYPE_OPERAND) | 289 | ACPI_DESC_TYPE_OPERAND) |
290 | && (ACPI_GET_OBJECT_TYPE(obj_desc) == | 290 | && (obj_desc->common.type == ACPI_TYPE_STRING)) { |
291 | ACPI_TYPE_STRING)) { | ||
292 | /* | 291 | /* |
293 | * String found - the string references a named object and | 292 | * String found - the string references a named object and |
294 | * must be resolved to a node | 293 | * must be resolved to a node |
@@ -336,7 +335,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
336 | * -- All others must be resolved below. | 335 | * -- All others must be resolved below. |
337 | */ | 336 | */ |
338 | if ((opcode == AML_STORE_OP) && | 337 | if ((opcode == AML_STORE_OP) && |
339 | (ACPI_GET_OBJECT_TYPE(*stack_ptr) == | 338 | ((*stack_ptr)->common.type == |
340 | ACPI_TYPE_LOCAL_REFERENCE) | 339 | ACPI_TYPE_LOCAL_REFERENCE) |
341 | && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) { | 340 | && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) { |
342 | goto next_operand; | 341 | goto next_operand; |
@@ -490,7 +489,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
490 | 489 | ||
491 | /* Need an operand of type INTEGER, STRING or BUFFER */ | 490 | /* Need an operand of type INTEGER, STRING or BUFFER */ |
492 | 491 | ||
493 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 492 | switch (obj_desc->common.type) { |
494 | case ACPI_TYPE_INTEGER: | 493 | case ACPI_TYPE_INTEGER: |
495 | case ACPI_TYPE_STRING: | 494 | case ACPI_TYPE_STRING: |
496 | case ACPI_TYPE_BUFFER: | 495 | case ACPI_TYPE_BUFFER: |
@@ -512,7 +511,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
512 | 511 | ||
513 | /* Need an operand of type STRING or BUFFER */ | 512 | /* Need an operand of type STRING or BUFFER */ |
514 | 513 | ||
515 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 514 | switch (obj_desc->common.type) { |
516 | case ACPI_TYPE_STRING: | 515 | case ACPI_TYPE_STRING: |
517 | case ACPI_TYPE_BUFFER: | 516 | case ACPI_TYPE_BUFFER: |
518 | 517 | ||
@@ -553,7 +552,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
553 | * The only reference allowed here is a direct reference to | 552 | * The only reference allowed here is a direct reference to |
554 | * a namespace node. | 553 | * a namespace node. |
555 | */ | 554 | */ |
556 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 555 | switch (obj_desc->common.type) { |
557 | case ACPI_TYPE_PACKAGE: | 556 | case ACPI_TYPE_PACKAGE: |
558 | case ACPI_TYPE_STRING: | 557 | case ACPI_TYPE_STRING: |
559 | case ACPI_TYPE_BUFFER: | 558 | case ACPI_TYPE_BUFFER: |
@@ -576,7 +575,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
576 | 575 | ||
577 | /* Need a buffer or package or (ACPI 2.0) String */ | 576 | /* Need a buffer or package or (ACPI 2.0) String */ |
578 | 577 | ||
579 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 578 | switch (obj_desc->common.type) { |
580 | case ACPI_TYPE_PACKAGE: | 579 | case ACPI_TYPE_PACKAGE: |
581 | case ACPI_TYPE_STRING: | 580 | case ACPI_TYPE_STRING: |
582 | case ACPI_TYPE_BUFFER: | 581 | case ACPI_TYPE_BUFFER: |
@@ -598,7 +597,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
598 | 597 | ||
599 | /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */ | 598 | /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */ |
600 | 599 | ||
601 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 600 | switch (obj_desc->common.type) { |
602 | case ACPI_TYPE_BUFFER: | 601 | case ACPI_TYPE_BUFFER: |
603 | case ACPI_TYPE_REGION: | 602 | case ACPI_TYPE_REGION: |
604 | 603 | ||
@@ -619,7 +618,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
619 | 618 | ||
620 | /* Used by the Store() operator only */ | 619 | /* Used by the Store() operator only */ |
621 | 620 | ||
622 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 621 | switch (obj_desc->common.type) { |
623 | case ACPI_TYPE_INTEGER: | 622 | case ACPI_TYPE_INTEGER: |
624 | case ACPI_TYPE_PACKAGE: | 623 | case ACPI_TYPE_PACKAGE: |
625 | case ACPI_TYPE_STRING: | 624 | case ACPI_TYPE_STRING: |
@@ -677,8 +676,8 @@ acpi_ex_resolve_operands(u16 opcode, | |||
677 | * required object type (Simple cases only). | 676 | * required object type (Simple cases only). |
678 | */ | 677 | */ |
679 | status = acpi_ex_check_object_type(type_needed, | 678 | status = acpi_ex_check_object_type(type_needed, |
680 | ACPI_GET_OBJECT_TYPE | 679 | (*stack_ptr)->common.type, |
681 | (*stack_ptr), *stack_ptr); | 680 | *stack_ptr); |
682 | if (ACPI_FAILURE(status)) { | 681 | if (ACPI_FAILURE(status)) { |
683 | return_ACPI_STATUS(status); | 682 | return_ACPI_STATUS(status); |
684 | } | 683 | } |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index e35e9b4f6a4e..90d606196c99 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -129,7 +129,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
129 | 129 | ||
130 | /* source_desc is of type ACPI_DESC_TYPE_OPERAND */ | 130 | /* source_desc is of type ACPI_DESC_TYPE_OPERAND */ |
131 | 131 | ||
132 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { | 132 | switch (source_desc->common.type) { |
133 | case ACPI_TYPE_INTEGER: | 133 | case ACPI_TYPE_INTEGER: |
134 | 134 | ||
135 | /* Output correct integer width */ | 135 | /* Output correct integer width */ |
@@ -324,7 +324,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, | |||
324 | 324 | ||
325 | /* Destination object must be a Reference or a Constant object */ | 325 | /* Destination object must be a Reference or a Constant object */ |
326 | 326 | ||
327 | switch (ACPI_GET_OBJECT_TYPE(dest_desc)) { | 327 | switch (dest_desc->common.type) { |
328 | case ACPI_TYPE_LOCAL_REFERENCE: | 328 | case ACPI_TYPE_LOCAL_REFERENCE: |
329 | break; | 329 | break; |
330 | 330 | ||
@@ -460,9 +460,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
460 | */ | 460 | */ |
461 | obj_desc = *(index_desc->reference.where); | 461 | obj_desc = *(index_desc->reference.where); |
462 | 462 | ||
463 | if (ACPI_GET_OBJECT_TYPE(source_desc) == | 463 | if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE && |
464 | ACPI_TYPE_LOCAL_REFERENCE | 464 | source_desc->reference.class == ACPI_REFCLASS_TABLE) { |
465 | && source_desc->reference.class == ACPI_REFCLASS_TABLE) { | ||
466 | 465 | ||
467 | /* This is a DDBHandle, just add a reference to it */ | 466 | /* This is a DDBHandle, just add a reference to it */ |
468 | 467 | ||
@@ -520,8 +519,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
520 | * by the INDEX_OP code. | 519 | * by the INDEX_OP code. |
521 | */ | 520 | */ |
522 | obj_desc = index_desc->reference.object; | 521 | obj_desc = index_desc->reference.object; |
523 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) && | 522 | if ((obj_desc->common.type != ACPI_TYPE_BUFFER) && |
524 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) { | 523 | (obj_desc->common.type != ACPI_TYPE_STRING)) { |
525 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 524 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
526 | } | 525 | } |
527 | 526 | ||
@@ -529,7 +528,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
529 | * The assignment of the individual elements will be slightly | 528 | * The assignment of the individual elements will be slightly |
530 | * different for each source type. | 529 | * different for each source type. |
531 | */ | 530 | */ |
532 | switch (ACPI_GET_OBJECT_TYPE(source_desc)) { | 531 | switch (source_desc->common.type) { |
533 | case ACPI_TYPE_INTEGER: | 532 | case ACPI_TYPE_INTEGER: |
534 | 533 | ||
535 | /* Use the least-significant byte of the integer */ | 534 | /* Use the least-significant byte of the integer */ |
@@ -707,8 +706,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
707 | /* No conversions for all other types. Just attach the source object */ | 706 | /* No conversions for all other types. Just attach the source object */ |
708 | 707 | ||
709 | status = acpi_ns_attach_object(node, source_desc, | 708 | status = acpi_ns_attach_object(node, source_desc, |
710 | ACPI_GET_OBJECT_TYPE | 709 | source_desc->common.type); |
711 | (source_desc)); | ||
712 | break; | 710 | break; |
713 | } | 711 | } |
714 | 712 | ||
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 145d15305f70..608e838d537e 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c | |||
@@ -96,8 +96,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, | |||
96 | * are all essentially the same. This case handles the | 96 | * are all essentially the same. This case handles the |
97 | * "interchangeable" types Integer, String, and Buffer. | 97 | * "interchangeable" types Integer, String, and Buffer. |
98 | */ | 98 | */ |
99 | if (ACPI_GET_OBJECT_TYPE(source_desc) == | 99 | if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) { |
100 | ACPI_TYPE_LOCAL_REFERENCE) { | ||
101 | 100 | ||
102 | /* Resolve a reference object first */ | 101 | /* Resolve a reference object first */ |
103 | 102 | ||
@@ -117,13 +116,11 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, | |||
117 | 116 | ||
118 | /* Must have a Integer, Buffer, or String */ | 117 | /* Must have a Integer, Buffer, or String */ |
119 | 118 | ||
120 | if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) && | 119 | if ((source_desc->common.type != ACPI_TYPE_INTEGER) && |
121 | (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) && | 120 | (source_desc->common.type != ACPI_TYPE_BUFFER) && |
122 | (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) && | 121 | (source_desc->common.type != ACPI_TYPE_STRING) && |
123 | !((ACPI_GET_OBJECT_TYPE(source_desc) == | 122 | !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) && |
124 | ACPI_TYPE_LOCAL_REFERENCE) | 123 | (source_desc->reference.class == ACPI_REFCLASS_TABLE))) { |
125 | && (source_desc->reference.class == | ||
126 | ACPI_REFCLASS_TABLE))) { | ||
127 | 124 | ||
128 | /* Conversion successful but still not a valid type */ | 125 | /* Conversion successful but still not a valid type */ |
129 | 126 | ||
@@ -218,8 +215,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, | |||
218 | return_ACPI_STATUS(status); | 215 | return_ACPI_STATUS(status); |
219 | } | 216 | } |
220 | 217 | ||
221 | if (ACPI_GET_OBJECT_TYPE(source_desc) != | 218 | if (source_desc->common.type != dest_desc->common.type) { |
222 | ACPI_GET_OBJECT_TYPE(dest_desc)) { | ||
223 | /* | 219 | /* |
224 | * The source type does not match the type of the destination. | 220 | * The source type does not match the type of the destination. |
225 | * Perform the "implicit conversion" of the source to the current type | 221 | * Perform the "implicit conversion" of the source to the current type |
@@ -229,11 +225,10 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, | |||
229 | * Otherwise, actual_src_desc is a temporary object to hold the | 225 | * Otherwise, actual_src_desc is a temporary object to hold the |
230 | * converted object. | 226 | * converted object. |
231 | */ | 227 | */ |
232 | status = | 228 | status = acpi_ex_convert_to_target_type(dest_desc->common.type, |
233 | acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE | 229 | source_desc, |
234 | (dest_desc), source_desc, | 230 | &actual_src_desc, |
235 | &actual_src_desc, | 231 | walk_state); |
236 | walk_state); | ||
237 | if (ACPI_FAILURE(status)) { | 232 | if (ACPI_FAILURE(status)) { |
238 | return_ACPI_STATUS(status); | 233 | return_ACPI_STATUS(status); |
239 | } | 234 | } |
@@ -252,7 +247,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc, | |||
252 | * We now have two objects of identical types, and we can perform a | 247 | * We now have two objects of identical types, and we can perform a |
253 | * copy of the *value* of the source object. | 248 | * copy of the *value* of the source object. |
254 | */ | 249 | */ |
255 | switch (ACPI_GET_OBJECT_TYPE(dest_desc)) { | 250 | switch (dest_desc->common.type) { |
256 | case ACPI_TYPE_INTEGER: | 251 | case ACPI_TYPE_INTEGER: |
257 | 252 | ||
258 | dest_desc->integer.value = actual_src_desc->integer.value; | 253 | dest_desc->integer.value = actual_src_desc->integer.value; |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 32b85d68e756..87730e944132 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -221,7 +221,7 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc) | |||
221 | */ | 221 | */ |
222 | if ((!obj_desc) || | 222 | if ((!obj_desc) || |
223 | (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) || | 223 | (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) || |
224 | (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { | 224 | (obj_desc->common.type != ACPI_TYPE_INTEGER)) { |
225 | return; | 225 | return; |
226 | } | 226 | } |
227 | 227 | ||
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index a9d4fea4167f..9af361a191e7 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c | |||
@@ -86,7 +86,8 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
86 | */ | 86 | */ |
87 | if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) { | 87 | if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) { |
88 | ACPI_ERROR((AE_INFO, | 88 | ACPI_ERROR((AE_INFO, |
89 | "No ACPI mode transition supported in this system (enable/disable both zero)")); | 89 | "No ACPI mode transition supported in this system " |
90 | "(enable/disable both zero)")); | ||
90 | return_ACPI_STATUS(AE_OK); | 91 | return_ACPI_STATUS(AE_OK); |
91 | } | 92 | } |
92 | 93 | ||
@@ -95,7 +96,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
95 | 96 | ||
96 | /* BIOS should have disabled ALL fixed and GP events */ | 97 | /* BIOS should have disabled ALL fixed and GP events */ |
97 | 98 | ||
98 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, | 99 | status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, |
99 | (u32) acpi_gbl_FADT.acpi_enable, 8); | 100 | (u32) acpi_gbl_FADT.acpi_enable, 8); |
100 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 101 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
101 | "Attempting to enable ACPI mode\n")); | 102 | "Attempting to enable ACPI mode\n")); |
@@ -107,7 +108,7 @@ acpi_status acpi_hw_set_mode(u32 mode) | |||
107 | * BIOS should clear all fixed status bits and restore fixed event | 108 | * BIOS should clear all fixed status bits and restore fixed event |
108 | * enable bits to default | 109 | * enable bits to default |
109 | */ | 110 | */ |
110 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, | 111 | status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, |
111 | (u32) acpi_gbl_FADT.acpi_disable, | 112 | (u32) acpi_gbl_FADT.acpi_disable, |
112 | 8); | 113 | 8); |
113 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 114 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -172,7 +173,7 @@ u32 acpi_hw_get_mode(void) | |||
172 | return_UINT32(ACPI_SYS_MODE_ACPI); | 173 | return_UINT32(ACPI_SYS_MODE_ACPI); |
173 | } | 174 | } |
174 | 175 | ||
175 | status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value); | 176 | status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value); |
176 | if (ACPI_FAILURE(status)) { | 177 | if (ACPI_FAILURE(status)) { |
177 | return_UINT32(ACPI_SYS_MODE_LEGACY); | 178 | return_UINT32(ACPI_SYS_MODE_LEGACY); |
178 | } | 179 | } |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 2013b66745d2..d3b7e37c9eed 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -89,10 +89,9 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
89 | 89 | ||
90 | /* Clear just the bit that corresponds to this GPE */ | 90 | /* Clear just the bit that corresponds to this GPE */ |
91 | 91 | ||
92 | ACPI_CLEAR_BIT(enable_mask, | 92 | ACPI_CLEAR_BIT(enable_mask, ((u32)1 << |
93 | ((u32) 1 << | 93 | (gpe_event_info->gpe_number - |
94 | (gpe_event_info->gpe_number - | 94 | gpe_register_info->base_gpe_number))); |
95 | gpe_register_info->base_gpe_number))); | ||
96 | 95 | ||
97 | /* Write the updated enable mask */ | 96 | /* Write the updated enable mask */ |
98 | 97 | ||
@@ -156,10 +155,9 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
156 | 155 | ||
157 | ACPI_FUNCTION_ENTRY(); | 156 | ACPI_FUNCTION_ENTRY(); |
158 | 157 | ||
159 | register_bit = (u8) | 158 | register_bit = (u8)(1 << |
160 | (1 << | 159 | (gpe_event_info->gpe_number - |
161 | (gpe_event_info->gpe_number - | 160 | gpe_event_info->register_info->base_gpe_number)); |
162 | gpe_event_info->register_info->base_gpe_number)); | ||
163 | 161 | ||
164 | /* | 162 | /* |
165 | * Write a one to the appropriate bit in the status register to | 163 | * Write a one to the appropriate bit in the status register to |
@@ -206,10 +204,9 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
206 | 204 | ||
207 | /* Get the register bitmask for this GPE */ | 205 | /* Get the register bitmask for this GPE */ |
208 | 206 | ||
209 | register_bit = (u8) | 207 | register_bit = (u8)(1 << |
210 | (1 << | 208 | (gpe_event_info->gpe_number - |
211 | (gpe_event_info->gpe_number - | 209 | gpe_event_info->register_info->base_gpe_number)); |
212 | gpe_event_info->register_info->base_gpe_number)); | ||
213 | 210 | ||
214 | /* GPE currently enabled? (enabled for runtime?) */ | 211 | /* GPE currently enabled? (enabled for runtime?) */ |
215 | 212 | ||
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 4dc43b018517..7b2fb602b5cb 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -51,6 +51,17 @@ | |||
51 | #define _COMPONENT ACPI_HARDWARE | 51 | #define _COMPONENT ACPI_HARDWARE |
52 | ACPI_MODULE_NAME("hwregs") | 52 | ACPI_MODULE_NAME("hwregs") |
53 | 53 | ||
54 | /* Local Prototypes */ | ||
55 | static acpi_status | ||
56 | acpi_hw_read_multiple(u32 *value, | ||
57 | struct acpi_generic_address *register_a, | ||
58 | struct acpi_generic_address *register_b); | ||
59 | |||
60 | static acpi_status | ||
61 | acpi_hw_write_multiple(u32 value, | ||
62 | struct acpi_generic_address *register_a, | ||
63 | struct acpi_generic_address *register_b); | ||
64 | |||
54 | /******************************************************************************* | 65 | /******************************************************************************* |
55 | * | 66 | * |
56 | * FUNCTION: acpi_hw_clear_acpi_status | 67 | * FUNCTION: acpi_hw_clear_acpi_status |
@@ -60,9 +71,9 @@ ACPI_MODULE_NAME("hwregs") | |||
60 | * RETURN: Status | 71 | * RETURN: Status |
61 | * | 72 | * |
62 | * DESCRIPTION: Clears all fixed and general purpose status bits | 73 | * DESCRIPTION: Clears all fixed and general purpose status bits |
63 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | ||
64 | * | 74 | * |
65 | ******************************************************************************/ | 75 | ******************************************************************************/ |
76 | |||
66 | acpi_status acpi_hw_clear_acpi_status(void) | 77 | acpi_status acpi_hw_clear_acpi_status(void) |
67 | { | 78 | { |
68 | acpi_status status; | 79 | acpi_status status; |
@@ -70,28 +81,20 @@ acpi_status acpi_hw_clear_acpi_status(void) | |||
70 | 81 | ||
71 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); | 82 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); |
72 | 83 | ||
73 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n", | 84 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n", |
74 | ACPI_BITMASK_ALL_FIXED_STATUS, | 85 | ACPI_BITMASK_ALL_FIXED_STATUS, |
75 | (u16) acpi_gbl_FADT.xpm1a_event_block.address)); | 86 | acpi_gbl_xpm1a_status.address)); |
76 | 87 | ||
77 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 88 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
78 | 89 | ||
90 | /* Clear the fixed events in PM1 A/B */ | ||
91 | |||
79 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | 92 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, |
80 | ACPI_BITMASK_ALL_FIXED_STATUS); | 93 | ACPI_BITMASK_ALL_FIXED_STATUS); |
81 | if (ACPI_FAILURE(status)) { | 94 | if (ACPI_FAILURE(status)) { |
82 | goto unlock_and_exit; | 95 | goto unlock_and_exit; |
83 | } | 96 | } |
84 | 97 | ||
85 | /* Clear the fixed events */ | ||
86 | |||
87 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | ||
88 | status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS, | ||
89 | &acpi_gbl_FADT.xpm1b_event_block); | ||
90 | if (ACPI_FAILURE(status)) { | ||
91 | goto unlock_and_exit; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | /* Clear the GPE Bits in all GPE registers in all GPE blocks */ | 98 | /* Clear the GPE Bits in all GPE registers in all GPE blocks */ |
96 | 99 | ||
97 | status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); | 100 | status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL); |
@@ -128,6 +131,42 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) | |||
128 | 131 | ||
129 | /****************************************************************************** | 132 | /****************************************************************************** |
130 | * | 133 | * |
134 | * FUNCTION: acpi_hw_write_pm1_control | ||
135 | * | ||
136 | * PARAMETERS: pm1a_control - Value to be written to PM1A control | ||
137 | * pm1b_control - Value to be written to PM1B control | ||
138 | * | ||
139 | * RETURN: Status | ||
140 | * | ||
141 | * DESCRIPTION: Write the PM1 A/B control registers. These registers are | ||
142 | * different than than the PM1 A/B status and enable registers | ||
143 | * in that different values can be written to the A/B registers. | ||
144 | * Most notably, the SLP_TYP bits can be different, as per the | ||
145 | * values returned from the _Sx predefined methods. | ||
146 | * | ||
147 | ******************************************************************************/ | ||
148 | |||
149 | acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) | ||
150 | { | ||
151 | acpi_status status; | ||
152 | |||
153 | ACPI_FUNCTION_TRACE(hw_write_pm1_control); | ||
154 | |||
155 | status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); | ||
156 | if (ACPI_FAILURE(status)) { | ||
157 | return_ACPI_STATUS(status); | ||
158 | } | ||
159 | |||
160 | if (acpi_gbl_FADT.xpm1b_control_block.address) { | ||
161 | status = | ||
162 | acpi_write(pm1b_control, | ||
163 | &acpi_gbl_FADT.xpm1b_control_block); | ||
164 | } | ||
165 | return_ACPI_STATUS(status); | ||
166 | } | ||
167 | |||
168 | /****************************************************************************** | ||
169 | * | ||
131 | * FUNCTION: acpi_hw_register_read | 170 | * FUNCTION: acpi_hw_register_read |
132 | * | 171 | * |
133 | * PARAMETERS: register_id - ACPI Register ID | 172 | * PARAMETERS: register_id - ACPI Register ID |
@@ -141,64 +180,56 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) | |||
141 | acpi_status | 180 | acpi_status |
142 | acpi_hw_register_read(u32 register_id, u32 * return_value) | 181 | acpi_hw_register_read(u32 register_id, u32 * return_value) |
143 | { | 182 | { |
144 | u32 value1 = 0; | 183 | u32 value = 0; |
145 | u32 value2 = 0; | ||
146 | acpi_status status; | 184 | acpi_status status; |
147 | 185 | ||
148 | ACPI_FUNCTION_TRACE(hw_register_read); | 186 | ACPI_FUNCTION_TRACE(hw_register_read); |
149 | 187 | ||
150 | switch (register_id) { | 188 | switch (register_id) { |
151 | case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ | 189 | case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ |
152 | |||
153 | status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block); | ||
154 | if (ACPI_FAILURE(status)) { | ||
155 | goto exit; | ||
156 | } | ||
157 | |||
158 | /* PM1B is optional */ | ||
159 | 190 | ||
160 | status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block); | 191 | status = acpi_hw_read_multiple(&value, |
161 | value1 |= value2; | 192 | &acpi_gbl_xpm1a_status, |
193 | &acpi_gbl_xpm1b_status); | ||
162 | break; | 194 | break; |
163 | 195 | ||
164 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ | 196 | case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ |
165 | 197 | ||
166 | status = acpi_read(&value1, &acpi_gbl_xpm1a_enable); | 198 | status = acpi_hw_read_multiple(&value, |
167 | if (ACPI_FAILURE(status)) { | 199 | &acpi_gbl_xpm1a_enable, |
168 | goto exit; | 200 | &acpi_gbl_xpm1b_enable); |
169 | } | ||
170 | |||
171 | /* PM1B is optional */ | ||
172 | |||
173 | status = acpi_read(&value2, &acpi_gbl_xpm1b_enable); | ||
174 | value1 |= value2; | ||
175 | break; | 201 | break; |
176 | 202 | ||
177 | case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ | 203 | case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ |
178 | 204 | ||
179 | status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block); | 205 | status = acpi_hw_read_multiple(&value, |
180 | if (ACPI_FAILURE(status)) { | 206 | &acpi_gbl_FADT. |
181 | goto exit; | 207 | xpm1a_control_block, |
182 | } | 208 | &acpi_gbl_FADT. |
209 | xpm1b_control_block); | ||
183 | 210 | ||
184 | status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block); | 211 | /* |
185 | value1 |= value2; | 212 | * Zero the write-only bits. From the ACPI specification, "Hardware |
213 | * Write-Only Bits": "Upon reads to registers with write-only bits, | ||
214 | * software masks out all write-only bits." | ||
215 | */ | ||
216 | value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; | ||
186 | break; | 217 | break; |
187 | 218 | ||
188 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 219 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
189 | 220 | ||
190 | status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block); | 221 | status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block); |
191 | break; | 222 | break; |
192 | 223 | ||
193 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 224 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
194 | 225 | ||
195 | status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block); | 226 | status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block); |
196 | break; | 227 | break; |
197 | 228 | ||
198 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 229 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
199 | 230 | ||
200 | status = | 231 | status = |
201 | acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8); | 232 | acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8); |
202 | break; | 233 | break; |
203 | 234 | ||
204 | default: | 235 | default: |
@@ -207,10 +238,8 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) | |||
207 | break; | 238 | break; |
208 | } | 239 | } |
209 | 240 | ||
210 | exit: | ||
211 | |||
212 | if (ACPI_SUCCESS(status)) { | 241 | if (ACPI_SUCCESS(status)) { |
213 | *return_value = value1; | 242 | *return_value = value; |
214 | } | 243 | } |
215 | 244 | ||
216 | return_ACPI_STATUS(status); | 245 | return_ACPI_STATUS(status); |
@@ -250,52 +279,42 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
250 | ACPI_FUNCTION_TRACE(hw_register_write); | 279 | ACPI_FUNCTION_TRACE(hw_register_write); |
251 | 280 | ||
252 | switch (register_id) { | 281 | switch (register_id) { |
253 | case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ | 282 | case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ |
254 | 283 | /* | |
255 | /* Perform a read first to preserve certain bits (per ACPI spec) */ | 284 | * Handle the "ignored" bit in PM1 Status. According to the ACPI |
256 | 285 | * specification, ignored bits are to be preserved when writing. | |
257 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, | 286 | * Normally, this would mean a read/modify/write sequence. However, |
258 | &read_value); | 287 | * preserving a bit in the status register is different. Writing a |
259 | if (ACPI_FAILURE(status)) { | 288 | * one clears the status, and writing a zero preserves the status. |
260 | goto exit; | 289 | * Therefore, we must always write zero to the ignored bit. |
261 | } | 290 | * |
262 | 291 | * This behavior is clarified in the ACPI 4.0 specification. | |
263 | /* Insert the bits to be preserved */ | 292 | */ |
264 | 293 | value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; | |
265 | ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS, | ||
266 | read_value); | ||
267 | |||
268 | /* Now we can write the data */ | ||
269 | |||
270 | status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block); | ||
271 | if (ACPI_FAILURE(status)) { | ||
272 | goto exit; | ||
273 | } | ||
274 | |||
275 | /* PM1B is optional */ | ||
276 | 294 | ||
277 | status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block); | 295 | status = acpi_hw_write_multiple(value, |
296 | &acpi_gbl_xpm1a_status, | ||
297 | &acpi_gbl_xpm1b_status); | ||
278 | break; | 298 | break; |
279 | 299 | ||
280 | case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ | 300 | case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access */ |
281 | 301 | ||
282 | status = acpi_write(value, &acpi_gbl_xpm1a_enable); | 302 | status = acpi_hw_write_multiple(value, |
283 | if (ACPI_FAILURE(status)) { | 303 | &acpi_gbl_xpm1a_enable, |
284 | goto exit; | 304 | &acpi_gbl_xpm1b_enable); |
285 | } | ||
286 | |||
287 | /* PM1B is optional */ | ||
288 | |||
289 | status = acpi_write(value, &acpi_gbl_xpm1b_enable); | ||
290 | break; | 305 | break; |
291 | 306 | ||
292 | case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ | 307 | case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ |
293 | 308 | ||
294 | /* | 309 | /* |
295 | * Perform a read first to preserve certain bits (per ACPI spec) | 310 | * Perform a read first to preserve certain bits (per ACPI spec) |
311 | * Note: This includes SCI_EN, we never want to change this bit | ||
296 | */ | 312 | */ |
297 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, | 313 | status = acpi_hw_read_multiple(&read_value, |
298 | &read_value); | 314 | &acpi_gbl_FADT. |
315 | xpm1a_control_block, | ||
316 | &acpi_gbl_FADT. | ||
317 | xpm1b_control_block); | ||
299 | if (ACPI_FAILURE(status)) { | 318 | if (ACPI_FAILURE(status)) { |
300 | goto exit; | 319 | goto exit; |
301 | } | 320 | } |
@@ -307,25 +326,29 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
307 | 326 | ||
308 | /* Now we can write the data */ | 327 | /* Now we can write the data */ |
309 | 328 | ||
310 | status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block); | 329 | status = acpi_hw_write_multiple(value, |
311 | if (ACPI_FAILURE(status)) { | 330 | &acpi_gbl_FADT. |
312 | goto exit; | 331 | xpm1a_control_block, |
313 | } | 332 | &acpi_gbl_FADT. |
314 | 333 | xpm1b_control_block); | |
315 | status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block); | ||
316 | break; | 334 | break; |
317 | 335 | ||
318 | case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ | 336 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
319 | |||
320 | status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block); | ||
321 | break; | ||
322 | 337 | ||
323 | case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ | 338 | /* |
339 | * For control registers, all reserved bits must be preserved, | ||
340 | * as per the ACPI spec. | ||
341 | */ | ||
342 | status = | ||
343 | acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block); | ||
344 | if (ACPI_FAILURE(status)) { | ||
345 | goto exit; | ||
346 | } | ||
324 | 347 | ||
325 | status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block); | 348 | /* Insert the bits to be preserved */ |
326 | break; | ||
327 | 349 | ||
328 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 350 | ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, |
351 | read_value); | ||
329 | 352 | ||
330 | status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); | 353 | status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); |
331 | break; | 354 | break; |
@@ -340,10 +363,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
340 | /* SMI_CMD is currently always in IO space */ | 363 | /* SMI_CMD is currently always in IO space */ |
341 | 364 | ||
342 | status = | 365 | status = |
343 | acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8); | 366 | acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8); |
344 | break; | 367 | break; |
345 | 368 | ||
346 | default: | 369 | default: |
370 | ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id)); | ||
347 | status = AE_BAD_PARAMETER; | 371 | status = AE_BAD_PARAMETER; |
348 | break; | 372 | break; |
349 | } | 373 | } |
@@ -351,3 +375,103 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
351 | exit: | 375 | exit: |
352 | return_ACPI_STATUS(status); | 376 | return_ACPI_STATUS(status); |
353 | } | 377 | } |
378 | |||
379 | /****************************************************************************** | ||
380 | * | ||
381 | * FUNCTION: acpi_hw_read_multiple | ||
382 | * | ||
383 | * PARAMETERS: Value - Where the register value is returned | ||
384 | * register_a - First ACPI register (required) | ||
385 | * register_b - Second ACPI register (optional) | ||
386 | * | ||
387 | * RETURN: Status | ||
388 | * | ||
389 | * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) | ||
390 | * | ||
391 | ******************************************************************************/ | ||
392 | |||
393 | static acpi_status | ||
394 | acpi_hw_read_multiple(u32 *value, | ||
395 | struct acpi_generic_address *register_a, | ||
396 | struct acpi_generic_address *register_b) | ||
397 | { | ||
398 | u32 value_a = 0; | ||
399 | u32 value_b = 0; | ||
400 | acpi_status status; | ||
401 | |||
402 | /* The first register is always required */ | ||
403 | |||
404 | status = acpi_read(&value_a, register_a); | ||
405 | if (ACPI_FAILURE(status)) { | ||
406 | return (status); | ||
407 | } | ||
408 | |||
409 | /* Second register is optional */ | ||
410 | |||
411 | if (register_b->address) { | ||
412 | status = acpi_read(&value_b, register_b); | ||
413 | if (ACPI_FAILURE(status)) { | ||
414 | return (status); | ||
415 | } | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * OR the two return values together. No shifting or masking is necessary, | ||
420 | * because of how the PM1 registers are defined in the ACPI specification: | ||
421 | * | ||
422 | * "Although the bits can be split between the two register blocks (each | ||
423 | * register block has a unique pointer within the FADT), the bit positions | ||
424 | * are maintained. The register block with unimplemented bits (that is, | ||
425 | * those implemented in the other register block) always returns zeros, | ||
426 | * and writes have no side effects" | ||
427 | */ | ||
428 | *value = (value_a | value_b); | ||
429 | return (AE_OK); | ||
430 | } | ||
431 | |||
432 | /****************************************************************************** | ||
433 | * | ||
434 | * FUNCTION: acpi_hw_write_multiple | ||
435 | * | ||
436 | * PARAMETERS: Value - The value to write | ||
437 | * register_a - First ACPI register (required) | ||
438 | * register_b - Second ACPI register (optional) | ||
439 | * | ||
440 | * RETURN: Status | ||
441 | * | ||
442 | * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) | ||
443 | * | ||
444 | ******************************************************************************/ | ||
445 | |||
446 | static acpi_status | ||
447 | acpi_hw_write_multiple(u32 value, | ||
448 | struct acpi_generic_address *register_a, | ||
449 | struct acpi_generic_address *register_b) | ||
450 | { | ||
451 | acpi_status status; | ||
452 | |||
453 | /* The first register is always required */ | ||
454 | |||
455 | status = acpi_write(value, register_a); | ||
456 | if (ACPI_FAILURE(status)) { | ||
457 | return (status); | ||
458 | } | ||
459 | |||
460 | /* | ||
461 | * Second register is optional | ||
462 | * | ||
463 | * No bit shifting or clearing is necessary, because of how the PM1 | ||
464 | * registers are defined in the ACPI specification: | ||
465 | * | ||
466 | * "Although the bits can be split between the two register blocks (each | ||
467 | * register block has a unique pointer within the FADT), the bit positions | ||
468 | * are maintained. The register block with unimplemented bits (that is, | ||
469 | * those implemented in the other register block) always returns zeros, | ||
470 | * and writes have no side effects" | ||
471 | */ | ||
472 | if (register_b->address) { | ||
473 | status = acpi_write(value, register_b); | ||
474 | } | ||
475 | |||
476 | return (status); | ||
477 | } | ||
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index a2af2a4f2f26..baa5fc05e124 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -90,6 +90,7 @@ acpi_set_firmware_waking_vector(u32 physical_address) | |||
90 | 90 | ||
91 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | 91 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) |
92 | 92 | ||
93 | #if ACPI_MACHINE_WIDTH == 64 | ||
93 | /******************************************************************************* | 94 | /******************************************************************************* |
94 | * | 95 | * |
95 | * FUNCTION: acpi_set_firmware_waking_vector64 | 96 | * FUNCTION: acpi_set_firmware_waking_vector64 |
@@ -100,7 +101,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector) | |||
100 | * RETURN: Status | 101 | * RETURN: Status |
101 | * | 102 | * |
102 | * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if | 103 | * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if |
103 | * it exists in the table. | 104 | * it exists in the table. This function is intended for use with |
105 | * 64-bit host operating systems. | ||
104 | * | 106 | * |
105 | ******************************************************************************/ | 107 | ******************************************************************************/ |
106 | acpi_status | 108 | acpi_status |
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 physical_address) | |||
124 | } | 126 | } |
125 | 127 | ||
126 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) | 128 | ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) |
129 | #endif | ||
127 | 130 | ||
128 | /******************************************************************************* | 131 | /******************************************************************************* |
129 | * | 132 | * |
@@ -147,9 +150,8 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
147 | 150 | ||
148 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); | 151 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep); |
149 | 152 | ||
150 | /* | 153 | /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */ |
151 | * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. | 154 | |
152 | */ | ||
153 | status = acpi_get_sleep_type_data(sleep_state, | 155 | status = acpi_get_sleep_type_data(sleep_state, |
154 | &acpi_gbl_sleep_type_a, | 156 | &acpi_gbl_sleep_type_a, |
155 | &acpi_gbl_sleep_type_b); | 157 | &acpi_gbl_sleep_type_b); |
@@ -223,8 +225,8 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | |||
223 | ******************************************************************************/ | 225 | ******************************************************************************/ |
224 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | 226 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) |
225 | { | 227 | { |
226 | u32 PM1Acontrol; | 228 | u32 pm1a_control; |
227 | u32 PM1Bcontrol; | 229 | u32 pm1b_control; |
228 | struct acpi_bit_register_info *sleep_type_reg_info; | 230 | struct acpi_bit_register_info *sleep_type_reg_info; |
229 | struct acpi_bit_register_info *sleep_enable_reg_info; | 231 | struct acpi_bit_register_info *sleep_enable_reg_info; |
230 | u32 in_value; | 232 | u32 in_value; |
@@ -242,13 +244,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
242 | } | 244 | } |
243 | 245 | ||
244 | sleep_type_reg_info = | 246 | sleep_type_reg_info = |
245 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); | 247 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); |
246 | sleep_enable_reg_info = | 248 | sleep_enable_reg_info = |
247 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); | 249 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); |
248 | 250 | ||
249 | /* Clear wake status */ | 251 | /* Clear wake status */ |
250 | 252 | ||
251 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); | 253 | status = |
254 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); | ||
252 | if (ACPI_FAILURE(status)) { | 255 | if (ACPI_FAILURE(status)) { |
253 | return_ACPI_STATUS(status); | 256 | return_ACPI_STATUS(status); |
254 | } | 257 | } |
@@ -289,24 +292,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
289 | 292 | ||
290 | /* Get current value of PM1A control */ | 293 | /* Get current value of PM1A control */ |
291 | 294 | ||
292 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); | 295 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, |
296 | &pm1a_control); | ||
293 | if (ACPI_FAILURE(status)) { | 297 | if (ACPI_FAILURE(status)) { |
294 | return_ACPI_STATUS(status); | 298 | return_ACPI_STATUS(status); |
295 | } | 299 | } |
296 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, | 300 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
297 | "Entering sleep state [S%d]\n", sleep_state)); | 301 | "Entering sleep state [S%d]\n", sleep_state)); |
298 | 302 | ||
299 | /* Clear SLP_EN and SLP_TYP fields */ | 303 | /* Clear the SLP_EN and SLP_TYP fields */ |
300 | 304 | ||
301 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | | 305 | pm1a_control &= ~(sleep_type_reg_info->access_bit_mask | |
302 | sleep_enable_reg_info->access_bit_mask); | 306 | sleep_enable_reg_info->access_bit_mask); |
303 | PM1Bcontrol = PM1Acontrol; | 307 | pm1b_control = pm1a_control; |
304 | 308 | ||
305 | /* Insert SLP_TYP bits */ | 309 | /* Insert the SLP_TYP bits */ |
306 | 310 | ||
307 | PM1Acontrol |= | 311 | pm1a_control |= |
308 | (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); | 312 | (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position); |
309 | PM1Bcontrol |= | 313 | pm1b_control |= |
310 | (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); | 314 | (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position); |
311 | 315 | ||
312 | /* | 316 | /* |
@@ -314,37 +318,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
314 | * poorly implemented hardware. | 318 | * poorly implemented hardware. |
315 | */ | 319 | */ |
316 | 320 | ||
317 | /* Write #1: fill in SLP_TYP data */ | 321 | /* Write #1: write the SLP_TYP data to the PM1 Control registers */ |
318 | 322 | ||
319 | status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, | 323 | status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); |
320 | PM1Acontrol); | ||
321 | if (ACPI_FAILURE(status)) { | 324 | if (ACPI_FAILURE(status)) { |
322 | return_ACPI_STATUS(status); | 325 | return_ACPI_STATUS(status); |
323 | } | 326 | } |
324 | 327 | ||
325 | status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, | 328 | /* Insert the sleep enable (SLP_EN) bit */ |
326 | PM1Bcontrol); | ||
327 | if (ACPI_FAILURE(status)) { | ||
328 | return_ACPI_STATUS(status); | ||
329 | } | ||
330 | 329 | ||
331 | /* Insert SLP_ENABLE bit */ | 330 | pm1a_control |= sleep_enable_reg_info->access_bit_mask; |
331 | pm1b_control |= sleep_enable_reg_info->access_bit_mask; | ||
332 | 332 | ||
333 | PM1Acontrol |= sleep_enable_reg_info->access_bit_mask; | 333 | /* Flush caches, as per ACPI specification */ |
334 | PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask; | ||
335 | |||
336 | /* Write #2: SLP_TYP + SLP_EN */ | ||
337 | 334 | ||
338 | ACPI_FLUSH_CPU_CACHE(); | 335 | ACPI_FLUSH_CPU_CACHE(); |
339 | 336 | ||
340 | status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, | 337 | /* Write #2: Write both SLP_TYP + SLP_EN */ |
341 | PM1Acontrol); | ||
342 | if (ACPI_FAILURE(status)) { | ||
343 | return_ACPI_STATUS(status); | ||
344 | } | ||
345 | 338 | ||
346 | status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, | 339 | status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); |
347 | PM1Bcontrol); | ||
348 | if (ACPI_FAILURE(status)) { | 340 | if (ACPI_FAILURE(status)) { |
349 | return_ACPI_STATUS(status); | 341 | return_ACPI_STATUS(status); |
350 | } | 342 | } |
@@ -357,8 +349,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
357 | * Wait ten seconds, then try again. This is to get S4/S5 to work on | 349 | * Wait ten seconds, then try again. This is to get S4/S5 to work on |
358 | * all machines. | 350 | * all machines. |
359 | * | 351 | * |
360 | * We wait so long to allow chipsets that poll this reg very slowly to | 352 | * We wait so long to allow chipsets that poll this reg very slowly |
361 | * still read the right value. Ideally, this block would go | 353 | * to still read the right value. Ideally, this block would go |
362 | * away entirely. | 354 | * away entirely. |
363 | */ | 355 | */ |
364 | acpi_os_stall(10000000); | 356 | acpi_os_stall(10000000); |
@@ -374,7 +366,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
374 | /* Wait until we enter sleep state */ | 366 | /* Wait until we enter sleep state */ |
375 | 367 | ||
376 | do { | 368 | do { |
377 | status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS, | 369 | status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, |
378 | &in_value); | 370 | &in_value); |
379 | if (ACPI_FAILURE(status)) { | 371 | if (ACPI_FAILURE(status)) { |
380 | return_ACPI_STATUS(status); | 372 | return_ACPI_STATUS(status); |
@@ -408,7 +400,10 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | |||
408 | 400 | ||
409 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); | 401 | ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios); |
410 | 402 | ||
411 | status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); | 403 | /* Clear the wake status bit (PM1) */ |
404 | |||
405 | status = | ||
406 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS); | ||
412 | if (ACPI_FAILURE(status)) { | 407 | if (ACPI_FAILURE(status)) { |
413 | return_ACPI_STATUS(status); | 408 | return_ACPI_STATUS(status); |
414 | } | 409 | } |
@@ -435,12 +430,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | |||
435 | 430 | ||
436 | ACPI_FLUSH_CPU_CACHE(); | 431 | ACPI_FLUSH_CPU_CACHE(); |
437 | 432 | ||
438 | status = acpi_os_write_port(acpi_gbl_FADT.smi_command, | 433 | status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, |
439 | (u32) acpi_gbl_FADT.S4bios_request, 8); | 434 | (u32) acpi_gbl_FADT.S4bios_request, 8); |
440 | 435 | ||
441 | do { | 436 | do { |
442 | acpi_os_stall(1000); | 437 | acpi_os_stall(1000); |
443 | status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); | 438 | status = |
439 | acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value); | ||
444 | if (ACPI_FAILURE(status)) { | 440 | if (ACPI_FAILURE(status)) { |
445 | return_ACPI_STATUS(status); | 441 | return_ACPI_STATUS(status); |
446 | } | 442 | } |
@@ -471,8 +467,8 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) | |||
471 | acpi_status status; | 467 | acpi_status status; |
472 | struct acpi_bit_register_info *sleep_type_reg_info; | 468 | struct acpi_bit_register_info *sleep_type_reg_info; |
473 | struct acpi_bit_register_info *sleep_enable_reg_info; | 469 | struct acpi_bit_register_info *sleep_enable_reg_info; |
474 | u32 PM1Acontrol; | 470 | u32 pm1a_control; |
475 | u32 PM1Bcontrol; | 471 | u32 pm1b_control; |
476 | 472 | ||
477 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); | 473 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); |
478 | 474 | ||
@@ -486,38 +482,34 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) | |||
486 | &acpi_gbl_sleep_type_b); | 482 | &acpi_gbl_sleep_type_b); |
487 | if (ACPI_SUCCESS(status)) { | 483 | if (ACPI_SUCCESS(status)) { |
488 | sleep_type_reg_info = | 484 | sleep_type_reg_info = |
489 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A); | 485 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); |
490 | sleep_enable_reg_info = | 486 | sleep_enable_reg_info = |
491 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); | 487 | acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE); |
492 | 488 | ||
493 | /* Get current value of PM1A control */ | 489 | /* Get current value of PM1A control */ |
494 | 490 | ||
495 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, | 491 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, |
496 | &PM1Acontrol); | 492 | &pm1a_control); |
497 | if (ACPI_SUCCESS(status)) { | 493 | if (ACPI_SUCCESS(status)) { |
498 | 494 | ||
499 | /* Clear SLP_EN and SLP_TYP fields */ | 495 | /* Clear the SLP_EN and SLP_TYP fields */ |
500 | 496 | ||
501 | PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | | 497 | pm1a_control &= ~(sleep_type_reg_info->access_bit_mask | |
502 | sleep_enable_reg_info-> | 498 | sleep_enable_reg_info-> |
503 | access_bit_mask); | 499 | access_bit_mask); |
504 | PM1Bcontrol = PM1Acontrol; | 500 | pm1b_control = pm1a_control; |
505 | 501 | ||
506 | /* Insert SLP_TYP bits */ | 502 | /* Insert the SLP_TYP bits */ |
507 | 503 | ||
508 | PM1Acontrol |= | 504 | pm1a_control |= (acpi_gbl_sleep_type_a << |
509 | (acpi_gbl_sleep_type_a << sleep_type_reg_info-> | 505 | sleep_type_reg_info->bit_position); |
510 | bit_position); | 506 | pm1b_control |= (acpi_gbl_sleep_type_b << |
511 | PM1Bcontrol |= | 507 | sleep_type_reg_info->bit_position); |
512 | (acpi_gbl_sleep_type_b << sleep_type_reg_info-> | ||
513 | bit_position); | ||
514 | 508 | ||
515 | /* Just ignore any errors */ | 509 | /* Write the control registers and ignore any errors */ |
516 | 510 | ||
517 | (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, | 511 | (void)acpi_hw_write_pm1_control(pm1a_control, |
518 | PM1Acontrol); | 512 | pm1b_control); |
519 | (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, | ||
520 | PM1Bcontrol); | ||
521 | } | 513 | } |
522 | } | 514 | } |
523 | 515 | ||
@@ -603,19 +595,21 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
603 | * it to determine whether the system is rebooting or resuming. Clear | 595 | * it to determine whether the system is rebooting or resuming. Clear |
604 | * it for compatibility. | 596 | * it for compatibility. |
605 | */ | 597 | */ |
606 | acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1); | 598 | acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1); |
607 | 599 | ||
608 | acpi_gbl_system_awake_and_running = TRUE; | 600 | acpi_gbl_system_awake_and_running = TRUE; |
609 | 601 | ||
610 | /* Enable power button */ | 602 | /* Enable power button */ |
611 | 603 | ||
612 | (void) | 604 | (void) |
613 | acpi_set_register(acpi_gbl_fixed_event_info | 605 | acpi_write_bit_register(acpi_gbl_fixed_event_info |
614 | [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1); | 606 | [ACPI_EVENT_POWER_BUTTON]. |
607 | enable_register_id, ACPI_ENABLE_EVENT); | ||
615 | 608 | ||
616 | (void) | 609 | (void) |
617 | acpi_set_register(acpi_gbl_fixed_event_info | 610 | acpi_write_bit_register(acpi_gbl_fixed_event_info |
618 | [ACPI_EVENT_POWER_BUTTON].status_register_id, 1); | 611 | [ACPI_EVENT_POWER_BUTTON]. |
612 | status_register_id, ACPI_CLEAR_STATUS); | ||
619 | 613 | ||
620 | arg.integer.value = ACPI_SST_WORKING; | 614 | arg.integer.value = ACPI_SST_WORKING; |
621 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); | 615 | status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); |
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c new file mode 100644 index 000000000000..bd3c937b0ac0 --- /dev/null +++ b/drivers/acpi/acpica/hwvalid.c | |||
@@ -0,0 +1,258 @@ | |||
1 | |||
2 | /****************************************************************************** | ||
3 | * | ||
4 | * Module Name: hwvalid - I/O request validation | ||
5 | * | ||
6 | *****************************************************************************/ | ||
7 | |||
8 | /* | ||
9 | * Copyright (C) 2000 - 2009, 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 | |||
48 | #define _COMPONENT ACPI_HARDWARE | ||
49 | ACPI_MODULE_NAME("hwvalid") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static acpi_status | ||
53 | acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width); | ||
54 | |||
55 | /* | ||
56 | * Protected I/O ports. Some ports are always illegal, and some are | ||
57 | * conditionally illegal. This table must remain ordered by port address. | ||
58 | * | ||
59 | * The table is used to implement the Microsoft port access rules that | ||
60 | * first appeared in Windows XP. Some ports are always illegal, and some | ||
61 | * ports are only illegal if the BIOS calls _OSI with a win_xP string or | ||
62 | * later (meaning that the BIOS itelf is post-XP.) | ||
63 | * | ||
64 | * This provides ACPICA with the desired port protections and | ||
65 | * Microsoft compatibility. | ||
66 | * | ||
67 | * Description of port entries: | ||
68 | * DMA: DMA controller | ||
69 | * PIC0: Programmable Interrupt Controller (8259_a) | ||
70 | * PIT1: System Timer 1 | ||
71 | * PIT2: System Timer 2 failsafe | ||
72 | * RTC: Real-time clock | ||
73 | * CMOS: Extended CMOS | ||
74 | * DMA1: DMA 1 page registers | ||
75 | * DMA1L: DMA 1 Ch 0 low page | ||
76 | * DMA2: DMA 2 page registers | ||
77 | * DMA2L: DMA 2 low page refresh | ||
78 | * ARBC: Arbitration control | ||
79 | * SETUP: Reserved system board setup | ||
80 | * POS: POS channel select | ||
81 | * PIC1: Cascaded PIC | ||
82 | * IDMA: ISA DMA | ||
83 | * ELCR: PIC edge/level registers | ||
84 | * PCI: PCI configuration space | ||
85 | */ | ||
86 | static const struct acpi_port_info acpi_protected_ports[] = { | ||
87 | {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP}, | ||
88 | {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL}, | ||
89 | {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP}, | ||
90 | {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, | ||
91 | {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, | ||
92 | {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP}, | ||
93 | {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP}, | ||
94 | {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP}, | ||
95 | {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, | ||
96 | {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP}, | ||
97 | {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP}, | ||
98 | {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP}, | ||
99 | {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP}, | ||
100 | {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL}, | ||
101 | {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP}, | ||
102 | {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL}, | ||
103 | {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP} | ||
104 | }; | ||
105 | |||
106 | #define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (acpi_protected_ports) | ||
107 | |||
108 | /****************************************************************************** | ||
109 | * | ||
110 | * FUNCTION: acpi_hw_validate_io_request | ||
111 | * | ||
112 | * PARAMETERS: Address Address of I/O port/register | ||
113 | * bit_width Number of bits (8,16,32) | ||
114 | * | ||
115 | * RETURN: Status | ||
116 | * | ||
117 | * DESCRIPTION: Validates an I/O request (address/length). Certain ports are | ||
118 | * always illegal and some ports are only illegal depending on | ||
119 | * the requests the BIOS AML code makes to the predefined | ||
120 | * _OSI method. | ||
121 | * | ||
122 | ******************************************************************************/ | ||
123 | |||
124 | static acpi_status | ||
125 | acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) | ||
126 | { | ||
127 | u32 i; | ||
128 | u32 byte_width; | ||
129 | acpi_io_address last_address; | ||
130 | const struct acpi_port_info *port_info; | ||
131 | |||
132 | ACPI_FUNCTION_TRACE(hw_validate_io_request); | ||
133 | |||
134 | /* Supported widths are 8/16/32 */ | ||
135 | |||
136 | if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) { | ||
137 | return AE_BAD_PARAMETER; | ||
138 | } | ||
139 | |||
140 | port_info = acpi_protected_ports; | ||
141 | byte_width = ACPI_DIV_8(bit_width); | ||
142 | last_address = address + byte_width - 1; | ||
143 | |||
144 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X", | ||
145 | ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void, | ||
146 | last_address), | ||
147 | byte_width)); | ||
148 | |||
149 | /* Maximum 16-bit address in I/O space */ | ||
150 | |||
151 | if (last_address > ACPI_UINT16_MAX) { | ||
152 | ACPI_ERROR((AE_INFO, | ||
153 | "Illegal I/O port address/length above 64K: 0x%p/%X", | ||
154 | ACPI_CAST_PTR(void, address), byte_width)); | ||
155 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | ||
156 | } | ||
157 | |||
158 | /* Exit if requested address is not within the protected port table */ | ||
159 | |||
160 | if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) { | ||
161 | return_ACPI_STATUS(AE_OK); | ||
162 | } | ||
163 | |||
164 | /* Check request against the list of protected I/O ports */ | ||
165 | |||
166 | for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) { | ||
167 | /* | ||
168 | * Check if the requested address range will write to a reserved | ||
169 | * port. Four cases to consider: | ||
170 | * | ||
171 | * 1) Address range is contained completely in the port address range | ||
172 | * 2) Address range overlaps port range at the port range start | ||
173 | * 3) Address range overlaps port range at the port range end | ||
174 | * 4) Address range completely encompasses the port range | ||
175 | */ | ||
176 | if ((address <= port_info->end) | ||
177 | && (last_address >= port_info->start)) { | ||
178 | |||
179 | /* Port illegality may depend on the _OSI calls made by the BIOS */ | ||
180 | |||
181 | if (acpi_gbl_osi_data >= port_info->osi_dependency) { | ||
182 | ACPI_ERROR((AE_INFO, | ||
183 | "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", | ||
184 | ACPI_CAST_PTR(void, address), | ||
185 | byte_width, port_info->name, | ||
186 | port_info->start, port_info->end)); | ||
187 | |||
188 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | /* Finished if address range ends before the end of this port */ | ||
193 | |||
194 | if (last_address <= port_info->end) { | ||
195 | break; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | return_ACPI_STATUS(AE_OK); | ||
200 | } | ||
201 | |||
202 | /****************************************************************************** | ||
203 | * | ||
204 | * FUNCTION: acpi_hw_read_port | ||
205 | * | ||
206 | * PARAMETERS: Address Address of I/O port/register to read | ||
207 | * Value Where value is placed | ||
208 | * Width Number of bits | ||
209 | * | ||
210 | * RETURN: Value read from port | ||
211 | * | ||
212 | * DESCRIPTION: Read data from an I/O port or register. This is a front-end | ||
213 | * to acpi_os_read_port that performs validation on both the port | ||
214 | * address and the length. | ||
215 | * | ||
216 | *****************************************************************************/ | ||
217 | |||
218 | acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) | ||
219 | { | ||
220 | acpi_status status; | ||
221 | |||
222 | status = acpi_hw_validate_io_request(address, width); | ||
223 | if (ACPI_FAILURE(status)) { | ||
224 | return status; | ||
225 | } | ||
226 | |||
227 | status = acpi_os_read_port(address, value, width); | ||
228 | return status; | ||
229 | } | ||
230 | |||
231 | /****************************************************************************** | ||
232 | * | ||
233 | * FUNCTION: acpi_hw_write_port | ||
234 | * | ||
235 | * PARAMETERS: Address Address of I/O port/register to write | ||
236 | * Value Value to write | ||
237 | * Width Number of bits | ||
238 | * | ||
239 | * RETURN: None | ||
240 | * | ||
241 | * DESCRIPTION: Write data to an I/O port or register. This is a front-end | ||
242 | * to acpi_os_write_port that performs validation on both the port | ||
243 | * address and the length. | ||
244 | * | ||
245 | *****************************************************************************/ | ||
246 | |||
247 | acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) | ||
248 | { | ||
249 | acpi_status status; | ||
250 | |||
251 | status = acpi_hw_validate_io_request(address, width); | ||
252 | if (ACPI_FAILURE(status)) { | ||
253 | return status; | ||
254 | } | ||
255 | |||
256 | status = acpi_os_write_port(address, value, width); | ||
257 | return status; | ||
258 | } | ||
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index ae597c0ab53f..9829979f2bdd 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -107,19 +107,18 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | |||
107 | ACPI_FUNCTION_NAME(acpi_read); | 107 | ACPI_FUNCTION_NAME(acpi_read); |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * Must have a valid pointer to a GAS structure, and | 110 | * Must have a valid pointer to a GAS structure, and a non-zero address |
111 | * a non-zero address within. However, don't return an error | 111 | * within. |
112 | * because the PM1A/B code must not fail if B isn't present. | ||
113 | */ | 112 | */ |
114 | if (!reg) { | 113 | if (!reg) { |
115 | return (AE_OK); | 114 | return (AE_BAD_PARAMETER); |
116 | } | 115 | } |
117 | 116 | ||
118 | /* Get a local copy of the address. Handles possible alignment issues */ | 117 | /* Get a local copy of the address. Handles possible alignment issues */ |
119 | 118 | ||
120 | ACPI_MOVE_64_TO_64(&address, ®->address); | 119 | ACPI_MOVE_64_TO_64(&address, ®->address); |
121 | if (!address) { | 120 | if (!address) { |
122 | return (AE_OK); | 121 | return (AE_BAD_ADDRESS); |
123 | } | 122 | } |
124 | 123 | ||
125 | /* Supported widths are 8/16/32 */ | 124 | /* Supported widths are 8/16/32 */ |
@@ -134,8 +133,8 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | |||
134 | *value = 0; | 133 | *value = 0; |
135 | 134 | ||
136 | /* | 135 | /* |
137 | * Two address spaces supported: Memory or IO. | 136 | * Two address spaces supported: Memory or IO. PCI_Config is |
138 | * PCI_Config is not supported here because the GAS struct is insufficient | 137 | * not supported here because the GAS structure is insufficient |
139 | */ | 138 | */ |
140 | switch (reg->space_id) { | 139 | switch (reg->space_id) { |
141 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 140 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: |
@@ -147,7 +146,7 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | |||
147 | case ACPI_ADR_SPACE_SYSTEM_IO: | 146 | case ACPI_ADR_SPACE_SYSTEM_IO: |
148 | 147 | ||
149 | status = | 148 | status = |
150 | acpi_os_read_port((acpi_io_address) address, value, width); | 149 | acpi_hw_read_port((acpi_io_address) address, value, width); |
151 | break; | 150 | break; |
152 | 151 | ||
153 | default: | 152 | default: |
@@ -187,19 +186,18 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | |||
187 | ACPI_FUNCTION_NAME(acpi_write); | 186 | ACPI_FUNCTION_NAME(acpi_write); |
188 | 187 | ||
189 | /* | 188 | /* |
190 | * Must have a valid pointer to a GAS structure, and | 189 | * Must have a valid pointer to a GAS structure, and a non-zero address |
191 | * a non-zero address within. However, don't return an error | 190 | * within. |
192 | * because the PM1A/B code must not fail if B isn't present. | ||
193 | */ | 191 | */ |
194 | if (!reg) { | 192 | if (!reg) { |
195 | return (AE_OK); | 193 | return (AE_BAD_PARAMETER); |
196 | } | 194 | } |
197 | 195 | ||
198 | /* Get a local copy of the address. Handles possible alignment issues */ | 196 | /* Get a local copy of the address. Handles possible alignment issues */ |
199 | 197 | ||
200 | ACPI_MOVE_64_TO_64(&address, ®->address); | 198 | ACPI_MOVE_64_TO_64(&address, ®->address); |
201 | if (!address) { | 199 | if (!address) { |
202 | return (AE_OK); | 200 | return (AE_BAD_ADDRESS); |
203 | } | 201 | } |
204 | 202 | ||
205 | /* Supported widths are 8/16/32 */ | 203 | /* Supported widths are 8/16/32 */ |
@@ -222,7 +220,7 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | |||
222 | 220 | ||
223 | case ACPI_ADR_SPACE_SYSTEM_IO: | 221 | case ACPI_ADR_SPACE_SYSTEM_IO: |
224 | 222 | ||
225 | status = acpi_os_write_port((acpi_io_address) address, value, | 223 | status = acpi_hw_write_port((acpi_io_address) address, value, |
226 | width); | 224 | width); |
227 | break; | 225 | break; |
228 | 226 | ||
@@ -244,24 +242,36 @@ ACPI_EXPORT_SYMBOL(acpi_write) | |||
244 | 242 | ||
245 | /******************************************************************************* | 243 | /******************************************************************************* |
246 | * | 244 | * |
247 | * FUNCTION: acpi_get_register_unlocked | 245 | * FUNCTION: acpi_read_bit_register |
248 | * | 246 | * |
249 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 247 | * PARAMETERS: register_id - ID of ACPI Bit Register to access |
250 | * return_value - Value that was read from the register | 248 | * return_value - Value that was read from the register, |
249 | * normalized to bit position zero. | ||
251 | * | 250 | * |
252 | * RETURN: Status and the value read from specified Register. Value | 251 | * RETURN: Status and the value read from the specified Register. Value |
253 | * returned is normalized to bit0 (is shifted all the way right) | 252 | * returned is normalized to bit0 (is shifted all the way right) |
254 | * | 253 | * |
255 | * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock. | 254 | * DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock. |
256 | * | 255 | * |
256 | * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and | ||
257 | * PM2 Control. | ||
258 | * | ||
259 | * Note: The hardware lock is not required when reading the ACPI bit registers | ||
260 | * since almost all of them are single bit and it does not matter that | ||
261 | * the parent hardware register can be split across two physical | ||
262 | * registers. The only multi-bit field is SLP_TYP in the PM1 control | ||
263 | * register, but this field does not cross an 8-bit boundary (nor does | ||
264 | * it make much sense to actually read this field.) | ||
265 | * | ||
257 | ******************************************************************************/ | 266 | ******************************************************************************/ |
258 | acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value) | 267 | acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value) |
259 | { | 268 | { |
260 | u32 register_value = 0; | ||
261 | struct acpi_bit_register_info *bit_reg_info; | 269 | struct acpi_bit_register_info *bit_reg_info; |
270 | u32 register_value; | ||
271 | u32 value; | ||
262 | acpi_status status; | 272 | acpi_status status; |
263 | 273 | ||
264 | ACPI_FUNCTION_TRACE(acpi_get_register_unlocked); | 274 | ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id); |
265 | 275 | ||
266 | /* Get the info structure corresponding to the requested ACPI Register */ | 276 | /* Get the info structure corresponding to the requested ACPI Register */ |
267 | 277 | ||
@@ -270,209 +280,133 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value) | |||
270 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 280 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
271 | } | 281 | } |
272 | 282 | ||
273 | /* Read from the register */ | 283 | /* Read the entire parent register */ |
274 | 284 | ||
275 | status = acpi_hw_register_read(bit_reg_info->parent_register, | 285 | status = acpi_hw_register_read(bit_reg_info->parent_register, |
276 | ®ister_value); | 286 | ®ister_value); |
277 | 287 | if (ACPI_FAILURE(status)) { | |
278 | if (ACPI_SUCCESS(status)) { | 288 | return_ACPI_STATUS(status); |
279 | |||
280 | /* Normalize the value that was read */ | ||
281 | |||
282 | register_value = | ||
283 | ((register_value & bit_reg_info->access_bit_mask) | ||
284 | >> bit_reg_info->bit_position); | ||
285 | |||
286 | *return_value = register_value; | ||
287 | |||
288 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n", | ||
289 | register_value, | ||
290 | bit_reg_info->parent_register)); | ||
291 | } | 289 | } |
292 | 290 | ||
293 | return_ACPI_STATUS(status); | 291 | /* Normalize the value that was read, mask off other bits */ |
294 | } | ||
295 | 292 | ||
296 | ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked) | 293 | value = ((register_value & bit_reg_info->access_bit_mask) |
294 | >> bit_reg_info->bit_position); | ||
297 | 295 | ||
298 | /******************************************************************************* | 296 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
299 | * | 297 | "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n", |
300 | * FUNCTION: acpi_get_register | 298 | register_id, bit_reg_info->parent_register, |
301 | * | 299 | register_value, value)); |
302 | * PARAMETERS: register_id - ID of ACPI bit_register to access | ||
303 | * return_value - Value that was read from the register | ||
304 | * | ||
305 | * RETURN: Status and the value read from specified Register. Value | ||
306 | * returned is normalized to bit0 (is shifted all the way right) | ||
307 | * | ||
308 | * DESCRIPTION: ACPI bit_register read function. | ||
309 | * | ||
310 | ******************************************************************************/ | ||
311 | acpi_status acpi_get_register(u32 register_id, u32 *return_value) | ||
312 | { | ||
313 | acpi_status status; | ||
314 | acpi_cpu_flags flags; | ||
315 | |||
316 | flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | ||
317 | status = acpi_get_register_unlocked(register_id, return_value); | ||
318 | acpi_os_release_lock(acpi_gbl_hardware_lock, flags); | ||
319 | 300 | ||
320 | return (status); | 301 | *return_value = value; |
302 | return_ACPI_STATUS(AE_OK); | ||
321 | } | 303 | } |
322 | 304 | ||
323 | ACPI_EXPORT_SYMBOL(acpi_get_register) | 305 | ACPI_EXPORT_SYMBOL(acpi_read_bit_register) |
324 | 306 | ||
325 | /******************************************************************************* | 307 | /******************************************************************************* |
326 | * | 308 | * |
327 | * FUNCTION: acpi_set_register | 309 | * FUNCTION: acpi_write_bit_register |
328 | * | 310 | * |
329 | * PARAMETERS: register_id - ID of ACPI bit_register to access | 311 | * PARAMETERS: register_id - ID of ACPI Bit Register to access |
330 | * Value - (only used on write) value to write to the | 312 | * Value - Value to write to the register, in bit |
331 | * Register, NOT pre-normalized to the bit pos | 313 | * position zero. The bit is automaticallly |
314 | * shifted to the correct position. | ||
332 | * | 315 | * |
333 | * RETURN: Status | 316 | * RETURN: Status |
334 | * | 317 | * |
335 | * DESCRIPTION: ACPI Bit Register write function. | 318 | * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock |
319 | * since most operations require a read/modify/write sequence. | ||
320 | * | ||
321 | * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and | ||
322 | * PM2 Control. | ||
323 | * | ||
324 | * Note that at this level, the fact that there may be actually two | ||
325 | * hardware registers (A and B - and B may not exist) is abstracted. | ||
336 | * | 326 | * |
337 | ******************************************************************************/ | 327 | ******************************************************************************/ |
338 | acpi_status acpi_set_register(u32 register_id, u32 value) | 328 | acpi_status acpi_write_bit_register(u32 register_id, u32 value) |
339 | { | 329 | { |
340 | u32 register_value = 0; | ||
341 | struct acpi_bit_register_info *bit_reg_info; | 330 | struct acpi_bit_register_info *bit_reg_info; |
342 | acpi_status status; | ||
343 | acpi_cpu_flags lock_flags; | 331 | acpi_cpu_flags lock_flags; |
332 | u32 register_value; | ||
333 | acpi_status status = AE_OK; | ||
344 | 334 | ||
345 | ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id); | 335 | ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id); |
346 | 336 | ||
347 | /* Get the info structure corresponding to the requested ACPI Register */ | 337 | /* Get the info structure corresponding to the requested ACPI Register */ |
348 | 338 | ||
349 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); | 339 | bit_reg_info = acpi_hw_get_bit_register_info(register_id); |
350 | if (!bit_reg_info) { | 340 | if (!bit_reg_info) { |
351 | ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X", | ||
352 | register_id)); | ||
353 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 341 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
354 | } | 342 | } |
355 | 343 | ||
356 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 344 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
357 | 345 | ||
358 | /* Always do a register read first so we can insert the new bits */ | ||
359 | |||
360 | status = acpi_hw_register_read(bit_reg_info->parent_register, | ||
361 | ®ister_value); | ||
362 | if (ACPI_FAILURE(status)) { | ||
363 | goto unlock_and_exit; | ||
364 | } | ||
365 | |||
366 | /* | 346 | /* |
367 | * Decode the Register ID | 347 | * At this point, we know that the parent register is one of the |
368 | * Register ID = [Register block ID] | [bit ID] | 348 | * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control |
369 | * | ||
370 | * Check bit ID to fine locate Register offset. | ||
371 | * Check Mask to determine Register offset, and then read-write. | ||
372 | */ | 349 | */ |
373 | switch (bit_reg_info->parent_register) { | 350 | if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) { |
374 | case ACPI_REGISTER_PM1_STATUS: | ||
375 | |||
376 | /* | 351 | /* |
377 | * Status Registers are different from the rest. Clear by | 352 | * 1) Case for PM1 Enable, PM1 Control, and PM2 Control |
378 | * writing 1, and writing 0 has no effect. So, the only relevant | 353 | * |
379 | * information is the single bit we're interested in, all others should | 354 | * Perform a register read to preserve the bits that we are not |
380 | * be written as 0 so they will be left unchanged. | 355 | * interested in |
381 | */ | 356 | */ |
382 | value = ACPI_REGISTER_PREPARE_BITS(value, | 357 | status = acpi_hw_register_read(bit_reg_info->parent_register, |
383 | bit_reg_info->bit_position, | ||
384 | bit_reg_info-> | ||
385 | access_bit_mask); | ||
386 | if (value) { | ||
387 | status = | ||
388 | acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | ||
389 | (u16) value); | ||
390 | register_value = 0; | ||
391 | } | ||
392 | break; | ||
393 | |||
394 | case ACPI_REGISTER_PM1_ENABLE: | ||
395 | |||
396 | ACPI_REGISTER_INSERT_VALUE(register_value, | ||
397 | bit_reg_info->bit_position, | ||
398 | bit_reg_info->access_bit_mask, | ||
399 | value); | ||
400 | |||
401 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE, | ||
402 | (u16) register_value); | ||
403 | break; | ||
404 | |||
405 | case ACPI_REGISTER_PM1_CONTROL: | ||
406 | |||
407 | /* | ||
408 | * Write the PM1 Control register. | ||
409 | * Note that at this level, the fact that there are actually TWO | ||
410 | * registers (A and B - and B may not exist) is abstracted. | ||
411 | */ | ||
412 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n", | ||
413 | register_value)); | ||
414 | |||
415 | ACPI_REGISTER_INSERT_VALUE(register_value, | ||
416 | bit_reg_info->bit_position, | ||
417 | bit_reg_info->access_bit_mask, | ||
418 | value); | ||
419 | |||
420 | status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, | ||
421 | (u16) register_value); | ||
422 | break; | ||
423 | |||
424 | case ACPI_REGISTER_PM2_CONTROL: | ||
425 | |||
426 | status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL, | ||
427 | ®ister_value); | 358 | ®ister_value); |
428 | if (ACPI_FAILURE(status)) { | 359 | if (ACPI_FAILURE(status)) { |
429 | goto unlock_and_exit; | 360 | goto unlock_and_exit; |
430 | } | 361 | } |
431 | 362 | ||
432 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 363 | /* |
433 | "PM2 control: Read %X from %8.8X%8.8X\n", | 364 | * Insert the input bit into the value that was just read |
434 | register_value, | 365 | * and write the register |
435 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. | 366 | */ |
436 | xpm2_control_block. | ||
437 | address))); | ||
438 | |||
439 | ACPI_REGISTER_INSERT_VALUE(register_value, | 367 | ACPI_REGISTER_INSERT_VALUE(register_value, |
440 | bit_reg_info->bit_position, | 368 | bit_reg_info->bit_position, |
441 | bit_reg_info->access_bit_mask, | 369 | bit_reg_info->access_bit_mask, |
442 | value); | 370 | value); |
443 | 371 | ||
444 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 372 | status = acpi_hw_register_write(bit_reg_info->parent_register, |
445 | "About to write %4.4X to %8.8X%8.8X\n", | 373 | register_value); |
446 | register_value, | 374 | } else { |
447 | ACPI_FORMAT_UINT64(acpi_gbl_FADT. | 375 | /* |
448 | xpm2_control_block. | 376 | * 2) Case for PM1 Status |
449 | address))); | 377 | * |
378 | * The Status register is different from the rest. Clear an event | ||
379 | * by writing 1, writing 0 has no effect. So, the only relevant | ||
380 | * information is the single bit we're interested in, all others | ||
381 | * should be written as 0 so they will be left unchanged. | ||
382 | */ | ||
383 | register_value = ACPI_REGISTER_PREPARE_BITS(value, | ||
384 | bit_reg_info-> | ||
385 | bit_position, | ||
386 | bit_reg_info-> | ||
387 | access_bit_mask); | ||
450 | 388 | ||
451 | status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL, | 389 | /* No need to write the register if value is all zeros */ |
452 | (u8) (register_value)); | ||
453 | break; | ||
454 | 390 | ||
455 | default: | 391 | if (register_value) { |
456 | break; | 392 | status = |
393 | acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, | ||
394 | register_value); | ||
395 | } | ||
457 | } | 396 | } |
458 | 397 | ||
459 | unlock_and_exit: | 398 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
460 | 399 | "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n", | |
461 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); | 400 | register_id, bit_reg_info->parent_register, value, |
462 | 401 | register_value)); | |
463 | /* Normalize the value that was read */ | ||
464 | 402 | ||
465 | ACPI_DEBUG_EXEC(register_value = | 403 | unlock_and_exit: |
466 | ((register_value & bit_reg_info->access_bit_mask) >> | ||
467 | bit_reg_info->bit_position)); | ||
468 | 404 | ||
469 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 405 | acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); |
470 | "Set bits: %8.8X actual %8.8X register %X\n", value, | ||
471 | register_value, bit_reg_info->parent_register)); | ||
472 | return_ACPI_STATUS(status); | 406 | return_ACPI_STATUS(status); |
473 | } | 407 | } |
474 | 408 | ||
475 | ACPI_EXPORT_SYMBOL(acpi_set_register) | 409 | ACPI_EXPORT_SYMBOL(acpi_write_bit_register) |
476 | 410 | ||
477 | /******************************************************************************* | 411 | /******************************************************************************* |
478 | * | 412 | * |
@@ -534,7 +468,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) | |||
534 | 468 | ||
535 | /* It must be of type Package */ | 469 | /* It must be of type Package */ |
536 | 470 | ||
537 | else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) { | 471 | else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) { |
538 | ACPI_ERROR((AE_INFO, | 472 | ACPI_ERROR((AE_INFO, |
539 | "Sleep State return object is not a Package")); | 473 | "Sleep State return object is not a Package")); |
540 | status = AE_AML_OPERAND_TYPE; | 474 | status = AE_AML_OPERAND_TYPE; |
@@ -555,12 +489,13 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) | |||
555 | 489 | ||
556 | /* The first two elements must both be of type Integer */ | 490 | /* The first two elements must both be of type Integer */ |
557 | 491 | ||
558 | else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0]) | 492 | else if (((info->return_object->package.elements[0])->common.type |
559 | != ACPI_TYPE_INTEGER) || | 493 | != ACPI_TYPE_INTEGER) || |
560 | (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1]) | 494 | ((info->return_object->package.elements[1])->common.type |
561 | != ACPI_TYPE_INTEGER)) { | 495 | != ACPI_TYPE_INTEGER)) { |
562 | ACPI_ERROR((AE_INFO, | 496 | ACPI_ERROR((AE_INFO, |
563 | "Sleep State return package elements are not both Integers (%s, %s)", | 497 | "Sleep State return package elements are not both Integers " |
498 | "(%s, %s)", | ||
564 | acpi_ut_get_object_type_name(info->return_object-> | 499 | acpi_ut_get_object_type_name(info->return_object-> |
565 | package.elements[0]), | 500 | package.elements[0]), |
566 | acpi_ut_get_object_type_name(info->return_object-> | 501 | acpi_ut_get_object_type_name(info->return_object-> |
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 88303ebe924c..9c3cdbe2d82a 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c | |||
@@ -118,9 +118,8 @@ acpi_status acpi_ns_root_initialize(void) | |||
118 | } | 118 | } |
119 | 119 | ||
120 | /* | 120 | /* |
121 | * Name entered successfully. | 121 | * Name entered successfully. If entry in pre_defined_names[] specifies |
122 | * If entry in pre_defined_names[] specifies an | 122 | * an initial value, create the initial value. |
123 | * initial value, create the initial value. | ||
124 | */ | 123 | */ |
125 | if (init_val->val) { | 124 | if (init_val->val) { |
126 | status = acpi_os_predefined_override(init_val, &val); | 125 | status = acpi_os_predefined_override(init_val, &val); |
@@ -178,9 +177,8 @@ acpi_status acpi_ns_root_initialize(void) | |||
178 | 177 | ||
179 | case ACPI_TYPE_STRING: | 178 | case ACPI_TYPE_STRING: |
180 | 179 | ||
181 | /* | 180 | /* Build an object around the static string */ |
182 | * Build an object around the static string | 181 | |
183 | */ | ||
184 | obj_desc->string.length = | 182 | obj_desc->string.length = |
185 | (u32) ACPI_STRLEN(val); | 183 | (u32) ACPI_STRLEN(val); |
186 | obj_desc->string.pointer = val; | 184 | obj_desc->string.pointer = val; |
@@ -234,8 +232,7 @@ acpi_status acpi_ns_root_initialize(void) | |||
234 | /* Store pointer to value descriptor in the Node */ | 232 | /* Store pointer to value descriptor in the Node */ |
235 | 233 | ||
236 | status = acpi_ns_attach_object(new_node, obj_desc, | 234 | status = acpi_ns_attach_object(new_node, obj_desc, |
237 | ACPI_GET_OBJECT_TYPE | 235 | obj_desc->common.type); |
238 | (obj_desc)); | ||
239 | 236 | ||
240 | /* Remove local reference to the object */ | 237 | /* Remove local reference to the object */ |
241 | 238 | ||
@@ -315,10 +312,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
315 | return_ACPI_STATUS(AE_NO_NAMESPACE); | 312 | return_ACPI_STATUS(AE_NO_NAMESPACE); |
316 | } | 313 | } |
317 | 314 | ||
318 | /* | 315 | /* Get the prefix scope. A null scope means use the root scope */ |
319 | * Get the prefix scope. | 316 | |
320 | * A null scope means use the root scope | ||
321 | */ | ||
322 | if ((!scope_info) || (!scope_info->scope.node)) { | 317 | if ((!scope_info) || (!scope_info->scope.node)) { |
323 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 318 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
324 | "Null scope prefix, using root node (%p)\n", | 319 | "Null scope prefix, using root node (%p)\n", |
@@ -338,8 +333,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
338 | if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) { | 333 | if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) { |
339 | /* | 334 | /* |
340 | * This node might not be a actual "scope" node (such as a | 335 | * This node might not be a actual "scope" node (such as a |
341 | * Device/Method, etc.) It could be a Package or other object node. | 336 | * Device/Method, etc.) It could be a Package or other object |
342 | * Backup up the tree to find the containing scope node. | 337 | * node. Backup up the tree to find the containing scope node. |
343 | */ | 338 | */ |
344 | while (!acpi_ns_opens_scope(prefix_node->type) && | 339 | while (!acpi_ns_opens_scope(prefix_node->type) && |
345 | prefix_node->type != ACPI_TYPE_ANY) { | 340 | prefix_node->type != ACPI_TYPE_ANY) { |
@@ -349,7 +344,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
349 | } | 344 | } |
350 | } | 345 | } |
351 | 346 | ||
352 | /* Save type TBD: may be no longer necessary */ | 347 | /* Save type. TBD: may be no longer necessary */ |
353 | 348 | ||
354 | type_to_check_for = type; | 349 | type_to_check_for = type; |
355 | 350 | ||
@@ -414,6 +409,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
414 | /* Name is fully qualified, no search rules apply */ | 409 | /* Name is fully qualified, no search rules apply */ |
415 | 410 | ||
416 | search_parent_flag = ACPI_NS_NO_UPSEARCH; | 411 | search_parent_flag = ACPI_NS_NO_UPSEARCH; |
412 | |||
417 | /* | 413 | /* |
418 | * Point past this prefix to the name segment | 414 | * Point past this prefix to the name segment |
419 | * part or the next Parent Prefix | 415 | * part or the next Parent Prefix |
@@ -429,7 +425,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
429 | /* Current scope has no parent scope */ | 425 | /* Current scope has no parent scope */ |
430 | 426 | ||
431 | ACPI_ERROR((AE_INFO, | 427 | ACPI_ERROR((AE_INFO, |
432 | "ACPI path has too many parent prefixes (^) - reached beyond root node")); | 428 | "ACPI path has too many parent prefixes (^) " |
429 | "- reached beyond root node")); | ||
433 | return_ACPI_STATUS(AE_NOT_FOUND); | 430 | return_ACPI_STATUS(AE_NOT_FOUND); |
434 | } | 431 | } |
435 | } | 432 | } |
@@ -531,9 +528,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
531 | while (num_segments && current_node) { | 528 | while (num_segments && current_node) { |
532 | num_segments--; | 529 | num_segments--; |
533 | if (!num_segments) { | 530 | if (!num_segments) { |
534 | /* | 531 | |
535 | * This is the last segment, enable typechecking | 532 | /* This is the last segment, enable typechecking */ |
536 | */ | 533 | |
537 | this_search_type = type; | 534 | this_search_type = type; |
538 | 535 | ||
539 | /* | 536 | /* |
@@ -584,9 +581,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
584 | if (num_segments > 0) { | 581 | if (num_segments > 0) { |
585 | /* | 582 | /* |
586 | * If we have an alias to an object that opens a scope (such as a | 583 | * If we have an alias to an object that opens a scope (such as a |
587 | * device or processor), we need to dereference the alias here so that | 584 | * device or processor), we need to dereference the alias here so |
588 | * we can access any children of the original node (via the remaining | 585 | * that we can access any children of the original node (via the |
589 | * segments). | 586 | * remaining segments). |
590 | */ | 587 | */ |
591 | if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { | 588 | if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) { |
592 | if (!this_node->object) { | 589 | if (!this_node->object) { |
@@ -594,8 +591,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
594 | } | 591 | } |
595 | 592 | ||
596 | if (acpi_ns_opens_scope | 593 | if (acpi_ns_opens_scope |
597 | (((struct acpi_namespace_node *)this_node-> | 594 | (((struct acpi_namespace_node *) |
598 | object)->type)) { | 595 | this_node->object)->type)) { |
599 | this_node = | 596 | this_node = |
600 | (struct acpi_namespace_node *) | 597 | (struct acpi_namespace_node *) |
601 | this_node->object; | 598 | this_node->object; |
@@ -639,8 +636,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
639 | 636 | ||
640 | /* | 637 | /* |
641 | * If this is the last name segment and we are not looking for a | 638 | * If this is the last name segment and we are not looking for a |
642 | * specific type, but the type of found object is known, use that type | 639 | * specific type, but the type of found object is known, use that |
643 | * to (later) see if it opens a scope. | 640 | * type to (later) see if it opens a scope. |
644 | */ | 641 | */ |
645 | if (type == ACPI_TYPE_ANY) { | 642 | if (type == ACPI_TYPE_ANY) { |
646 | type = this_node->type; | 643 | type = this_node->type; |
@@ -653,9 +650,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
653 | current_node = this_node; | 650 | current_node = this_node; |
654 | } | 651 | } |
655 | 652 | ||
656 | /* | 653 | /* Always check if we need to open a new scope */ |
657 | * Always check if we need to open a new scope | 654 | |
658 | */ | ||
659 | if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) { | 655 | if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) { |
660 | /* | 656 | /* |
661 | * If entry is a type which opens a scope, push the new scope on the | 657 | * If entry is a type which opens a scope, push the new scope on the |
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index f976d848fe82..aceb93111967 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -76,8 +76,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) | |||
76 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); | 76 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++); |
77 | 77 | ||
78 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | 78 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS |
79 | temp = | 79 | temp = acpi_gbl_ns_node_list->total_allocated - |
80 | acpi_gbl_ns_node_list->total_allocated - | ||
81 | acpi_gbl_ns_node_list->total_freed; | 80 | acpi_gbl_ns_node_list->total_freed; |
82 | if (temp > acpi_gbl_ns_node_list->max_occupied) { | 81 | if (temp > acpi_gbl_ns_node_list->max_occupied) { |
83 | acpi_gbl_ns_node_list->max_occupied = temp; | 82 | acpi_gbl_ns_node_list->max_occupied = temp; |
@@ -145,9 +144,8 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) | |||
145 | 144 | ||
146 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 145 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); |
147 | 146 | ||
148 | /* | 147 | /* Detach an object if there is one, then delete the node */ |
149 | * Detach an object if there is one, then delete the node | 148 | |
150 | */ | ||
151 | acpi_ns_detach_object(node); | 149 | acpi_ns_detach_object(node); |
152 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | 150 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); |
153 | return_VOID; | 151 | return_VOID; |
@@ -183,9 +181,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp | |||
183 | ACPI_FUNCTION_TRACE(ns_install_node); | 181 | ACPI_FUNCTION_TRACE(ns_install_node); |
184 | 182 | ||
185 | /* | 183 | /* |
186 | * Get the owner ID from the Walk state | 184 | * Get the owner ID from the Walk state. The owner ID is used to track |
187 | * The owner ID is used to track table deletion and | 185 | * table deletion and deletion of objects created by methods. |
188 | * deletion of objects created by methods | ||
189 | */ | 186 | */ |
190 | if (walk_state) { | 187 | if (walk_state) { |
191 | owner_id = walk_state->owner_id; | 188 | owner_id = walk_state->owner_id; |
@@ -260,9 +257,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
260 | return_VOID; | 257 | return_VOID; |
261 | } | 258 | } |
262 | 259 | ||
263 | /* | 260 | /* Deallocate all children at this level */ |
264 | * Deallocate all children at this level | 261 | |
265 | */ | ||
266 | do { | 262 | do { |
267 | 263 | ||
268 | /* Get the things we need */ | 264 | /* Get the things we need */ |
@@ -285,9 +281,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
285 | "Object %p, Remaining %X\n", child_node, | 281 | "Object %p, Remaining %X\n", child_node, |
286 | acpi_gbl_current_node_count)); | 282 | acpi_gbl_current_node_count)); |
287 | 283 | ||
288 | /* | 284 | /* Detach an object if there is one, then free the child node */ |
289 | * Detach an object if there is one, then free the child node | 285 | |
290 | */ | ||
291 | acpi_ns_detach_object(child_node); | 286 | acpi_ns_detach_object(child_node); |
292 | 287 | ||
293 | /* Now we can delete the node */ | 288 | /* Now we can delete the node */ |
@@ -304,7 +299,6 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
304 | /* Clear the parent's child pointer */ | 299 | /* Clear the parent's child pointer */ |
305 | 300 | ||
306 | parent_node->child = NULL; | 301 | parent_node->child = NULL; |
307 | |||
308 | return_VOID; | 302 | return_VOID; |
309 | } | 303 | } |
310 | 304 | ||
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 0da33c8e9ba2..2bad613db73a 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -181,6 +181,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
181 | } | 181 | } |
182 | 182 | ||
183 | this_node = acpi_ns_map_handle_to_node(obj_handle); | 183 | this_node = acpi_ns_map_handle_to_node(obj_handle); |
184 | if (!this_node) { | ||
185 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n", | ||
186 | obj_handle)); | ||
187 | return (AE_OK); | ||
188 | } | ||
189 | |||
184 | type = this_node->type; | 190 | type = this_node->type; |
185 | 191 | ||
186 | /* Check if the owner matches */ | 192 | /* Check if the owner matches */ |
@@ -214,9 +220,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
214 | acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); | 220 | acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); |
215 | } | 221 | } |
216 | 222 | ||
217 | /* | 223 | /* Now we can print out the pertinent information */ |
218 | * Now we can print out the pertinent information | 224 | |
219 | */ | ||
220 | acpi_os_printf(" %-12s %p %2.2X ", | 225 | acpi_os_printf(" %-12s %p %2.2X ", |
221 | acpi_ut_get_type_name(type), this_node, | 226 | acpi_ut_get_type_name(type), this_node, |
222 | this_node->owner_id); | 227 | this_node->owner_id); |
@@ -509,7 +514,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
509 | 514 | ||
510 | case ACPI_DESC_TYPE_OPERAND: | 515 | case ACPI_DESC_TYPE_OPERAND: |
511 | 516 | ||
512 | obj_type = ACPI_GET_OBJECT_TYPE(obj_desc); | 517 | obj_type = obj_desc->common.type; |
513 | 518 | ||
514 | if (obj_type > ACPI_TYPE_LOCAL_MAX) { | 519 | if (obj_type > ACPI_TYPE_LOCAL_MAX) { |
515 | acpi_os_printf | 520 | acpi_os_printf |
@@ -539,9 +544,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
539 | goto cleanup; | 544 | goto cleanup; |
540 | } | 545 | } |
541 | 546 | ||
542 | /* | 547 | /* Valid object, get the pointer to next level, if any */ |
543 | * Valid object, get the pointer to next level, if any | 548 | |
544 | */ | ||
545 | switch (obj_type) { | 549 | switch (obj_type) { |
546 | case ACPI_TYPE_BUFFER: | 550 | case ACPI_TYPE_BUFFER: |
547 | case ACPI_TYPE_STRING: | 551 | case ACPI_TYPE_STRING: |
@@ -602,14 +606,14 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
602 | * display_type - 0 or ACPI_DISPLAY_SUMMARY | 606 | * display_type - 0 or ACPI_DISPLAY_SUMMARY |
603 | * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX | 607 | * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX |
604 | * for an effectively unlimited depth. | 608 | * for an effectively unlimited depth. |
605 | * owner_id - Dump only objects owned by this ID. Use | 609 | * owner_id - Dump only objects owned by this ID. Use |
606 | * ACPI_UINT32_MAX to match all owners. | 610 | * ACPI_UINT32_MAX to match all owners. |
607 | * start_handle - Where in namespace to start/end search | 611 | * start_handle - Where in namespace to start/end search |
608 | * | 612 | * |
609 | * RETURN: None | 613 | * RETURN: None |
610 | * | 614 | * |
611 | * DESCRIPTION: Dump typed objects within the loaded namespace. | 615 | * DESCRIPTION: Dump typed objects within the loaded namespace. Uses |
612 | * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object. | 616 | * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object. |
613 | * | 617 | * |
614 | ******************************************************************************/ | 618 | ******************************************************************************/ |
615 | 619 | ||
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 0f3d5f9b5966..8e7dec1176c9 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -155,7 +155,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
155 | } | 155 | } |
156 | 156 | ||
157 | 157 | ||
158 | ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:", | 158 | ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method", |
159 | ACPI_LV_INFO, _COMPONENT); | 159 | ACPI_LV_INFO, _COMPONENT); |
160 | 160 | ||
161 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 161 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 13501cb81863..2adfcf329e15 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -103,7 +103,8 @@ acpi_status acpi_ns_initialize_objects(void) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 105 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
106 | "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n", | 106 | "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd " |
107 | "Buffers %hd/%hd Packages (%hd nodes)\n", | ||
107 | info.op_region_init, info.op_region_count, | 108 | info.op_region_init, info.op_region_count, |
108 | info.field_init, info.field_count, | 109 | info.field_init, info.field_count, |
109 | info.buffer_init, info.buffer_count, | 110 | info.buffer_init, info.buffer_count, |
@@ -148,7 +149,8 @@ acpi_status acpi_ns_initialize_devices(void) | |||
148 | info.num_INI = 0; | 149 | info.num_INI = 0; |
149 | 150 | ||
150 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 151 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
151 | "Initializing Device/Processor/Thermal objects by executing _INI methods:")); | 152 | "Initializing Device/Processor/Thermal objects " |
153 | "by executing _INI methods:")); | ||
152 | 154 | ||
153 | /* Tree analysis: find all subtrees that contain _INI methods */ | 155 | /* Tree analysis: find all subtrees that contain _INI methods */ |
154 | 156 | ||
@@ -180,7 +182,8 @@ acpi_status acpi_ns_initialize_devices(void) | |||
180 | } | 182 | } |
181 | 183 | ||
182 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, | 184 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, |
183 | "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n", | 185 | "\nExecuted %hd _INI methods requiring %hd _STA executions " |
186 | "(examined %hd objects)\n", | ||
184 | info.num_INI, info.num_STA, info.device_count)); | 187 | info.num_INI, info.num_STA, info.device_count)); |
185 | 188 | ||
186 | return_ACPI_STATUS(status); | 189 | return_ACPI_STATUS(status); |
@@ -263,16 +266,14 @@ acpi_ns_init_one_object(acpi_handle obj_handle, | |||
263 | return (AE_OK); | 266 | return (AE_OK); |
264 | } | 267 | } |
265 | 268 | ||
266 | /* | 269 | /* If the object is already initialized, nothing else to do */ |
267 | * If the object is already initialized, nothing else to do | 270 | |
268 | */ | ||
269 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { | 271 | if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { |
270 | return (AE_OK); | 272 | return (AE_OK); |
271 | } | 273 | } |
272 | 274 | ||
273 | /* | 275 | /* Must lock the interpreter before executing AML code */ |
274 | * Must lock the interpreter before executing AML code | 276 | |
275 | */ | ||
276 | acpi_ex_enter_interpreter(); | 277 | acpi_ex_enter_interpreter(); |
277 | 278 | ||
278 | /* | 279 | /* |
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index a0ba9e12379e..dcd7a6adbbbc 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -128,12 +128,12 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | |||
128 | * parse trees. | 128 | * parse trees. |
129 | */ | 129 | */ |
130 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 130 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
131 | "**** Begin Table Method Parsing and Object Initialization ****\n")); | 131 | "**** Begin Table Method Parsing and Object Initialization\n")); |
132 | 132 | ||
133 | status = acpi_ds_initialize_objects(table_index, node); | 133 | status = acpi_ds_initialize_objects(table_index, node); |
134 | 134 | ||
135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 135 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
136 | "**** Completed Table Method Parsing and Object Initialization ****\n")); | 136 | "**** Completed Table Method Parsing and Object Initialization\n")); |
137 | 137 | ||
138 | return_ACPI_STATUS(status); | 138 | return_ACPI_STATUS(status); |
139 | } | 139 | } |
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 08a97a57f8f9..3eb20bfda9d8 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
@@ -209,8 +209,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
209 | 209 | ||
210 | obj_desc = node->object; | 210 | obj_desc = node->object; |
211 | 211 | ||
212 | if (!obj_desc || | 212 | if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) { |
213 | (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) { | ||
214 | return_VOID; | 213 | return_VOID; |
215 | } | 214 | } |
216 | 215 | ||
@@ -220,8 +219,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
220 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { | 219 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { |
221 | node->object = obj_desc->common.next_object; | 220 | node->object = obj_desc->common.next_object; |
222 | if (node->object && | 221 | if (node->object && |
223 | (ACPI_GET_OBJECT_TYPE(node->object) != | 222 | ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) { |
224 | ACPI_TYPE_LOCAL_DATA)) { | ||
225 | node->object = node->object->common.next_object; | 223 | node->object = node->object->common.next_object; |
226 | } | 224 | } |
227 | } | 225 | } |
@@ -267,7 +265,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct | |||
267 | ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND) | 265 | ((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND) |
268 | && (ACPI_GET_DESCRIPTOR_TYPE(node->object) != | 266 | && (ACPI_GET_DESCRIPTOR_TYPE(node->object) != |
269 | ACPI_DESC_TYPE_NAMED)) | 267 | ACPI_DESC_TYPE_NAMED)) |
270 | || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) { | 268 | || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) { |
271 | return_PTR(NULL); | 269 | return_PTR(NULL); |
272 | } | 270 | } |
273 | 271 | ||
@@ -294,9 +292,9 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union | |||
294 | ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc); | 292 | ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc); |
295 | 293 | ||
296 | if ((!obj_desc) || | 294 | if ((!obj_desc) || |
297 | (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) || | 295 | (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) || |
298 | (!obj_desc->common.next_object) || | 296 | (!obj_desc->common.next_object) || |
299 | (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) == | 297 | ((obj_desc->common.next_object)->common.type == |
300 | ACPI_TYPE_LOCAL_DATA)) { | 298 | ACPI_TYPE_LOCAL_DATA)) { |
301 | return_PTR(NULL); | 299 | return_PTR(NULL); |
302 | } | 300 | } |
@@ -331,7 +329,7 @@ acpi_ns_attach_data(struct acpi_namespace_node *node, | |||
331 | prev_obj_desc = NULL; | 329 | prev_obj_desc = NULL; |
332 | obj_desc = node->object; | 330 | obj_desc = node->object; |
333 | while (obj_desc) { | 331 | while (obj_desc) { |
334 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && | 332 | if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) && |
335 | (obj_desc->data.handler == handler)) { | 333 | (obj_desc->data.handler == handler)) { |
336 | return (AE_ALREADY_EXISTS); | 334 | return (AE_ALREADY_EXISTS); |
337 | } | 335 | } |
@@ -385,7 +383,7 @@ acpi_ns_detach_data(struct acpi_namespace_node * node, | |||
385 | prev_obj_desc = NULL; | 383 | prev_obj_desc = NULL; |
386 | obj_desc = node->object; | 384 | obj_desc = node->object; |
387 | while (obj_desc) { | 385 | while (obj_desc) { |
388 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && | 386 | if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) && |
389 | (obj_desc->data.handler == handler)) { | 387 | (obj_desc->data.handler == handler)) { |
390 | if (prev_obj_desc) { | 388 | if (prev_obj_desc) { |
391 | prev_obj_desc->common.next_object = | 389 | prev_obj_desc->common.next_object = |
@@ -428,7 +426,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node * node, | |||
428 | 426 | ||
429 | obj_desc = node->object; | 427 | obj_desc = node->object; |
430 | while (obj_desc) { | 428 | while (obj_desc) { |
431 | if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) && | 429 | if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) && |
432 | (obj_desc->data.handler == handler)) { | 430 | (obj_desc->data.handler == handler)) { |
433 | *data = obj_desc->data.pointer; | 431 | *data = obj_desc->data.pointer; |
434 | return (AE_OK); | 432 | return (AE_OK); |
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index b9e8d0070b6f..662a4bd5b621 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c | |||
@@ -176,9 +176,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) | |||
176 | * performs another complete parse of the AML. | 176 | * performs another complete parse of the AML. |
177 | */ | 177 | */ |
178 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); | 178 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); |
179 | status = | 179 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, |
180 | acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index, | 180 | table_index, start_node); |
181 | start_node); | ||
182 | if (ACPI_FAILURE(status)) { | 181 | if (ACPI_FAILURE(status)) { |
183 | return_ACPI_STATUS(status); | 182 | return_ACPI_STATUS(status); |
184 | } | 183 | } |
@@ -193,9 +192,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) | |||
193 | * parse objects are all cached. | 192 | * parse objects are all cached. |
194 | */ | 193 | */ |
195 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); | 194 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n")); |
196 | status = | 195 | status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, |
197 | acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index, | 196 | table_index, start_node); |
198 | start_node); | ||
199 | if (ACPI_FAILURE(status)) { | 197 | if (ACPI_FAILURE(status)) { |
200 | return_ACPI_STATUS(status); | 198 | return_ACPI_STATUS(status); |
201 | } | 199 | } |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 452703290d35..d9e8cbc6e679 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -79,7 +79,9 @@ acpi_ns_check_package(char *pathname, | |||
79 | static acpi_status | 79 | static acpi_status |
80 | acpi_ns_check_package_elements(char *pathname, | 80 | acpi_ns_check_package_elements(char *pathname, |
81 | union acpi_operand_object **elements, | 81 | union acpi_operand_object **elements, |
82 | u8 type1, u32 count1, u8 type2, u32 count2); | 82 | u8 type1, |
83 | u32 count1, | ||
84 | u8 type2, u32 count2, u32 start_index); | ||
83 | 85 | ||
84 | static acpi_status | 86 | static acpi_status |
85 | acpi_ns_check_object_type(char *pathname, | 87 | acpi_ns_check_object_type(char *pathname, |
@@ -221,7 +223,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
221 | 223 | ||
222 | /* For returned Package objects, check the type of all sub-objects */ | 224 | /* For returned Package objects, check the type of all sub-objects */ |
223 | 225 | ||
224 | if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) { | 226 | if (return_object->common.type == ACPI_TYPE_PACKAGE) { |
225 | status = | 227 | status = |
226 | acpi_ns_check_package(pathname, return_object_ptr, | 228 | acpi_ns_check_package(pathname, return_object_ptr, |
227 | predefined); | 229 | predefined); |
@@ -302,7 +304,8 @@ acpi_ns_check_parameter_count(char *pathname, | |||
302 | if ((user_param_count != required_params_current) && | 304 | if ((user_param_count != required_params_current) && |
303 | (user_param_count != required_params_old)) { | 305 | (user_param_count != required_params_old)) { |
304 | ACPI_WARNING((AE_INFO, | 306 | ACPI_WARNING((AE_INFO, |
305 | "%s: Parameter count mismatch - caller passed %d, ACPI requires %d", | 307 | "%s: Parameter count mismatch - " |
308 | "caller passed %d, ACPI requires %d", | ||
306 | pathname, user_param_count, | 309 | pathname, user_param_count, |
307 | required_params_current)); | 310 | required_params_current)); |
308 | } | 311 | } |
@@ -472,7 +475,7 @@ acpi_ns_check_package(char *pathname, | |||
472 | package->ret_info. | 475 | package->ret_info. |
473 | object_type2, | 476 | object_type2, |
474 | package->ret_info. | 477 | package->ret_info. |
475 | count2); | 478 | count2, 0); |
476 | if (ACPI_FAILURE(status)) { | 479 | if (ACPI_FAILURE(status)) { |
477 | return (status); | 480 | return (status); |
478 | } | 481 | } |
@@ -623,7 +626,7 @@ acpi_ns_check_package(char *pathname, | |||
623 | object_type2, | 626 | object_type2, |
624 | package-> | 627 | package-> |
625 | ret_info. | 628 | ret_info. |
626 | count2); | 629 | count2, 0); |
627 | if (ACPI_FAILURE(status)) { | 630 | if (ACPI_FAILURE(status)) { |
628 | return (status); | 631 | return (status); |
629 | } | 632 | } |
@@ -672,7 +675,8 @@ acpi_ns_check_package(char *pathname, | |||
672 | object_type1, | 675 | object_type1, |
673 | sub_package-> | 676 | sub_package-> |
674 | package. | 677 | package. |
675 | count, 0, 0); | 678 | count, 0, 0, |
679 | 0); | ||
676 | if (ACPI_FAILURE(status)) { | 680 | if (ACPI_FAILURE(status)) { |
677 | return (status); | 681 | return (status); |
678 | } | 682 | } |
@@ -710,7 +714,8 @@ acpi_ns_check_package(char *pathname, | |||
710 | ret_info. | 714 | ret_info. |
711 | object_type1, | 715 | object_type1, |
712 | (expected_count | 716 | (expected_count |
713 | - 1), 0, 0); | 717 | - 1), 0, 0, |
718 | 1); | ||
714 | if (ACPI_FAILURE(status)) { | 719 | if (ACPI_FAILURE(status)) { |
715 | return (status); | 720 | return (status); |
716 | } | 721 | } |
@@ -758,6 +763,7 @@ acpi_ns_check_package(char *pathname, | |||
758 | * Count1 - Count for first group | 763 | * Count1 - Count for first group |
759 | * Type2 - Object type for second group | 764 | * Type2 - Object type for second group |
760 | * Count2 - Count for second group | 765 | * Count2 - Count for second group |
766 | * start_index - Start of the first group of elements | ||
761 | * | 767 | * |
762 | * RETURN: Status | 768 | * RETURN: Status |
763 | * | 769 | * |
@@ -769,7 +775,9 @@ acpi_ns_check_package(char *pathname, | |||
769 | static acpi_status | 775 | static acpi_status |
770 | acpi_ns_check_package_elements(char *pathname, | 776 | acpi_ns_check_package_elements(char *pathname, |
771 | union acpi_operand_object **elements, | 777 | union acpi_operand_object **elements, |
772 | u8 type1, u32 count1, u8 type2, u32 count2) | 778 | u8 type1, |
779 | u32 count1, | ||
780 | u8 type2, u32 count2, u32 start_index) | ||
773 | { | 781 | { |
774 | union acpi_operand_object **this_element = elements; | 782 | union acpi_operand_object **this_element = elements; |
775 | acpi_status status; | 783 | acpi_status status; |
@@ -782,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
782 | */ | 790 | */ |
783 | for (i = 0; i < count1; i++) { | 791 | for (i = 0; i < count1; i++) { |
784 | status = acpi_ns_check_object_type(pathname, this_element, | 792 | status = acpi_ns_check_object_type(pathname, this_element, |
785 | type1, i); | 793 | type1, i + start_index); |
786 | if (ACPI_FAILURE(status)) { | 794 | if (ACPI_FAILURE(status)) { |
787 | return (status); | 795 | return (status); |
788 | } | 796 | } |
@@ -791,7 +799,8 @@ acpi_ns_check_package_elements(char *pathname, | |||
791 | 799 | ||
792 | for (i = 0; i < count2; i++) { | 800 | for (i = 0; i < count2; i++) { |
793 | status = acpi_ns_check_object_type(pathname, this_element, | 801 | status = acpi_ns_check_object_type(pathname, this_element, |
794 | type2, (i + count1)); | 802 | type2, |
803 | (i + count1 + start_index)); | ||
795 | if (ACPI_FAILURE(status)) { | 804 | if (ACPI_FAILURE(status)) { |
796 | return (status); | 805 | return (status); |
797 | } | 806 | } |
@@ -858,7 +867,7 @@ acpi_ns_check_object_type(char *pathname, | |||
858 | * from all of the predefined names (including elements of returned | 867 | * from all of the predefined names (including elements of returned |
859 | * packages) | 868 | * packages) |
860 | */ | 869 | */ |
861 | switch (ACPI_GET_OBJECT_TYPE(return_object)) { | 870 | switch (return_object->common.type) { |
862 | case ACPI_TYPE_INTEGER: | 871 | case ACPI_TYPE_INTEGER: |
863 | return_btype = ACPI_RTYPE_INTEGER; | 872 | return_btype = ACPI_RTYPE_INTEGER; |
864 | break; | 873 | break; |
@@ -901,7 +910,7 @@ acpi_ns_check_object_type(char *pathname, | |||
901 | 910 | ||
902 | /* For reference objects, check that the reference type is correct */ | 911 | /* For reference objects, check that the reference type is correct */ |
903 | 912 | ||
904 | if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) { | 913 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { |
905 | status = acpi_ns_check_reference(pathname, return_object); | 914 | status = acpi_ns_check_reference(pathname, return_object); |
906 | } | 915 | } |
907 | 916 | ||
@@ -974,7 +983,8 @@ acpi_ns_check_reference(char *pathname, | |||
974 | } | 983 | } |
975 | 984 | ||
976 | ACPI_WARNING((AE_INFO, | 985 | ACPI_WARNING((AE_INFO, |
977 | "%s: Return type mismatch - unexpected reference object type [%s] %2.2X", | 986 | "%s: Return type mismatch - " |
987 | "unexpected reference object type [%s] %2.2X", | ||
978 | pathname, acpi_ut_get_reference_name(return_object), | 988 | pathname, acpi_ut_get_reference_name(return_object), |
979 | return_object->reference.class)); | 989 | return_object->reference.class)); |
980 | 990 | ||
@@ -1006,7 +1016,7 @@ acpi_ns_repair_object(u32 expected_btypes, | |||
1006 | union acpi_operand_object *new_object; | 1016 | union acpi_operand_object *new_object; |
1007 | acpi_size length; | 1017 | acpi_size length; |
1008 | 1018 | ||
1009 | switch (ACPI_GET_OBJECT_TYPE(return_object)) { | 1019 | switch (return_object->common.type) { |
1010 | case ACPI_TYPE_BUFFER: | 1020 | case ACPI_TYPE_BUFFER: |
1011 | 1021 | ||
1012 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | 1022 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { |
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 6fea13f3f52d..f9b4f51bf8f2 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -167,7 +167,8 @@ acpi_ns_search_one_scope(u32 target_name, | |||
167 | /* Searched entire namespace level, not found */ | 167 | /* Searched entire namespace level, not found */ |
168 | 168 | ||
169 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 169 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
170 | "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n", | 170 | "Name [%4.4s] (%s) not found in search in scope [%4.4s] " |
171 | "%p first child %p\n", | ||
171 | ACPI_CAST_PTR(char, &target_name), | 172 | ACPI_CAST_PTR(char, &target_name), |
172 | acpi_ut_get_type_name(type), | 173 | acpi_ut_get_type_name(type), |
173 | acpi_ut_get_node_name(parent_node), parent_node, | 174 | acpi_ut_get_node_name(parent_node), parent_node, |
@@ -239,9 +240,8 @@ acpi_ns_search_parent_tree(u32 target_name, | |||
239 | acpi_ut_get_node_name(parent_node), | 240 | acpi_ut_get_node_name(parent_node), |
240 | ACPI_CAST_PTR(char, &target_name))); | 241 | ACPI_CAST_PTR(char, &target_name))); |
241 | 242 | ||
242 | /* | 243 | /* Search parents until target is found or we have backed up to the root */ |
243 | * Search parents until target is found or we have backed up to the root | 244 | |
244 | */ | ||
245 | while (parent_node) { | 245 | while (parent_node) { |
246 | /* | 246 | /* |
247 | * Search parent scope. Use TYPE_ANY because we don't care about the | 247 | * Search parent scope. Use TYPE_ANY because we don't care about the |
@@ -395,9 +395,9 @@ acpi_ns_search_and_enter(u32 target_name, | |||
395 | return_ACPI_STATUS(AE_NO_MEMORY); | 395 | return_ACPI_STATUS(AE_NO_MEMORY); |
396 | } | 396 | } |
397 | #ifdef ACPI_ASL_COMPILER | 397 | #ifdef ACPI_ASL_COMPILER |
398 | /* | 398 | |
399 | * Node is an object defined by an External() statement | 399 | /* Node is an object defined by an External() statement */ |
400 | */ | 400 | |
401 | if (flags & ACPI_NS_EXTERNAL) { | 401 | if (flags & ACPI_NS_EXTERNAL) { |
402 | new_node->flags |= ANOBJ_IS_EXTERNAL; | 402 | new_node->flags |= ANOBJ_IS_EXTERNAL; |
403 | } | 403 | } |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 3e1149bf4aa5..78277ed08339 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -325,9 +325,8 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) | |||
325 | next_external_char++; | 325 | next_external_char++; |
326 | } | 326 | } |
327 | } else { | 327 | } else { |
328 | /* | 328 | /* Handle Carat prefixes */ |
329 | * Handle Carat prefixes | 329 | |
330 | */ | ||
331 | while (*next_external_char == '^') { | 330 | while (*next_external_char == '^') { |
332 | info->num_carats++; | 331 | info->num_carats++; |
333 | next_external_char++; | 332 | next_external_char++; |
@@ -552,9 +551,8 @@ acpi_ns_externalize_name(u32 internal_name_length, | |||
552 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 551 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
553 | } | 552 | } |
554 | 553 | ||
555 | /* | 554 | /* Check for a prefix (one '\' | one or more '^') */ |
556 | * Check for a prefix (one '\' | one or more '^'). | 555 | |
557 | */ | ||
558 | switch (internal_name[0]) { | 556 | switch (internal_name[0]) { |
559 | case '\\': | 557 | case '\\': |
560 | prefix_length = 1; | 558 | prefix_length = 1; |
@@ -580,7 +578,7 @@ acpi_ns_externalize_name(u32 internal_name_length, | |||
580 | } | 578 | } |
581 | 579 | ||
582 | /* | 580 | /* |
583 | * Check for object names. Note that there could be 0-255 of these | 581 | * Check for object names. Note that there could be 0-255 of these |
584 | * 4-byte elements. | 582 | * 4-byte elements. |
585 | */ | 583 | */ |
586 | if (prefix_length < internal_name_length) { | 584 | if (prefix_length < internal_name_length) { |
@@ -637,9 +635,8 @@ acpi_ns_externalize_name(u32 internal_name_length, | |||
637 | return_ACPI_STATUS(AE_BAD_PATHNAME); | 635 | return_ACPI_STATUS(AE_BAD_PATHNAME); |
638 | } | 636 | } |
639 | 637 | ||
640 | /* | 638 | /* Build the converted_name */ |
641 | * Build converted_name | 639 | |
642 | */ | ||
643 | *converted_name = ACPI_ALLOCATE_ZEROED(required_length); | 640 | *converted_name = ACPI_ALLOCATE_ZEROED(required_length); |
644 | if (!(*converted_name)) { | 641 | if (!(*converted_name)) { |
645 | return_ACPI_STATUS(AE_NO_MEMORY); | 642 | return_ACPI_STATUS(AE_NO_MEMORY); |
@@ -685,6 +682,9 @@ acpi_ns_externalize_name(u32 internal_name_length, | |||
685 | * and keep all pointers within this subsystem - however this introduces | 682 | * and keep all pointers within this subsystem - however this introduces |
686 | * more (and perhaps unnecessary) overhead. | 683 | * more (and perhaps unnecessary) overhead. |
687 | * | 684 | * |
685 | * The current implemenation is basically a placeholder until such time comes | ||
686 | * that it is needed. | ||
687 | * | ||
688 | ******************************************************************************/ | 688 | ******************************************************************************/ |
689 | 689 | ||
690 | struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) | 690 | struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) |
@@ -692,9 +692,8 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) | |||
692 | 692 | ||
693 | ACPI_FUNCTION_ENTRY(); | 693 | ACPI_FUNCTION_ENTRY(); |
694 | 694 | ||
695 | /* | 695 | /* Parameter validation */ |
696 | * Simple implementation | 696 | |
697 | */ | ||
698 | if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { | 697 | if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { |
699 | return (acpi_gbl_root_node); | 698 | return (acpi_gbl_root_node); |
700 | } | 699 | } |
@@ -872,7 +871,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
872 | (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, | 871 | (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, |
873 | return_node); | 872 | return_node); |
874 | if (ACPI_FAILURE(status)) { | 873 | if (ACPI_FAILURE(status)) { |
875 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", | 874 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n", |
876 | pathname, acpi_format_exception(status))); | 875 | pathname, acpi_format_exception(status))); |
877 | } | 876 | } |
878 | 877 | ||
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 200895fa2728..83e3aa6d4b9b 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -135,8 +135,8 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct | |||
135 | * starting (and ending) at the node specified by start_handle. | 135 | * starting (and ending) at the node specified by start_handle. |
136 | * The user_function is called whenever a node that matches | 136 | * The user_function is called whenever a node that matches |
137 | * the type parameter is found. If the user function returns | 137 | * the type parameter is found. If the user function returns |
138 | * a non-zero value, the search is terminated immediately and this | 138 | * a non-zero value, the search is terminated immediately and |
139 | * value is returned to the caller. | 139 | * this value is returned to the caller. |
140 | * | 140 | * |
141 | * The point of this procedure is to provide a generic namespace | 141 | * The point of this procedure is to provide a generic namespace |
142 | * walk routine that can be called from multiple places to | 142 | * walk routine that can be called from multiple places to |
@@ -200,10 +200,10 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
200 | /* | 200 | /* |
201 | * Ignore all temporary namespace nodes (created during control | 201 | * Ignore all temporary namespace nodes (created during control |
202 | * method execution) unless told otherwise. These temporary nodes | 202 | * method execution) unless told otherwise. These temporary nodes |
203 | * can cause a race condition because they can be deleted during the | 203 | * can cause a race condition because they can be deleted during |
204 | * execution of the user function (if the namespace is unlocked before | 204 | * the execution of the user function (if the namespace is |
205 | * invocation of the user function.) Only the debugger namespace dump | 205 | * unlocked before invocation of the user function.) Only the |
206 | * will examine the temporary nodes. | 206 | * debugger namespace dump will examine the temporary nodes. |
207 | */ | 207 | */ |
208 | if ((child_node->flags & ANOBJ_TEMPORARY) && | 208 | if ((child_node->flags & ANOBJ_TEMPORARY) && |
209 | !(flags & ACPI_NS_WALK_TEMP_NODES)) { | 209 | !(flags & ACPI_NS_WALK_TEMP_NODES)) { |
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 22a7171ac1ed..045054037c2d 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -387,8 +387,7 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) | |||
387 | 387 | ||
388 | /* We are interested in reference objects only */ | 388 | /* We are interested in reference objects only */ |
389 | 389 | ||
390 | if (ACPI_GET_OBJECT_TYPE(info->return_object) != | 390 | if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) { |
391 | ACPI_TYPE_LOCAL_REFERENCE) { | ||
392 | return; | 391 | return; |
393 | } | 392 | } |
394 | 393 | ||
@@ -476,21 +475,40 @@ acpi_walk_namespace(acpi_object_type type, | |||
476 | } | 475 | } |
477 | 476 | ||
478 | /* | 477 | /* |
479 | * Lock the namespace around the walk. | 478 | * Need to acquire the namespace reader lock to prevent interference |
480 | * The namespace will be unlocked/locked around each call | 479 | * with any concurrent table unloads (which causes the deletion of |
481 | * to the user function - since this function | 480 | * namespace objects). We cannot allow the deletion of a namespace node |
482 | * must be allowed to make Acpi calls itself. | 481 | * while the user function is using it. The exception to this are the |
482 | * nodes created and deleted during control method execution -- these | ||
483 | * nodes are marked as temporary nodes and are ignored by the namespace | ||
484 | * walk. Thus, control methods can be executed while holding the | ||
485 | * namespace deletion lock (and the user function can execute control | ||
486 | * methods.) | ||
487 | */ | ||
488 | status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock); | ||
489 | if (ACPI_FAILURE(status)) { | ||
490 | return status; | ||
491 | } | ||
492 | |||
493 | /* | ||
494 | * Lock the namespace around the walk. The namespace will be | ||
495 | * unlocked/locked around each call to the user function - since the user | ||
496 | * function must be allowed to make ACPICA calls itself (for example, it | ||
497 | * will typically execute control methods during device enumeration.) | ||
483 | */ | 498 | */ |
484 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 499 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
485 | if (ACPI_FAILURE(status)) { | 500 | if (ACPI_FAILURE(status)) { |
486 | return_ACPI_STATUS(status); | 501 | goto unlock_and_exit; |
487 | } | 502 | } |
488 | 503 | ||
489 | status = acpi_ns_walk_namespace(type, start_object, max_depth, | 504 | status = acpi_ns_walk_namespace(type, start_object, max_depth, |
490 | ACPI_NS_WALK_UNLOCK, | 505 | ACPI_NS_WALK_UNLOCK, user_function, |
491 | user_function, context, return_value); | 506 | context, return_value); |
492 | 507 | ||
493 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 508 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
509 | |||
510 | unlock_and_exit: | ||
511 | (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock); | ||
494 | return_ACPI_STATUS(status); | 512 | return_ACPI_STATUS(status); |
495 | } | 513 | } |
496 | 514 | ||
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 52865ee6bc77..b6667ff059e5 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -557,9 +557,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
557 | table_index++) { | 557 | table_index++) { |
558 | if (*sub_object_list && /* Null object allowed */ | 558 | if (*sub_object_list && /* Null object allowed */ |
559 | ((ACPI_TYPE_STRING == | 559 | ((ACPI_TYPE_STRING == |
560 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) || | 560 | (*sub_object_list)->common.type) || |
561 | ((ACPI_TYPE_LOCAL_REFERENCE == | 561 | ((ACPI_TYPE_LOCAL_REFERENCE == |
562 | ACPI_GET_OBJECT_TYPE(*sub_object_list)) && | 562 | (*sub_object_list)->common.type) && |
563 | ((*sub_object_list)->reference.class == | 563 | ((*sub_object_list)->reference.class == |
564 | ACPI_REFCLASS_NAME)))) { | 564 | ACPI_REFCLASS_NAME)))) { |
565 | name_found = TRUE; | 565 | name_found = TRUE; |
@@ -575,8 +575,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
575 | /* Was a String type found? */ | 575 | /* Was a String type found? */ |
576 | 576 | ||
577 | if (name_found) { | 577 | if (name_found) { |
578 | if (ACPI_GET_OBJECT_TYPE(*sub_object_list) == | 578 | if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) { |
579 | ACPI_TYPE_STRING) { | ||
580 | /* | 579 | /* |
581 | * The length String.Length field does not include the | 580 | * The length String.Length field does not include the |
582 | * terminating NULL, add 1 | 581 | * terminating NULL, add 1 |
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 61566b1a0616..663f692fffcf 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c | |||
@@ -212,7 +212,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
212 | 212 | ||
213 | /* Each element of the top-level package must also be a package */ | 213 | /* Each element of the top-level package must also be a package */ |
214 | 214 | ||
215 | if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) { | 215 | if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) { |
216 | ACPI_ERROR((AE_INFO, | 216 | ACPI_ERROR((AE_INFO, |
217 | "(PRT[%X]) Need sub-package, found %s", | 217 | "(PRT[%X]) Need sub-package, found %s", |
218 | index, | 218 | index, |
@@ -240,7 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
240 | /* 1) First subobject: Dereference the PRT.Address */ | 240 | /* 1) First subobject: Dereference the PRT.Address */ |
241 | 241 | ||
242 | obj_desc = sub_object_list[0]; | 242 | obj_desc = sub_object_list[0]; |
243 | if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) { | 243 | if (obj_desc->common.type != ACPI_TYPE_INTEGER) { |
244 | ACPI_ERROR((AE_INFO, | 244 | ACPI_ERROR((AE_INFO, |
245 | "(PRT[%X].Address) Need Integer, found %s", | 245 | "(PRT[%X].Address) Need Integer, found %s", |
246 | index, | 246 | index, |
@@ -253,7 +253,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
253 | /* 2) Second subobject: Dereference the PRT.Pin */ | 253 | /* 2) Second subobject: Dereference the PRT.Pin */ |
254 | 254 | ||
255 | obj_desc = sub_object_list[1]; | 255 | obj_desc = sub_object_list[1]; |
256 | if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) { | 256 | if (obj_desc->common.type != ACPI_TYPE_INTEGER) { |
257 | ACPI_ERROR((AE_INFO, | 257 | ACPI_ERROR((AE_INFO, |
258 | "(PRT[%X].Pin) Need Integer, found %s", | 258 | "(PRT[%X].Pin) Need Integer, found %s", |
259 | index, | 259 | index, |
@@ -265,7 +265,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
265 | * If BIOS erroneously reversed the _PRT source_name and source_index, | 265 | * If BIOS erroneously reversed the _PRT source_name and source_index, |
266 | * then reverse them back. | 266 | * then reverse them back. |
267 | */ | 267 | */ |
268 | if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) != | 268 | if ((sub_object_list[3])->common.type != |
269 | ACPI_TYPE_INTEGER) { | 269 | ACPI_TYPE_INTEGER) { |
270 | if (acpi_gbl_enable_interpreter_slack) { | 270 | if (acpi_gbl_enable_interpreter_slack) { |
271 | source_name_index = 3; | 271 | source_name_index = 3; |
@@ -291,8 +291,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
291 | * other ACPI implementations. | 291 | * other ACPI implementations. |
292 | */ | 292 | */ |
293 | obj_desc = sub_object_list[3]; | 293 | obj_desc = sub_object_list[3]; |
294 | if (!obj_desc | 294 | if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) { |
295 | || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) { | ||
296 | sub_object_list[3] = sub_object_list[2]; | 295 | sub_object_list[3] = sub_object_list[2]; |
297 | sub_object_list[2] = obj_desc; | 296 | sub_object_list[2] = obj_desc; |
298 | 297 | ||
@@ -307,7 +306,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
307 | */ | 306 | */ |
308 | obj_desc = sub_object_list[source_name_index]; | 307 | obj_desc = sub_object_list[source_name_index]; |
309 | if (obj_desc) { | 308 | if (obj_desc) { |
310 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 309 | switch (obj_desc->common.type) { |
311 | case ACPI_TYPE_LOCAL_REFERENCE: | 310 | case ACPI_TYPE_LOCAL_REFERENCE: |
312 | 311 | ||
313 | if (obj_desc->reference.class != | 312 | if (obj_desc->reference.class != |
@@ -380,7 +379,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
380 | /* 4) Fourth subobject: Dereference the PRT.source_index */ | 379 | /* 4) Fourth subobject: Dereference the PRT.source_index */ |
381 | 380 | ||
382 | obj_desc = sub_object_list[source_index_index]; | 381 | obj_desc = sub_object_list[source_index_index]; |
383 | if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) { | 382 | if (obj_desc->common.type != ACPI_TYPE_INTEGER) { |
384 | ACPI_ERROR((AE_INFO, | 383 | ACPI_ERROR((AE_INFO, |
385 | "(PRT[%X].SourceIndex) Need Integer, found %s", | 384 | "(PRT[%X].SourceIndex) Need Integer, found %s", |
386 | index, | 385 | index, |
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 3636e4f8fb73..71e655d14cb0 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void); | |||
57 | 57 | ||
58 | static void acpi_tb_validate_fadt(void); | 58 | static void acpi_tb_validate_fadt(void); |
59 | 59 | ||
60 | static void acpi_tb_setup_fadt_registers(void); | ||
61 | |||
60 | /* Table for conversion of FADT to common internal format and FADT validation */ | 62 | /* Table for conversion of FADT to common internal format and FADT validation */ |
61 | 63 | ||
62 | typedef struct acpi_fadt_info { | 64 | typedef struct acpi_fadt_info { |
@@ -130,7 +132,38 @@ static struct acpi_fadt_info fadt_info_table[] = { | |||
130 | ACPI_FADT_SEPARATE_LENGTH} | 132 | ACPI_FADT_SEPARATE_LENGTH} |
131 | }; | 133 | }; |
132 | 134 | ||
133 | #define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) | 135 | #define ACPI_FADT_INFO_ENTRIES \ |
136 | (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info)) | ||
137 | |||
138 | /* Table used to split Event Blocks into separate status/enable registers */ | ||
139 | |||
140 | typedef struct acpi_fadt_pm_info { | ||
141 | struct acpi_generic_address *target; | ||
142 | u8 source; | ||
143 | u8 register_num; | ||
144 | |||
145 | } acpi_fadt_pm_info; | ||
146 | |||
147 | static struct acpi_fadt_pm_info fadt_pm_info_table[] = { | ||
148 | {&acpi_gbl_xpm1a_status, | ||
149 | ACPI_FADT_OFFSET(xpm1a_event_block), | ||
150 | 0}, | ||
151 | |||
152 | {&acpi_gbl_xpm1a_enable, | ||
153 | ACPI_FADT_OFFSET(xpm1a_event_block), | ||
154 | 1}, | ||
155 | |||
156 | {&acpi_gbl_xpm1b_status, | ||
157 | ACPI_FADT_OFFSET(xpm1b_event_block), | ||
158 | 0}, | ||
159 | |||
160 | {&acpi_gbl_xpm1b_enable, | ||
161 | ACPI_FADT_OFFSET(xpm1b_event_block), | ||
162 | 1} | ||
163 | }; | ||
164 | |||
165 | #define ACPI_FADT_PM_INFO_ENTRIES \ | ||
166 | (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info)) | ||
134 | 167 | ||
135 | /******************************************************************************* | 168 | /******************************************************************************* |
136 | * | 169 | * |
@@ -172,7 +205,6 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | |||
172 | * FUNCTION: acpi_tb_parse_fadt | 205 | * FUNCTION: acpi_tb_parse_fadt |
173 | * | 206 | * |
174 | * PARAMETERS: table_index - Index for the FADT | 207 | * PARAMETERS: table_index - Index for the FADT |
175 | * Flags - Flags | ||
176 | * | 208 | * |
177 | * RETURN: None | 209 | * RETURN: None |
178 | * | 210 | * |
@@ -181,7 +213,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, | |||
181 | * | 213 | * |
182 | ******************************************************************************/ | 214 | ******************************************************************************/ |
183 | 215 | ||
184 | void acpi_tb_parse_fadt(u32 table_index, u8 flags) | 216 | void acpi_tb_parse_fadt(u32 table_index) |
185 | { | 217 | { |
186 | u32 length; | 218 | u32 length; |
187 | struct acpi_table_header *table; | 219 | struct acpi_table_header *table; |
@@ -208,7 +240,7 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags) | |||
208 | */ | 240 | */ |
209 | (void)acpi_tb_verify_checksum(table, length); | 241 | (void)acpi_tb_verify_checksum(table, length); |
210 | 242 | ||
211 | /* Obtain a local copy of the FADT in common ACPI 2.0+ format */ | 243 | /* Create a local copy of the FADT in common ACPI 2.0+ format */ |
212 | 244 | ||
213 | acpi_tb_create_local_fadt(table, length); | 245 | acpi_tb_create_local_fadt(table, length); |
214 | 246 | ||
@@ -219,10 +251,10 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags) | |||
219 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ | 251 | /* Obtain the DSDT and FACS tables via their addresses within the FADT */ |
220 | 252 | ||
221 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, | 253 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt, |
222 | flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); | 254 | ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); |
223 | 255 | ||
224 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, | 256 | acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs, |
225 | flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); | 257 | ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); |
226 | } | 258 | } |
227 | 259 | ||
228 | /******************************************************************************* | 260 | /******************************************************************************* |
@@ -266,11 +298,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
266 | ACPI_MEMCPY(&acpi_gbl_FADT, table, | 298 | ACPI_MEMCPY(&acpi_gbl_FADT, table, |
267 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); | 299 | ACPI_MIN(length, sizeof(struct acpi_table_fadt))); |
268 | 300 | ||
269 | /* | 301 | /* Convert the local copy of the FADT to the common internal format */ |
270 | * 1) Convert the local copy of the FADT to the common internal format | 302 | |
271 | * 2) Validate some of the important values within the FADT | ||
272 | */ | ||
273 | acpi_tb_convert_fadt(); | 303 | acpi_tb_convert_fadt(); |
304 | |||
305 | /* Validate FADT values now, before we make any changes */ | ||
306 | |||
307 | acpi_tb_validate_fadt(); | ||
308 | |||
309 | /* Initialize the global ACPI register structures */ | ||
310 | |||
311 | acpi_tb_setup_fadt_registers(); | ||
274 | } | 312 | } |
275 | 313 | ||
276 | /******************************************************************************* | 314 | /******************************************************************************* |
@@ -282,31 +320,35 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
282 | * RETURN: None | 320 | * RETURN: None |
283 | * | 321 | * |
284 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. | 322 | * DESCRIPTION: Converts all versions of the FADT to a common internal format. |
285 | * Expand all 32-bit addresses to 64-bit. | 323 | * Expand 32-bit addresses to 64-bit as necessary. |
286 | * | 324 | * |
287 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), | 325 | * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), |
288 | * and must contain a copy of the actual FADT. | 326 | * and must contain a copy of the actual FADT. |
289 | * | 327 | * |
290 | * ACPICA will use the "X" fields of the FADT for all addresses. | 328 | * Notes on 64-bit register addresses: |
329 | * | ||
330 | * After this FADT conversion, later ACPICA code will only use the 64-bit "X" | ||
331 | * fields of the FADT for all ACPI register addresses. | ||
291 | * | 332 | * |
292 | * "X" fields are optional extensions to the original V1.0 fields. Even if | 333 | * The 64-bit "X" fields are optional extensions to the original 32-bit FADT |
293 | * they are present in the structure, they can be optionally not used by | 334 | * V1.0 fields. Even if they are present in the FADT, they are optional and |
294 | * setting them to zero. Therefore, we must selectively expand V1.0 fields | 335 | * are unused if the BIOS sets them to zero. Therefore, we must copy/expand |
295 | * if the corresponding X field is zero. | 336 | * 32-bit V1.0 fields if the corresponding X field is zero. |
296 | * | 337 | * |
297 | * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding | 338 | * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the |
298 | * "X" fields. | 339 | * corresponding "X" fields in the internal FADT. |
299 | * | 340 | * |
300 | * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by | 341 | * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded |
301 | * expanding the corresponding ACPI 1.0 field. | 342 | * to the corresponding 64-bit X fields. For compatibility with other ACPI |
343 | * implementations, we ignore the 64-bit field if the 32-bit field is valid, | ||
344 | * regardless of whether the host OS is 32-bit or 64-bit. | ||
302 | * | 345 | * |
303 | ******************************************************************************/ | 346 | ******************************************************************************/ |
304 | 347 | ||
305 | static void acpi_tb_convert_fadt(void) | 348 | static void acpi_tb_convert_fadt(void) |
306 | { | 349 | { |
307 | u8 pm1_register_bit_width; | 350 | struct acpi_generic_address *address64; |
308 | u8 pm1_register_byte_width; | 351 | u32 address32; |
309 | struct acpi_generic_address *target64; | ||
310 | u32 i; | 352 | u32 i; |
311 | 353 | ||
312 | /* Update the local FADT table header length */ | 354 | /* Update the local FADT table header length */ |
@@ -355,140 +397,56 @@ static void acpi_tb_convert_fadt(void) | |||
355 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" | 397 | * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X" |
356 | * generic address structures as necessary. Later code will always use | 398 | * generic address structures as necessary. Later code will always use |
357 | * the 64-bit address structures. | 399 | * the 64-bit address structures. |
400 | * | ||
401 | * March 2009: | ||
402 | * We now always use the 32-bit address if it is valid (non-null). This | ||
403 | * is not in accordance with the ACPI specification which states that | ||
404 | * the 64-bit address supersedes the 32-bit version, but we do this for | ||
405 | * compatibility with other ACPI implementations. Most notably, in the | ||
406 | * case where both the 32 and 64 versions are non-null, we use the 32-bit | ||
407 | * version. This is the only address that is guaranteed to have been | ||
408 | * tested by the BIOS manufacturer. | ||
358 | */ | 409 | */ |
359 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 410 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
360 | target64 = | 411 | address32 = *ACPI_ADD_PTR(u32, |
361 | ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, | 412 | &acpi_gbl_FADT, |
362 | fadt_info_table[i].address64); | 413 | fadt_info_table[i].address32); |
363 | 414 | ||
364 | /* Expand only if the 64-bit X target is null */ | 415 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, |
416 | &acpi_gbl_FADT, | ||
417 | fadt_info_table[i].address64); | ||
365 | 418 | ||
366 | if (!target64->address) { | 419 | /* |
420 | * If both 32- and 64-bit addresses are valid (non-zero), | ||
421 | * they must match. | ||
422 | */ | ||
423 | if (address64->address && address32 && | ||
424 | (address64->address != (u64) address32)) { | ||
425 | ACPI_ERROR((AE_INFO, | ||
426 | "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32", | ||
427 | fadt_info_table[i].name, address32, | ||
428 | ACPI_FORMAT_UINT64(address64->address))); | ||
429 | } | ||
367 | 430 | ||
368 | /* The space_id is always I/O for the 32-bit legacy address fields */ | 431 | /* Always use 32-bit address if it is valid (non-null) */ |
369 | 432 | ||
370 | acpi_tb_init_generic_address(target64, | 433 | if (address32) { |
434 | /* | ||
435 | * Copy the 32-bit address to the 64-bit GAS structure. The | ||
436 | * Space ID is always I/O for 32-bit legacy address fields | ||
437 | */ | ||
438 | acpi_tb_init_generic_address(address64, | ||
371 | ACPI_ADR_SPACE_SYSTEM_IO, | 439 | ACPI_ADR_SPACE_SYSTEM_IO, |
372 | *ACPI_ADD_PTR(u8, | 440 | *ACPI_ADD_PTR(u8, |
373 | &acpi_gbl_FADT, | 441 | &acpi_gbl_FADT, |
374 | fadt_info_table | 442 | fadt_info_table |
375 | [i].length), | 443 | [i].length), |
376 | (u64) * ACPI_ADD_PTR(u32, | 444 | address32); |
377 | &acpi_gbl_FADT, | ||
378 | fadt_info_table | ||
379 | [i]. | ||
380 | address32)); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* Validate FADT values now, before we make any changes */ | ||
385 | |||
386 | acpi_tb_validate_fadt(); | ||
387 | |||
388 | /* | ||
389 | * Optionally check all register lengths against the default values and | ||
390 | * update them if they are incorrect. | ||
391 | */ | ||
392 | if (acpi_gbl_use_default_register_widths) { | ||
393 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | ||
394 | target64 = | ||
395 | ACPI_ADD_PTR(struct acpi_generic_address, | ||
396 | &acpi_gbl_FADT, | ||
397 | fadt_info_table[i].address64); | ||
398 | |||
399 | /* | ||
400 | * If a valid register (Address != 0) and the (default_length > 0) | ||
401 | * (Not a GPE register), then check the width against the default. | ||
402 | */ | ||
403 | if ((target64->address) && | ||
404 | (fadt_info_table[i].default_length > 0) && | ||
405 | (fadt_info_table[i].default_length != | ||
406 | target64->bit_width)) { | ||
407 | ACPI_WARNING((AE_INFO, | ||
408 | "Invalid length for %s: %d, using default %d", | ||
409 | fadt_info_table[i].name, | ||
410 | target64->bit_width, | ||
411 | fadt_info_table[i]. | ||
412 | default_length)); | ||
413 | |||
414 | /* Incorrect size, set width to the default */ | ||
415 | |||
416 | target64->bit_width = | ||
417 | fadt_info_table[i].default_length; | ||
418 | } | ||
419 | } | 445 | } |
420 | } | 446 | } |
421 | |||
422 | /* | ||
423 | * Get the length of the individual PM1 registers (enable and status). | ||
424 | * Each register is defined to be (event block length / 2). | ||
425 | */ | ||
426 | pm1_register_bit_width = | ||
427 | (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width); | ||
428 | pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width); | ||
429 | |||
430 | /* | ||
431 | * Adjust the lengths of the PM1 Event Blocks so that they can be used to | ||
432 | * access the PM1 status register(s). Use (width / 2) | ||
433 | */ | ||
434 | acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width; | ||
435 | acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width; | ||
436 | |||
437 | /* | ||
438 | * Calculate separate GAS structs for the PM1 Enable registers. | ||
439 | * These addresses do not appear (directly) in the FADT, so it is | ||
440 | * useful to calculate them once, here. | ||
441 | * | ||
442 | * The PM event blocks are split into two register blocks, first is the | ||
443 | * PM Status Register block, followed immediately by the PM Enable | ||
444 | * Register block. Each is of length (xpm1x_event_block.bit_width/2). | ||
445 | * | ||
446 | * On various systems the v2 fields (and particularly the bit widths) | ||
447 | * cannot be relied upon, though. Hence resort to using the v1 length | ||
448 | * here (and warn about the inconsistency). | ||
449 | */ | ||
450 | if (acpi_gbl_FADT.xpm1a_event_block.bit_width | ||
451 | != acpi_gbl_FADT.pm1_event_length * 8) | ||
452 | printk(KERN_WARNING "FADT: " | ||
453 | "X_PM1a_EVT_BLK.bit_width (%u) does not match" | ||
454 | " PM1_EVT_LEN (%u)\n", | ||
455 | acpi_gbl_FADT.xpm1a_event_block.bit_width, | ||
456 | acpi_gbl_FADT.pm1_event_length); | ||
457 | |||
458 | /* The PM1A register block is required */ | ||
459 | |||
460 | acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable, | ||
461 | acpi_gbl_FADT.xpm1a_event_block.space_id, | ||
462 | pm1_register_byte_width, | ||
463 | (acpi_gbl_FADT.xpm1a_event_block.address + | ||
464 | pm1_register_byte_width)); | ||
465 | /* Don't forget to copy space_id of the GAS */ | ||
466 | acpi_gbl_xpm1a_enable.space_id = | ||
467 | acpi_gbl_FADT.xpm1a_event_block.space_id; | ||
468 | |||
469 | /* The PM1B register block is optional, ignore if not present */ | ||
470 | |||
471 | if (acpi_gbl_FADT.xpm1b_event_block.address) { | ||
472 | if (acpi_gbl_FADT.xpm1b_event_block.bit_width | ||
473 | != acpi_gbl_FADT.pm1_event_length * 8) | ||
474 | printk(KERN_WARNING "FADT: " | ||
475 | "X_PM1b_EVT_BLK.bit_width (%u) does not match" | ||
476 | " PM1_EVT_LEN (%u)\n", | ||
477 | acpi_gbl_FADT.xpm1b_event_block.bit_width, | ||
478 | acpi_gbl_FADT.pm1_event_length); | ||
479 | acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable, | ||
480 | acpi_gbl_FADT.xpm1b_event_block.space_id, | ||
481 | pm1_register_byte_width, | ||
482 | (acpi_gbl_FADT.xpm1b_event_block. | ||
483 | address + pm1_register_byte_width)); | ||
484 | /* Don't forget to copy space_id of the GAS */ | ||
485 | acpi_gbl_xpm1b_enable.space_id = | ||
486 | acpi_gbl_FADT.xpm1b_event_block.space_id; | ||
487 | |||
488 | } | ||
489 | } | 447 | } |
490 | 448 | ||
491 | /****************************************************************************** | 449 | /******************************************************************************* |
492 | * | 450 | * |
493 | * FUNCTION: acpi_tb_validate_fadt | 451 | * FUNCTION: acpi_tb_validate_fadt |
494 | * | 452 | * |
@@ -525,18 +483,22 @@ static void acpi_tb_validate_fadt(void) | |||
525 | (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { | 483 | (acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) { |
526 | ACPI_WARNING((AE_INFO, | 484 | ACPI_WARNING((AE_INFO, |
527 | "32/64X FACS address mismatch in FADT - " | 485 | "32/64X FACS address mismatch in FADT - " |
528 | "two FACS tables! %8.8X/%8.8X%8.8X", | 486 | "%8.8X/%8.8X%8.8X, using 32", |
529 | acpi_gbl_FADT.facs, | 487 | acpi_gbl_FADT.facs, |
530 | ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs))); | 488 | ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs))); |
489 | |||
490 | acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs; | ||
531 | } | 491 | } |
532 | 492 | ||
533 | if (acpi_gbl_FADT.dsdt && | 493 | if (acpi_gbl_FADT.dsdt && |
534 | (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { | 494 | (acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) { |
535 | ACPI_WARNING((AE_INFO, | 495 | ACPI_WARNING((AE_INFO, |
536 | "32/64X DSDT address mismatch in FADT - " | 496 | "32/64X DSDT address mismatch in FADT - " |
537 | "two DSDT tables! %8.8X/%8.8X%8.8X", | 497 | "%8.8X/%8.8X%8.8X, using 32", |
538 | acpi_gbl_FADT.dsdt, | 498 | acpi_gbl_FADT.dsdt, |
539 | ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt))); | 499 | ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt))); |
500 | |||
501 | acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt; | ||
540 | } | 502 | } |
541 | 503 | ||
542 | /* Examine all of the 64-bit extended address fields (X fields) */ | 504 | /* Examine all of the 64-bit extended address fields (X fields) */ |
@@ -561,7 +523,8 @@ static void acpi_tb_validate_fadt(void) | |||
561 | * For each extended field, check for length mismatch between the | 523 | * For each extended field, check for length mismatch between the |
562 | * legacy length field and the corresponding 64-bit X length field. | 524 | * legacy length field and the corresponding 64-bit X length field. |
563 | */ | 525 | */ |
564 | if (address64 && (address64->bit_width != ACPI_MUL_8(length))) { | 526 | if (address64->address && |
527 | (address64->bit_width != ACPI_MUL_8(length))) { | ||
565 | ACPI_WARNING((AE_INFO, | 528 | ACPI_WARNING((AE_INFO, |
566 | "32/64X length mismatch in %s: %d/%d", | 529 | "32/64X length mismatch in %s: %d/%d", |
567 | name, ACPI_MUL_8(length), | 530 | name, ACPI_MUL_8(length), |
@@ -575,7 +538,8 @@ static void acpi_tb_validate_fadt(void) | |||
575 | */ | 538 | */ |
576 | if (!address64->address || !length) { | 539 | if (!address64->address || !length) { |
577 | ACPI_ERROR((AE_INFO, | 540 | ACPI_ERROR((AE_INFO, |
578 | "Required field %s has zero address and/or length: %8.8X%8.8X/%X", | 541 | "Required field %s has zero address and/or length:" |
542 | " %8.8X%8.8X/%X", | ||
579 | name, | 543 | name, |
580 | ACPI_FORMAT_UINT64(address64-> | 544 | ACPI_FORMAT_UINT64(address64-> |
581 | address), | 545 | address), |
@@ -584,27 +548,112 @@ static void acpi_tb_validate_fadt(void) | |||
584 | } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { | 548 | } else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) { |
585 | /* | 549 | /* |
586 | * Field is optional (PM2Control, GPE0, GPE1) AND has its own | 550 | * Field is optional (PM2Control, GPE0, GPE1) AND has its own |
587 | * length field. If present, both the address and length must be valid. | 551 | * length field. If present, both the address and length must |
552 | * be valid. | ||
588 | */ | 553 | */ |
589 | if ((address64->address && !length) | 554 | if ((address64->address && !length) || |
590 | || (!address64->address && length)) { | 555 | (!address64->address && length)) { |
591 | ACPI_WARNING((AE_INFO, | 556 | ACPI_WARNING((AE_INFO, |
592 | "Optional field %s has zero address or length: %8.8X%8.8X/%X", | 557 | "Optional field %s has zero address or length: " |
558 | "%8.8X%8.8X/%X", | ||
593 | name, | 559 | name, |
594 | ACPI_FORMAT_UINT64(address64-> | 560 | ACPI_FORMAT_UINT64(address64-> |
595 | address), | 561 | address), |
596 | length)); | 562 | length)); |
597 | } | 563 | } |
598 | } | 564 | } |
565 | } | ||
566 | } | ||
599 | 567 | ||
600 | /* If both 32- and 64-bit addresses are valid (non-zero), they must match */ | 568 | /******************************************************************************* |
569 | * | ||
570 | * FUNCTION: acpi_tb_setup_fadt_registers | ||
571 | * | ||
572 | * PARAMETERS: None, uses acpi_gbl_FADT. | ||
573 | * | ||
574 | * RETURN: None | ||
575 | * | ||
576 | * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally, | ||
577 | * force FADT register definitions to their default lengths. | ||
578 | * | ||
579 | ******************************************************************************/ | ||
601 | 580 | ||
602 | if (address64->address && *address32 && | 581 | static void acpi_tb_setup_fadt_registers(void) |
603 | (address64->address != (u64) * address32)) { | 582 | { |
604 | ACPI_ERROR((AE_INFO, | 583 | struct acpi_generic_address *target64; |
605 | "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X", | 584 | struct acpi_generic_address *source64; |
606 | name, *address32, | 585 | u8 pm1_register_byte_width; |
607 | ACPI_FORMAT_UINT64(address64->address))); | 586 | u32 i; |
587 | |||
588 | /* | ||
589 | * Optionally check all register lengths against the default values and | ||
590 | * update them if they are incorrect. | ||
591 | */ | ||
592 | if (acpi_gbl_use_default_register_widths) { | ||
593 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | ||
594 | target64 = | ||
595 | ACPI_ADD_PTR(struct acpi_generic_address, | ||
596 | &acpi_gbl_FADT, | ||
597 | fadt_info_table[i].address64); | ||
598 | |||
599 | /* | ||
600 | * If a valid register (Address != 0) and the (default_length > 0) | ||
601 | * (Not a GPE register), then check the width against the default. | ||
602 | */ | ||
603 | if ((target64->address) && | ||
604 | (fadt_info_table[i].default_length > 0) && | ||
605 | (fadt_info_table[i].default_length != | ||
606 | target64->bit_width)) { | ||
607 | ACPI_WARNING((AE_INFO, | ||
608 | "Invalid length for %s: %d, using default %d", | ||
609 | fadt_info_table[i].name, | ||
610 | target64->bit_width, | ||
611 | fadt_info_table[i]. | ||
612 | default_length)); | ||
613 | |||
614 | /* Incorrect size, set width to the default */ | ||
615 | |||
616 | target64->bit_width = | ||
617 | fadt_info_table[i].default_length; | ||
618 | } | ||
619 | } | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * Get the length of the individual PM1 registers (enable and status). | ||
624 | * Each register is defined to be (event block length / 2). Extra divide | ||
625 | * by 8 converts bits to bytes. | ||
626 | */ | ||
627 | pm1_register_byte_width = (u8) | ||
628 | ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width); | ||
629 | |||
630 | /* | ||
631 | * Calculate separate GAS structs for the PM1x (A/B) Status and Enable | ||
632 | * registers. These addresses do not appear (directly) in the FADT, so it | ||
633 | * is useful to pre-calculate them from the PM1 Event Block definitions. | ||
634 | * | ||
635 | * The PM event blocks are split into two register blocks, first is the | ||
636 | * PM Status Register block, followed immediately by the PM Enable | ||
637 | * Register block. Each is of length (pm1_event_length/2) | ||
638 | * | ||
639 | * Note: The PM1A event block is required by the ACPI specification. | ||
640 | * However, the PM1B event block is optional and is rarely, if ever, | ||
641 | * used. | ||
642 | */ | ||
643 | |||
644 | for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) { | ||
645 | source64 = | ||
646 | ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT, | ||
647 | fadt_pm_info_table[i].source); | ||
648 | |||
649 | if (source64->address) { | ||
650 | acpi_tb_init_generic_address(fadt_pm_info_table[i]. | ||
651 | target, source64->space_id, | ||
652 | pm1_register_byte_width, | ||
653 | source64->address + | ||
654 | (fadt_pm_info_table[i]. | ||
655 | register_num * | ||
656 | pm1_register_byte_width)); | ||
608 | } | 657 | } |
609 | } | 658 | } |
610 | } | 659 | } |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 37374b21969d..f865d5a096de 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -103,7 +103,9 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |||
103 | * | 103 | * |
104 | * RETURN: Status | 104 | * RETURN: Status |
105 | * | 105 | * |
106 | * DESCRIPTION: This function is called to add the ACPI table | 106 | * DESCRIPTION: This function is called to add an ACPI table. It is used to |
107 | * dynamically load tables via the Load and load_table AML | ||
108 | * operators. | ||
107 | * | 109 | * |
108 | ******************************************************************************/ | 110 | ******************************************************************************/ |
109 | 111 | ||
@@ -112,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
112 | { | 114 | { |
113 | u32 i; | 115 | u32 i; |
114 | acpi_status status = AE_OK; | 116 | acpi_status status = AE_OK; |
117 | struct acpi_table_header *override_table = NULL; | ||
115 | 118 | ||
116 | ACPI_FUNCTION_TRACE(tb_add_table); | 119 | ACPI_FUNCTION_TRACE(tb_add_table); |
117 | 120 | ||
@@ -201,6 +204,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
201 | } | 204 | } |
202 | } | 205 | } |
203 | 206 | ||
207 | /* | ||
208 | * ACPI Table Override: | ||
209 | * Allow the host to override dynamically loaded tables. | ||
210 | */ | ||
211 | status = acpi_os_table_override(table_desc->pointer, &override_table); | ||
212 | if (ACPI_SUCCESS(status) && override_table) { | ||
213 | ACPI_INFO((AE_INFO, | ||
214 | "%4.4s @ 0x%p Table override, replaced with:", | ||
215 | table_desc->pointer->signature, | ||
216 | ACPI_CAST_PTR(void, table_desc->address))); | ||
217 | |||
218 | /* We can delete the table that was passed as a parameter */ | ||
219 | |||
220 | acpi_tb_delete_table(table_desc); | ||
221 | |||
222 | /* Setup descriptor for the new table */ | ||
223 | |||
224 | table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table); | ||
225 | table_desc->pointer = override_table; | ||
226 | table_desc->length = override_table->length; | ||
227 | table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE; | ||
228 | } | ||
229 | |||
204 | /* Add the table to the global root table list */ | 230 | /* Add the table to the global root table list */ |
205 | 231 | ||
206 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, | 232 | status = acpi_tb_store_table(table_desc->address, table_desc->pointer, |
@@ -247,8 +273,9 @@ acpi_status acpi_tb_resize_root_table_list(void) | |||
247 | /* Increase the Table Array size */ | 273 | /* Increase the Table Array size */ |
248 | 274 | ||
249 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. | 275 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. |
250 | size + ACPI_ROOT_TABLE_SIZE_INCREMENT) | 276 | size + |
251 | * sizeof(struct acpi_table_desc)); | 277 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * |
278 | sizeof(struct acpi_table_desc)); | ||
252 | if (!tables) { | 279 | if (!tables) { |
253 | ACPI_ERROR((AE_INFO, | 280 | ACPI_ERROR((AE_INFO, |
254 | "Could not allocate new root table array")); | 281 | "Could not allocate new root table array")); |
@@ -407,27 +434,56 @@ void acpi_tb_terminate(void) | |||
407 | * | 434 | * |
408 | * PARAMETERS: table_index - Table index | 435 | * PARAMETERS: table_index - Table index |
409 | * | 436 | * |
410 | * RETURN: None | 437 | * RETURN: Status |
411 | * | 438 | * |
412 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. | 439 | * DESCRIPTION: Delete all namespace objects created when this table was loaded. |
413 | * | 440 | * |
414 | ******************************************************************************/ | 441 | ******************************************************************************/ |
415 | 442 | ||
416 | void acpi_tb_delete_namespace_by_owner(u32 table_index) | 443 | acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) |
417 | { | 444 | { |
418 | acpi_owner_id owner_id; | 445 | acpi_owner_id owner_id; |
446 | acpi_status status; | ||
447 | |||
448 | ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); | ||
449 | |||
450 | status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
451 | if (ACPI_FAILURE(status)) { | ||
452 | return_ACPI_STATUS(status); | ||
453 | } | ||
454 | |||
455 | if (table_index >= acpi_gbl_root_table_list.count) { | ||
456 | |||
457 | /* The table index does not exist */ | ||
419 | 458 | ||
420 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | ||
421 | if (table_index < acpi_gbl_root_table_list.count) { | ||
422 | owner_id = | ||
423 | acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
424 | } else { | ||
425 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 459 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
426 | return; | 460 | return_ACPI_STATUS(AE_NOT_EXIST); |
427 | } | 461 | } |
428 | 462 | ||
463 | /* Get the owner ID for this table, used to delete namespace nodes */ | ||
464 | |||
465 | owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; | ||
429 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 466 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
467 | |||
468 | /* | ||
469 | * Need to acquire the namespace writer lock to prevent interference | ||
470 | * with any concurrent namespace walks. The interpreter must be | ||
471 | * released during the deletion since the acquisition of the deletion | ||
472 | * lock may block, and also since the execution of a namespace walk | ||
473 | * must be allowed to use the interpreter. | ||
474 | */ | ||
475 | acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | ||
476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | ||
477 | |||
430 | acpi_ns_delete_namespace_by_owner(owner_id); | 478 | acpi_ns_delete_namespace_by_owner(owner_id); |
479 | if (ACPI_FAILURE(status)) { | ||
480 | return_ACPI_STATUS(status); | ||
481 | } | ||
482 | |||
483 | acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); | ||
484 | |||
485 | status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); | ||
486 | return_ACPI_STATUS(status); | ||
431 | } | 487 | } |
432 | 488 | ||
433 | /******************************************************************************* | 489 | /******************************************************************************* |
@@ -535,8 +591,8 @@ u8 acpi_tb_is_table_loaded(u32 table_index) | |||
535 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 591 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
536 | if (table_index < acpi_gbl_root_table_list.count) { | 592 | if (table_index < acpi_gbl_root_table_list.count) { |
537 | is_loaded = (u8) | 593 | is_loaded = (u8) |
538 | (acpi_gbl_root_table_list.tables[table_index]. | 594 | (acpi_gbl_root_table_list.tables[table_index].flags & |
539 | flags & ACPI_TABLE_IS_LOADED); | 595 | ACPI_TABLE_IS_LOADED); |
540 | } | 596 | } |
541 | 597 | ||
542 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 598 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 22ce48985720..ef7d2c2d8f0b 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -177,19 +177,23 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
177 | struct acpi_table_header *header) | 177 | struct acpi_table_header *header) |
178 | { | 178 | { |
179 | 179 | ||
180 | /* | ||
181 | * The reason that the Address is cast to a void pointer is so that we | ||
182 | * can use %p which will work properly on both 32-bit and 64-bit hosts. | ||
183 | */ | ||
180 | if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { | 184 | if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) { |
181 | 185 | ||
182 | /* FACS only has signature and length fields of common table header */ | 186 | /* FACS only has signature and length fields */ |
183 | 187 | ||
184 | ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X", | 188 | ACPI_INFO((AE_INFO, "%4.4s %p %05X", |
185 | header->signature, (unsigned long)address, | 189 | header->signature, ACPI_CAST_PTR(void, address), |
186 | header->length)); | 190 | header->length)); |
187 | } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { | 191 | } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { |
188 | 192 | ||
189 | /* RSDP has no common fields */ | 193 | /* RSDP has no common fields */ |
190 | 194 | ||
191 | ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)", | 195 | ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", |
192 | (unsigned long)address, | 196 | ACPI_CAST_PTR (void, address), |
193 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> | 197 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> |
194 | revision > | 198 | revision > |
195 | 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, | 199 | 0) ? ACPI_CAST_PTR(struct acpi_table_rsdp, |
@@ -202,8 +206,8 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
202 | /* Standard ACPI table with full common header */ | 206 | /* Standard ACPI table with full common header */ |
203 | 207 | ||
204 | ACPI_INFO((AE_INFO, | 208 | ACPI_INFO((AE_INFO, |
205 | "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)", | 209 | "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", |
206 | header->signature, (unsigned long)address, | 210 | header->signature, ACPI_CAST_PTR (void, address), |
207 | header->length, header->revision, header->oem_id, | 211 | header->length, header->revision, header->oem_id, |
208 | header->oem_table_id, header->oem_revision, | 212 | header->oem_table_id, header->oem_revision, |
209 | header->asl_compiler_id, | 213 | header->asl_compiler_id, |
@@ -280,22 +284,28 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length) | |||
280 | * FUNCTION: acpi_tb_install_table | 284 | * FUNCTION: acpi_tb_install_table |
281 | * | 285 | * |
282 | * PARAMETERS: Address - Physical address of DSDT or FACS | 286 | * PARAMETERS: Address - Physical address of DSDT or FACS |
283 | * Flags - Flags | ||
284 | * Signature - Table signature, NULL if no need to | 287 | * Signature - Table signature, NULL if no need to |
285 | * match | 288 | * match |
286 | * table_index - Index into root table array | 289 | * table_index - Index into root table array |
287 | * | 290 | * |
288 | * RETURN: None | 291 | * RETURN: None |
289 | * | 292 | * |
290 | * DESCRIPTION: Install an ACPI table into the global data structure. | 293 | * DESCRIPTION: Install an ACPI table into the global data structure. The |
294 | * table override mechanism is implemented here to allow the host | ||
295 | * OS to replace any table before it is installed in the root | ||
296 | * table array. | ||
291 | * | 297 | * |
292 | ******************************************************************************/ | 298 | ******************************************************************************/ |
293 | 299 | ||
294 | void | 300 | void |
295 | acpi_tb_install_table(acpi_physical_address address, | 301 | acpi_tb_install_table(acpi_physical_address address, |
296 | u8 flags, char *signature, u32 table_index) | 302 | char *signature, u32 table_index) |
297 | { | 303 | { |
298 | struct acpi_table_header *table; | 304 | u8 flags; |
305 | acpi_status status; | ||
306 | struct acpi_table_header *table_to_install; | ||
307 | struct acpi_table_header *mapped_table; | ||
308 | struct acpi_table_header *override_table = NULL; | ||
299 | 309 | ||
300 | if (!address) { | 310 | if (!address) { |
301 | ACPI_ERROR((AE_INFO, | 311 | ACPI_ERROR((AE_INFO, |
@@ -306,41 +316,69 @@ acpi_tb_install_table(acpi_physical_address address, | |||
306 | 316 | ||
307 | /* Map just the table header */ | 317 | /* Map just the table header */ |
308 | 318 | ||
309 | table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); | 319 | mapped_table = |
310 | if (!table) { | 320 | acpi_os_map_memory(address, sizeof(struct acpi_table_header)); |
321 | if (!mapped_table) { | ||
311 | return; | 322 | return; |
312 | } | 323 | } |
313 | 324 | ||
314 | /* If a particular signature is expected, signature must match */ | 325 | /* If a particular signature is expected (DSDT/FACS), it must match */ |
315 | 326 | ||
316 | if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) { | 327 | if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) { |
317 | ACPI_ERROR((AE_INFO, | 328 | ACPI_ERROR((AE_INFO, |
318 | "Invalid signature 0x%X for ACPI table [%s]", | 329 | "Invalid signature 0x%X for ACPI table, expected [%s]", |
319 | *ACPI_CAST_PTR(u32, table->signature), signature)); | 330 | *ACPI_CAST_PTR(u32, mapped_table->signature), |
331 | signature)); | ||
320 | goto unmap_and_exit; | 332 | goto unmap_and_exit; |
321 | } | 333 | } |
322 | 334 | ||
335 | /* | ||
336 | * ACPI Table Override: | ||
337 | * | ||
338 | * Before we install the table, let the host OS override it with a new | ||
339 | * one if desired. Any table within the RSDT/XSDT can be replaced, | ||
340 | * including the DSDT which is pointed to by the FADT. | ||
341 | */ | ||
342 | status = acpi_os_table_override(mapped_table, &override_table); | ||
343 | if (ACPI_SUCCESS(status) && override_table) { | ||
344 | ACPI_INFO((AE_INFO, | ||
345 | "%4.4s @ 0x%p Table override, replaced with:", | ||
346 | mapped_table->signature, ACPI_CAST_PTR(void, | ||
347 | address))); | ||
348 | |||
349 | acpi_gbl_root_table_list.tables[table_index].pointer = | ||
350 | override_table; | ||
351 | address = ACPI_PTR_TO_PHYSADDR(override_table); | ||
352 | |||
353 | table_to_install = override_table; | ||
354 | flags = ACPI_TABLE_ORIGIN_OVERRIDE; | ||
355 | } else { | ||
356 | table_to_install = mapped_table; | ||
357 | flags = ACPI_TABLE_ORIGIN_MAPPED; | ||
358 | } | ||
359 | |||
323 | /* Initialize the table entry */ | 360 | /* Initialize the table entry */ |
324 | 361 | ||
325 | acpi_gbl_root_table_list.tables[table_index].address = address; | 362 | acpi_gbl_root_table_list.tables[table_index].address = address; |
326 | acpi_gbl_root_table_list.tables[table_index].length = table->length; | 363 | acpi_gbl_root_table_list.tables[table_index].length = |
364 | table_to_install->length; | ||
327 | acpi_gbl_root_table_list.tables[table_index].flags = flags; | 365 | acpi_gbl_root_table_list.tables[table_index].flags = flags; |
328 | 366 | ||
329 | ACPI_MOVE_32_TO_32(& | 367 | ACPI_MOVE_32_TO_32(& |
330 | (acpi_gbl_root_table_list.tables[table_index]. | 368 | (acpi_gbl_root_table_list.tables[table_index]. |
331 | signature), table->signature); | 369 | signature), table_to_install->signature); |
332 | 370 | ||
333 | acpi_tb_print_table_header(address, table); | 371 | acpi_tb_print_table_header(address, table_to_install); |
334 | 372 | ||
335 | if (table_index == ACPI_TABLE_INDEX_DSDT) { | 373 | if (table_index == ACPI_TABLE_INDEX_DSDT) { |
336 | 374 | ||
337 | /* Global integer width is based upon revision of the DSDT */ | 375 | /* Global integer width is based upon revision of the DSDT */ |
338 | 376 | ||
339 | acpi_ut_set_integer_width(table->revision); | 377 | acpi_ut_set_integer_width(table_to_install->revision); |
340 | } | 378 | } |
341 | 379 | ||
342 | unmap_and_exit: | 380 | unmap_and_exit: |
343 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | 381 | acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header)); |
344 | } | 382 | } |
345 | 383 | ||
346 | /******************************************************************************* | 384 | /******************************************************************************* |
@@ -379,7 +417,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
379 | } else { | 417 | } else { |
380 | /* | 418 | /* |
381 | * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return | 419 | * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return |
382 | * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit | 420 | * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, |
421 | * return 64-bit | ||
383 | */ | 422 | */ |
384 | ACPI_MOVE_64_TO_64(&address64, table_entry); | 423 | ACPI_MOVE_64_TO_64(&address64, table_entry); |
385 | 424 | ||
@@ -389,7 +428,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
389 | /* Will truncate 64-bit address to 32 bits, issue warning */ | 428 | /* Will truncate 64-bit address to 32 bits, issue warning */ |
390 | 429 | ||
391 | ACPI_WARNING((AE_INFO, | 430 | ACPI_WARNING((AE_INFO, |
392 | "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating", | 431 | "64-bit Physical Address in XSDT is too large (%8.8X%8.8X)," |
432 | " truncating", | ||
393 | ACPI_FORMAT_UINT64(address64))); | 433 | ACPI_FORMAT_UINT64(address64))); |
394 | } | 434 | } |
395 | #endif | 435 | #endif |
@@ -402,7 +442,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
402 | * FUNCTION: acpi_tb_parse_root_table | 442 | * FUNCTION: acpi_tb_parse_root_table |
403 | * | 443 | * |
404 | * PARAMETERS: Rsdp - Pointer to the RSDP | 444 | * PARAMETERS: Rsdp - Pointer to the RSDP |
405 | * Flags - Flags | ||
406 | * | 445 | * |
407 | * RETURN: Status | 446 | * RETURN: Status |
408 | * | 447 | * |
@@ -416,7 +455,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
416 | ******************************************************************************/ | 455 | ******************************************************************************/ |
417 | 456 | ||
418 | acpi_status __init | 457 | acpi_status __init |
419 | acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) | 458 | acpi_tb_parse_root_table(acpi_physical_address rsdp_address) |
420 | { | 459 | { |
421 | struct acpi_table_rsdp *rsdp; | 460 | struct acpi_table_rsdp *rsdp; |
422 | u32 table_entry_size; | 461 | u32 table_entry_size; |
@@ -513,13 +552,12 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) | |||
513 | 552 | ||
514 | /* Calculate the number of tables described in the root table */ | 553 | /* Calculate the number of tables described in the root table */ |
515 | 554 | ||
516 | table_count = | 555 | table_count = (u32)((table->length - sizeof(struct acpi_table_header)) / |
517 | (u32) ((table->length - | 556 | table_entry_size); |
518 | sizeof(struct acpi_table_header)) / table_entry_size); | ||
519 | |||
520 | /* | 557 | /* |
521 | * First two entries in the table array are reserved for the DSDT and FACS, | 558 | * First two entries in the table array are reserved for the DSDT |
522 | * which are not actually present in the RSDT/XSDT - they come from the FADT | 559 | * and FACS, which are not actually present in the RSDT/XSDT - they |
560 | * come from the FADT | ||
523 | */ | 561 | */ |
524 | table_entry = | 562 | table_entry = |
525 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); | 563 | ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); |
@@ -567,14 +605,14 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) | |||
567 | */ | 605 | */ |
568 | for (i = 2; i < acpi_gbl_root_table_list.count; i++) { | 606 | for (i = 2; i < acpi_gbl_root_table_list.count; i++) { |
569 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. | 607 | acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. |
570 | address, flags, NULL, i); | 608 | address, NULL, i); |
571 | 609 | ||
572 | /* Special case for FADT - get the DSDT and FACS */ | 610 | /* Special case for FADT - get the DSDT and FACS */ |
573 | 611 | ||
574 | if (ACPI_COMPARE_NAME | 612 | if (ACPI_COMPARE_NAME |
575 | (&acpi_gbl_root_table_list.tables[i].signature, | 613 | (&acpi_gbl_root_table_list.tables[i].signature, |
576 | ACPI_SIG_FADT)) { | 614 | ACPI_SIG_FADT)) { |
577 | acpi_tb_parse_fadt(i, flags); | 615 | acpi_tb_parse_fadt(i); |
578 | } | 616 | } |
579 | } | 617 | } |
580 | 618 | ||
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index c3e841f3cde9..dbca22651504 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -150,8 +150,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, | |||
150 | * Root Table Array. This array contains the information of the RSDT/XSDT | 150 | * Root Table Array. This array contains the information of the RSDT/XSDT |
151 | * in a common, more useable format. | 151 | * in a common, more useable format. |
152 | */ | 152 | */ |
153 | status = | 153 | status = acpi_tb_parse_root_table(rsdp_address); |
154 | acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED); | ||
155 | return_ACPI_STATUS(status); | 154 | return_ACPI_STATUS(status); |
156 | } | 155 | } |
157 | 156 | ||
@@ -247,7 +246,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) | |||
247 | 246 | ||
248 | ACPI_EXPORT_SYMBOL(acpi_load_table) | 247 | ACPI_EXPORT_SYMBOL(acpi_load_table) |
249 | 248 | ||
250 | /****************************************************************************** | 249 | /******************************************************************************* |
251 | * | 250 | * |
252 | * FUNCTION: acpi_get_table_header | 251 | * FUNCTION: acpi_get_table_header |
253 | * | 252 | * |
@@ -262,7 +261,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) | |||
262 | * NOTE: Caller is responsible in unmapping the header with | 261 | * NOTE: Caller is responsible in unmapping the header with |
263 | * acpi_os_unmap_memory | 262 | * acpi_os_unmap_memory |
264 | * | 263 | * |
265 | *****************************************************************************/ | 264 | ******************************************************************************/ |
266 | acpi_status | 265 | acpi_status |
267 | acpi_get_table_header(char *signature, | 266 | acpi_get_table_header(char *signature, |
268 | u32 instance, struct acpi_table_header *out_table_header) | 267 | u32 instance, struct acpi_table_header *out_table_header) |
@@ -277,9 +276,8 @@ acpi_get_table_header(char *signature, | |||
277 | return (AE_BAD_PARAMETER); | 276 | return (AE_BAD_PARAMETER); |
278 | } | 277 | } |
279 | 278 | ||
280 | /* | 279 | /* Walk the root table list */ |
281 | * Walk the root table list | 280 | |
282 | */ | ||
283 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | 281 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { |
284 | if (!ACPI_COMPARE_NAME | 282 | if (!ACPI_COMPARE_NAME |
285 | (&(acpi_gbl_root_table_list.tables[i].signature), | 283 | (&(acpi_gbl_root_table_list.tables[i].signature), |
@@ -292,8 +290,8 @@ acpi_get_table_header(char *signature, | |||
292 | } | 290 | } |
293 | 291 | ||
294 | if (!acpi_gbl_root_table_list.tables[i].pointer) { | 292 | if (!acpi_gbl_root_table_list.tables[i].pointer) { |
295 | if ((acpi_gbl_root_table_list.tables[i]. | 293 | if ((acpi_gbl_root_table_list.tables[i].flags & |
296 | flags & ACPI_TABLE_ORIGIN_MASK) == | 294 | ACPI_TABLE_ORIGIN_MASK) == |
297 | ACPI_TABLE_ORIGIN_MAPPED) { | 295 | ACPI_TABLE_ORIGIN_MAPPED) { |
298 | header = | 296 | header = |
299 | acpi_os_map_memory(acpi_gbl_root_table_list. | 297 | acpi_os_map_memory(acpi_gbl_root_table_list. |
@@ -324,7 +322,7 @@ acpi_get_table_header(char *signature, | |||
324 | 322 | ||
325 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) | 323 | ACPI_EXPORT_SYMBOL(acpi_get_table_header) |
326 | 324 | ||
327 | /****************************************************************************** | 325 | /******************************************************************************* |
328 | * | 326 | * |
329 | * FUNCTION: acpi_unload_table_id | 327 | * FUNCTION: acpi_unload_table_id |
330 | * | 328 | * |
@@ -375,7 +373,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id) | |||
375 | * | 373 | * |
376 | * DESCRIPTION: Finds and verifies an ACPI table. | 374 | * DESCRIPTION: Finds and verifies an ACPI table. |
377 | * | 375 | * |
378 | *****************************************************************************/ | 376 | ******************************************************************************/ |
379 | acpi_status | 377 | acpi_status |
380 | acpi_get_table(char *signature, | 378 | acpi_get_table(char *signature, |
381 | u32 instance, struct acpi_table_header **out_table) | 379 | u32 instance, struct acpi_table_header **out_table) |
@@ -390,9 +388,8 @@ acpi_get_table(char *signature, | |||
390 | return (AE_BAD_PARAMETER); | 388 | return (AE_BAD_PARAMETER); |
391 | } | 389 | } |
392 | 390 | ||
393 | /* | 391 | /* Walk the root table list */ |
394 | * Walk the root table list | 392 | |
395 | */ | ||
396 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { | 393 | for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { |
397 | if (!ACPI_COMPARE_NAME | 394 | if (!ACPI_COMPARE_NAME |
398 | (&(acpi_gbl_root_table_list.tables[i].signature), | 395 | (&(acpi_gbl_root_table_list.tables[i].signature), |
@@ -491,7 +488,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) | |||
491 | static acpi_status acpi_tb_load_namespace(void) | 488 | static acpi_status acpi_tb_load_namespace(void) |
492 | { | 489 | { |
493 | acpi_status status; | 490 | acpi_status status; |
494 | struct acpi_table_header *table; | ||
495 | u32 i; | 491 | u32 i; |
496 | 492 | ||
497 | ACPI_FUNCTION_TRACE(tb_load_namespace); | 493 | ACPI_FUNCTION_TRACE(tb_load_namespace); |
@@ -515,58 +511,28 @@ static acpi_status acpi_tb_load_namespace(void) | |||
515 | goto unlock_and_exit; | 511 | goto unlock_and_exit; |
516 | } | 512 | } |
517 | 513 | ||
518 | /* | 514 | /* A valid DSDT is required */ |
519 | * Find DSDT table | ||
520 | */ | ||
521 | status = | ||
522 | acpi_os_table_override(acpi_gbl_root_table_list. | ||
523 | tables[ACPI_TABLE_INDEX_DSDT].pointer, | ||
524 | &table); | ||
525 | if (ACPI_SUCCESS(status) && table) { | ||
526 | /* | ||
527 | * DSDT table has been found | ||
528 | */ | ||
529 | acpi_tb_delete_table(&acpi_gbl_root_table_list. | ||
530 | tables[ACPI_TABLE_INDEX_DSDT]); | ||
531 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = | ||
532 | table; | ||
533 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = | ||
534 | table->length; | ||
535 | acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = | ||
536 | ACPI_TABLE_ORIGIN_UNKNOWN; | ||
537 | |||
538 | ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); | ||
539 | acpi_tb_print_table_header(0, table); | ||
540 | |||
541 | if (no_auto_ssdt == 0) { | ||
542 | printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); | ||
543 | } | ||
544 | } | ||
545 | 515 | ||
546 | status = | 516 | status = |
547 | acpi_tb_verify_table(&acpi_gbl_root_table_list. | 517 | acpi_tb_verify_table(&acpi_gbl_root_table_list. |
548 | tables[ACPI_TABLE_INDEX_DSDT]); | 518 | tables[ACPI_TABLE_INDEX_DSDT]); |
549 | if (ACPI_FAILURE(status)) { | 519 | if (ACPI_FAILURE(status)) { |
550 | 520 | ||
551 | /* A valid DSDT is required */ | ||
552 | |||
553 | status = AE_NO_ACPI_TABLES; | 521 | status = AE_NO_ACPI_TABLES; |
554 | goto unlock_and_exit; | 522 | goto unlock_and_exit; |
555 | } | 523 | } |
556 | 524 | ||
557 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 525 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
558 | 526 | ||
559 | /* | 527 | /* Load and parse tables */ |
560 | * Load and parse tables. | 528 | |
561 | */ | ||
562 | status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); | 529 | status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); |
563 | if (ACPI_FAILURE(status)) { | 530 | if (ACPI_FAILURE(status)) { |
564 | return_ACPI_STATUS(status); | 531 | return_ACPI_STATUS(status); |
565 | } | 532 | } |
566 | 533 | ||
567 | /* | 534 | /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ |
568 | * Load any SSDT or PSDT tables. Note: Loop leaves tables locked | 535 | |
569 | */ | ||
570 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); | 536 | (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); |
571 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { | 537 | for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { |
572 | if ((!ACPI_COMPARE_NAME | 538 | if ((!ACPI_COMPARE_NAME |
@@ -619,9 +585,8 @@ acpi_status acpi_load_tables(void) | |||
619 | 585 | ||
620 | ACPI_FUNCTION_TRACE(acpi_load_tables); | 586 | ACPI_FUNCTION_TRACE(acpi_load_tables); |
621 | 587 | ||
622 | /* | 588 | /* Load the namespace from the tables */ |
623 | * Load the namespace from the tables | 589 | |
624 | */ | ||
625 | status = acpi_tb_load_namespace(); | 590 | status = acpi_tb_load_namespace(); |
626 | if (ACPI_FAILURE(status)) { | 591 | if (ACPI_FAILURE(status)) { |
627 | ACPI_EXCEPTION((AE_INFO, status, | 592 | ACPI_EXCEPTION((AE_INFO, status, |
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index b7fc8dd43341..85ea834199e2 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c | |||
@@ -75,8 +75,8 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | |||
75 | * Note: Sometimes there exists more than one RSDP in memory; the valid | 75 | * Note: Sometimes there exists more than one RSDP in memory; the valid |
76 | * RSDP has a valid checksum, all others have an invalid checksum. | 76 | * RSDP has a valid checksum, all others have an invalid checksum. |
77 | */ | 77 | */ |
78 | if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1) | 78 | if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, |
79 | != 0) { | 79 | sizeof(ACPI_SIG_RSDP) - 1) != 0) { |
80 | 80 | ||
81 | /* Nope, BAD Signature */ | 81 | /* Nope, BAD Signature */ |
82 | 82 | ||
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index b0dcfd3c872a..919624f123d5 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
@@ -135,11 +135,11 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | |||
135 | * In general, the external object will be the same type as | 135 | * In general, the external object will be the same type as |
136 | * the internal object | 136 | * the internal object |
137 | */ | 137 | */ |
138 | external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); | 138 | external_object->type = internal_object->common.type; |
139 | 139 | ||
140 | /* However, only a limited number of external types are supported */ | 140 | /* However, only a limited number of external types are supported */ |
141 | 141 | ||
142 | switch (ACPI_GET_OBJECT_TYPE(internal_object)) { | 142 | switch (internal_object->common.type) { |
143 | case ACPI_TYPE_STRING: | 143 | case ACPI_TYPE_STRING: |
144 | 144 | ||
145 | external_object->string.pointer = (char *)data_space; | 145 | external_object->string.pointer = (char *)data_space; |
@@ -222,8 +222,8 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, | |||
222 | */ | 222 | */ |
223 | ACPI_ERROR((AE_INFO, | 223 | ACPI_ERROR((AE_INFO, |
224 | "Unsupported object type, cannot convert to external object: %s", | 224 | "Unsupported object type, cannot convert to external object: %s", |
225 | acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE | 225 | acpi_ut_get_type_name(internal_object->common. |
226 | (internal_object)))); | 226 | type))); |
227 | 227 | ||
228 | return_ACPI_STATUS(AE_SUPPORT); | 228 | return_ACPI_STATUS(AE_SUPPORT); |
229 | } | 229 | } |
@@ -355,7 +355,7 @@ acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object, | |||
355 | info.object_space = 0; | 355 | info.object_space = 0; |
356 | info.num_packages = 1; | 356 | info.num_packages = 1; |
357 | 357 | ||
358 | external_object->type = ACPI_GET_OBJECT_TYPE(internal_object); | 358 | external_object->type = internal_object->common.type; |
359 | external_object->package.count = internal_object->package.count; | 359 | external_object->package.count = internal_object->package.count; |
360 | external_object->package.elements = ACPI_CAST_PTR(union acpi_object, | 360 | external_object->package.elements = ACPI_CAST_PTR(union acpi_object, |
361 | info.free_space); | 361 | info.free_space); |
@@ -399,7 +399,7 @@ acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object, | |||
399 | 399 | ||
400 | ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject); | 400 | ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject); |
401 | 401 | ||
402 | if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) { | 402 | if (internal_object->common.type == ACPI_TYPE_PACKAGE) { |
403 | /* | 403 | /* |
404 | * Package object: Copy all subobjects (including | 404 | * Package object: Copy all subobjects (including |
405 | * nested packages) | 405 | * nested packages) |
@@ -496,8 +496,9 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
496 | case ACPI_TYPE_STRING: | 496 | case ACPI_TYPE_STRING: |
497 | 497 | ||
498 | internal_object->string.pointer = | 498 | internal_object->string.pointer = |
499 | ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string. | 499 | ACPI_ALLOCATE_ZEROED((acpi_size) |
500 | length + 1); | 500 | external_object->string.length + 1); |
501 | |||
501 | if (!internal_object->string.pointer) { | 502 | if (!internal_object->string.pointer) { |
502 | goto error_exit; | 503 | goto error_exit; |
503 | } | 504 | } |
@@ -697,7 +698,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
697 | 698 | ||
698 | /* Handle the objects with extra data */ | 699 | /* Handle the objects with extra data */ |
699 | 700 | ||
700 | switch (ACPI_GET_OBJECT_TYPE(dest_desc)) { | 701 | switch (dest_desc->common.type) { |
701 | case ACPI_TYPE_BUFFER: | 702 | case ACPI_TYPE_BUFFER: |
702 | /* | 703 | /* |
703 | * Allocate and copy the actual buffer if and only if: | 704 | * Allocate and copy the actual buffer if and only if: |
@@ -814,8 +815,8 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type, | |||
814 | * This is a simple object, just copy it | 815 | * This is a simple object, just copy it |
815 | */ | 816 | */ |
816 | target_object = | 817 | target_object = |
817 | acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE | 818 | acpi_ut_create_internal_object(source_object-> |
818 | (source_object)); | 819 | common.type); |
819 | if (!target_object) { | 820 | if (!target_object) { |
820 | return (AE_NO_MEMORY); | 821 | return (AE_NO_MEMORY); |
821 | } | 822 | } |
@@ -892,7 +893,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj, | |||
892 | 893 | ||
893 | ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage); | 894 | ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage); |
894 | 895 | ||
895 | dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj); | 896 | dest_obj->common.type = source_obj->common.type; |
896 | dest_obj->common.flags = source_obj->common.flags; | 897 | dest_obj->common.flags = source_obj->common.flags; |
897 | dest_obj->package.count = source_obj->package.count; | 898 | dest_obj->package.count = source_obj->package.count; |
898 | 899 | ||
@@ -950,15 +951,14 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, | |||
950 | 951 | ||
951 | /* Create the top level object */ | 952 | /* Create the top level object */ |
952 | 953 | ||
953 | *dest_desc = | 954 | *dest_desc = acpi_ut_create_internal_object(source_desc->common.type); |
954 | acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc)); | ||
955 | if (!*dest_desc) { | 955 | if (!*dest_desc) { |
956 | return_ACPI_STATUS(AE_NO_MEMORY); | 956 | return_ACPI_STATUS(AE_NO_MEMORY); |
957 | } | 957 | } |
958 | 958 | ||
959 | /* Copy the object and possible subobjects */ | 959 | /* Copy the object and possible subobjects */ |
960 | 960 | ||
961 | if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) { | 961 | if (source_desc->common.type == ACPI_TYPE_PACKAGE) { |
962 | status = | 962 | status = |
963 | acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc, | 963 | acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc, |
964 | walk_state); | 964 | walk_state); |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index a0be9e39531e..a5ee23bc4f55 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -86,7 +86,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
86 | * Must delete or free any pointers within the object that are not | 86 | * Must delete or free any pointers within the object that are not |
87 | * actual ACPI objects (for example, a raw buffer pointer). | 87 | * actual ACPI objects (for example, a raw buffer pointer). |
88 | */ | 88 | */ |
89 | switch (ACPI_GET_OBJECT_TYPE(object)) { | 89 | switch (object->common.type) { |
90 | case ACPI_TYPE_STRING: | 90 | case ACPI_TYPE_STRING: |
91 | 91 | ||
92 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 92 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, |
@@ -382,7 +382,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) | |||
382 | object, new_count)); | 382 | object, new_count)); |
383 | } | 383 | } |
384 | 384 | ||
385 | if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) { | 385 | if (object->common.type == ACPI_TYPE_METHOD) { |
386 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 386 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, |
387 | "Method Obj %p Refs=%X, [Decremented]\n", | 387 | "Method Obj %p Refs=%X, [Decremented]\n", |
388 | object, new_count)); | 388 | object, new_count)); |
@@ -469,7 +469,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) | |||
469 | * All sub-objects must have their reference count incremented also. | 469 | * All sub-objects must have their reference count incremented also. |
470 | * Different object types have different subobjects. | 470 | * Different object types have different subobjects. |
471 | */ | 471 | */ |
472 | switch (ACPI_GET_OBJECT_TYPE(object)) { | 472 | switch (object->common.type) { |
473 | case ACPI_TYPE_DEVICE: | 473 | case ACPI_TYPE_DEVICE: |
474 | case ACPI_TYPE_PROCESSOR: | 474 | case ACPI_TYPE_PROCESSOR: |
475 | case ACPI_TYPE_POWER: | 475 | case ACPI_TYPE_POWER: |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 9c9897dbe907..006b16c26017 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -59,26 +59,35 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | |||
59 | 59 | ||
60 | /* | 60 | /* |
61 | * Strings supported by the _OSI predefined (internal) method. | 61 | * Strings supported by the _OSI predefined (internal) method. |
62 | * | ||
63 | * March 2009: Removed "Linux" as this host no longer wants to respond true | ||
64 | * for this string. Basically, the only safe OS strings are windows-related | ||
65 | * and in many or most cases represent the only test path within the | ||
66 | * BIOS-provided ASL code. | ||
67 | * | ||
68 | * The second element of each entry is used to track the newest version of | ||
69 | * Windows that the BIOS has requested. | ||
62 | */ | 70 | */ |
63 | static char *acpi_interfaces_supported[] = { | 71 | static struct acpi_interface_info acpi_interfaces_supported[] = { |
64 | /* Operating System Vendor Strings */ | 72 | /* Operating System Vendor Strings */ |
65 | 73 | ||
66 | "Windows 2000", /* Windows 2000 */ | 74 | {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */ |
67 | "Windows 2001", /* Windows XP */ | 75 | {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */ |
68 | "Windows 2001 SP1", /* Windows XP SP1 */ | 76 | {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */ |
69 | "Windows 2001 SP2", /* Windows XP SP2 */ | 77 | {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */ |
70 | "Windows 2001.1", /* Windows Server 2003 */ | 78 | {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ |
71 | "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */ | 79 | {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ |
72 | "Windows 2006", /* Windows Vista - Added 03/2006 */ | 80 | {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ |
73 | 81 | ||
74 | /* Feature Group Strings */ | 82 | /* Feature Group Strings */ |
75 | 83 | ||
76 | "Extended Address Space Descriptor" | 84 | {"Extended Address Space Descriptor", 0} |
77 | /* | 85 | |
78 | * All "optional" feature group strings (features that are implemented | 86 | /* |
79 | * by the host) should be implemented in the host version of | 87 | * All "optional" feature group strings (features that are implemented |
80 | * acpi_os_validate_interface and should not be added here. | 88 | * by the host) should be implemented in the host version of |
81 | */ | 89 | * acpi_os_validate_interface and should not be added here. |
90 | */ | ||
82 | }; | 91 | }; |
83 | 92 | ||
84 | /******************************************************************************* | 93 | /******************************************************************************* |
@@ -98,6 +107,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
98 | acpi_status status; | 107 | acpi_status status; |
99 | union acpi_operand_object *string_desc; | 108 | union acpi_operand_object *string_desc; |
100 | union acpi_operand_object *return_desc; | 109 | union acpi_operand_object *return_desc; |
110 | u32 return_value; | ||
101 | u32 i; | 111 | u32 i; |
102 | 112 | ||
103 | ACPI_FUNCTION_TRACE(ut_osi_implementation); | 113 | ACPI_FUNCTION_TRACE(ut_osi_implementation); |
@@ -116,19 +126,28 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
116 | return_ACPI_STATUS(AE_NO_MEMORY); | 126 | return_ACPI_STATUS(AE_NO_MEMORY); |
117 | } | 127 | } |
118 | 128 | ||
119 | /* Default return value is 0, NOT-SUPPORTED */ | 129 | /* Default return value is 0, NOT SUPPORTED */ |
120 | 130 | ||
121 | return_desc->integer.value = 0; | 131 | return_value = 0; |
122 | walk_state->return_desc = return_desc; | ||
123 | 132 | ||
124 | /* Compare input string to static table of supported interfaces */ | 133 | /* Compare input string to static table of supported interfaces */ |
125 | 134 | ||
126 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { | 135 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { |
127 | if (!ACPI_STRCMP | 136 | if (!ACPI_STRCMP(string_desc->string.pointer, |
128 | (string_desc->string.pointer, | 137 | acpi_interfaces_supported[i].name)) { |
129 | acpi_interfaces_supported[i])) { | 138 | /* |
130 | return_desc->integer.value = ACPI_UINT32_MAX; | 139 | * The interface is supported. |
131 | goto done; | 140 | * Update the osi_data if necessary. We keep track of the latest |
141 | * version of Windows that has been requested by the BIOS. | ||
142 | */ | ||
143 | if (acpi_interfaces_supported[i].value > | ||
144 | acpi_gbl_osi_data) { | ||
145 | acpi_gbl_osi_data = | ||
146 | acpi_interfaces_supported[i].value; | ||
147 | } | ||
148 | |||
149 | return_value = ACPI_UINT32_MAX; | ||
150 | goto exit; | ||
132 | } | 151 | } |
133 | } | 152 | } |
134 | 153 | ||
@@ -139,15 +158,22 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state) | |||
139 | */ | 158 | */ |
140 | status = acpi_os_validate_interface(string_desc->string.pointer); | 159 | status = acpi_os_validate_interface(string_desc->string.pointer); |
141 | if (ACPI_SUCCESS(status)) { | 160 | if (ACPI_SUCCESS(status)) { |
142 | return_desc->integer.value = ACPI_UINT32_MAX; | 161 | |
162 | /* The interface is supported */ | ||
163 | |||
164 | return_value = ACPI_UINT32_MAX; | ||
143 | } | 165 | } |
144 | 166 | ||
145 | done: | 167 | exit: |
146 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n", | 168 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, |
147 | string_desc->string.pointer, | 169 | "ACPI: BIOS _OSI(%s) is %ssupported\n", |
148 | return_desc->integer.value == 0 ? "not-" : "")); | 170 | string_desc->string.pointer, return_value == 0 ? "not " : "")); |
149 | 171 | ||
150 | return_ACPI_STATUS(AE_OK); | 172 | /* Complete the return value */ |
173 | |||
174 | return_desc->integer.value = return_value; | ||
175 | walk_state->return_desc = return_desc; | ||
176 | return_ACPI_STATUS (AE_OK); | ||
151 | } | 177 | } |
152 | 178 | ||
153 | /******************************************************************************* | 179 | /******************************************************************************* |
@@ -167,8 +193,8 @@ acpi_status acpi_osi_invalidate(char *interface) | |||
167 | int i; | 193 | int i; |
168 | 194 | ||
169 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { | 195 | for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) { |
170 | if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) { | 196 | if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) { |
171 | *acpi_interfaces_supported[i] = '\0'; | 197 | *acpi_interfaces_supported[i].name = '\0'; |
172 | return AE_OK; | 198 | return AE_OK; |
173 | } | 199 | } |
174 | } | 200 | } |
@@ -248,7 +274,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
248 | 274 | ||
249 | /* Map the return object type to the bitmapped type */ | 275 | /* Map the return object type to the bitmapped type */ |
250 | 276 | ||
251 | switch (ACPI_GET_OBJECT_TYPE(info->return_object)) { | 277 | switch ((info->return_object)->common.type) { |
252 | case ACPI_TYPE_INTEGER: | 278 | case ACPI_TYPE_INTEGER: |
253 | return_btype = ACPI_BTYPE_INTEGER; | 279 | return_btype = ACPI_BTYPE_INTEGER; |
254 | break; | 280 | break; |
@@ -418,7 +444,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | |||
418 | return_ACPI_STATUS(status); | 444 | return_ACPI_STATUS(status); |
419 | } | 445 | } |
420 | 446 | ||
421 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 447 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { |
422 | 448 | ||
423 | /* Convert the Numeric HID to string */ | 449 | /* Convert the Numeric HID to string */ |
424 | 450 | ||
@@ -459,7 +485,7 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | |||
459 | struct acpi_compatible_id *one_cid) | 485 | struct acpi_compatible_id *one_cid) |
460 | { | 486 | { |
461 | 487 | ||
462 | switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { | 488 | switch (obj_desc->common.type) { |
463 | case ACPI_TYPE_INTEGER: | 489 | case ACPI_TYPE_INTEGER: |
464 | 490 | ||
465 | /* Convert the Numeric CID to string */ | 491 | /* Convert the Numeric CID to string */ |
@@ -527,7 +553,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | |||
527 | /* Get the number of _CIDs returned */ | 553 | /* Get the number of _CIDs returned */ |
528 | 554 | ||
529 | count = 1; | 555 | count = 1; |
530 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { | 556 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { |
531 | count = obj_desc->package.count; | 557 | count = obj_desc->package.count; |
532 | } | 558 | } |
533 | 559 | ||
@@ -555,7 +581,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | |||
555 | 581 | ||
556 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | 582 | /* The _CID object can be either a single CID or a package (list) of CIDs */ |
557 | 583 | ||
558 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) { | 584 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { |
559 | 585 | ||
560 | /* Translate each package element */ | 586 | /* Translate each package element */ |
561 | 587 | ||
@@ -620,7 +646,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | |||
620 | return_ACPI_STATUS(status); | 646 | return_ACPI_STATUS(status); |
621 | } | 647 | } |
622 | 648 | ||
623 | if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { | 649 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { |
624 | 650 | ||
625 | /* Convert the Numeric UID to string */ | 651 | /* Convert the Numeric UID to string */ |
626 | 652 | ||
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index a3ab9d9da299..59e46f257c02 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -294,12 +294,9 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = { | |||
294 | /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, | 294 | /* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL, |
295 | ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, | 295 | ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE, |
296 | ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, | 296 | ACPI_BITMASK_GLOBAL_LOCK_RELEASE}, |
297 | /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL, | 297 | /* ACPI_BITREG_SLEEP_TYPE */ {ACPI_REGISTER_PM1_CONTROL, |
298 | ACPI_BITPOSITION_SLEEP_TYPE_X, | 298 | ACPI_BITPOSITION_SLEEP_TYPE, |
299 | ACPI_BITMASK_SLEEP_TYPE_X}, | 299 | ACPI_BITMASK_SLEEP_TYPE}, |
300 | /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL, | ||
301 | ACPI_BITPOSITION_SLEEP_TYPE_X, | ||
302 | ACPI_BITMASK_SLEEP_TYPE_X}, | ||
303 | /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, | 300 | /* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL, |
304 | ACPI_BITPOSITION_SLEEP_ENABLE, | 301 | ACPI_BITPOSITION_SLEEP_ENABLE, |
305 | ACPI_BITMASK_SLEEP_ENABLE}, | 302 | ACPI_BITMASK_SLEEP_ENABLE}, |
@@ -476,7 +473,7 @@ char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc) | |||
476 | return ("[NULL Object Descriptor]"); | 473 | return ("[NULL Object Descriptor]"); |
477 | } | 474 | } |
478 | 475 | ||
479 | return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc))); | 476 | return (acpi_ut_get_type_name(obj_desc->common.type)); |
480 | } | 477 | } |
481 | 478 | ||
482 | /******************************************************************************* | 479 | /******************************************************************************* |
@@ -749,7 +746,10 @@ acpi_status acpi_ut_init_globals(void) | |||
749 | for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { | 746 | for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) { |
750 | acpi_gbl_owner_id_mask[i] = 0; | 747 | acpi_gbl_owner_id_mask[i] = 0; |
751 | } | 748 | } |
752 | acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */ | 749 | |
750 | /* Last owner_iD is never valid */ | ||
751 | |||
752 | acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; | ||
753 | 753 | ||
754 | /* GPE support */ | 754 | /* GPE support */ |
755 | 755 | ||
@@ -789,6 +789,7 @@ acpi_status acpi_ut_init_globals(void) | |||
789 | acpi_gbl_trace_dbg_layer = 0; | 789 | acpi_gbl_trace_dbg_layer = 0; |
790 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; | 790 | acpi_gbl_debugger_configuration = DEBUGGER_THREADING; |
791 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; | 791 | acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT; |
792 | acpi_gbl_osi_data = 0; | ||
792 | 793 | ||
793 | /* Hardware oriented */ | 794 | /* Hardware oriented */ |
794 | 795 | ||
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c new file mode 100644 index 000000000000..25e03120686d --- /dev/null +++ b/drivers/acpi/acpica/utlock.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utlock - Reader/Writer lock interfaces | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2009, 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 | ||
48 | ACPI_MODULE_NAME("utlock") | ||
49 | |||
50 | /******************************************************************************* | ||
51 | * | ||
52 | * FUNCTION: acpi_ut_create_rw_lock | ||
53 | * acpi_ut_delete_rw_lock | ||
54 | * | ||
55 | * PARAMETERS: Lock - Pointer to a valid RW lock | ||
56 | * | ||
57 | * RETURN: Status | ||
58 | * | ||
59 | * DESCRIPTION: Reader/writer lock creation and deletion interfaces. | ||
60 | * | ||
61 | ******************************************************************************/ | ||
62 | acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock) | ||
63 | { | ||
64 | acpi_status status; | ||
65 | |||
66 | lock->num_readers = 0; | ||
67 | status = acpi_os_create_mutex(&lock->reader_mutex); | ||
68 | if (ACPI_FAILURE(status)) { | ||
69 | return status; | ||
70 | } | ||
71 | |||
72 | status = acpi_os_create_mutex(&lock->writer_mutex); | ||
73 | return status; | ||
74 | } | ||
75 | |||
76 | void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock) | ||
77 | { | ||
78 | |||
79 | acpi_os_delete_mutex(lock->reader_mutex); | ||
80 | acpi_os_delete_mutex(lock->writer_mutex); | ||
81 | |||
82 | lock->num_readers = 0; | ||
83 | lock->reader_mutex = NULL; | ||
84 | lock->writer_mutex = NULL; | ||
85 | } | ||
86 | |||
87 | /******************************************************************************* | ||
88 | * | ||
89 | * FUNCTION: acpi_ut_acquire_read_lock | ||
90 | * acpi_ut_release_read_lock | ||
91 | * | ||
92 | * PARAMETERS: Lock - Pointer to a valid RW lock | ||
93 | * | ||
94 | * RETURN: Status | ||
95 | * | ||
96 | * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition, | ||
97 | * only the first reader acquires the write mutex. On release, | ||
98 | * only the last reader releases the write mutex. Although this | ||
99 | * algorithm can in theory starve writers, this should not be a | ||
100 | * problem with ACPICA since the subsystem is infrequently used | ||
101 | * in comparison to (for example) an I/O system. | ||
102 | * | ||
103 | ******************************************************************************/ | ||
104 | |||
105 | acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock) | ||
106 | { | ||
107 | acpi_status status; | ||
108 | |||
109 | status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER); | ||
110 | if (ACPI_FAILURE(status)) { | ||
111 | return status; | ||
112 | } | ||
113 | |||
114 | /* Acquire the write lock only for the first reader */ | ||
115 | |||
116 | lock->num_readers++; | ||
117 | if (lock->num_readers == 1) { | ||
118 | status = | ||
119 | acpi_os_acquire_mutex(lock->writer_mutex, | ||
120 | ACPI_WAIT_FOREVER); | ||
121 | } | ||
122 | |||
123 | acpi_os_release_mutex(lock->reader_mutex); | ||
124 | return status; | ||
125 | } | ||
126 | |||
127 | acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock) | ||
128 | { | ||
129 | acpi_status status; | ||
130 | |||
131 | status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER); | ||
132 | if (ACPI_FAILURE(status)) { | ||
133 | return status; | ||
134 | } | ||
135 | |||
136 | /* Release the write lock only for the very last reader */ | ||
137 | |||
138 | lock->num_readers--; | ||
139 | if (lock->num_readers == 0) { | ||
140 | acpi_os_release_mutex(lock->writer_mutex); | ||
141 | } | ||
142 | |||
143 | acpi_os_release_mutex(lock->reader_mutex); | ||
144 | return status; | ||
145 | } | ||
146 | |||
147 | /******************************************************************************* | ||
148 | * | ||
149 | * FUNCTION: acpi_ut_acquire_write_lock | ||
150 | * acpi_ut_release_write_lock | ||
151 | * | ||
152 | * PARAMETERS: Lock - Pointer to a valid RW lock | ||
153 | * | ||
154 | * RETURN: Status | ||
155 | * | ||
156 | * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or | ||
157 | * release the writer mutex associated with the lock. Acquisition | ||
158 | * of the lock is fully exclusive and will block all readers and | ||
159 | * writers until it is released. | ||
160 | * | ||
161 | ******************************************************************************/ | ||
162 | |||
163 | acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock) | ||
164 | { | ||
165 | acpi_status status; | ||
166 | |||
167 | status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER); | ||
168 | return status; | ||
169 | } | ||
170 | |||
171 | void acpi_ut_release_write_lock(struct acpi_rw_lock *lock) | ||
172 | { | ||
173 | |||
174 | acpi_os_release_mutex(lock->writer_mutex); | ||
175 | } | ||
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index c1f7f4e1a72d..1c9e250caefb 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -938,8 +938,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, | |||
938 | if ((!this_source_obj) || | 938 | if ((!this_source_obj) || |
939 | (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) != | 939 | (ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) != |
940 | ACPI_DESC_TYPE_OPERAND) | 940 | ACPI_DESC_TYPE_OPERAND) |
941 | || (ACPI_GET_OBJECT_TYPE(this_source_obj) != | 941 | || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) { |
942 | ACPI_TYPE_PACKAGE)) { | ||
943 | status = | 942 | status = |
944 | walk_callback(ACPI_COPY_TYPE_SIMPLE, | 943 | walk_callback(ACPI_COPY_TYPE_SIMPLE, |
945 | this_source_obj, state, context); | 944 | this_source_obj, state, context); |
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 14eb52c4d647..26c93a748e64 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -60,7 +60,8 @@ static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id); | |||
60 | * | 60 | * |
61 | * RETURN: Status | 61 | * RETURN: Status |
62 | * | 62 | * |
63 | * DESCRIPTION: Create the system mutex objects. | 63 | * DESCRIPTION: Create the system mutex objects. This includes mutexes, |
64 | * spin locks, and reader/writer locks. | ||
64 | * | 65 | * |
65 | ******************************************************************************/ | 66 | ******************************************************************************/ |
66 | 67 | ||
@@ -71,9 +72,8 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
71 | 72 | ||
72 | ACPI_FUNCTION_TRACE(ut_mutex_initialize); | 73 | ACPI_FUNCTION_TRACE(ut_mutex_initialize); |
73 | 74 | ||
74 | /* | 75 | /* Create each of the predefined mutex objects */ |
75 | * Create each of the predefined mutex objects | 76 | |
76 | */ | ||
77 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { | 77 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { |
78 | status = acpi_ut_create_mutex(i); | 78 | status = acpi_ut_create_mutex(i); |
79 | if (ACPI_FAILURE(status)) { | 79 | if (ACPI_FAILURE(status)) { |
@@ -86,6 +86,9 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
86 | spin_lock_init(acpi_gbl_gpe_lock); | 86 | spin_lock_init(acpi_gbl_gpe_lock); |
87 | spin_lock_init(acpi_gbl_hardware_lock); | 87 | spin_lock_init(acpi_gbl_hardware_lock); |
88 | 88 | ||
89 | /* Create the reader/writer lock for namespace access */ | ||
90 | |||
91 | status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock); | ||
89 | return_ACPI_STATUS(status); | 92 | return_ACPI_STATUS(status); |
90 | } | 93 | } |
91 | 94 | ||
@@ -97,7 +100,8 @@ acpi_status acpi_ut_mutex_initialize(void) | |||
97 | * | 100 | * |
98 | * RETURN: None. | 101 | * RETURN: None. |
99 | * | 102 | * |
100 | * DESCRIPTION: Delete all of the system mutex objects. | 103 | * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes, |
104 | * spin locks, and reader/writer locks. | ||
101 | * | 105 | * |
102 | ******************************************************************************/ | 106 | ******************************************************************************/ |
103 | 107 | ||
@@ -107,9 +111,8 @@ void acpi_ut_mutex_terminate(void) | |||
107 | 111 | ||
108 | ACPI_FUNCTION_TRACE(ut_mutex_terminate); | 112 | ACPI_FUNCTION_TRACE(ut_mutex_terminate); |
109 | 113 | ||
110 | /* | 114 | /* Delete each predefined mutex object */ |
111 | * Delete each predefined mutex object | 115 | |
112 | */ | ||
113 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { | 116 | for (i = 0; i < ACPI_NUM_MUTEX; i++) { |
114 | (void)acpi_ut_delete_mutex(i); | 117 | (void)acpi_ut_delete_mutex(i); |
115 | } | 118 | } |
@@ -118,6 +121,10 @@ void acpi_ut_mutex_terminate(void) | |||
118 | 121 | ||
119 | acpi_os_delete_lock(acpi_gbl_gpe_lock); | 122 | acpi_os_delete_lock(acpi_gbl_gpe_lock); |
120 | acpi_os_delete_lock(acpi_gbl_hardware_lock); | 123 | acpi_os_delete_lock(acpi_gbl_hardware_lock); |
124 | |||
125 | /* Delete the reader/writer lock */ | ||
126 | |||
127 | acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock); | ||
121 | return_VOID; | 128 | return_VOID; |
122 | } | 129 | } |
123 | 130 | ||
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index fd5ea7543e5b..0207b625274a 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c | |||
@@ -310,7 +310,7 @@ u8 acpi_ut_valid_internal_object(void *object) | |||
310 | /* Check for a null pointer */ | 310 | /* Check for a null pointer */ |
311 | 311 | ||
312 | if (!object) { | 312 | if (!object) { |
313 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n")); | 313 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n")); |
314 | return (FALSE); | 314 | return (FALSE); |
315 | } | 315 | } |
316 | 316 | ||
@@ -324,7 +324,7 @@ u8 acpi_ut_valid_internal_object(void *object) | |||
324 | return (TRUE); | 324 | return (TRUE); |
325 | 325 | ||
326 | default: | 326 | default: |
327 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 327 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
328 | "%p is not not an ACPI operand obj [%s]\n", | 328 | "%p is not not an ACPI operand obj [%s]\n", |
329 | object, acpi_ut_get_descriptor_name(object))); | 329 | object, acpi_ut_get_descriptor_name(object))); |
330 | break; | 330 | break; |
@@ -457,7 +457,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
457 | * must be accessed bytewise or there may be alignment problems on | 457 | * must be accessed bytewise or there may be alignment problems on |
458 | * certain processors | 458 | * certain processors |
459 | */ | 459 | */ |
460 | switch (ACPI_GET_OBJECT_TYPE(internal_object)) { | 460 | switch (internal_object->common.type) { |
461 | case ACPI_TYPE_STRING: | 461 | case ACPI_TYPE_STRING: |
462 | 462 | ||
463 | length += (acpi_size) internal_object->string.length + 1; | 463 | length += (acpi_size) internal_object->string.length + 1; |
@@ -518,8 +518,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
518 | ACPI_ERROR((AE_INFO, "Cannot convert to external object - " | 518 | ACPI_ERROR((AE_INFO, "Cannot convert to external object - " |
519 | "unsupported type [%s] %X in object %p", | 519 | "unsupported type [%s] %X in object %p", |
520 | acpi_ut_get_object_type_name(internal_object), | 520 | acpi_ut_get_object_type_name(internal_object), |
521 | ACPI_GET_OBJECT_TYPE(internal_object), | 521 | internal_object->common.type, internal_object)); |
522 | internal_object)); | ||
523 | status = AE_TYPE; | 522 | status = AE_TYPE; |
524 | break; | 523 | break; |
525 | } | 524 | } |
@@ -664,7 +663,7 @@ acpi_ut_get_object_size(union acpi_operand_object *internal_object, | |||
664 | 663 | ||
665 | if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) == | 664 | if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) == |
666 | ACPI_DESC_TYPE_OPERAND) | 665 | ACPI_DESC_TYPE_OPERAND) |
667 | && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) { | 666 | && (internal_object->common.type == ACPI_TYPE_PACKAGE)) { |
668 | status = | 667 | status = |
669 | acpi_ut_get_package_object_size(internal_object, | 668 | acpi_ut_get_package_object_size(internal_object, |
670 | obj_length); | 669 | obj_length); |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 69cbc57c2d1c..5dfe18bf24cb 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | #include <linux/async.h> | ||
33 | 34 | ||
34 | #ifdef CONFIG_ACPI_PROCFS_POWER | 35 | #ifdef CONFIG_ACPI_PROCFS_POWER |
35 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
@@ -92,7 +93,7 @@ struct acpi_battery { | |||
92 | #endif | 93 | #endif |
93 | struct acpi_device *device; | 94 | struct acpi_device *device; |
94 | unsigned long update_time; | 95 | unsigned long update_time; |
95 | int current_now; | 96 | int rate_now; |
96 | int capacity_now; | 97 | int capacity_now; |
97 | int voltage_now; | 98 | int voltage_now; |
98 | int design_capacity; | 99 | int design_capacity; |
@@ -196,7 +197,8 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
196 | val->intval = battery->voltage_now * 1000; | 197 | val->intval = battery->voltage_now * 1000; |
197 | break; | 198 | break; |
198 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 199 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
199 | val->intval = battery->current_now * 1000; | 200 | case POWER_SUPPLY_PROP_POWER_NOW: |
201 | val->intval = battery->rate_now * 1000; | ||
200 | break; | 202 | break; |
201 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: | 203 | case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: |
202 | case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: | 204 | case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: |
@@ -247,6 +249,7 @@ static enum power_supply_property energy_battery_props[] = { | |||
247 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, | 249 | POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, |
248 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 250 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
249 | POWER_SUPPLY_PROP_CURRENT_NOW, | 251 | POWER_SUPPLY_PROP_CURRENT_NOW, |
252 | POWER_SUPPLY_PROP_POWER_NOW, | ||
250 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 253 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
251 | POWER_SUPPLY_PROP_ENERGY_FULL, | 254 | POWER_SUPPLY_PROP_ENERGY_FULL, |
252 | POWER_SUPPLY_PROP_ENERGY_NOW, | 255 | POWER_SUPPLY_PROP_ENERGY_NOW, |
@@ -273,7 +276,7 @@ struct acpi_offsets { | |||
273 | 276 | ||
274 | static struct acpi_offsets state_offsets[] = { | 277 | static struct acpi_offsets state_offsets[] = { |
275 | {offsetof(struct acpi_battery, state), 0}, | 278 | {offsetof(struct acpi_battery, state), 0}, |
276 | {offsetof(struct acpi_battery, current_now), 0}, | 279 | {offsetof(struct acpi_battery, rate_now), 0}, |
277 | {offsetof(struct acpi_battery, capacity_now), 0}, | 280 | {offsetof(struct acpi_battery, capacity_now), 0}, |
278 | {offsetof(struct acpi_battery, voltage_now), 0}, | 281 | {offsetof(struct acpi_battery, voltage_now), 0}, |
279 | }; | 282 | }; |
@@ -605,11 +608,11 @@ static int acpi_battery_print_state(struct seq_file *seq, int result) | |||
605 | else | 608 | else |
606 | seq_printf(seq, "charging state: charged\n"); | 609 | seq_printf(seq, "charging state: charged\n"); |
607 | 610 | ||
608 | if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN) | 611 | if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) |
609 | seq_printf(seq, "present rate: unknown\n"); | 612 | seq_printf(seq, "present rate: unknown\n"); |
610 | else | 613 | else |
611 | seq_printf(seq, "present rate: %d %s\n", | 614 | seq_printf(seq, "present rate: %d %s\n", |
612 | battery->current_now, acpi_battery_units(battery)); | 615 | battery->rate_now, acpi_battery_units(battery)); |
613 | 616 | ||
614 | if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) | 617 | if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) |
615 | seq_printf(seq, "remaining capacity: unknown\n"); | 618 | seq_printf(seq, "remaining capacity: unknown\n"); |
@@ -901,21 +904,27 @@ static struct acpi_driver acpi_battery_driver = { | |||
901 | }, | 904 | }, |
902 | }; | 905 | }; |
903 | 906 | ||
904 | static int __init acpi_battery_init(void) | 907 | static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) |
905 | { | 908 | { |
906 | if (acpi_disabled) | 909 | if (acpi_disabled) |
907 | return -ENODEV; | 910 | return; |
908 | #ifdef CONFIG_ACPI_PROCFS_POWER | 911 | #ifdef CONFIG_ACPI_PROCFS_POWER |
909 | acpi_battery_dir = acpi_lock_battery_dir(); | 912 | acpi_battery_dir = acpi_lock_battery_dir(); |
910 | if (!acpi_battery_dir) | 913 | if (!acpi_battery_dir) |
911 | return -ENODEV; | 914 | return; |
912 | #endif | 915 | #endif |
913 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { | 916 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { |
914 | #ifdef CONFIG_ACPI_PROCFS_POWER | 917 | #ifdef CONFIG_ACPI_PROCFS_POWER |
915 | acpi_unlock_battery_dir(acpi_battery_dir); | 918 | acpi_unlock_battery_dir(acpi_battery_dir); |
916 | #endif | 919 | #endif |
917 | return -ENODEV; | 920 | return; |
918 | } | 921 | } |
922 | return; | ||
923 | } | ||
924 | |||
925 | static int __init acpi_battery_init(void) | ||
926 | { | ||
927 | async_schedule(acpi_battery_init_async, NULL); | ||
919 | return 0; | 928 | return 0; |
920 | } | 929 | } |
921 | 930 | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index bee64b73c919..e8f7b64e92da 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
40 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
41 | 41 | ||
42 | #include "internal.h" | ||
43 | |||
42 | #define _COMPONENT ACPI_BUS_COMPONENT | 44 | #define _COMPONENT ACPI_BUS_COMPONENT |
43 | ACPI_MODULE_NAME("bus"); | 45 | ACPI_MODULE_NAME("bus"); |
44 | 46 | ||
@@ -846,6 +848,7 @@ static int __init acpi_init(void) | |||
846 | acpi_kobj = NULL; | 848 | acpi_kobj = NULL; |
847 | } | 849 | } |
848 | 850 | ||
851 | init_acpi_device_notify(); | ||
849 | result = acpi_bus_init(); | 852 | result = acpi_bus_init(); |
850 | 853 | ||
851 | if (!result) { | 854 | if (!result) { |
@@ -860,11 +863,23 @@ static int __init acpi_init(void) | |||
860 | } | 863 | } |
861 | } else | 864 | } else |
862 | disable_acpi(); | 865 | disable_acpi(); |
866 | |||
867 | if (acpi_disabled) | ||
868 | return result; | ||
869 | |||
863 | /* | 870 | /* |
864 | * If the laptop falls into the DMI check table, the power state check | 871 | * If the laptop falls into the DMI check table, the power state check |
865 | * will be disabled in the course of device power transistion. | 872 | * will be disabled in the course of device power transistion. |
866 | */ | 873 | */ |
867 | dmi_check_system(power_nocheck_dmi_table); | 874 | dmi_check_system(power_nocheck_dmi_table); |
875 | |||
876 | acpi_scan_init(); | ||
877 | acpi_ec_init(); | ||
878 | acpi_power_init(); | ||
879 | acpi_system_init(); | ||
880 | acpi_debug_init(); | ||
881 | acpi_sleep_proc_init(); | ||
882 | acpi_wakeup_device_init(); | ||
868 | return result; | 883 | return result; |
869 | } | 884 | } |
870 | 885 | ||
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 20223cbd0d1c..a8287be0870e 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
@@ -13,11 +13,6 @@ | |||
13 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 13 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
14 | ACPI_MODULE_NAME("debug"); | 14 | ACPI_MODULE_NAME("debug"); |
15 | 15 | ||
16 | #ifdef MODULE_PARAM_PREFIX | ||
17 | #undef MODULE_PARAM_PREFIX | ||
18 | #endif | ||
19 | #define MODULE_PARAM_PREFIX "acpi." | ||
20 | |||
21 | struct acpi_dlayer { | 16 | struct acpi_dlayer { |
22 | const char *name; | 17 | const char *name; |
23 | unsigned long value; | 18 | unsigned long value; |
@@ -297,17 +292,15 @@ acpi_system_write_debug(struct file *file, | |||
297 | 292 | ||
298 | return count; | 293 | return count; |
299 | } | 294 | } |
295 | #endif | ||
300 | 296 | ||
301 | static int __init acpi_debug_init(void) | 297 | int __init acpi_debug_init(void) |
302 | { | 298 | { |
299 | #ifdef CONFIG_ACPI_PROCFS | ||
303 | struct proc_dir_entry *entry; | 300 | struct proc_dir_entry *entry; |
304 | int error = 0; | 301 | int error = 0; |
305 | char *name; | 302 | char *name; |
306 | 303 | ||
307 | |||
308 | if (acpi_disabled) | ||
309 | return 0; | ||
310 | |||
311 | /* 'debug_layer' [R/W] */ | 304 | /* 'debug_layer' [R/W] */ |
312 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; | 305 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; |
313 | entry = | 306 | entry = |
@@ -338,7 +331,7 @@ static int __init acpi_debug_init(void) | |||
338 | remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); | 331 | remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir); |
339 | error = -ENODEV; | 332 | error = -ENODEV; |
340 | goto Done; | 333 | goto Done; |
341 | } | 334 | #else |
342 | 335 | return 0; | |
343 | subsys_initcall(acpi_debug_init); | ||
344 | #endif | 336 | #endif |
337 | } | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ac9dd3b386b1..03107bce03ed 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -765,6 +765,10 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
765 | unsigned long long tmp = 0; | 765 | unsigned long long tmp = 0; |
766 | 766 | ||
767 | struct acpi_ec *ec = context; | 767 | struct acpi_ec *ec = context; |
768 | |||
769 | /* clear addr values, ec_parse_io_ports depend on it */ | ||
770 | ec->command_addr = ec->data_addr = 0; | ||
771 | |||
768 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 772 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
769 | ec_parse_io_ports, ec); | 773 | ec_parse_io_ports, ec); |
770 | if (ACPI_FAILURE(status)) | 774 | if (ACPI_FAILURE(status)) |
@@ -814,11 +818,11 @@ static int acpi_ec_add(struct acpi_device *device) | |||
814 | ec = make_acpi_ec(); | 818 | ec = make_acpi_ec(); |
815 | if (!ec) | 819 | if (!ec) |
816 | return -ENOMEM; | 820 | return -ENOMEM; |
817 | if (ec_parse_device(device->handle, 0, ec, NULL) != | 821 | } |
818 | AE_CTRL_TERMINATE) { | 822 | if (ec_parse_device(device->handle, 0, ec, NULL) != |
823 | AE_CTRL_TERMINATE) { | ||
819 | kfree(ec); | 824 | kfree(ec); |
820 | return -EINVAL; | 825 | return -EINVAL; |
821 | } | ||
822 | } | 826 | } |
823 | 827 | ||
824 | ec->handle = device->handle; | 828 | ec->handle = device->handle; |
@@ -996,12 +1000,12 @@ int __init acpi_ec_ecdt_probe(void) | |||
996 | boot_ec->handle = ACPI_ROOT_OBJECT; | 1000 | boot_ec->handle = ACPI_ROOT_OBJECT; |
997 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 1001 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
998 | /* Don't trust ECDT, which comes from ASUSTek */ | 1002 | /* Don't trust ECDT, which comes from ASUSTek */ |
999 | if (!dmi_name_in_vendors("ASUS")) | 1003 | if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) |
1000 | goto install; | 1004 | goto install; |
1001 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 1005 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
1002 | if (!saved_ec) | 1006 | if (!saved_ec) |
1003 | return -ENOMEM; | 1007 | return -ENOMEM; |
1004 | memcpy(saved_ec, boot_ec, sizeof(*saved_ec)); | 1008 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); |
1005 | /* fall through */ | 1009 | /* fall through */ |
1006 | } | 1010 | } |
1007 | /* This workaround is needed only on some broken machines, | 1011 | /* This workaround is needed only on some broken machines, |
@@ -1079,13 +1083,10 @@ static struct acpi_driver acpi_ec_driver = { | |||
1079 | }, | 1083 | }, |
1080 | }; | 1084 | }; |
1081 | 1085 | ||
1082 | static int __init acpi_ec_init(void) | 1086 | int __init acpi_ec_init(void) |
1083 | { | 1087 | { |
1084 | int result = 0; | 1088 | int result = 0; |
1085 | 1089 | ||
1086 | if (acpi_disabled) | ||
1087 | return 0; | ||
1088 | |||
1089 | acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); | 1090 | acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir); |
1090 | if (!acpi_ec_dir) | 1091 | if (!acpi_ec_dir) |
1091 | return -ENODEV; | 1092 | return -ENODEV; |
@@ -1100,8 +1101,6 @@ static int __init acpi_ec_init(void) | |||
1100 | return result; | 1101 | return result; |
1101 | } | 1102 | } |
1102 | 1103 | ||
1103 | subsys_initcall(acpi_ec_init); | ||
1104 | |||
1105 | /* EC driver currently not unloadable */ | 1104 | /* EC driver currently not unloadable */ |
1106 | #if 0 | 1105 | #if 0 |
1107 | static void __exit acpi_ec_exit(void) | 1106 | static void __exit acpi_ec_exit(void) |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index eaaee1660bdf..ae41cf3cf4e5 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -68,31 +68,35 @@ static struct acpi_driver acpi_fan_driver = { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | /* thermal cooling device callbacks */ | 70 | /* thermal cooling device callbacks */ |
71 | static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf) | 71 | static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long |
72 | *state) | ||
72 | { | 73 | { |
73 | /* ACPI fan device only support two states: ON/OFF */ | 74 | /* ACPI fan device only support two states: ON/OFF */ |
74 | return sprintf(buf, "1\n"); | 75 | *state = 1; |
76 | return 0; | ||
75 | } | 77 | } |
76 | 78 | ||
77 | static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf) | 79 | static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long |
80 | *state) | ||
78 | { | 81 | { |
79 | struct acpi_device *device = cdev->devdata; | 82 | struct acpi_device *device = cdev->devdata; |
80 | int state; | ||
81 | int result; | 83 | int result; |
84 | int acpi_state; | ||
82 | 85 | ||
83 | if (!device) | 86 | if (!device) |
84 | return -EINVAL; | 87 | return -EINVAL; |
85 | 88 | ||
86 | result = acpi_bus_get_power(device->handle, &state); | 89 | result = acpi_bus_get_power(device->handle, &acpi_state); |
87 | if (result) | 90 | if (result) |
88 | return result; | 91 | return result; |
89 | 92 | ||
90 | return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" : | 93 | *state = (acpi_state == ACPI_STATE_D3 ? 0 : |
91 | (state == ACPI_STATE_D0 ? "1" : "unknown")); | 94 | (acpi_state == ACPI_STATE_D0 ? 1 : -1)); |
95 | return 0; | ||
92 | } | 96 | } |
93 | 97 | ||
94 | static int | 98 | static int |
95 | fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) | 99 | fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) |
96 | { | 100 | { |
97 | struct acpi_device *device = cdev->devdata; | 101 | struct acpi_device *device = cdev->devdata; |
98 | int result; | 102 | int result; |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 5479b9f42513..8bd2c2a6884d 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -286,10 +286,8 @@ static int acpi_platform_notify_remove(struct device *dev) | |||
286 | return 0; | 286 | return 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | static int __init init_acpi_device_notify(void) | 289 | int __init init_acpi_device_notify(void) |
290 | { | 290 | { |
291 | if (acpi_disabled) | ||
292 | return 0; | ||
293 | if (platform_notify || platform_notify_remove) { | 291 | if (platform_notify || platform_notify_remove) { |
294 | printk(KERN_ERR PREFIX "Can't use platform_notify\n"); | 292 | printk(KERN_ERR PREFIX "Can't use platform_notify\n"); |
295 | return 0; | 293 | return 0; |
@@ -298,5 +296,3 @@ static int __init init_acpi_device_notify(void) | |||
298 | platform_notify_remove = acpi_platform_notify_remove; | 296 | platform_notify_remove = acpi_platform_notify_remove; |
299 | return 0; | 297 | return 0; |
300 | } | 298 | } |
301 | |||
302 | arch_initcall(init_acpi_device_notify); | ||
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h new file mode 100644 index 000000000000..11a69b53004e --- /dev/null +++ b/drivers/acpi/internal.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* For use by Linux/ACPI infrastructure, not drivers */ | ||
2 | |||
3 | int init_acpi_device_notify(void); | ||
4 | int acpi_scan_init(void); | ||
5 | int acpi_system_init(void); | ||
6 | |||
7 | #ifdef CONFIG_ACPI_DEBUG | ||
8 | int acpi_debug_init(void); | ||
9 | #else | ||
10 | static inline int acpi_debug_init(void) { return 0; } | ||
11 | #endif | ||
12 | |||
13 | /* -------------------------------------------------------------------------- | ||
14 | Power Resource | ||
15 | -------------------------------------------------------------------------- */ | ||
16 | int acpi_power_init(void); | ||
17 | int acpi_device_sleep_wake(struct acpi_device *dev, | ||
18 | int enable, int sleep_state, int dev_state); | ||
19 | int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state); | ||
20 | int acpi_disable_wakeup_device_power(struct acpi_device *dev); | ||
21 | int acpi_power_get_inferred_state(struct acpi_device *device); | ||
22 | int acpi_power_transition(struct acpi_device *device, int state); | ||
23 | extern int acpi_power_nocheck; | ||
24 | |||
25 | int acpi_wakeup_device_init(void); | ||
26 | |||
27 | /* -------------------------------------------------------------------------- | ||
28 | Embedded Controller | ||
29 | -------------------------------------------------------------------------- */ | ||
30 | int acpi_ec_init(void); | ||
31 | int acpi_ec_ecdt_probe(void); | ||
32 | int acpi_boot_ec_enable(void); | ||
33 | |||
34 | /*-------------------------------------------------------------------------- | ||
35 | Suspend/Resume | ||
36 | -------------------------------------------------------------------------- */ | ||
37 | extern int acpi_sleep_init(void); | ||
38 | |||
39 | #ifdef CONFIG_ACPI_SLEEP | ||
40 | int acpi_sleep_proc_init(void); | ||
41 | #else | ||
42 | static inline int acpi_sleep_proc_init(void) { return 0; } | ||
43 | #endif | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 1e35f342957c..f50ca1ea80c3 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -1063,9 +1063,9 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); | |||
1063 | * in arbitrary AML code and can interfere with legacy drivers. | 1063 | * in arbitrary AML code and can interfere with legacy drivers. |
1064 | * acpi_enforce_resources= can be set to: | 1064 | * acpi_enforce_resources= can be set to: |
1065 | * | 1065 | * |
1066 | * - strict (2) | 1066 | * - strict (default) (2) |
1067 | * -> further driver trying to access the resources will not load | 1067 | * -> further driver trying to access the resources will not load |
1068 | * - lax (default) (1) | 1068 | * - lax (1) |
1069 | * -> further driver trying to access the resources will load, but you | 1069 | * -> further driver trying to access the resources will load, but you |
1070 | * get a system message that something might go wrong... | 1070 | * get a system message that something might go wrong... |
1071 | * | 1071 | * |
@@ -1077,7 +1077,7 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); | |||
1077 | #define ENFORCE_RESOURCES_LAX 1 | 1077 | #define ENFORCE_RESOURCES_LAX 1 |
1078 | #define ENFORCE_RESOURCES_NO 0 | 1078 | #define ENFORCE_RESOURCES_NO 0 |
1079 | 1079 | ||
1080 | static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX; | 1080 | static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT; |
1081 | 1081 | ||
1082 | static int __init acpi_enforce_resources_setup(char *str) | 1082 | static int __init acpi_enforce_resources_setup(char *str) |
1083 | { | 1083 | { |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 891bdf6679f3..be6b9093f8df 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -319,7 +319,7 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | |||
319 | */ | 319 | */ |
320 | bridge = dev->bus->self; | 320 | bridge = dev->bus->self; |
321 | while (bridge) { | 321 | while (bridge) { |
322 | pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1; | 322 | pin = pci_swizzle_interrupt_pin(dev, pin); |
323 | 323 | ||
324 | if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { | 324 | if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) { |
325 | /* PC card has the same IRQ as its cardbridge */ | 325 | /* PC card has the same IRQ as its cardbridge */ |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 6c772ca76bd1..16e0f9d3d17c 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -43,13 +43,14 @@ | |||
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | 45 | ||
46 | #define _COMPONENT ACPI_PCI_COMPONENT | 46 | #define _COMPONENT ACPI_PCI_COMPONENT |
47 | ACPI_MODULE_NAME("pci_link"); | 47 | ACPI_MODULE_NAME("pci_link"); |
48 | #define ACPI_PCI_LINK_CLASS "pci_irq_routing" | 48 | #define ACPI_PCI_LINK_CLASS "pci_irq_routing" |
49 | #define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" | 49 | #define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" |
50 | #define ACPI_PCI_LINK_FILE_INFO "info" | 50 | #define ACPI_PCI_LINK_FILE_INFO "info" |
51 | #define ACPI_PCI_LINK_FILE_STATUS "state" | 51 | #define ACPI_PCI_LINK_FILE_STATUS "state" |
52 | #define ACPI_PCI_LINK_MAX_POSSIBLE 16 | 52 | #define ACPI_PCI_LINK_MAX_POSSIBLE 16 |
53 | |||
53 | static int acpi_pci_link_add(struct acpi_device *device); | 54 | static int acpi_pci_link_add(struct acpi_device *device); |
54 | static int acpi_pci_link_remove(struct acpi_device *device, int type); | 55 | static int acpi_pci_link_remove(struct acpi_device *device, int type); |
55 | 56 | ||
@@ -66,7 +67,7 @@ static struct acpi_driver acpi_pci_link_driver = { | |||
66 | .ops = { | 67 | .ops = { |
67 | .add = acpi_pci_link_add, | 68 | .add = acpi_pci_link_add, |
68 | .remove = acpi_pci_link_remove, | 69 | .remove = acpi_pci_link_remove, |
69 | }, | 70 | }, |
70 | }; | 71 | }; |
71 | 72 | ||
72 | /* | 73 | /* |
@@ -76,7 +77,7 @@ static struct acpi_driver acpi_pci_link_driver = { | |||
76 | struct acpi_pci_link_irq { | 77 | struct acpi_pci_link_irq { |
77 | u8 active; /* Current IRQ */ | 78 | u8 active; /* Current IRQ */ |
78 | u8 triggering; /* All IRQs */ | 79 | u8 triggering; /* All IRQs */ |
79 | u8 polarity; /* All IRQs */ | 80 | u8 polarity; /* All IRQs */ |
80 | u8 resource_type; | 81 | u8 resource_type; |
81 | u8 possible_count; | 82 | u8 possible_count; |
82 | u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; | 83 | u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; |
@@ -85,16 +86,13 @@ struct acpi_pci_link_irq { | |||
85 | }; | 86 | }; |
86 | 87 | ||
87 | struct acpi_pci_link { | 88 | struct acpi_pci_link { |
88 | struct list_head node; | 89 | struct list_head list; |
89 | struct acpi_device *device; | 90 | struct acpi_device *device; |
90 | struct acpi_pci_link_irq irq; | 91 | struct acpi_pci_link_irq irq; |
91 | int refcnt; | 92 | int refcnt; |
92 | }; | 93 | }; |
93 | 94 | ||
94 | static struct { | 95 | static LIST_HEAD(acpi_link_list); |
95 | int count; | ||
96 | struct list_head entries; | ||
97 | } acpi_link; | ||
98 | static DEFINE_MUTEX(acpi_link_lock); | 96 | static DEFINE_MUTEX(acpi_link_lock); |
99 | 97 | ||
100 | /* -------------------------------------------------------------------------- | 98 | /* -------------------------------------------------------------------------- |
@@ -104,12 +102,11 @@ static DEFINE_MUTEX(acpi_link_lock); | |||
104 | /* | 102 | /* |
105 | * set context (link) possible list from resource list | 103 | * set context (link) possible list from resource list |
106 | */ | 104 | */ |
107 | static acpi_status | 105 | static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, |
108 | acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) | 106 | void *context) |
109 | { | 107 | { |
110 | struct acpi_pci_link *link = context; | 108 | struct acpi_pci_link *link = context; |
111 | u32 i = 0; | 109 | u32 i; |
112 | |||
113 | 110 | ||
114 | switch (resource->type) { | 111 | switch (resource->type) { |
115 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | 112 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
@@ -179,10 +176,6 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link) | |||
179 | { | 176 | { |
180 | acpi_status status; | 177 | acpi_status status; |
181 | 178 | ||
182 | |||
183 | if (!link) | ||
184 | return -EINVAL; | ||
185 | |||
186 | status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS, | 179 | status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS, |
187 | acpi_pci_link_check_possible, link); | 180 | acpi_pci_link_check_possible, link); |
188 | if (ACPI_FAILURE(status)) { | 181 | if (ACPI_FAILURE(status)) { |
@@ -197,11 +190,10 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link) | |||
197 | return 0; | 190 | return 0; |
198 | } | 191 | } |
199 | 192 | ||
200 | static acpi_status | 193 | static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource, |
201 | acpi_pci_link_check_current(struct acpi_resource *resource, void *context) | 194 | void *context) |
202 | { | 195 | { |
203 | int *irq = (int *)context; | 196 | int *irq = context; |
204 | |||
205 | 197 | ||
206 | switch (resource->type) { | 198 | switch (resource->type) { |
207 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: | 199 | case ACPI_RESOURCE_TYPE_START_DEPENDENT: |
@@ -258,12 +250,9 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context) | |||
258 | static int acpi_pci_link_get_current(struct acpi_pci_link *link) | 250 | static int acpi_pci_link_get_current(struct acpi_pci_link *link) |
259 | { | 251 | { |
260 | int result = 0; | 252 | int result = 0; |
261 | acpi_status status = AE_OK; | 253 | acpi_status status; |
262 | int irq = 0; | 254 | int irq = 0; |
263 | 255 | ||
264 | if (!link) | ||
265 | return -EINVAL; | ||
266 | |||
267 | link->irq.active = 0; | 256 | link->irq.active = 0; |
268 | 257 | ||
269 | /* in practice, status disabled is meaningless, ignore it */ | 258 | /* in practice, status disabled is meaningless, ignore it */ |
@@ -308,16 +297,15 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link) | |||
308 | 297 | ||
309 | static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) | 298 | static int acpi_pci_link_set(struct acpi_pci_link *link, int irq) |
310 | { | 299 | { |
311 | int result = 0; | 300 | int result; |
312 | acpi_status status = AE_OK; | 301 | acpi_status status; |
313 | struct { | 302 | struct { |
314 | struct acpi_resource res; | 303 | struct acpi_resource res; |
315 | struct acpi_resource end; | 304 | struct acpi_resource end; |
316 | } *resource; | 305 | } *resource; |
317 | struct acpi_buffer buffer = { 0, NULL }; | 306 | struct acpi_buffer buffer = { 0, NULL }; |
318 | 307 | ||
319 | 308 | if (!irq) | |
320 | if (!link || !irq) | ||
321 | return -EINVAL; | 309 | return -EINVAL; |
322 | 310 | ||
323 | resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); | 311 | resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); |
@@ -479,30 +467,22 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = { | |||
479 | PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */ | 467 | PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */ |
480 | PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */ | 468 | PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */ |
481 | PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */ | 469 | PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */ |
482 | PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */ | 470 | PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */ |
483 | PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */ | 471 | PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */ |
484 | PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */ | 472 | PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */ |
485 | PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */ | 473 | PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */ |
486 | /* >IRQ15 */ | 474 | /* >IRQ15 */ |
487 | }; | 475 | }; |
488 | 476 | ||
489 | int __init acpi_irq_penalty_init(void) | 477 | int __init acpi_irq_penalty_init(void) |
490 | { | 478 | { |
491 | struct list_head *node = NULL; | 479 | struct acpi_pci_link *link; |
492 | struct acpi_pci_link *link = NULL; | 480 | int i; |
493 | int i = 0; | ||
494 | |||
495 | 481 | ||
496 | /* | 482 | /* |
497 | * Update penalties to facilitate IRQ balancing. | 483 | * Update penalties to facilitate IRQ balancing. |
498 | */ | 484 | */ |
499 | list_for_each(node, &acpi_link.entries) { | 485 | list_for_each_entry(link, &acpi_link_list, list) { |
500 | |||
501 | link = list_entry(node, struct acpi_pci_link, node); | ||
502 | if (!link) { | ||
503 | printk(KERN_ERR PREFIX "Invalid link context\n"); | ||
504 | continue; | ||
505 | } | ||
506 | 486 | ||
507 | /* | 487 | /* |
508 | * reflect the possible and active irqs in the penalty table -- | 488 | * reflect the possible and active irqs in the penalty table -- |
@@ -527,7 +507,6 @@ int __init acpi_irq_penalty_init(void) | |||
527 | } | 507 | } |
528 | /* Add a penalty for the SCI */ | 508 | /* Add a penalty for the SCI */ |
529 | acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; | 509 | acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING; |
530 | |||
531 | return 0; | 510 | return 0; |
532 | } | 511 | } |
533 | 512 | ||
@@ -538,7 +517,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) | |||
538 | int irq; | 517 | int irq; |
539 | int i; | 518 | int i; |
540 | 519 | ||
541 | |||
542 | if (link->irq.initialized) { | 520 | if (link->irq.initialized) { |
543 | if (link->refcnt == 0) | 521 | if (link->refcnt == 0) |
544 | /* This means the link is disabled but initialized */ | 522 | /* This means the link is disabled but initialized */ |
@@ -566,11 +544,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) | |||
566 | /* | 544 | /* |
567 | * if active found, use it; else pick entry from end of possible list. | 545 | * if active found, use it; else pick entry from end of possible list. |
568 | */ | 546 | */ |
569 | if (link->irq.active) { | 547 | if (link->irq.active) |
570 | irq = link->irq.active; | 548 | irq = link->irq.active; |
571 | } else { | 549 | else |
572 | irq = link->irq.possible[link->irq.possible_count - 1]; | 550 | irq = link->irq.possible[link->irq.possible_count - 1]; |
573 | } | ||
574 | 551 | ||
575 | if (acpi_irq_balance || !link->irq.active) { | 552 | if (acpi_irq_balance || !link->irq.active) { |
576 | /* | 553 | /* |
@@ -599,7 +576,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) | |||
599 | } | 576 | } |
600 | 577 | ||
601 | link->irq.initialized = 1; | 578 | link->irq.initialized = 1; |
602 | |||
603 | return 0; | 579 | return 0; |
604 | } | 580 | } |
605 | 581 | ||
@@ -608,16 +584,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link) | |||
608 | * success: return IRQ >= 0 | 584 | * success: return IRQ >= 0 |
609 | * failure: return -1 | 585 | * failure: return -1 |
610 | */ | 586 | */ |
611 | 587 | int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, | |
612 | int | 588 | int *polarity, char **name) |
613 | acpi_pci_link_allocate_irq(acpi_handle handle, | ||
614 | int index, | ||
615 | int *triggering, int *polarity, char **name) | ||
616 | { | 589 | { |
617 | int result = 0; | 590 | int result; |
618 | struct acpi_device *device = NULL; | 591 | struct acpi_device *device; |
619 | struct acpi_pci_link *link = NULL; | 592 | struct acpi_pci_link *link; |
620 | |||
621 | 593 | ||
622 | result = acpi_bus_get_device(handle, &device); | 594 | result = acpi_bus_get_device(handle, &device); |
623 | if (result) { | 595 | if (result) { |
@@ -669,11 +641,10 @@ acpi_pci_link_allocate_irq(acpi_handle handle, | |||
669 | */ | 641 | */ |
670 | int acpi_pci_link_free_irq(acpi_handle handle) | 642 | int acpi_pci_link_free_irq(acpi_handle handle) |
671 | { | 643 | { |
672 | struct acpi_device *device = NULL; | 644 | struct acpi_device *device; |
673 | struct acpi_pci_link *link = NULL; | 645 | struct acpi_pci_link *link; |
674 | acpi_status result; | 646 | acpi_status result; |
675 | 647 | ||
676 | |||
677 | result = acpi_bus_get_device(handle, &device); | 648 | result = acpi_bus_get_device(handle, &device); |
678 | if (result) { | 649 | if (result) { |
679 | printk(KERN_ERR PREFIX "Invalid link device\n"); | 650 | printk(KERN_ERR PREFIX "Invalid link device\n"); |
@@ -708,9 +679,9 @@ int acpi_pci_link_free_irq(acpi_handle handle) | |||
708 | "Link %s is dereferenced\n", | 679 | "Link %s is dereferenced\n", |
709 | acpi_device_bid(link->device))); | 680 | acpi_device_bid(link->device))); |
710 | 681 | ||
711 | if (link->refcnt == 0) { | 682 | if (link->refcnt == 0) |
712 | acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL); | 683 | acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL); |
713 | } | 684 | |
714 | mutex_unlock(&acpi_link_lock); | 685 | mutex_unlock(&acpi_link_lock); |
715 | return (link->irq.active); | 686 | return (link->irq.active); |
716 | } | 687 | } |
@@ -721,15 +692,11 @@ int acpi_pci_link_free_irq(acpi_handle handle) | |||
721 | 692 | ||
722 | static int acpi_pci_link_add(struct acpi_device *device) | 693 | static int acpi_pci_link_add(struct acpi_device *device) |
723 | { | 694 | { |
724 | int result = 0; | 695 | int result; |
725 | struct acpi_pci_link *link = NULL; | 696 | struct acpi_pci_link *link; |
726 | int i = 0; | 697 | int i; |
727 | int found = 0; | 698 | int found = 0; |
728 | 699 | ||
729 | |||
730 | if (!device) | ||
731 | return -EINVAL; | ||
732 | |||
733 | link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); | 700 | link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); |
734 | if (!link) | 701 | if (!link) |
735 | return -ENOMEM; | 702 | return -ENOMEM; |
@@ -767,9 +734,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
767 | 734 | ||
768 | printk("\n"); | 735 | printk("\n"); |
769 | 736 | ||
770 | /* TBD: Acquire/release lock */ | 737 | list_add_tail(&link->list, &acpi_link_list); |
771 | list_add_tail(&link->node, &acpi_link.entries); | ||
772 | acpi_link.count++; | ||
773 | 738 | ||
774 | end: | 739 | end: |
775 | /* disable all links -- to be activated on use */ | 740 | /* disable all links -- to be activated on use */ |
@@ -784,24 +749,17 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
784 | 749 | ||
785 | static int acpi_pci_link_resume(struct acpi_pci_link *link) | 750 | static int acpi_pci_link_resume(struct acpi_pci_link *link) |
786 | { | 751 | { |
787 | |||
788 | if (link->refcnt && link->irq.active && link->irq.initialized) | 752 | if (link->refcnt && link->irq.active && link->irq.initialized) |
789 | return (acpi_pci_link_set(link, link->irq.active)); | 753 | return (acpi_pci_link_set(link, link->irq.active)); |
790 | else | 754 | |
791 | return 0; | 755 | return 0; |
792 | } | 756 | } |
793 | 757 | ||
794 | static int irqrouter_resume(struct sys_device *dev) | 758 | static int irqrouter_resume(struct sys_device *dev) |
795 | { | 759 | { |
796 | struct list_head *node = NULL; | 760 | struct acpi_pci_link *link; |
797 | struct acpi_pci_link *link = NULL; | ||
798 | 761 | ||
799 | list_for_each(node, &acpi_link.entries) { | 762 | list_for_each_entry(link, &acpi_link_list, list) { |
800 | link = list_entry(node, struct acpi_pci_link, node); | ||
801 | if (!link) { | ||
802 | printk(KERN_ERR PREFIX "Invalid link context\n"); | ||
803 | continue; | ||
804 | } | ||
805 | acpi_pci_link_resume(link); | 763 | acpi_pci_link_resume(link); |
806 | } | 764 | } |
807 | return 0; | 765 | return 0; |
@@ -809,20 +767,15 @@ static int irqrouter_resume(struct sys_device *dev) | |||
809 | 767 | ||
810 | static int acpi_pci_link_remove(struct acpi_device *device, int type) | 768 | static int acpi_pci_link_remove(struct acpi_device *device, int type) |
811 | { | 769 | { |
812 | struct acpi_pci_link *link = NULL; | 770 | struct acpi_pci_link *link; |
813 | |||
814 | |||
815 | if (!device || !acpi_driver_data(device)) | ||
816 | return -EINVAL; | ||
817 | 771 | ||
818 | link = acpi_driver_data(device); | 772 | link = acpi_driver_data(device); |
819 | 773 | ||
820 | mutex_lock(&acpi_link_lock); | 774 | mutex_lock(&acpi_link_lock); |
821 | list_del(&link->node); | 775 | list_del(&link->list); |
822 | mutex_unlock(&acpi_link_lock); | 776 | mutex_unlock(&acpi_link_lock); |
823 | 777 | ||
824 | kfree(link); | 778 | kfree(link); |
825 | |||
826 | return 0; | 779 | return 0; |
827 | } | 780 | } |
828 | 781 | ||
@@ -931,7 +884,6 @@ static int __init irqrouter_init_sysfs(void) | |||
931 | { | 884 | { |
932 | int error; | 885 | int error; |
933 | 886 | ||
934 | |||
935 | if (acpi_disabled || acpi_noirq) | 887 | if (acpi_disabled || acpi_noirq) |
936 | return 0; | 888 | return 0; |
937 | 889 | ||
@@ -957,9 +909,6 @@ static int __init acpi_pci_link_init(void) | |||
957 | acpi_irq_balance = 0; | 909 | acpi_irq_balance = 0; |
958 | } | 910 | } |
959 | 911 | ||
960 | acpi_link.count = 0; | ||
961 | INIT_LIST_HEAD(&acpi_link.entries); | ||
962 | |||
963 | if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) | 912 | if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) |
964 | return -ENODEV; | 913 | return -ENODEV; |
965 | 914 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index c926e7d4a0d6..56665a63bf19 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -54,10 +54,6 @@ ACPI_MODULE_NAME("power"); | |||
54 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 | 54 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 |
55 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF | 55 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF |
56 | 56 | ||
57 | #ifdef MODULE_PARAM_PREFIX | ||
58 | #undef MODULE_PARAM_PREFIX | ||
59 | #endif | ||
60 | #define MODULE_PARAM_PREFIX "acpi." | ||
61 | int acpi_power_nocheck; | 57 | int acpi_power_nocheck; |
62 | module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | 58 | module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); |
63 | 59 | ||
@@ -773,14 +769,10 @@ static int acpi_power_resume(struct acpi_device *device) | |||
773 | return 0; | 769 | return 0; |
774 | } | 770 | } |
775 | 771 | ||
776 | static int __init acpi_power_init(void) | 772 | int __init acpi_power_init(void) |
777 | { | 773 | { |
778 | int result = 0; | 774 | int result = 0; |
779 | 775 | ||
780 | |||
781 | if (acpi_disabled) | ||
782 | return 0; | ||
783 | |||
784 | INIT_LIST_HEAD(&acpi_power_resource_list); | 776 | INIT_LIST_HEAD(&acpi_power_resource_list); |
785 | 777 | ||
786 | acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); | 778 | acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir); |
@@ -795,5 +787,3 @@ static int __init acpi_power_init(void) | |||
795 | 787 | ||
796 | return 0; | 788 | return 0; |
797 | } | 789 | } |
798 | |||
799 | subsys_initcall(acpi_power_init); | ||
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 428c911dba08..05dfdc96802e 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -496,11 +496,8 @@ static u32 rtc_handler(void *context) | |||
496 | } | 496 | } |
497 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | 497 | #endif /* HAVE_ACPI_LEGACY_ALARM */ |
498 | 498 | ||
499 | static int __init acpi_sleep_proc_init(void) | 499 | int __init acpi_sleep_proc_init(void) |
500 | { | 500 | { |
501 | if (acpi_disabled) | ||
502 | return 0; | ||
503 | |||
504 | #ifdef CONFIG_ACPI_PROCFS | 501 | #ifdef CONFIG_ACPI_PROCFS |
505 | /* 'sleep' [R/W] */ | 502 | /* 'sleep' [R/W] */ |
506 | proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR, | 503 | proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR, |
@@ -527,5 +524,3 @@ static int __init acpi_sleep_proc_init(void) | |||
527 | 524 | ||
528 | return 0; | 525 | return 0; |
529 | } | 526 | } |
530 | |||
531 | late_initcall(acpi_sleep_proc_init); | ||
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 7bc22a471fe3..4e6e758bd397 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -64,7 +64,6 @@ | |||
64 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 64 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
65 | ACPI_MODULE_NAME("processor_idle"); | 65 | ACPI_MODULE_NAME("processor_idle"); |
66 | #define ACPI_PROCESSOR_FILE_POWER "power" | 66 | #define ACPI_PROCESSOR_FILE_POWER "power" |
67 | #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) | ||
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 */ |
@@ -78,6 +77,10 @@ module_param(nocst, uint, 0000); | |||
78 | static unsigned int latency_factor __read_mostly = 2; | 77 | static unsigned int latency_factor __read_mostly = 2; |
79 | module_param(latency_factor, uint, 0644); | 78 | module_param(latency_factor, uint, 0644); |
80 | 79 | ||
80 | static s64 us_to_pm_timer_ticks(s64 t) | ||
81 | { | ||
82 | return div64_u64(t * PM_TIMER_FREQUENCY, 1000000); | ||
83 | } | ||
81 | /* | 84 | /* |
82 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. | 85 | * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. |
83 | * For now disable this. Probably a bug somewhere else. | 86 | * For now disable this. Probably a bug somewhere else. |
@@ -101,57 +104,6 @@ static int set_max_cstate(const struct dmi_system_id *id) | |||
101 | /* Actually this shouldn't be __cpuinitdata, would be better to fix the | 104 | /* Actually this shouldn't be __cpuinitdata, would be better to fix the |
102 | callers to only run once -AK */ | 105 | callers to only run once -AK */ |
103 | static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { | 106 | static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { |
104 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
105 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
106 | DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1}, | ||
107 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
108 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
109 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, | ||
110 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
111 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
112 | DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1}, | ||
113 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
114 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
115 | DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1}, | ||
116 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
117 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
118 | DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1}, | ||
119 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
120 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
121 | DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1}, | ||
122 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
123 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
124 | DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1}, | ||
125 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
126 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
127 | DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1}, | ||
128 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
129 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
130 | DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1}, | ||
131 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
132 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
133 | DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1}, | ||
134 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
135 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
136 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, | ||
137 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
138 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
139 | DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1}, | ||
140 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
141 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
142 | DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1}, | ||
143 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
144 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
145 | DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1}, | ||
146 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
147 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
148 | DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1}, | ||
149 | { set_max_cstate, "IBM ThinkPad R40e", { | ||
150 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | ||
151 | DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1}, | ||
152 | { set_max_cstate, "Medion 41700", { | ||
153 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | ||
154 | DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1}, | ||
155 | { set_max_cstate, "Clevo 5600D", { | 107 | { set_max_cstate, "Clevo 5600D", { |
156 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | 108 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
157 | DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, | 109 | DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, |
@@ -159,25 +111,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { | |||
159 | {}, | 111 | {}, |
160 | }; | 112 | }; |
161 | 113 | ||
162 | static inline u32 ticks_elapsed(u32 t1, u32 t2) | ||
163 | { | ||
164 | if (t2 >= t1) | ||
165 | return (t2 - t1); | ||
166 | else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) | ||
167 | return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); | ||
168 | else | ||
169 | return ((0xFFFFFFFF - t1) + t2); | ||
170 | } | ||
171 | |||
172 | static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) | ||
173 | { | ||
174 | if (t2 >= t1) | ||
175 | return PM_TIMER_TICKS_TO_US(t2 - t1); | ||
176 | else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) | ||
177 | return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); | ||
178 | else | ||
179 | return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); | ||
180 | } | ||
181 | 114 | ||
182 | /* | 115 | /* |
183 | * Callers should disable interrupts before the call and enable | 116 | * Callers should disable interrupts before the call and enable |
@@ -630,7 +563,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
630 | * In either case, the proper way to | 563 | * In either case, the proper way to |
631 | * handle BM_RLD is to set it and leave it set. | 564 | * handle BM_RLD is to set it and leave it set. |
632 | */ | 565 | */ |
633 | acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); | 566 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1); |
634 | 567 | ||
635 | return; | 568 | return; |
636 | } | 569 | } |
@@ -800,9 +733,9 @@ static int acpi_idle_bm_check(void) | |||
800 | { | 733 | { |
801 | u32 bm_status = 0; | 734 | u32 bm_status = 0; |
802 | 735 | ||
803 | acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); | 736 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); |
804 | if (bm_status) | 737 | if (bm_status) |
805 | acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); | 738 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); |
806 | /* | 739 | /* |
807 | * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect | 740 | * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect |
808 | * the true state of bus mastering activity; forcing us to | 741 | * the true state of bus mastering activity; forcing us to |
@@ -853,7 +786,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) | |||
853 | static int acpi_idle_enter_c1(struct cpuidle_device *dev, | 786 | static int acpi_idle_enter_c1(struct cpuidle_device *dev, |
854 | struct cpuidle_state *state) | 787 | struct cpuidle_state *state) |
855 | { | 788 | { |
856 | u32 t1, t2; | 789 | ktime_t kt1, kt2; |
790 | s64 idle_time; | ||
857 | struct acpi_processor *pr; | 791 | struct acpi_processor *pr; |
858 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 792 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
859 | 793 | ||
@@ -871,14 +805,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
871 | return 0; | 805 | return 0; |
872 | } | 806 | } |
873 | 807 | ||
874 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 808 | kt1 = ktime_get_real(); |
875 | acpi_idle_do_entry(cx); | 809 | acpi_idle_do_entry(cx); |
876 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 810 | kt2 = ktime_get_real(); |
811 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); | ||
877 | 812 | ||
878 | local_irq_enable(); | 813 | local_irq_enable(); |
879 | cx->usage++; | 814 | cx->usage++; |
880 | 815 | ||
881 | return ticks_elapsed_in_us(t1, t2); | 816 | return idle_time; |
882 | } | 817 | } |
883 | 818 | ||
884 | /** | 819 | /** |
@@ -891,8 +826,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
891 | { | 826 | { |
892 | struct acpi_processor *pr; | 827 | struct acpi_processor *pr; |
893 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 828 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
894 | u32 t1, t2; | 829 | ktime_t kt1, kt2; |
895 | int sleep_ticks = 0; | 830 | s64 idle_time; |
831 | s64 sleep_ticks = 0; | ||
896 | 832 | ||
897 | pr = __get_cpu_var(processors); | 833 | pr = __get_cpu_var(processors); |
898 | 834 | ||
@@ -925,18 +861,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
925 | if (cx->type == ACPI_STATE_C3) | 861 | if (cx->type == ACPI_STATE_C3) |
926 | ACPI_FLUSH_CPU_CACHE(); | 862 | ACPI_FLUSH_CPU_CACHE(); |
927 | 863 | ||
928 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 864 | kt1 = ktime_get_real(); |
929 | /* Tell the scheduler that we are going deep-idle: */ | 865 | /* Tell the scheduler that we are going deep-idle: */ |
930 | sched_clock_idle_sleep_event(); | 866 | sched_clock_idle_sleep_event(); |
931 | acpi_idle_do_entry(cx); | 867 | acpi_idle_do_entry(cx); |
932 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 868 | kt2 = ktime_get_real(); |
869 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); | ||
933 | 870 | ||
934 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) | 871 | #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) |
935 | /* TSC could halt in idle, so notify users */ | 872 | /* TSC could halt in idle, so notify users */ |
936 | if (tsc_halts_in_c(cx->type)) | 873 | if (tsc_halts_in_c(cx->type)) |
937 | mark_tsc_unstable("TSC halts in idle");; | 874 | mark_tsc_unstable("TSC halts in idle");; |
938 | #endif | 875 | #endif |
939 | sleep_ticks = ticks_elapsed(t1, t2); | 876 | sleep_ticks = us_to_pm_timer_ticks(idle_time); |
940 | 877 | ||
941 | /* Tell the scheduler how much we idled: */ | 878 | /* Tell the scheduler how much we idled: */ |
942 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | 879 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); |
@@ -948,7 +885,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
948 | 885 | ||
949 | acpi_state_timer_broadcast(pr, cx, 0); | 886 | acpi_state_timer_broadcast(pr, cx, 0); |
950 | cx->time += sleep_ticks; | 887 | cx->time += sleep_ticks; |
951 | return ticks_elapsed_in_us(t1, t2); | 888 | return idle_time; |
952 | } | 889 | } |
953 | 890 | ||
954 | static int c3_cpu_count; | 891 | static int c3_cpu_count; |
@@ -966,8 +903,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
966 | { | 903 | { |
967 | struct acpi_processor *pr; | 904 | struct acpi_processor *pr; |
968 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 905 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
969 | u32 t1, t2; | 906 | ktime_t kt1, kt2; |
970 | int sleep_ticks = 0; | 907 | s64 idle_time; |
908 | s64 sleep_ticks = 0; | ||
909 | |||
971 | 910 | ||
972 | pr = __get_cpu_var(processors); | 911 | pr = __get_cpu_var(processors); |
973 | 912 | ||
@@ -1028,20 +967,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1028 | c3_cpu_count++; | 967 | c3_cpu_count++; |
1029 | /* Disable bus master arbitration when all CPUs are in C3 */ | 968 | /* Disable bus master arbitration when all CPUs are in C3 */ |
1030 | if (c3_cpu_count == num_online_cpus()) | 969 | if (c3_cpu_count == num_online_cpus()) |
1031 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | 970 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); |
1032 | spin_unlock(&c3_lock); | 971 | spin_unlock(&c3_lock); |
1033 | } else if (!pr->flags.bm_check) { | 972 | } else if (!pr->flags.bm_check) { |
1034 | ACPI_FLUSH_CPU_CACHE(); | 973 | ACPI_FLUSH_CPU_CACHE(); |
1035 | } | 974 | } |
1036 | 975 | ||
1037 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 976 | kt1 = ktime_get_real(); |
1038 | acpi_idle_do_entry(cx); | 977 | acpi_idle_do_entry(cx); |
1039 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 978 | kt2 = ktime_get_real(); |
979 | idle_time = ktime_to_us(ktime_sub(kt2, kt1)); | ||
1040 | 980 | ||
1041 | /* Re-enable bus master arbitration */ | 981 | /* Re-enable bus master arbitration */ |
1042 | if (pr->flags.bm_check && pr->flags.bm_control) { | 982 | if (pr->flags.bm_check && pr->flags.bm_control) { |
1043 | spin_lock(&c3_lock); | 983 | spin_lock(&c3_lock); |
1044 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | 984 | acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); |
1045 | c3_cpu_count--; | 985 | c3_cpu_count--; |
1046 | spin_unlock(&c3_lock); | 986 | spin_unlock(&c3_lock); |
1047 | } | 987 | } |
@@ -1051,7 +991,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1051 | if (tsc_halts_in_c(ACPI_STATE_C3)) | 991 | if (tsc_halts_in_c(ACPI_STATE_C3)) |
1052 | mark_tsc_unstable("TSC halts in idle"); | 992 | mark_tsc_unstable("TSC halts in idle"); |
1053 | #endif | 993 | #endif |
1054 | sleep_ticks = ticks_elapsed(t1, t2); | 994 | sleep_ticks = us_to_pm_timer_ticks(idle_time); |
1055 | /* Tell the scheduler how much we idled: */ | 995 | /* Tell the scheduler how much we idled: */ |
1056 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | 996 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); |
1057 | 997 | ||
@@ -1062,7 +1002,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1062 | 1002 | ||
1063 | acpi_state_timer_broadcast(pr, cx, 0); | 1003 | acpi_state_timer_broadcast(pr, cx, 0); |
1064 | cx->time += sleep_ticks; | 1004 | cx->time += sleep_ticks; |
1065 | return ticks_elapsed_in_us(t1, t2); | 1005 | return idle_time; |
1066 | } | 1006 | } |
1067 | 1007 | ||
1068 | struct cpuidle_driver acpi_idle_driver = { | 1008 | struct cpuidle_driver acpi_idle_driver = { |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 9cc769b587ff..215f1bf7d4c1 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -479,6 +479,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) | |||
479 | goto end; | 479 | goto end; |
480 | } | 480 | } |
481 | 481 | ||
482 | if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && | ||
483 | pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && | ||
484 | pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { | ||
485 | printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n"); | ||
486 | result = -EFAULT; | ||
487 | goto end; | ||
488 | } | ||
482 | end: | 489 | end: |
483 | kfree(buffer.pointer); | 490 | kfree(buffer.pointer); |
484 | return result; | 491 | return result; |
@@ -501,9 +508,10 @@ int acpi_processor_preregister_performance( | |||
501 | 508 | ||
502 | mutex_lock(&performance_mutex); | 509 | mutex_lock(&performance_mutex); |
503 | 510 | ||
504 | retval = 0; | 511 | /* |
505 | 512 | * Check if another driver has already registered, and abort before | |
506 | /* Call _PSD for all CPUs */ | 513 | * changing pr->performance if it has. Check input data as well. |
514 | */ | ||
507 | for_each_possible_cpu(i) { | 515 | for_each_possible_cpu(i) { |
508 | pr = per_cpu(processors, i); | 516 | pr = per_cpu(processors, i); |
509 | if (!pr) { | 517 | if (!pr) { |
@@ -513,13 +521,20 @@ int acpi_processor_preregister_performance( | |||
513 | 521 | ||
514 | if (pr->performance) { | 522 | if (pr->performance) { |
515 | retval = -EBUSY; | 523 | retval = -EBUSY; |
516 | continue; | 524 | goto err_out; |
517 | } | 525 | } |
518 | 526 | ||
519 | if (!performance || !percpu_ptr(performance, i)) { | 527 | if (!performance || !percpu_ptr(performance, i)) { |
520 | retval = -EINVAL; | 528 | retval = -EINVAL; |
521 | continue; | 529 | goto err_out; |
522 | } | 530 | } |
531 | } | ||
532 | |||
533 | /* Call _PSD for all CPUs */ | ||
534 | for_each_possible_cpu(i) { | ||
535 | pr = per_cpu(processors, i); | ||
536 | if (!pr) | ||
537 | continue; | ||
523 | 538 | ||
524 | pr->performance = percpu_ptr(performance, i); | 539 | pr->performance = percpu_ptr(performance, i); |
525 | cpumask_set_cpu(i, pr->performance->shared_cpu_map); | 540 | cpumask_set_cpu(i, pr->performance->shared_cpu_map); |
@@ -535,26 +550,6 @@ int acpi_processor_preregister_performance( | |||
535 | * Now that we have _PSD data from all CPUs, lets setup P-state | 550 | * Now that we have _PSD data from all CPUs, lets setup P-state |
536 | * domain info. | 551 | * domain info. |
537 | */ | 552 | */ |
538 | for_each_possible_cpu(i) { | ||
539 | pr = per_cpu(processors, i); | ||
540 | if (!pr) | ||
541 | continue; | ||
542 | |||
543 | /* Basic validity check for domain info */ | ||
544 | pdomain = &(pr->performance->domain_info); | ||
545 | if ((pdomain->revision != ACPI_PSD_REV0_REVISION) || | ||
546 | (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) { | ||
547 | retval = -EINVAL; | ||
548 | goto err_ret; | ||
549 | } | ||
550 | if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL && | ||
551 | pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY && | ||
552 | pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) { | ||
553 | retval = -EINVAL; | ||
554 | goto err_ret; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | cpumask_clear(covered_cpus); | 553 | cpumask_clear(covered_cpus); |
559 | for_each_possible_cpu(i) { | 554 | for_each_possible_cpu(i) { |
560 | pr = per_cpu(processors, i); | 555 | pr = per_cpu(processors, i); |
@@ -643,6 +638,7 @@ err_ret: | |||
643 | pr->performance = NULL; /* Will be set for real in register */ | 638 | pr->performance = NULL; /* Will be set for real in register */ |
644 | } | 639 | } |
645 | 640 | ||
641 | err_out: | ||
646 | mutex_unlock(&performance_mutex); | 642 | mutex_unlock(&performance_mutex); |
647 | free_cpumask_var(covered_cpus); | 643 | free_cpumask_var(covered_cpus); |
648 | return retval; | 644 | return retval; |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index b1eb376fae45..0e47e299a9ac 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -373,7 +373,8 @@ static int acpi_processor_max_state(struct acpi_processor *pr) | |||
373 | return max_state; | 373 | return max_state; |
374 | } | 374 | } |
375 | static int | 375 | static int |
376 | processor_get_max_state(struct thermal_cooling_device *cdev, char *buf) | 376 | processor_get_max_state(struct thermal_cooling_device *cdev, |
377 | unsigned long *state) | ||
377 | { | 378 | { |
378 | struct acpi_device *device = cdev->devdata; | 379 | struct acpi_device *device = cdev->devdata; |
379 | struct acpi_processor *pr = acpi_driver_data(device); | 380 | struct acpi_processor *pr = acpi_driver_data(device); |
@@ -381,28 +382,29 @@ processor_get_max_state(struct thermal_cooling_device *cdev, char *buf) | |||
381 | if (!device || !pr) | 382 | if (!device || !pr) |
382 | return -EINVAL; | 383 | return -EINVAL; |
383 | 384 | ||
384 | return sprintf(buf, "%d\n", acpi_processor_max_state(pr)); | 385 | *state = acpi_processor_max_state(pr); |
386 | return 0; | ||
385 | } | 387 | } |
386 | 388 | ||
387 | static int | 389 | static int |
388 | processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf) | 390 | processor_get_cur_state(struct thermal_cooling_device *cdev, |
391 | unsigned long *cur_state) | ||
389 | { | 392 | { |
390 | struct acpi_device *device = cdev->devdata; | 393 | struct acpi_device *device = cdev->devdata; |
391 | struct acpi_processor *pr = acpi_driver_data(device); | 394 | struct acpi_processor *pr = acpi_driver_data(device); |
392 | int cur_state; | ||
393 | 395 | ||
394 | if (!device || !pr) | 396 | if (!device || !pr) |
395 | return -EINVAL; | 397 | return -EINVAL; |
396 | 398 | ||
397 | cur_state = cpufreq_get_cur_state(pr->id); | 399 | *cur_state = cpufreq_get_cur_state(pr->id); |
398 | if (pr->flags.throttling) | 400 | if (pr->flags.throttling) |
399 | cur_state += pr->throttling.state; | 401 | *cur_state += pr->throttling.state; |
400 | 402 | return 0; | |
401 | return sprintf(buf, "%d\n", cur_state); | ||
402 | } | 403 | } |
403 | 404 | ||
404 | static int | 405 | static int |
405 | processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) | 406 | processor_set_cur_state(struct thermal_cooling_device *cdev, |
407 | unsigned long state) | ||
406 | { | 408 | { |
407 | struct acpi_device *device = cdev->devdata; | 409 | struct acpi_device *device = cdev->devdata; |
408 | struct acpi_processor *pr = acpi_driver_data(device); | 410 | struct acpi_processor *pr = acpi_driver_data(device); |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 6050ce481873..3963cb6e0f19 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -102,8 +102,8 @@ struct acpi_battery { | |||
102 | u16 cycle_count; | 102 | u16 cycle_count; |
103 | u16 temp_now; | 103 | u16 temp_now; |
104 | u16 voltage_now; | 104 | u16 voltage_now; |
105 | s16 current_now; | 105 | s16 rate_now; |
106 | s16 current_avg; | 106 | s16 rate_avg; |
107 | u16 capacity_now; | 107 | u16 capacity_now; |
108 | u16 state_of_charge; | 108 | u16 state_of_charge; |
109 | u16 state; | 109 | u16 state; |
@@ -202,9 +202,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy, | |||
202 | return -ENODEV; | 202 | return -ENODEV; |
203 | switch (psp) { | 203 | switch (psp) { |
204 | case POWER_SUPPLY_PROP_STATUS: | 204 | case POWER_SUPPLY_PROP_STATUS: |
205 | if (battery->current_now < 0) | 205 | if (battery->rate_now < 0) |
206 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; | 206 | val->intval = POWER_SUPPLY_STATUS_DISCHARGING; |
207 | else if (battery->current_now > 0) | 207 | else if (battery->rate_now > 0) |
208 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 208 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
209 | else | 209 | else |
210 | val->intval = POWER_SUPPLY_STATUS_FULL; | 210 | val->intval = POWER_SUPPLY_STATUS_FULL; |
@@ -224,11 +224,13 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy, | |||
224 | acpi_battery_vscale(battery) * 1000; | 224 | acpi_battery_vscale(battery) * 1000; |
225 | break; | 225 | break; |
226 | case POWER_SUPPLY_PROP_CURRENT_NOW: | 226 | case POWER_SUPPLY_PROP_CURRENT_NOW: |
227 | val->intval = abs(battery->current_now) * | 227 | case POWER_SUPPLY_PROP_POWER_NOW: |
228 | val->intval = abs(battery->rate_now) * | ||
228 | acpi_battery_ipscale(battery) * 1000; | 229 | acpi_battery_ipscale(battery) * 1000; |
229 | break; | 230 | break; |
230 | case POWER_SUPPLY_PROP_CURRENT_AVG: | 231 | case POWER_SUPPLY_PROP_CURRENT_AVG: |
231 | val->intval = abs(battery->current_avg) * | 232 | case POWER_SUPPLY_PROP_POWER_AVG: |
233 | val->intval = abs(battery->rate_avg) * | ||
232 | acpi_battery_ipscale(battery) * 1000; | 234 | acpi_battery_ipscale(battery) * 1000; |
233 | break; | 235 | break; |
234 | case POWER_SUPPLY_PROP_CAPACITY: | 236 | case POWER_SUPPLY_PROP_CAPACITY: |
@@ -293,6 +295,8 @@ static enum power_supply_property sbs_energy_battery_props[] = { | |||
293 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | 295 | POWER_SUPPLY_PROP_VOLTAGE_NOW, |
294 | POWER_SUPPLY_PROP_CURRENT_NOW, | 296 | POWER_SUPPLY_PROP_CURRENT_NOW, |
295 | POWER_SUPPLY_PROP_CURRENT_AVG, | 297 | POWER_SUPPLY_PROP_CURRENT_AVG, |
298 | POWER_SUPPLY_PROP_POWER_NOW, | ||
299 | POWER_SUPPLY_PROP_POWER_AVG, | ||
296 | POWER_SUPPLY_PROP_CAPACITY, | 300 | POWER_SUPPLY_PROP_CAPACITY, |
297 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, | 301 | POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, |
298 | POWER_SUPPLY_PROP_ENERGY_FULL, | 302 | POWER_SUPPLY_PROP_ENERGY_FULL, |
@@ -301,6 +305,7 @@ static enum power_supply_property sbs_energy_battery_props[] = { | |||
301 | POWER_SUPPLY_PROP_MODEL_NAME, | 305 | POWER_SUPPLY_PROP_MODEL_NAME, |
302 | POWER_SUPPLY_PROP_MANUFACTURER, | 306 | POWER_SUPPLY_PROP_MANUFACTURER, |
303 | }; | 307 | }; |
308 | |||
304 | #endif | 309 | #endif |
305 | 310 | ||
306 | /* -------------------------------------------------------------------------- | 311 | /* -------------------------------------------------------------------------- |
@@ -330,8 +335,8 @@ static struct acpi_battery_reader info_readers[] = { | |||
330 | static struct acpi_battery_reader state_readers[] = { | 335 | static struct acpi_battery_reader state_readers[] = { |
331 | {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)}, | 336 | {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)}, |
332 | {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)}, | 337 | {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)}, |
333 | {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)}, | 338 | {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)}, |
334 | {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)}, | 339 | {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)}, |
335 | {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)}, | 340 | {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)}, |
336 | {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)}, | 341 | {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)}, |
337 | {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)}, | 342 | {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)}, |
@@ -589,9 +594,9 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) | |||
589 | seq_printf(seq, "capacity state: %s\n", | 594 | seq_printf(seq, "capacity state: %s\n", |
590 | (battery->state & 0x0010) ? "critical" : "ok"); | 595 | (battery->state & 0x0010) ? "critical" : "ok"); |
591 | seq_printf(seq, "charging state: %s\n", | 596 | seq_printf(seq, "charging state: %s\n", |
592 | (battery->current_now < 0) ? "discharging" : | 597 | (battery->rate_now < 0) ? "discharging" : |
593 | ((battery->current_now > 0) ? "charging" : "charged")); | 598 | ((battery->rate_now > 0) ? "charging" : "charged")); |
594 | rate = abs(battery->current_now) * acpi_battery_ipscale(battery); | 599 | rate = abs(battery->rate_now) * acpi_battery_ipscale(battery); |
595 | rate *= (acpi_battery_mode(battery))?(battery->voltage_now * | 600 | rate *= (acpi_battery_mode(battery))?(battery->voltage_now * |
596 | acpi_battery_vscale(battery)/1000):1; | 601 | acpi_battery_vscale(battery)/1000):1; |
597 | seq_printf(seq, "present rate: %d%s\n", rate, | 602 | seq_printf(seq, "present rate: %d%s\n", rate, |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c54d7b6c4066..b7308efce458 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -11,6 +11,8 @@ | |||
11 | 11 | ||
12 | #include <acpi/acpi_drivers.h> | 12 | #include <acpi/acpi_drivers.h> |
13 | 13 | ||
14 | #include "internal.h" | ||
15 | |||
14 | #define _COMPONENT ACPI_BUS_COMPONENT | 16 | #define _COMPONENT ACPI_BUS_COMPONENT |
15 | ACPI_MODULE_NAME("scan"); | 17 | ACPI_MODULE_NAME("scan"); |
16 | #define STRUCT_TO_INT(s) (*((int*)&s)) | 18 | #define STRUCT_TO_INT(s) (*((int*)&s)) |
@@ -395,22 +397,10 @@ static int acpi_device_remove(struct device * dev) | |||
395 | return 0; | 397 | return 0; |
396 | } | 398 | } |
397 | 399 | ||
398 | static void acpi_device_shutdown(struct device *dev) | ||
399 | { | ||
400 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
401 | struct acpi_driver *acpi_drv = acpi_dev->driver; | ||
402 | |||
403 | if (acpi_drv && acpi_drv->ops.shutdown) | ||
404 | acpi_drv->ops.shutdown(acpi_dev); | ||
405 | |||
406 | return ; | ||
407 | } | ||
408 | |||
409 | struct bus_type acpi_bus_type = { | 400 | struct bus_type acpi_bus_type = { |
410 | .name = "acpi", | 401 | .name = "acpi", |
411 | .suspend = acpi_device_suspend, | 402 | .suspend = acpi_device_suspend, |
412 | .resume = acpi_device_resume, | 403 | .resume = acpi_device_resume, |
413 | .shutdown = acpi_device_shutdown, | ||
414 | .match = acpi_bus_match, | 404 | .match = acpi_bus_match, |
415 | .probe = acpi_device_probe, | 405 | .probe = acpi_device_probe, |
416 | .remove = acpi_device_remove, | 406 | .remove = acpi_device_remove, |
@@ -1524,16 +1514,11 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) | |||
1524 | return result; | 1514 | return result; |
1525 | } | 1515 | } |
1526 | 1516 | ||
1527 | 1517 | int __init acpi_scan_init(void) | |
1528 | static int __init acpi_scan_init(void) | ||
1529 | { | 1518 | { |
1530 | int result; | 1519 | int result; |
1531 | struct acpi_bus_ops ops; | 1520 | struct acpi_bus_ops ops; |
1532 | 1521 | ||
1533 | |||
1534 | if (acpi_disabled) | ||
1535 | return 0; | ||
1536 | |||
1537 | memset(&ops, 0, sizeof(ops)); | 1522 | memset(&ops, 0, sizeof(ops)); |
1538 | ops.acpi_op_add = 1; | 1523 | ops.acpi_op_add = 1; |
1539 | ops.acpi_op_start = 1; | 1524 | ops.acpi_op_start = 1; |
@@ -1566,5 +1551,3 @@ static int __init acpi_scan_init(void) | |||
1566 | Done: | 1551 | Done: |
1567 | return result; | 1552 | return result; |
1568 | } | 1553 | } |
1569 | |||
1570 | subsys_initcall(acpi_scan_init); | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 00456fccfa38..91a284b54dbf 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -21,6 +21,8 @@ | |||
21 | 21 | ||
22 | #include <acpi/acpi_bus.h> | 22 | #include <acpi/acpi_bus.h> |
23 | #include <acpi/acpi_drivers.h> | 23 | #include <acpi/acpi_drivers.h> |
24 | |||
25 | #include "internal.h" | ||
24 | #include "sleep.h" | 26 | #include "sleep.h" |
25 | 27 | ||
26 | u8 sleep_states[ACPI_S_STATE_COUNT]; | 28 | u8 sleep_states[ACPI_S_STATE_COUNT]; |
@@ -248,7 +250,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
248 | 250 | ||
249 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ | 251 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ |
250 | if (set_sci_en_on_resume) | 252 | if (set_sci_en_on_resume) |
251 | acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); | 253 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); |
252 | else | 254 | else |
253 | acpi_enable(); | 255 | acpi_enable(); |
254 | 256 | ||
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 391d0358a592..da51f05ef8d8 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -33,10 +33,6 @@ | |||
33 | 33 | ||
34 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 34 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
35 | ACPI_MODULE_NAME("system"); | 35 | ACPI_MODULE_NAME("system"); |
36 | #ifdef MODULE_PARAM_PREFIX | ||
37 | #undef MODULE_PARAM_PREFIX | ||
38 | #endif | ||
39 | #define MODULE_PARAM_PREFIX "acpi." | ||
40 | 36 | ||
41 | #define ACPI_SYSTEM_CLASS "system" | 37 | #define ACPI_SYSTEM_CLASS "system" |
42 | #define ACPI_SYSTEM_DEVICE_NAME "System" | 38 | #define ACPI_SYSTEM_DEVICE_NAME "System" |
@@ -62,6 +58,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); | |||
62 | -------------------------------------------------------------------------- */ | 58 | -------------------------------------------------------------------------- */ |
63 | static LIST_HEAD(acpi_table_attr_list); | 59 | static LIST_HEAD(acpi_table_attr_list); |
64 | static struct kobject *tables_kobj; | 60 | static struct kobject *tables_kobj; |
61 | static struct kobject *dynamic_tables_kobj; | ||
65 | 62 | ||
66 | struct acpi_table_attr { | 63 | struct acpi_table_attr { |
67 | struct bin_attribute attr; | 64 | struct bin_attribute attr; |
@@ -128,6 +125,40 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
128 | return; | 125 | return; |
129 | } | 126 | } |
130 | 127 | ||
128 | static acpi_status | ||
129 | acpi_sysfs_table_handler(u32 event, void *table, void *context) | ||
130 | { | ||
131 | struct acpi_table_attr *table_attr; | ||
132 | |||
133 | switch (event) { | ||
134 | case ACPI_TABLE_EVENT_LOAD: | ||
135 | table_attr = | ||
136 | kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); | ||
137 | if (!table_attr) | ||
138 | return AE_NO_MEMORY; | ||
139 | |||
140 | acpi_table_attr_init(table_attr, table); | ||
141 | if (sysfs_create_bin_file(dynamic_tables_kobj, | ||
142 | &table_attr->attr)) { | ||
143 | kfree(table_attr); | ||
144 | return AE_ERROR; | ||
145 | } else | ||
146 | list_add_tail(&table_attr->node, | ||
147 | &acpi_table_attr_list); | ||
148 | break; | ||
149 | case ACPI_TABLE_EVENT_UNLOAD: | ||
150 | /* | ||
151 | * we do not need to do anything right now | ||
152 | * because the table is not deleted from the | ||
153 | * global table list when unloading it. | ||
154 | */ | ||
155 | break; | ||
156 | default: | ||
157 | return AE_BAD_PARAMETER; | ||
158 | } | ||
159 | return AE_OK; | ||
160 | } | ||
161 | |||
131 | static int acpi_system_sysfs_init(void) | 162 | static int acpi_system_sysfs_init(void) |
132 | { | 163 | { |
133 | struct acpi_table_attr *table_attr; | 164 | struct acpi_table_attr *table_attr; |
@@ -137,7 +168,11 @@ static int acpi_system_sysfs_init(void) | |||
137 | 168 | ||
138 | tables_kobj = kobject_create_and_add("tables", acpi_kobj); | 169 | tables_kobj = kobject_create_and_add("tables", acpi_kobj); |
139 | if (!tables_kobj) | 170 | if (!tables_kobj) |
140 | return -ENOMEM; | 171 | goto err; |
172 | |||
173 | dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj); | ||
174 | if (!dynamic_tables_kobj) | ||
175 | goto err_dynamic_tables; | ||
141 | 176 | ||
142 | do { | 177 | do { |
143 | result = acpi_get_table_by_index(table_index, &table_header); | 178 | result = acpi_get_table_by_index(table_index, &table_header); |
@@ -162,8 +197,14 @@ static int acpi_system_sysfs_init(void) | |||
162 | } | 197 | } |
163 | } while (!result); | 198 | } while (!result); |
164 | kobject_uevent(tables_kobj, KOBJ_ADD); | 199 | kobject_uevent(tables_kobj, KOBJ_ADD); |
165 | 200 | kobject_uevent(dynamic_tables_kobj, KOBJ_ADD); | |
166 | return 0; | 201 | result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL); |
202 | |||
203 | return result == AE_OK ? 0 : -EINVAL; | ||
204 | err_dynamic_tables: | ||
205 | kobject_put(tables_kobj); | ||
206 | err: | ||
207 | return -ENOMEM; | ||
167 | } | 208 | } |
168 | 209 | ||
169 | /* | 210 | /* |
@@ -571,12 +612,9 @@ static int acpi_system_procfs_init(void) | |||
571 | } | 612 | } |
572 | #endif | 613 | #endif |
573 | 614 | ||
574 | static int __init acpi_system_init(void) | 615 | int __init acpi_system_init(void) |
575 | { | 616 | { |
576 | int result = 0; | 617 | int result; |
577 | |||
578 | if (acpi_disabled) | ||
579 | return 0; | ||
580 | 618 | ||
581 | result = acpi_system_procfs_init(); | 619 | result = acpi_system_procfs_init(); |
582 | if (result) | 620 | if (result) |
@@ -586,5 +624,3 @@ static int __init acpi_system_init(void) | |||
586 | 624 | ||
587 | return result; | 625 | return result; |
588 | } | 626 | } |
589 | |||
590 | subsys_initcall(acpi_system_init); | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 99e6f1f8ea45..6b959976b7a4 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -37,11 +37,11 @@ | |||
37 | #include <linux/init.h> | 37 | #include <linux/init.h> |
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <linux/proc_fs.h> | 39 | #include <linux/proc_fs.h> |
40 | #include <linux/timer.h> | ||
41 | #include <linux/jiffies.h> | 40 | #include <linux/jiffies.h> |
42 | #include <linux/kmod.h> | 41 | #include <linux/kmod.h> |
43 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
44 | #include <linux/reboot.h> | 43 | #include <linux/reboot.h> |
44 | #include <linux/device.h> | ||
45 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
46 | #include <linux/thermal.h> | 46 | #include <linux/thermal.h> |
47 | #include <acpi/acpi_bus.h> | 47 | #include <acpi/acpi_bus.h> |
@@ -190,7 +190,6 @@ struct acpi_thermal { | |||
190 | struct acpi_thermal_state state; | 190 | struct acpi_thermal_state state; |
191 | struct acpi_thermal_trips trips; | 191 | struct acpi_thermal_trips trips; |
192 | struct acpi_handle_list devices; | 192 | struct acpi_handle_list devices; |
193 | struct timer_list timer; | ||
194 | struct thermal_zone_device *thermal_zone; | 193 | struct thermal_zone_device *thermal_zone; |
195 | int tz_enabled; | 194 | int tz_enabled; |
196 | struct mutex lock; | 195 | struct mutex lock; |
@@ -290,6 +289,11 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) | |||
290 | 289 | ||
291 | tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ | 290 | tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ |
292 | 291 | ||
292 | tz->thermal_zone->polling_delay = seconds * 1000; | ||
293 | |||
294 | if (tz->tz_enabled) | ||
295 | thermal_zone_device_update(tz->thermal_zone); | ||
296 | |||
293 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
294 | "Polling frequency set to %lu seconds\n", | 298 | "Polling frequency set to %lu seconds\n", |
295 | tz->polling_frequency/10)); | 299 | tz->polling_frequency/10)); |
@@ -569,392 +573,18 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
569 | return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); | 573 | return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); |
570 | } | 574 | } |
571 | 575 | ||
572 | static int acpi_thermal_critical(struct acpi_thermal *tz) | ||
573 | { | ||
574 | if (!tz || !tz->trips.critical.flags.valid) | ||
575 | return -EINVAL; | ||
576 | |||
577 | if (tz->temperature >= tz->trips.critical.temperature) { | ||
578 | printk(KERN_WARNING PREFIX "Critical trip point\n"); | ||
579 | tz->trips.critical.flags.enabled = 1; | ||
580 | } else if (tz->trips.critical.flags.enabled) | ||
581 | tz->trips.critical.flags.enabled = 0; | ||
582 | |||
583 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, | ||
584 | tz->trips.critical.flags.enabled); | ||
585 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | ||
586 | dev_name(&tz->device->dev), | ||
587 | ACPI_THERMAL_NOTIFY_CRITICAL, | ||
588 | tz->trips.critical.flags.enabled); | ||
589 | |||
590 | /* take no action if nocrt is set */ | ||
591 | if(!nocrt) { | ||
592 | printk(KERN_EMERG | ||
593 | "Critical temperature reached (%ld C), shutting down.\n", | ||
594 | KELVIN_TO_CELSIUS(tz->temperature)); | ||
595 | orderly_poweroff(true); | ||
596 | } | ||
597 | |||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static int acpi_thermal_hot(struct acpi_thermal *tz) | ||
602 | { | ||
603 | if (!tz || !tz->trips.hot.flags.valid) | ||
604 | return -EINVAL; | ||
605 | |||
606 | if (tz->temperature >= tz->trips.hot.temperature) { | ||
607 | printk(KERN_WARNING PREFIX "Hot trip point\n"); | ||
608 | tz->trips.hot.flags.enabled = 1; | ||
609 | } else if (tz->trips.hot.flags.enabled) | ||
610 | tz->trips.hot.flags.enabled = 0; | ||
611 | |||
612 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, | ||
613 | tz->trips.hot.flags.enabled); | ||
614 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | ||
615 | dev_name(&tz->device->dev), | ||
616 | ACPI_THERMAL_NOTIFY_HOT, | ||
617 | tz->trips.hot.flags.enabled); | ||
618 | |||
619 | /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */ | ||
620 | |||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | static void acpi_thermal_passive(struct acpi_thermal *tz) | ||
625 | { | ||
626 | int result = 1; | ||
627 | struct acpi_thermal_passive *passive = NULL; | ||
628 | int trend = 0; | ||
629 | int i = 0; | ||
630 | |||
631 | |||
632 | if (!tz || !tz->trips.passive.flags.valid) | ||
633 | return; | ||
634 | |||
635 | passive = &(tz->trips.passive); | ||
636 | |||
637 | /* | ||
638 | * Above Trip? | ||
639 | * ----------- | ||
640 | * Calculate the thermal trend (using the passive cooling equation) | ||
641 | * and modify the performance limit for all passive cooling devices | ||
642 | * accordingly. Note that we assume symmetry. | ||
643 | */ | ||
644 | if (tz->temperature >= passive->temperature) { | ||
645 | trend = | ||
646 | (passive->tc1 * (tz->temperature - tz->last_temperature)) + | ||
647 | (passive->tc2 * (tz->temperature - passive->temperature)); | ||
648 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
649 | "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", | ||
650 | trend, passive->tc1, tz->temperature, | ||
651 | tz->last_temperature, passive->tc2, | ||
652 | tz->temperature, passive->temperature)); | ||
653 | passive->flags.enabled = 1; | ||
654 | /* Heating up? */ | ||
655 | if (trend > 0) | ||
656 | for (i = 0; i < passive->devices.count; i++) | ||
657 | acpi_processor_set_thermal_limit(passive-> | ||
658 | devices. | ||
659 | handles[i], | ||
660 | ACPI_PROCESSOR_LIMIT_INCREMENT); | ||
661 | /* Cooling off? */ | ||
662 | else if (trend < 0) { | ||
663 | for (i = 0; i < passive->devices.count; i++) | ||
664 | /* | ||
665 | * assume that we are on highest | ||
666 | * freq/lowest thrott and can leave | ||
667 | * passive mode, even in error case | ||
668 | */ | ||
669 | if (!acpi_processor_set_thermal_limit | ||
670 | (passive->devices.handles[i], | ||
671 | ACPI_PROCESSOR_LIMIT_DECREMENT)) | ||
672 | result = 0; | ||
673 | /* | ||
674 | * Leave cooling mode, even if the temp might | ||
675 | * higher than trip point This is because some | ||
676 | * machines might have long thermal polling | ||
677 | * frequencies (tsp) defined. We will fall back | ||
678 | * into passive mode in next cycle (probably quicker) | ||
679 | */ | ||
680 | if (result) { | ||
681 | passive->flags.enabled = 0; | ||
682 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
683 | "Disabling passive cooling, still above threshold," | ||
684 | " but we are cooling down\n")); | ||
685 | } | ||
686 | } | ||
687 | return; | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * Below Trip? | ||
692 | * ----------- | ||
693 | * Implement passive cooling hysteresis to slowly increase performance | ||
694 | * and avoid thrashing around the passive trip point. Note that we | ||
695 | * assume symmetry. | ||
696 | */ | ||
697 | if (!passive->flags.enabled) | ||
698 | return; | ||
699 | for (i = 0; i < passive->devices.count; i++) | ||
700 | if (!acpi_processor_set_thermal_limit | ||
701 | (passive->devices.handles[i], | ||
702 | ACPI_PROCESSOR_LIMIT_DECREMENT)) | ||
703 | result = 0; | ||
704 | if (result) { | ||
705 | passive->flags.enabled = 0; | ||
706 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
707 | "Disabling passive cooling (zone is cool)\n")); | ||
708 | } | ||
709 | } | ||
710 | |||
711 | static void acpi_thermal_active(struct acpi_thermal *tz) | ||
712 | { | ||
713 | int result = 0; | ||
714 | struct acpi_thermal_active *active = NULL; | ||
715 | int i = 0; | ||
716 | int j = 0; | ||
717 | unsigned long maxtemp = 0; | ||
718 | |||
719 | |||
720 | if (!tz) | ||
721 | return; | ||
722 | |||
723 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { | ||
724 | active = &(tz->trips.active[i]); | ||
725 | if (!active || !active->flags.valid) | ||
726 | break; | ||
727 | if (tz->temperature >= active->temperature) { | ||
728 | /* | ||
729 | * Above Threshold? | ||
730 | * ---------------- | ||
731 | * If not already enabled, turn ON all cooling devices | ||
732 | * associated with this active threshold. | ||
733 | */ | ||
734 | if (active->temperature > maxtemp) | ||
735 | tz->state.active_index = i; | ||
736 | maxtemp = active->temperature; | ||
737 | if (active->flags.enabled) | ||
738 | continue; | ||
739 | for (j = 0; j < active->devices.count; j++) { | ||
740 | result = | ||
741 | acpi_bus_set_power(active->devices. | ||
742 | handles[j], | ||
743 | ACPI_STATE_D0); | ||
744 | if (result) { | ||
745 | printk(KERN_WARNING PREFIX | ||
746 | "Unable to turn cooling device [%p] 'on'\n", | ||
747 | active->devices. | ||
748 | handles[j]); | ||
749 | continue; | ||
750 | } | ||
751 | active->flags.enabled = 1; | ||
752 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
753 | "Cooling device [%p] now 'on'\n", | ||
754 | active->devices.handles[j])); | ||
755 | } | ||
756 | continue; | ||
757 | } | ||
758 | if (!active->flags.enabled) | ||
759 | continue; | ||
760 | /* | ||
761 | * Below Threshold? | ||
762 | * ---------------- | ||
763 | * Turn OFF all cooling devices associated with this | ||
764 | * threshold. | ||
765 | */ | ||
766 | for (j = 0; j < active->devices.count; j++) { | ||
767 | result = acpi_bus_set_power(active->devices.handles[j], | ||
768 | ACPI_STATE_D3); | ||
769 | if (result) { | ||
770 | printk(KERN_WARNING PREFIX | ||
771 | "Unable to turn cooling device [%p] 'off'\n", | ||
772 | active->devices.handles[j]); | ||
773 | continue; | ||
774 | } | ||
775 | active->flags.enabled = 0; | ||
776 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
777 | "Cooling device [%p] now 'off'\n", | ||
778 | active->devices.handles[j])); | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | |||
783 | static void acpi_thermal_check(void *context); | ||
784 | |||
785 | static void acpi_thermal_run(unsigned long data) | ||
786 | { | ||
787 | struct acpi_thermal *tz = (struct acpi_thermal *)data; | ||
788 | if (!tz->zombie) | ||
789 | acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data); | ||
790 | } | ||
791 | |||
792 | static void acpi_thermal_active_off(void *data) | ||
793 | { | ||
794 | int result = 0; | ||
795 | struct acpi_thermal *tz = data; | ||
796 | int i = 0; | ||
797 | int j = 0; | ||
798 | struct acpi_thermal_active *active = NULL; | ||
799 | |||
800 | if (!tz) { | ||
801 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
802 | return; | ||
803 | } | ||
804 | |||
805 | result = acpi_thermal_get_temperature(tz); | ||
806 | if (result) | ||
807 | return; | ||
808 | |||
809 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { | ||
810 | active = &(tz->trips.active[i]); | ||
811 | if (!active || !active->flags.valid) | ||
812 | break; | ||
813 | if (tz->temperature >= active->temperature) { | ||
814 | /* | ||
815 | * If the thermal temperature is greater than the | ||
816 | * active threshod, unnecessary to turn off the | ||
817 | * the active cooling device. | ||
818 | */ | ||
819 | continue; | ||
820 | } | ||
821 | /* | ||
822 | * Below Threshold? | ||
823 | * ---------------- | ||
824 | * Turn OFF all cooling devices associated with this | ||
825 | * threshold. | ||
826 | */ | ||
827 | for (j = 0; j < active->devices.count; j++) | ||
828 | result = acpi_bus_set_power(active->devices.handles[j], | ||
829 | ACPI_STATE_D3); | ||
830 | } | ||
831 | } | ||
832 | |||
833 | static void acpi_thermal_check(void *data) | 576 | static void acpi_thermal_check(void *data) |
834 | { | 577 | { |
835 | int result = 0; | ||
836 | struct acpi_thermal *tz = data; | 578 | struct acpi_thermal *tz = data; |
837 | unsigned long sleep_time = 0; | ||
838 | unsigned long timeout_jiffies = 0; | ||
839 | int i = 0; | ||
840 | struct acpi_thermal_state state; | ||
841 | |||
842 | |||
843 | if (!tz) { | ||
844 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
845 | return; | ||
846 | } | ||
847 | |||
848 | /* Check if someone else is already running */ | ||
849 | if (!mutex_trylock(&tz->lock)) | ||
850 | return; | ||
851 | |||
852 | state = tz->state; | ||
853 | |||
854 | result = acpi_thermal_get_temperature(tz); | ||
855 | if (result) | ||
856 | goto unlock; | ||
857 | |||
858 | if (!tz->tz_enabled) | ||
859 | goto unlock; | ||
860 | |||
861 | memset(&tz->state, 0, sizeof(tz->state)); | ||
862 | |||
863 | /* | ||
864 | * Check Trip Points | ||
865 | * ----------------- | ||
866 | * Compare the current temperature to the trip point values to see | ||
867 | * if we've entered one of the thermal policy states. Note that | ||
868 | * this function determines when a state is entered, but the | ||
869 | * individual policy decides when it is exited (e.g. hysteresis). | ||
870 | */ | ||
871 | if (tz->trips.critical.flags.valid) | ||
872 | state.critical |= | ||
873 | (tz->temperature >= tz->trips.critical.temperature); | ||
874 | if (tz->trips.hot.flags.valid) | ||
875 | state.hot |= (tz->temperature >= tz->trips.hot.temperature); | ||
876 | if (tz->trips.passive.flags.valid) | ||
877 | state.passive |= | ||
878 | (tz->temperature >= tz->trips.passive.temperature); | ||
879 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) | ||
880 | if (tz->trips.active[i].flags.valid) | ||
881 | state.active |= | ||
882 | (tz->temperature >= | ||
883 | tz->trips.active[i].temperature); | ||
884 | |||
885 | /* | ||
886 | * Invoke Policy | ||
887 | * ------------- | ||
888 | * Separated from the above check to allow individual policy to | ||
889 | * determine when to exit a given state. | ||
890 | */ | ||
891 | if (state.critical) | ||
892 | acpi_thermal_critical(tz); | ||
893 | if (state.hot) | ||
894 | acpi_thermal_hot(tz); | ||
895 | if (state.passive) | ||
896 | acpi_thermal_passive(tz); | ||
897 | if (state.active) | ||
898 | acpi_thermal_active(tz); | ||
899 | |||
900 | /* | ||
901 | * Calculate State | ||
902 | * --------------- | ||
903 | * Again, separated from the above two to allow independent policy | ||
904 | * decisions. | ||
905 | */ | ||
906 | tz->state.critical = tz->trips.critical.flags.enabled; | ||
907 | tz->state.hot = tz->trips.hot.flags.enabled; | ||
908 | tz->state.passive = tz->trips.passive.flags.enabled; | ||
909 | tz->state.active = 0; | ||
910 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) | ||
911 | tz->state.active |= tz->trips.active[i].flags.enabled; | ||
912 | |||
913 | /* | ||
914 | * Calculate Sleep Time | ||
915 | * -------------------- | ||
916 | * If we're in the passive state, use _TSP's value. Otherwise | ||
917 | * use the default polling frequency (e.g. _TZP). If no polling | ||
918 | * frequency is specified then we'll wait forever (at least until | ||
919 | * a thermal event occurs). Note that _TSP and _TZD values are | ||
920 | * given in 1/10th seconds (we must covert to milliseconds). | ||
921 | */ | ||
922 | if (tz->state.passive) { | ||
923 | sleep_time = tz->trips.passive.tsp * 100; | ||
924 | timeout_jiffies = jiffies + (HZ * sleep_time) / 1000; | ||
925 | } else if (tz->polling_frequency > 0) { | ||
926 | sleep_time = tz->polling_frequency * 100; | ||
927 | timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000); | ||
928 | } | ||
929 | 579 | ||
930 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", | 580 | thermal_zone_device_update(tz->thermal_zone); |
931 | tz->name, tz->temperature, sleep_time)); | ||
932 | |||
933 | /* | ||
934 | * Schedule Next Poll | ||
935 | * ------------------ | ||
936 | */ | ||
937 | if (!sleep_time) { | ||
938 | if (timer_pending(&(tz->timer))) | ||
939 | del_timer(&(tz->timer)); | ||
940 | } else { | ||
941 | if (timer_pending(&(tz->timer))) | ||
942 | mod_timer(&(tz->timer), timeout_jiffies); | ||
943 | else { | ||
944 | tz->timer.data = (unsigned long)tz; | ||
945 | tz->timer.function = acpi_thermal_run; | ||
946 | tz->timer.expires = timeout_jiffies; | ||
947 | add_timer(&(tz->timer)); | ||
948 | } | ||
949 | } | ||
950 | unlock: | ||
951 | mutex_unlock(&tz->lock); | ||
952 | } | 581 | } |
953 | 582 | ||
954 | /* sys I/F for generic thermal sysfs support */ | 583 | /* sys I/F for generic thermal sysfs support */ |
955 | #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) | 584 | #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) |
956 | 585 | ||
957 | static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) | 586 | static int thermal_get_temp(struct thermal_zone_device *thermal, |
587 | unsigned long *temp) | ||
958 | { | 588 | { |
959 | struct acpi_thermal *tz = thermal->devdata; | 589 | struct acpi_thermal *tz = thermal->devdata; |
960 | int result; | 590 | int result; |
@@ -966,25 +596,28 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) | |||
966 | if (result) | 596 | if (result) |
967 | return result; | 597 | return result; |
968 | 598 | ||
969 | return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature)); | 599 | *temp = KELVIN_TO_MILLICELSIUS(tz->temperature); |
600 | return 0; | ||
970 | } | 601 | } |
971 | 602 | ||
972 | static const char enabled[] = "kernel"; | 603 | static const char enabled[] = "kernel"; |
973 | static const char disabled[] = "user"; | 604 | static const char disabled[] = "user"; |
974 | static int thermal_get_mode(struct thermal_zone_device *thermal, | 605 | static int thermal_get_mode(struct thermal_zone_device *thermal, |
975 | char *buf) | 606 | enum thermal_device_mode *mode) |
976 | { | 607 | { |
977 | struct acpi_thermal *tz = thermal->devdata; | 608 | struct acpi_thermal *tz = thermal->devdata; |
978 | 609 | ||
979 | if (!tz) | 610 | if (!tz) |
980 | return -EINVAL; | 611 | return -EINVAL; |
981 | 612 | ||
982 | return sprintf(buf, "%s\n", tz->tz_enabled ? | 613 | *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED : |
983 | enabled : disabled); | 614 | THERMAL_DEVICE_DISABLED; |
615 | |||
616 | return 0; | ||
984 | } | 617 | } |
985 | 618 | ||
986 | static int thermal_set_mode(struct thermal_zone_device *thermal, | 619 | static int thermal_set_mode(struct thermal_zone_device *thermal, |
987 | const char *buf) | 620 | enum thermal_device_mode mode) |
988 | { | 621 | { |
989 | struct acpi_thermal *tz = thermal->devdata; | 622 | struct acpi_thermal *tz = thermal->devdata; |
990 | int enable; | 623 | int enable; |
@@ -995,9 +628,9 @@ static int thermal_set_mode(struct thermal_zone_device *thermal, | |||
995 | /* | 628 | /* |
996 | * enable/disable thermal management from ACPI thermal driver | 629 | * enable/disable thermal management from ACPI thermal driver |
997 | */ | 630 | */ |
998 | if (!strncmp(buf, enabled, sizeof enabled - 1)) | 631 | if (mode == THERMAL_DEVICE_ENABLED) |
999 | enable = 1; | 632 | enable = 1; |
1000 | else if (!strncmp(buf, disabled, sizeof disabled - 1)) | 633 | else if (mode == THERMAL_DEVICE_DISABLED) |
1001 | enable = 0; | 634 | enable = 0; |
1002 | else | 635 | else |
1003 | return -EINVAL; | 636 | return -EINVAL; |
@@ -1013,7 +646,7 @@ static int thermal_set_mode(struct thermal_zone_device *thermal, | |||
1013 | } | 646 | } |
1014 | 647 | ||
1015 | static int thermal_get_trip_type(struct thermal_zone_device *thermal, | 648 | static int thermal_get_trip_type(struct thermal_zone_device *thermal, |
1016 | int trip, char *buf) | 649 | int trip, enum thermal_trip_type *type) |
1017 | { | 650 | { |
1018 | struct acpi_thermal *tz = thermal->devdata; | 651 | struct acpi_thermal *tz = thermal->devdata; |
1019 | int i; | 652 | int i; |
@@ -1022,27 +655,35 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal, | |||
1022 | return -EINVAL; | 655 | return -EINVAL; |
1023 | 656 | ||
1024 | if (tz->trips.critical.flags.valid) { | 657 | if (tz->trips.critical.flags.valid) { |
1025 | if (!trip) | 658 | if (!trip) { |
1026 | return sprintf(buf, "critical\n"); | 659 | *type = THERMAL_TRIP_CRITICAL; |
660 | return 0; | ||
661 | } | ||
1027 | trip--; | 662 | trip--; |
1028 | } | 663 | } |
1029 | 664 | ||
1030 | if (tz->trips.hot.flags.valid) { | 665 | if (tz->trips.hot.flags.valid) { |
1031 | if (!trip) | 666 | if (!trip) { |
1032 | return sprintf(buf, "hot\n"); | 667 | *type = THERMAL_TRIP_HOT; |
668 | return 0; | ||
669 | } | ||
1033 | trip--; | 670 | trip--; |
1034 | } | 671 | } |
1035 | 672 | ||
1036 | if (tz->trips.passive.flags.valid) { | 673 | if (tz->trips.passive.flags.valid) { |
1037 | if (!trip) | 674 | if (!trip) { |
1038 | return sprintf(buf, "passive\n"); | 675 | *type = THERMAL_TRIP_PASSIVE; |
676 | return 0; | ||
677 | } | ||
1039 | trip--; | 678 | trip--; |
1040 | } | 679 | } |
1041 | 680 | ||
1042 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && | 681 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && |
1043 | tz->trips.active[i].flags.valid; i++) { | 682 | tz->trips.active[i].flags.valid; i++) { |
1044 | if (!trip) | 683 | if (!trip) { |
1045 | return sprintf(buf, "active%d\n", i); | 684 | *type = THERMAL_TRIP_ACTIVE; |
685 | return 0; | ||
686 | } | ||
1046 | trip--; | 687 | trip--; |
1047 | } | 688 | } |
1048 | 689 | ||
@@ -1050,7 +691,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal, | |||
1050 | } | 691 | } |
1051 | 692 | ||
1052 | static int thermal_get_trip_temp(struct thermal_zone_device *thermal, | 693 | static int thermal_get_trip_temp(struct thermal_zone_device *thermal, |
1053 | int trip, char *buf) | 694 | int trip, unsigned long *temp) |
1054 | { | 695 | { |
1055 | struct acpi_thermal *tz = thermal->devdata; | 696 | struct acpi_thermal *tz = thermal->devdata; |
1056 | int i; | 697 | int i; |
@@ -1059,31 +700,39 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, | |||
1059 | return -EINVAL; | 700 | return -EINVAL; |
1060 | 701 | ||
1061 | if (tz->trips.critical.flags.valid) { | 702 | if (tz->trips.critical.flags.valid) { |
1062 | if (!trip) | 703 | if (!trip) { |
1063 | return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( | 704 | *temp = KELVIN_TO_MILLICELSIUS( |
1064 | tz->trips.critical.temperature)); | 705 | tz->trips.critical.temperature); |
706 | return 0; | ||
707 | } | ||
1065 | trip--; | 708 | trip--; |
1066 | } | 709 | } |
1067 | 710 | ||
1068 | if (tz->trips.hot.flags.valid) { | 711 | if (tz->trips.hot.flags.valid) { |
1069 | if (!trip) | 712 | if (!trip) { |
1070 | return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( | 713 | *temp = KELVIN_TO_MILLICELSIUS( |
1071 | tz->trips.hot.temperature)); | 714 | tz->trips.hot.temperature); |
715 | return 0; | ||
716 | } | ||
1072 | trip--; | 717 | trip--; |
1073 | } | 718 | } |
1074 | 719 | ||
1075 | if (tz->trips.passive.flags.valid) { | 720 | if (tz->trips.passive.flags.valid) { |
1076 | if (!trip) | 721 | if (!trip) { |
1077 | return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( | 722 | *temp = KELVIN_TO_MILLICELSIUS( |
1078 | tz->trips.passive.temperature)); | 723 | tz->trips.passive.temperature); |
724 | return 0; | ||
725 | } | ||
1079 | trip--; | 726 | trip--; |
1080 | } | 727 | } |
1081 | 728 | ||
1082 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && | 729 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && |
1083 | tz->trips.active[i].flags.valid; i++) { | 730 | tz->trips.active[i].flags.valid; i++) { |
1084 | if (!trip) | 731 | if (!trip) { |
1085 | return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( | 732 | *temp = KELVIN_TO_MILLICELSIUS( |
1086 | tz->trips.active[i].temperature)); | 733 | tz->trips.active[i].temperature); |
734 | return 0; | ||
735 | } | ||
1087 | trip--; | 736 | trip--; |
1088 | } | 737 | } |
1089 | 738 | ||
@@ -1102,6 +751,29 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal, | |||
1102 | return -EINVAL; | 751 | return -EINVAL; |
1103 | } | 752 | } |
1104 | 753 | ||
754 | static int thermal_notify(struct thermal_zone_device *thermal, int trip, | ||
755 | enum thermal_trip_type trip_type) | ||
756 | { | ||
757 | u8 type = 0; | ||
758 | struct acpi_thermal *tz = thermal->devdata; | ||
759 | |||
760 | if (trip_type == THERMAL_TRIP_CRITICAL) | ||
761 | type = ACPI_THERMAL_NOTIFY_CRITICAL; | ||
762 | else if (trip_type == THERMAL_TRIP_HOT) | ||
763 | type = ACPI_THERMAL_NOTIFY_HOT; | ||
764 | else | ||
765 | return 0; | ||
766 | |||
767 | acpi_bus_generate_proc_event(tz->device, type, 1); | ||
768 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | ||
769 | dev_name(&tz->device->dev), type, 1); | ||
770 | |||
771 | if (trip_type == THERMAL_TRIP_CRITICAL && nocrt) | ||
772 | return 1; | ||
773 | |||
774 | return 0; | ||
775 | } | ||
776 | |||
1105 | typedef int (*cb)(struct thermal_zone_device *, int, | 777 | typedef int (*cb)(struct thermal_zone_device *, int, |
1106 | struct thermal_cooling_device *); | 778 | struct thermal_cooling_device *); |
1107 | static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, | 779 | static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, |
@@ -1194,6 +866,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = { | |||
1194 | .get_trip_type = thermal_get_trip_type, | 866 | .get_trip_type = thermal_get_trip_type, |
1195 | .get_trip_temp = thermal_get_trip_temp, | 867 | .get_trip_temp = thermal_get_trip_temp, |
1196 | .get_crit_temp = thermal_get_crit_temp, | 868 | .get_crit_temp = thermal_get_crit_temp, |
869 | .notify = thermal_notify, | ||
1197 | }; | 870 | }; |
1198 | 871 | ||
1199 | static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | 872 | static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) |
@@ -1214,8 +887,21 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | |||
1214 | 887 | ||
1215 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && | 888 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && |
1216 | tz->trips.active[i].flags.valid; i++, trips++); | 889 | tz->trips.active[i].flags.valid; i++, trips++); |
1217 | tz->thermal_zone = thermal_zone_device_register("acpitz", | 890 | |
1218 | trips, tz, &acpi_thermal_zone_ops); | 891 | if (tz->trips.passive.flags.valid) |
892 | tz->thermal_zone = | ||
893 | thermal_zone_device_register("acpitz", trips, tz, | ||
894 | &acpi_thermal_zone_ops, | ||
895 | tz->trips.passive.tc1, | ||
896 | tz->trips.passive.tc2, | ||
897 | tz->trips.passive.tsp*100, | ||
898 | tz->polling_frequency*100); | ||
899 | else | ||
900 | tz->thermal_zone = | ||
901 | thermal_zone_device_register("acpitz", trips, tz, | ||
902 | &acpi_thermal_zone_ops, | ||
903 | 0, 0, 0, | ||
904 | tz->polling_frequency); | ||
1219 | if (IS_ERR(tz->thermal_zone)) | 905 | if (IS_ERR(tz->thermal_zone)) |
1220 | return -ENODEV; | 906 | return -ENODEV; |
1221 | 907 | ||
@@ -1447,13 +1133,13 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) | |||
1447 | if (!tz) | 1133 | if (!tz) |
1448 | goto end; | 1134 | goto end; |
1449 | 1135 | ||
1450 | if (!tz->polling_frequency) { | 1136 | if (!tz->thermal_zone->polling_delay) { |
1451 | seq_puts(seq, "<polling disabled>\n"); | 1137 | seq_puts(seq, "<polling disabled>\n"); |
1452 | goto end; | 1138 | goto end; |
1453 | } | 1139 | } |
1454 | 1140 | ||
1455 | seq_printf(seq, "polling frequency: %lu seconds\n", | 1141 | seq_printf(seq, "polling frequency: %d seconds\n", |
1456 | (tz->polling_frequency / 10)); | 1142 | (tz->thermal_zone->polling_delay / 1000)); |
1457 | 1143 | ||
1458 | end: | 1144 | end: |
1459 | return 0; | 1145 | return 0; |
@@ -1683,12 +1369,6 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1683 | if (result) | 1369 | if (result) |
1684 | goto unregister_thermal_zone; | 1370 | goto unregister_thermal_zone; |
1685 | 1371 | ||
1686 | init_timer(&tz->timer); | ||
1687 | |||
1688 | acpi_thermal_active_off(tz); | ||
1689 | |||
1690 | acpi_thermal_check(tz); | ||
1691 | |||
1692 | status = acpi_install_notify_handler(device->handle, | 1372 | status = acpi_install_notify_handler(device->handle, |
1693 | ACPI_DEVICE_NOTIFY, | 1373 | ACPI_DEVICE_NOTIFY, |
1694 | acpi_thermal_notify, tz); | 1374 | acpi_thermal_notify, tz); |
@@ -1717,36 +1397,15 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1717 | acpi_status status = AE_OK; | 1397 | acpi_status status = AE_OK; |
1718 | struct acpi_thermal *tz = NULL; | 1398 | struct acpi_thermal *tz = NULL; |
1719 | 1399 | ||
1720 | |||
1721 | if (!device || !acpi_driver_data(device)) | 1400 | if (!device || !acpi_driver_data(device)) |
1722 | return -EINVAL; | 1401 | return -EINVAL; |
1723 | 1402 | ||
1724 | tz = acpi_driver_data(device); | 1403 | tz = acpi_driver_data(device); |
1725 | 1404 | ||
1726 | /* avoid timer adding new defer task */ | ||
1727 | tz->zombie = 1; | ||
1728 | /* wait for running timer (on other CPUs) finish */ | ||
1729 | del_timer_sync(&(tz->timer)); | ||
1730 | /* synchronize deferred task */ | ||
1731 | acpi_os_wait_events_complete(NULL); | ||
1732 | /* deferred task may reinsert timer */ | ||
1733 | del_timer_sync(&(tz->timer)); | ||
1734 | |||
1735 | status = acpi_remove_notify_handler(device->handle, | 1405 | status = acpi_remove_notify_handler(device->handle, |
1736 | ACPI_DEVICE_NOTIFY, | 1406 | ACPI_DEVICE_NOTIFY, |
1737 | acpi_thermal_notify); | 1407 | acpi_thermal_notify); |
1738 | 1408 | ||
1739 | /* Terminate policy */ | ||
1740 | if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { | ||
1741 | tz->trips.passive.flags.enabled = 0; | ||
1742 | acpi_thermal_passive(tz); | ||
1743 | } | ||
1744 | if (tz->trips.active[0].flags.valid | ||
1745 | && tz->trips.active[0].flags.enabled) { | ||
1746 | tz->trips.active[0].flags.enabled = 0; | ||
1747 | acpi_thermal_active(tz); | ||
1748 | } | ||
1749 | |||
1750 | acpi_thermal_remove_fs(device); | 1409 | acpi_thermal_remove_fs(device); |
1751 | acpi_thermal_unregister_thermal_zone(tz); | 1410 | acpi_thermal_unregister_thermal_zone(tz); |
1752 | mutex_destroy(&tz->lock); | 1411 | mutex_destroy(&tz->lock); |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index bb5ed059114a..100c8eeaa5dd 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <linux/thermal.h> | 37 | #include <linux/thermal.h> |
38 | #include <linux/video_output.h> | 38 | #include <linux/video_output.h> |
39 | #include <linux/sort.h> | 39 | #include <linux/sort.h> |
40 | #include <linux/pci.h> | ||
41 | #include <linux/pci_ids.h> | ||
40 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
41 | 43 | ||
42 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
@@ -162,16 +164,26 @@ struct acpi_video_device_cap { | |||
162 | u8 _BCL:1; /*Query list of brightness control levels supported */ | 164 | u8 _BCL:1; /*Query list of brightness control levels supported */ |
163 | u8 _BCM:1; /*Set the brightness level */ | 165 | u8 _BCM:1; /*Set the brightness level */ |
164 | u8 _BQC:1; /* Get current brightness level */ | 166 | u8 _BQC:1; /* Get current brightness level */ |
167 | u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ | ||
165 | u8 _DDC:1; /*Return the EDID for this device */ | 168 | u8 _DDC:1; /*Return the EDID for this device */ |
166 | u8 _DCS:1; /*Return status of output device */ | 169 | u8 _DCS:1; /*Return status of output device */ |
167 | u8 _DGS:1; /*Query graphics state */ | 170 | u8 _DGS:1; /*Query graphics state */ |
168 | u8 _DSS:1; /*Device state set */ | 171 | u8 _DSS:1; /*Device state set */ |
169 | }; | 172 | }; |
170 | 173 | ||
174 | struct acpi_video_brightness_flags { | ||
175 | u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */ | ||
176 | u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/ | ||
177 | u8 _BCL_use_index:1; /* levels in _BCL are index values */ | ||
178 | u8 _BCM_use_index:1; /* input of _BCM is an index value */ | ||
179 | u8 _BQC_use_index:1; /* _BQC returns an index value */ | ||
180 | }; | ||
181 | |||
171 | struct acpi_video_device_brightness { | 182 | struct acpi_video_device_brightness { |
172 | int curr; | 183 | int curr; |
173 | int count; | 184 | int count; |
174 | int *levels; | 185 | int *levels; |
186 | struct acpi_video_brightness_flags flags; | ||
175 | }; | 187 | }; |
176 | 188 | ||
177 | struct acpi_video_device { | 189 | struct acpi_video_device { |
@@ -294,7 +306,7 @@ static int acpi_video_device_lcd_get_level_current( | |||
294 | unsigned long long *level); | 306 | unsigned long long *level); |
295 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 307 | static int acpi_video_get_next_level(struct acpi_video_device *device, |
296 | u32 level_current, u32 event); | 308 | u32 level_current, u32 event); |
297 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 309 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
298 | int event); | 310 | int event); |
299 | static int acpi_video_device_get_state(struct acpi_video_device *device, | 311 | static int acpi_video_device_get_state(struct acpi_video_device *device, |
300 | unsigned long long *state); | 312 | unsigned long long *state); |
@@ -308,7 +320,9 @@ static int acpi_video_get_brightness(struct backlight_device *bd) | |||
308 | int i; | 320 | int i; |
309 | struct acpi_video_device *vd = | 321 | struct acpi_video_device *vd = |
310 | (struct acpi_video_device *)bl_get_data(bd); | 322 | (struct acpi_video_device *)bl_get_data(bd); |
311 | acpi_video_device_lcd_get_level_current(vd, &cur_level); | 323 | |
324 | if (acpi_video_device_lcd_get_level_current(vd, &cur_level)) | ||
325 | return -EINVAL; | ||
312 | for (i = 2; i < vd->brightness->count; i++) { | 326 | for (i = 2; i < vd->brightness->count; i++) { |
313 | if (vd->brightness->levels[i] == cur_level) | 327 | if (vd->brightness->levels[i] == cur_level) |
314 | /* The first two entries are special - see page 575 | 328 | /* The first two entries are special - see page 575 |
@@ -320,12 +334,12 @@ static int acpi_video_get_brightness(struct backlight_device *bd) | |||
320 | 334 | ||
321 | static int acpi_video_set_brightness(struct backlight_device *bd) | 335 | static int acpi_video_set_brightness(struct backlight_device *bd) |
322 | { | 336 | { |
323 | int request_level = bd->props.brightness+2; | 337 | int request_level = bd->props.brightness + 2; |
324 | struct acpi_video_device *vd = | 338 | struct acpi_video_device *vd = |
325 | (struct acpi_video_device *)bl_get_data(bd); | 339 | (struct acpi_video_device *)bl_get_data(bd); |
326 | acpi_video_device_lcd_set_level(vd, | 340 | |
327 | vd->brightness->levels[request_level]); | 341 | return acpi_video_device_lcd_set_level(vd, |
328 | return 0; | 342 | vd->brightness->levels[request_level]); |
329 | } | 343 | } |
330 | 344 | ||
331 | static struct backlight_ops acpi_backlight_ops = { | 345 | static struct backlight_ops acpi_backlight_ops = { |
@@ -358,32 +372,37 @@ static struct output_properties acpi_output_properties = { | |||
358 | 372 | ||
359 | 373 | ||
360 | /* thermal cooling device callbacks */ | 374 | /* thermal cooling device callbacks */ |
361 | static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf) | 375 | static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned |
376 | long *state) | ||
362 | { | 377 | { |
363 | struct acpi_device *device = cdev->devdata; | 378 | struct acpi_device *device = cdev->devdata; |
364 | struct acpi_video_device *video = acpi_driver_data(device); | 379 | struct acpi_video_device *video = acpi_driver_data(device); |
365 | 380 | ||
366 | return sprintf(buf, "%d\n", video->brightness->count - 3); | 381 | *state = video->brightness->count - 3; |
382 | return 0; | ||
367 | } | 383 | } |
368 | 384 | ||
369 | static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) | 385 | static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned |
386 | long *state) | ||
370 | { | 387 | { |
371 | struct acpi_device *device = cdev->devdata; | 388 | struct acpi_device *device = cdev->devdata; |
372 | struct acpi_video_device *video = acpi_driver_data(device); | 389 | struct acpi_video_device *video = acpi_driver_data(device); |
373 | unsigned long long level; | 390 | unsigned long long level; |
374 | int state; | 391 | int offset; |
375 | 392 | ||
376 | acpi_video_device_lcd_get_level_current(video, &level); | 393 | if (acpi_video_device_lcd_get_level_current(video, &level)) |
377 | for (state = 2; state < video->brightness->count; state++) | 394 | return -EINVAL; |
378 | if (level == video->brightness->levels[state]) | 395 | for (offset = 2; offset < video->brightness->count; offset++) |
379 | return sprintf(buf, "%d\n", | 396 | if (level == video->brightness->levels[offset]) { |
380 | video->brightness->count - state - 1); | 397 | *state = video->brightness->count - offset - 1; |
398 | return 0; | ||
399 | } | ||
381 | 400 | ||
382 | return -EINVAL; | 401 | return -EINVAL; |
383 | } | 402 | } |
384 | 403 | ||
385 | static int | 404 | static int |
386 | video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) | 405 | video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) |
387 | { | 406 | { |
388 | struct acpi_device *device = cdev->devdata; | 407 | struct acpi_device *device = cdev->devdata; |
389 | struct acpi_video_device *video = acpi_driver_data(device); | 408 | struct acpi_video_device *video = acpi_driver_data(device); |
@@ -479,34 +498,68 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device, | |||
479 | static int | 498 | static int |
480 | acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) | 499 | acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) |
481 | { | 500 | { |
482 | int status = AE_OK; | 501 | int status; |
483 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | 502 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; |
484 | struct acpi_object_list args = { 1, &arg0 }; | 503 | struct acpi_object_list args = { 1, &arg0 }; |
485 | int state; | 504 | int state; |
486 | 505 | ||
487 | |||
488 | arg0.integer.value = level; | 506 | arg0.integer.value = level; |
489 | 507 | ||
490 | if (device->cap._BCM) | 508 | status = acpi_evaluate_object(device->dev->handle, "_BCM", |
491 | status = acpi_evaluate_object(device->dev->handle, "_BCM", | 509 | &args, NULL); |
492 | &args, NULL); | 510 | if (ACPI_FAILURE(status)) { |
511 | ACPI_ERROR((AE_INFO, "Evaluating _BCM failed")); | ||
512 | return -EIO; | ||
513 | } | ||
514 | |||
493 | device->brightness->curr = level; | 515 | device->brightness->curr = level; |
494 | for (state = 2; state < device->brightness->count; state++) | 516 | for (state = 2; state < device->brightness->count; state++) |
495 | if (level == device->brightness->levels[state]) | 517 | if (level == device->brightness->levels[state]) { |
496 | device->backlight->props.brightness = state - 2; | 518 | if (device->backlight) |
519 | device->backlight->props.brightness = state - 2; | ||
520 | return 0; | ||
521 | } | ||
497 | 522 | ||
498 | return status; | 523 | ACPI_ERROR((AE_INFO, "Current brightness invalid")); |
524 | return -EINVAL; | ||
499 | } | 525 | } |
500 | 526 | ||
501 | static int | 527 | static int |
502 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | 528 | acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, |
503 | unsigned long long *level) | 529 | unsigned long long *level) |
504 | { | 530 | { |
505 | if (device->cap._BQC) | 531 | acpi_status status = AE_OK; |
506 | return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, | 532 | |
507 | level); | 533 | if (device->cap._BQC || device->cap._BCQ) { |
534 | char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; | ||
535 | |||
536 | status = acpi_evaluate_integer(device->dev->handle, buf, | ||
537 | NULL, level); | ||
538 | if (ACPI_SUCCESS(status)) { | ||
539 | if (device->brightness->flags._BQC_use_index) { | ||
540 | if (device->brightness->flags._BCL_reversed) | ||
541 | *level = device->brightness->count | ||
542 | - 3 - (*level); | ||
543 | *level = device->brightness->levels[*level + 2]; | ||
544 | |||
545 | } | ||
546 | device->brightness->curr = *level; | ||
547 | return 0; | ||
548 | } else { | ||
549 | /* Fixme: | ||
550 | * should we return an error or ignore this failure? | ||
551 | * dev->brightness->curr is a cached value which stores | ||
552 | * the correct current backlight level in most cases. | ||
553 | * ACPI video backlight still works w/ buggy _BQC. | ||
554 | * http://bugzilla.kernel.org/show_bug.cgi?id=12233 | ||
555 | */ | ||
556 | ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf)); | ||
557 | device->cap._BQC = device->cap._BCQ = 0; | ||
558 | } | ||
559 | } | ||
560 | |||
508 | *level = device->brightness->curr; | 561 | *level = device->brightness->curr; |
509 | return AE_OK; | 562 | return 0; |
510 | } | 563 | } |
511 | 564 | ||
512 | static int | 565 | static int |
@@ -655,9 +708,11 @@ static int | |||
655 | acpi_video_init_brightness(struct acpi_video_device *device) | 708 | acpi_video_init_brightness(struct acpi_video_device *device) |
656 | { | 709 | { |
657 | union acpi_object *obj = NULL; | 710 | union acpi_object *obj = NULL; |
658 | int i, max_level = 0, count = 0; | 711 | int i, max_level = 0, count = 0, level_ac_battery = 0; |
712 | unsigned long long level, level_old; | ||
659 | union acpi_object *o; | 713 | union acpi_object *o; |
660 | struct acpi_video_device_brightness *br = NULL; | 714 | struct acpi_video_device_brightness *br = NULL; |
715 | int result = -EINVAL; | ||
661 | 716 | ||
662 | if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { | 717 | if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { |
663 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " | 718 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " |
@@ -671,13 +726,16 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
671 | br = kzalloc(sizeof(*br), GFP_KERNEL); | 726 | br = kzalloc(sizeof(*br), GFP_KERNEL); |
672 | if (!br) { | 727 | if (!br) { |
673 | printk(KERN_ERR "can't allocate memory\n"); | 728 | printk(KERN_ERR "can't allocate memory\n"); |
729 | result = -ENOMEM; | ||
674 | goto out; | 730 | goto out; |
675 | } | 731 | } |
676 | 732 | ||
677 | br->levels = kmalloc(obj->package.count * sizeof *(br->levels), | 733 | br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels), |
678 | GFP_KERNEL); | 734 | GFP_KERNEL); |
679 | if (!br->levels) | 735 | if (!br->levels) { |
736 | result = -ENOMEM; | ||
680 | goto out_free; | 737 | goto out_free; |
738 | } | ||
681 | 739 | ||
682 | for (i = 0; i < obj->package.count; i++) { | 740 | for (i = 0; i < obj->package.count; i++) { |
683 | o = (union acpi_object *)&obj->package.elements[i]; | 741 | o = (union acpi_object *)&obj->package.elements[i]; |
@@ -692,18 +750,86 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
692 | count++; | 750 | count++; |
693 | } | 751 | } |
694 | 752 | ||
695 | /* don't sort the first two brightness levels */ | 753 | /* |
696 | sort(&br->levels[2], count - 2, sizeof(br->levels[2]), | 754 | * some buggy BIOS don't export the levels |
697 | acpi_video_cmp_level, NULL); | 755 | * when machine is on AC/Battery in _BCL package. |
698 | 756 | * In this case, the first two elements in _BCL packages | |
699 | if (count < 2) | 757 | * are also supported brightness levels that OS should take care of. |
700 | goto out_free_levels; | 758 | */ |
759 | for (i = 2; i < count; i++) | ||
760 | if (br->levels[i] == br->levels[0] || | ||
761 | br->levels[i] == br->levels[1]) | ||
762 | level_ac_battery++; | ||
763 | |||
764 | if (level_ac_battery < 2) { | ||
765 | level_ac_battery = 2 - level_ac_battery; | ||
766 | br->flags._BCL_no_ac_battery_levels = 1; | ||
767 | for (i = (count - 1 + level_ac_battery); i >= 2; i--) | ||
768 | br->levels[i] = br->levels[i - level_ac_battery]; | ||
769 | count += level_ac_battery; | ||
770 | } else if (level_ac_battery > 2) | ||
771 | ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n")); | ||
772 | |||
773 | /* Check if the _BCL package is in a reversed order */ | ||
774 | if (max_level == br->levels[2]) { | ||
775 | br->flags._BCL_reversed = 1; | ||
776 | sort(&br->levels[2], count - 2, sizeof(br->levels[2]), | ||
777 | acpi_video_cmp_level, NULL); | ||
778 | } else if (max_level != br->levels[count - 1]) | ||
779 | ACPI_ERROR((AE_INFO, | ||
780 | "Found unordered _BCL package\n")); | ||
701 | 781 | ||
702 | br->count = count; | 782 | br->count = count; |
703 | device->brightness = br; | 783 | device->brightness = br; |
704 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); | 784 | |
785 | /* Check the input/output of _BQC/_BCL/_BCM */ | ||
786 | if ((max_level < 100) && (max_level <= (count - 2))) | ||
787 | br->flags._BCL_use_index = 1; | ||
788 | |||
789 | /* | ||
790 | * _BCM is always consistent with _BCL, | ||
791 | * at least for all the laptops we have ever seen. | ||
792 | */ | ||
793 | br->flags._BCM_use_index = br->flags._BCL_use_index; | ||
794 | |||
795 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ | ||
796 | br->curr = max_level; | ||
797 | result = acpi_video_device_lcd_get_level_current(device, &level_old); | ||
798 | if (result) | ||
799 | goto out_free_levels; | ||
800 | |||
801 | result = acpi_video_device_lcd_set_level(device, br->curr); | ||
802 | if (result) | ||
803 | goto out_free_levels; | ||
804 | |||
805 | result = acpi_video_device_lcd_get_level_current(device, &level); | ||
806 | if (result) | ||
807 | goto out_free_levels; | ||
808 | |||
809 | if ((level != level_old) && !br->flags._BCM_use_index) { | ||
810 | /* Note: | ||
811 | * This piece of code does not work correctly if the current | ||
812 | * brightness levels is 0. | ||
813 | * But I guess boxes that boot with such a dark screen are rare | ||
814 | * and no more code is needed to cover this specifial case. | ||
815 | */ | ||
816 | |||
817 | if (level_ac_battery != 2) { | ||
818 | /* | ||
819 | * For now, we don't support the _BCL like this: | ||
820 | * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16 | ||
821 | * because we may mess up the index returned by _BQC. | ||
822 | * Plus: we have not got a box like this. | ||
823 | */ | ||
824 | ACPI_ERROR((AE_INFO, "_BCL not supported\n")); | ||
825 | } | ||
826 | br->flags._BQC_use_index = 1; | ||
827 | } | ||
828 | |||
829 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
830 | "found %d brightness levels\n", count - 2)); | ||
705 | kfree(obj); | 831 | kfree(obj); |
706 | return max_level; | 832 | return result; |
707 | 833 | ||
708 | out_free_levels: | 834 | out_free_levels: |
709 | kfree(br->levels); | 835 | kfree(br->levels); |
@@ -712,7 +838,7 @@ out_free: | |||
712 | out: | 838 | out: |
713 | device->brightness = NULL; | 839 | device->brightness = NULL; |
714 | kfree(obj); | 840 | kfree(obj); |
715 | return 0; | 841 | return result; |
716 | } | 842 | } |
717 | 843 | ||
718 | /* | 844 | /* |
@@ -729,7 +855,6 @@ out: | |||
729 | static void acpi_video_device_find_cap(struct acpi_video_device *device) | 855 | static void acpi_video_device_find_cap(struct acpi_video_device *device) |
730 | { | 856 | { |
731 | acpi_handle h_dummy1; | 857 | acpi_handle h_dummy1; |
732 | u32 max_level = 0; | ||
733 | 858 | ||
734 | 859 | ||
735 | memset(&device->cap, 0, sizeof(device->cap)); | 860 | memset(&device->cap, 0, sizeof(device->cap)); |
@@ -745,6 +870,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
745 | } | 870 | } |
746 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) | 871 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1))) |
747 | device->cap._BQC = 1; | 872 | device->cap._BQC = 1; |
873 | else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ", | ||
874 | &h_dummy1))) { | ||
875 | printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n"); | ||
876 | device->cap._BCQ = 1; | ||
877 | } | ||
878 | |||
748 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { | 879 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { |
749 | device->cap._DDC = 1; | 880 | device->cap._DDC = 1; |
750 | } | 881 | } |
@@ -758,13 +889,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
758 | device->cap._DSS = 1; | 889 | device->cap._DSS = 1; |
759 | } | 890 | } |
760 | 891 | ||
761 | if (acpi_video_backlight_support()) | 892 | if (acpi_video_backlight_support()) { |
762 | max_level = acpi_video_init_brightness(device); | ||
763 | |||
764 | if (device->cap._BCL && device->cap._BCM && max_level > 0) { | ||
765 | int result; | 893 | int result; |
766 | static int count = 0; | 894 | static int count = 0; |
767 | char *name; | 895 | char *name; |
896 | |||
897 | result = acpi_video_init_brightness(device); | ||
898 | if (result) | ||
899 | return; | ||
768 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 900 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); |
769 | if (!name) | 901 | if (!name) |
770 | return; | 902 | return; |
@@ -773,18 +905,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
773 | device->backlight = backlight_device_register(name, | 905 | device->backlight = backlight_device_register(name, |
774 | NULL, device, &acpi_backlight_ops); | 906 | NULL, device, &acpi_backlight_ops); |
775 | device->backlight->props.max_brightness = device->brightness->count-3; | 907 | device->backlight->props.max_brightness = device->brightness->count-3; |
776 | /* | ||
777 | * If there exists the _BQC object, the _BQC object will be | ||
778 | * called to get the current backlight brightness. Otherwise | ||
779 | * the brightness will be set to the maximum. | ||
780 | */ | ||
781 | if (device->cap._BQC) | ||
782 | device->backlight->props.brightness = | ||
783 | acpi_video_get_brightness(device->backlight); | ||
784 | else | ||
785 | device->backlight->props.brightness = | ||
786 | device->backlight->props.max_brightness; | ||
787 | backlight_update_status(device->backlight); | ||
788 | kfree(name); | 908 | kfree(name); |
789 | 909 | ||
790 | device->cdev = thermal_cooling_device_register("LCD", | 910 | device->cdev = thermal_cooling_device_register("LCD", |
@@ -1061,13 +1181,12 @@ acpi_video_device_write_brightness(struct file *file, | |||
1061 | /* validate through the list of available levels */ | 1181 | /* validate through the list of available levels */ |
1062 | for (i = 2; i < dev->brightness->count; i++) | 1182 | for (i = 2; i < dev->brightness->count; i++) |
1063 | if (level == dev->brightness->levels[i]) { | 1183 | if (level == dev->brightness->levels[i]) { |
1064 | if (ACPI_SUCCESS | 1184 | if (!acpi_video_device_lcd_set_level(dev, level)) |
1065 | (acpi_video_device_lcd_set_level(dev, level))) | 1185 | return count; |
1066 | dev->brightness->curr = level; | ||
1067 | break; | 1186 | break; |
1068 | } | 1187 | } |
1069 | 1188 | ||
1070 | return count; | 1189 | return -EINVAL; |
1071 | } | 1190 | } |
1072 | 1191 | ||
1073 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) | 1192 | static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) |
@@ -1749,15 +1868,29 @@ acpi_video_get_next_level(struct acpi_video_device *device, | |||
1749 | } | 1868 | } |
1750 | } | 1869 | } |
1751 | 1870 | ||
1752 | static void | 1871 | static int |
1753 | acpi_video_switch_brightness(struct acpi_video_device *device, int event) | 1872 | acpi_video_switch_brightness(struct acpi_video_device *device, int event) |
1754 | { | 1873 | { |
1755 | unsigned long long level_current, level_next; | 1874 | unsigned long long level_current, level_next; |
1875 | int result = -EINVAL; | ||
1876 | |||
1756 | if (!device->brightness) | 1877 | if (!device->brightness) |
1757 | return; | 1878 | goto out; |
1758 | acpi_video_device_lcd_get_level_current(device, &level_current); | 1879 | |
1880 | result = acpi_video_device_lcd_get_level_current(device, | ||
1881 | &level_current); | ||
1882 | if (result) | ||
1883 | goto out; | ||
1884 | |||
1759 | level_next = acpi_video_get_next_level(device, level_current, event); | 1885 | level_next = acpi_video_get_next_level(device, level_current, event); |
1760 | acpi_video_device_lcd_set_level(device, level_next); | 1886 | |
1887 | result = acpi_video_device_lcd_set_level(device, level_next); | ||
1888 | |||
1889 | out: | ||
1890 | if (result) | ||
1891 | printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); | ||
1892 | |||
1893 | return result; | ||
1761 | } | 1894 | } |
1762 | 1895 | ||
1763 | static int | 1896 | static int |
@@ -2124,7 +2257,27 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) | |||
2124 | return 0; | 2257 | return 0; |
2125 | } | 2258 | } |
2126 | 2259 | ||
2127 | static int __init acpi_video_init(void) | 2260 | static int __init intel_opregion_present(void) |
2261 | { | ||
2262 | #if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE) | ||
2263 | struct pci_dev *dev = NULL; | ||
2264 | u32 address; | ||
2265 | |||
2266 | for_each_pci_dev(dev) { | ||
2267 | if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
2268 | continue; | ||
2269 | if (dev->vendor != PCI_VENDOR_ID_INTEL) | ||
2270 | continue; | ||
2271 | pci_read_config_dword(dev, 0xfc, &address); | ||
2272 | if (!address) | ||
2273 | continue; | ||
2274 | return 1; | ||
2275 | } | ||
2276 | #endif | ||
2277 | return 0; | ||
2278 | } | ||
2279 | |||
2280 | int acpi_video_register(void) | ||
2128 | { | 2281 | { |
2129 | int result = 0; | 2282 | int result = 0; |
2130 | 2283 | ||
@@ -2141,6 +2294,22 @@ static int __init acpi_video_init(void) | |||
2141 | 2294 | ||
2142 | return 0; | 2295 | return 0; |
2143 | } | 2296 | } |
2297 | EXPORT_SYMBOL(acpi_video_register); | ||
2298 | |||
2299 | /* | ||
2300 | * This is kind of nasty. Hardware using Intel chipsets may require | ||
2301 | * the video opregion code to be run first in order to initialise | ||
2302 | * state before any ACPI video calls are made. To handle this we defer | ||
2303 | * registration of the video class until the opregion code has run. | ||
2304 | */ | ||
2305 | |||
2306 | static int __init acpi_video_init(void) | ||
2307 | { | ||
2308 | if (intel_opregion_present()) | ||
2309 | return 0; | ||
2310 | |||
2311 | return acpi_video_register(); | ||
2312 | } | ||
2144 | 2313 | ||
2145 | static void __exit acpi_video_exit(void) | 2314 | static void __exit acpi_video_exit(void) |
2146 | { | 2315 | { |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 50e3d2dbf3af..09737275e25f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -55,6 +55,9 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | |||
55 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " | 55 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " |
56 | "support\n")); | 56 | "support\n")); |
57 | *cap |= ACPI_VIDEO_BACKLIGHT; | 57 | *cap |= ACPI_VIDEO_BACKLIGHT; |
58 | if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy))) | ||
59 | printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness " | ||
60 | "control misses _BQC function\n"); | ||
58 | /* We have backlight support, no need to scan further */ | 61 | /* We have backlight support, no need to scan further */ |
59 | return AE_CTRL_TERMINATE; | 62 | return AE_CTRL_TERMINATE; |
60 | } | 63 | } |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 2d34806d45dd..5aee8c26cc9f 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <acpi/acpi_drivers.h> | 8 | #include <acpi/acpi_drivers.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | |||
12 | #include "internal.h" | ||
11 | #include "sleep.h" | 13 | #include "sleep.h" |
12 | 14 | ||
13 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 15 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
@@ -136,13 +138,10 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
136 | spin_unlock(&acpi_device_lock); | 138 | spin_unlock(&acpi_device_lock); |
137 | } | 139 | } |
138 | 140 | ||
139 | static int __init acpi_wakeup_device_init(void) | 141 | int __init acpi_wakeup_device_init(void) |
140 | { | 142 | { |
141 | struct list_head *node, *next; | 143 | struct list_head *node, *next; |
142 | 144 | ||
143 | if (acpi_disabled) | ||
144 | return 0; | ||
145 | |||
146 | spin_lock(&acpi_device_lock); | 145 | spin_lock(&acpi_device_lock); |
147 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | 146 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { |
148 | struct acpi_device *dev = container_of(node, | 147 | struct acpi_device *dev = container_of(node, |
@@ -163,5 +162,3 @@ static int __init acpi_wakeup_device_init(void) | |||
163 | spin_unlock(&acpi_device_lock); | 162 | spin_unlock(&acpi_device_lock); |
164 | return 0; | 163 | return 0; |
165 | } | 164 | } |
166 | |||
167 | late_initcall(acpi_wakeup_device_init); | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 6d21b9e48b89..638686904e06 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1144,8 +1144,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1144 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 1144 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
1145 | pci_enable_msi(dev->pdev); | 1145 | pci_enable_msi(dev->pdev); |
1146 | 1146 | ||
1147 | intel_opregion_init(dev); | ||
1148 | |||
1149 | spin_lock_init(&dev_priv->user_irq_lock); | 1147 | spin_lock_init(&dev_priv->user_irq_lock); |
1150 | dev_priv->user_irq_refcount = 0; | 1148 | dev_priv->user_irq_refcount = 0; |
1151 | 1149 | ||
@@ -1164,6 +1162,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1164 | } | 1162 | } |
1165 | } | 1163 | } |
1166 | 1164 | ||
1165 | /* Must be done after probing outputs */ | ||
1166 | intel_opregion_init(dev, 0); | ||
1167 | |||
1167 | return 0; | 1168 | return 0; |
1168 | 1169 | ||
1169 | out_iomapfree: | 1170 | out_iomapfree: |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b293ef0bae71..209592fdb7e7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -99,7 +99,7 @@ static int i915_resume(struct drm_device *dev) | |||
99 | 99 | ||
100 | i915_restore_state(dev); | 100 | i915_restore_state(dev); |
101 | 101 | ||
102 | intel_opregion_init(dev); | 102 | intel_opregion_init(dev, 1); |
103 | 103 | ||
104 | /* KMS EnterVT equivalent */ | 104 | /* KMS EnterVT equivalent */ |
105 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 105 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d6cc9861e0a1..b9a92c250b91 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -659,12 +659,12 @@ extern int i915_restore_state(struct drm_device *dev); | |||
659 | 659 | ||
660 | #ifdef CONFIG_ACPI | 660 | #ifdef CONFIG_ACPI |
661 | /* i915_opregion.c */ | 661 | /* i915_opregion.c */ |
662 | extern int intel_opregion_init(struct drm_device *dev); | 662 | extern int intel_opregion_init(struct drm_device *dev, int resume); |
663 | extern void intel_opregion_free(struct drm_device *dev); | 663 | extern void intel_opregion_free(struct drm_device *dev); |
664 | extern void opregion_asle_intr(struct drm_device *dev); | 664 | extern void opregion_asle_intr(struct drm_device *dev); |
665 | extern void opregion_enable_asle(struct drm_device *dev); | 665 | extern void opregion_enable_asle(struct drm_device *dev); |
666 | #else | 666 | #else |
667 | static inline int intel_opregion_init(struct drm_device *dev) { return 0; } | 667 | static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; } |
668 | static inline void intel_opregion_free(struct drm_device *dev) { return; } | 668 | static inline void intel_opregion_free(struct drm_device *dev) { return; } |
669 | static inline void opregion_asle_intr(struct drm_device *dev) { return; } | 669 | static inline void opregion_asle_intr(struct drm_device *dev) { return; } |
670 | static inline void opregion_enable_asle(struct drm_device *dev) { return; } | 670 | static inline void opregion_enable_asle(struct drm_device *dev) { return; } |
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index ff012835a386..69427722d20e 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
29 | #include <acpi/video.h> | ||
29 | 30 | ||
30 | #include "drmP.h" | 31 | #include "drmP.h" |
31 | #include "i915_drm.h" | 32 | #include "i915_drm.h" |
@@ -136,6 +137,12 @@ struct opregion_asle { | |||
136 | 137 | ||
137 | #define ASLE_CBLV_VALID (1<<31) | 138 | #define ASLE_CBLV_VALID (1<<31) |
138 | 139 | ||
140 | #define ACPI_OTHER_OUTPUT (0<<8) | ||
141 | #define ACPI_VGA_OUTPUT (1<<8) | ||
142 | #define ACPI_TV_OUTPUT (2<<8) | ||
143 | #define ACPI_DIGITAL_OUTPUT (3<<8) | ||
144 | #define ACPI_LVDS_OUTPUT (4<<8) | ||
145 | |||
139 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 146 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
140 | { | 147 | { |
141 | struct drm_i915_private *dev_priv = dev->dev_private; | 148 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -282,7 +289,58 @@ static struct notifier_block intel_opregion_notifier = { | |||
282 | .notifier_call = intel_opregion_video_event, | 289 | .notifier_call = intel_opregion_video_event, |
283 | }; | 290 | }; |
284 | 291 | ||
285 | int intel_opregion_init(struct drm_device *dev) | 292 | /* |
293 | * Initialise the DIDL field in opregion. This passes a list of devices to | ||
294 | * the firmware. Values are defined by section B.4.2 of the ACPI specification | ||
295 | * (version 3) | ||
296 | */ | ||
297 | |||
298 | static void intel_didl_outputs(struct drm_device *dev) | ||
299 | { | ||
300 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
301 | struct intel_opregion *opregion = &dev_priv->opregion; | ||
302 | struct drm_connector *connector; | ||
303 | int i = 0; | ||
304 | |||
305 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
306 | int output_type = ACPI_OTHER_OUTPUT; | ||
307 | if (i >= 8) { | ||
308 | dev_printk (KERN_ERR, &dev->pdev->dev, | ||
309 | "More than 8 outputs detected\n"); | ||
310 | return; | ||
311 | } | ||
312 | switch (connector->connector_type) { | ||
313 | case DRM_MODE_CONNECTOR_VGA: | ||
314 | case DRM_MODE_CONNECTOR_DVIA: | ||
315 | output_type = ACPI_VGA_OUTPUT; | ||
316 | break; | ||
317 | case DRM_MODE_CONNECTOR_Composite: | ||
318 | case DRM_MODE_CONNECTOR_SVIDEO: | ||
319 | case DRM_MODE_CONNECTOR_Component: | ||
320 | case DRM_MODE_CONNECTOR_9PinDIN: | ||
321 | output_type = ACPI_TV_OUTPUT; | ||
322 | break; | ||
323 | case DRM_MODE_CONNECTOR_DVII: | ||
324 | case DRM_MODE_CONNECTOR_DVID: | ||
325 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
326 | case DRM_MODE_CONNECTOR_HDMIA: | ||
327 | case DRM_MODE_CONNECTOR_HDMIB: | ||
328 | output_type = ACPI_DIGITAL_OUTPUT; | ||
329 | break; | ||
330 | case DRM_MODE_CONNECTOR_LVDS: | ||
331 | output_type = ACPI_LVDS_OUTPUT; | ||
332 | break; | ||
333 | } | ||
334 | opregion->acpi->didl[i] |= (1<<31) | output_type | i; | ||
335 | i++; | ||
336 | } | ||
337 | |||
338 | /* If fewer than 8 outputs, the list must be null terminated */ | ||
339 | if (i < 8) | ||
340 | opregion->acpi->didl[i] = 0; | ||
341 | } | ||
342 | |||
343 | int intel_opregion_init(struct drm_device *dev, int resume) | ||
286 | { | 344 | { |
287 | struct drm_i915_private *dev_priv = dev->dev_private; | 345 | struct drm_i915_private *dev_priv = dev->dev_private; |
288 | struct intel_opregion *opregion = &dev_priv->opregion; | 346 | struct intel_opregion *opregion = &dev_priv->opregion; |
@@ -312,6 +370,11 @@ int intel_opregion_init(struct drm_device *dev) | |||
312 | if (mboxes & MBOX_ACPI) { | 370 | if (mboxes & MBOX_ACPI) { |
313 | DRM_DEBUG("Public ACPI methods supported\n"); | 371 | DRM_DEBUG("Public ACPI methods supported\n"); |
314 | opregion->acpi = base + OPREGION_ACPI_OFFSET; | 372 | opregion->acpi = base + OPREGION_ACPI_OFFSET; |
373 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
374 | intel_didl_outputs(dev); | ||
375 | if (!resume) | ||
376 | acpi_video_register(); | ||
377 | } | ||
315 | } else { | 378 | } else { |
316 | DRM_DEBUG("Public ACPI methods not supported\n"); | 379 | DRM_DEBUG("Public ACPI methods not supported\n"); |
317 | err = -ENOTSUPP; | 380 | err = -ENOTSUPP; |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index deea8a187eb8..368ca72dffbc 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -386,12 +386,12 @@ static int __init acpi_pci_init(void) | |||
386 | { | 386 | { |
387 | int ret; | 387 | int ret; |
388 | 388 | ||
389 | if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) { | 389 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) { |
390 | printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n"); | 390 | printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n"); |
391 | pci_no_msi(); | 391 | pci_no_msi(); |
392 | } | 392 | } |
393 | 393 | ||
394 | if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) { | 394 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { |
395 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); | 395 | printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); |
396 | pcie_no_aspm(); | 396 | pcie_no_aspm(); |
397 | } | 397 | } |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 3608081bc3e0..eb6908a6fe0b 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -165,6 +165,7 @@ config SONY_LAPTOP | |||
165 | depends on ACPI | 165 | depends on ACPI |
166 | select BACKLIGHT_CLASS_DEVICE | 166 | select BACKLIGHT_CLASS_DEVICE |
167 | depends on INPUT | 167 | depends on INPUT |
168 | depends on RFKILL | ||
168 | ---help--- | 169 | ---help--- |
169 | This mini-driver drives the SNC and SPIC devices present in the ACPI | 170 | This mini-driver drives the SNC and SPIC devices present in the ACPI |
170 | BIOS of the Sony Vaio laptops. | 171 | BIOS of the Sony Vaio laptops. |
@@ -226,6 +227,30 @@ config THINKPAD_ACPI_DEBUG | |||
226 | 227 | ||
227 | If you are not sure, say N here. | 228 | If you are not sure, say N here. |
228 | 229 | ||
230 | config THINKPAD_ACPI_UNSAFE_LEDS | ||
231 | bool "Allow control of important LEDs (unsafe)" | ||
232 | depends on THINKPAD_ACPI | ||
233 | default n | ||
234 | ---help--- | ||
235 | Overriding LED state on ThinkPads can mask important | ||
236 | firmware alerts (like critical battery condition), or misled | ||
237 | the user into damaging the hardware (undocking or ejecting | ||
238 | the bay while buses are still active), etc. | ||
239 | |||
240 | LED control on the ThinkPad is write-only (with very few | ||
241 | exceptions on very ancient models), which makes it | ||
242 | impossible to know beforehand if important information will | ||
243 | be lost when one changes LED state. | ||
244 | |||
245 | Users that know what they are doing can enable this option | ||
246 | and the driver will allow control of every LED, including | ||
247 | the ones on the dock stations. | ||
248 | |||
249 | Never enable this option on a distribution kernel. | ||
250 | |||
251 | Say N here, unless you are building a kernel for your own | ||
252 | use, and need to control the important firmware LEDs. | ||
253 | |||
229 | config THINKPAD_ACPI_DOCK | 254 | config THINKPAD_ACPI_DOCK |
230 | bool "Legacy Docking Station Support" | 255 | bool "Legacy Docking Station Support" |
231 | depends on THINKPAD_ACPI | 256 | depends on THINKPAD_ACPI |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index a6a42e8c060b..0f6e43bf4fc2 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Acer WMI Laptop Extras | 2 | * Acer WMI Laptop Extras |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk> | 4 | * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk> |
5 | * | 5 | * |
6 | * Based on acer_acpi: | 6 | * Based on acer_acpi: |
7 | * Copyright (C) 2005-2007 E.M. Smith | 7 | * Copyright (C) 2005-2007 E.M. Smith |
@@ -225,6 +225,25 @@ static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { | |||
225 | .wireless = 2, | 225 | .wireless = 2, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | /* The Aspire One has a dummy ACPI-WMI interface - disable it */ | ||
229 | static struct dmi_system_id __devinitdata acer_blacklist[] = { | ||
230 | { | ||
231 | .ident = "Acer Aspire One (SSD)", | ||
232 | .matches = { | ||
233 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
234 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), | ||
235 | }, | ||
236 | }, | ||
237 | { | ||
238 | .ident = "Acer Aspire One (HDD)", | ||
239 | .matches = { | ||
240 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
241 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), | ||
242 | }, | ||
243 | }, | ||
244 | {} | ||
245 | }; | ||
246 | |||
228 | static struct dmi_system_id acer_quirks[] = { | 247 | static struct dmi_system_id acer_quirks[] = { |
229 | { | 248 | { |
230 | .callback = dmi_matched, | 249 | .callback = dmi_matched, |
@@ -1117,11 +1136,17 @@ static int __devinit acer_platform_probe(struct platform_device *device) | |||
1117 | } | 1136 | } |
1118 | 1137 | ||
1119 | err = acer_rfkill_init(&device->dev); | 1138 | err = acer_rfkill_init(&device->dev); |
1139 | if (err) | ||
1140 | goto error_rfkill; | ||
1120 | 1141 | ||
1121 | return err; | 1142 | return err; |
1122 | 1143 | ||
1144 | error_rfkill: | ||
1145 | if (has_cap(ACER_CAP_BRIGHTNESS)) | ||
1146 | acer_backlight_exit(); | ||
1123 | error_brightness: | 1147 | error_brightness: |
1124 | acer_led_exit(); | 1148 | if (has_cap(ACER_CAP_MAILLED)) |
1149 | acer_led_exit(); | ||
1125 | error_mailled: | 1150 | error_mailled: |
1126 | return err; | 1151 | return err; |
1127 | } | 1152 | } |
@@ -1254,6 +1279,12 @@ static int __init acer_wmi_init(void) | |||
1254 | 1279 | ||
1255 | printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n"); | 1280 | printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n"); |
1256 | 1281 | ||
1282 | if (dmi_check_system(acer_blacklist)) { | ||
1283 | printk(ACER_INFO "Blacklisted hardware detected - " | ||
1284 | "not loading\n"); | ||
1285 | return -ENODEV; | ||
1286 | } | ||
1287 | |||
1257 | find_quirks(); | 1288 | find_quirks(); |
1258 | 1289 | ||
1259 | /* | 1290 | /* |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f41135f2fb29..50d9019de2be 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); | |||
53 | 53 | ||
54 | static int __init hp_wmi_bios_setup(struct platform_device *device); | 54 | static int __init hp_wmi_bios_setup(struct platform_device *device); |
55 | static int __exit hp_wmi_bios_remove(struct platform_device *device); | 55 | static int __exit hp_wmi_bios_remove(struct platform_device *device); |
56 | static int hp_wmi_resume_handler(struct platform_device *device); | ||
56 | 57 | ||
57 | struct bios_args { | 58 | struct bios_args { |
58 | u32 signature; | 59 | u32 signature; |
@@ -101,6 +102,7 @@ static struct platform_driver hp_wmi_driver = { | |||
101 | }, | 102 | }, |
102 | .probe = hp_wmi_bios_setup, | 103 | .probe = hp_wmi_bios_setup, |
103 | .remove = hp_wmi_bios_remove, | 104 | .remove = hp_wmi_bios_remove, |
105 | .resume = hp_wmi_resume_handler, | ||
104 | }; | 106 | }; |
105 | 107 | ||
106 | static int hp_wmi_perform_query(int query, int write, int value) | 108 | static int hp_wmi_perform_query(int query, int write, int value) |
@@ -487,6 +489,29 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device) | |||
487 | return 0; | 489 | return 0; |
488 | } | 490 | } |
489 | 491 | ||
492 | static int hp_wmi_resume_handler(struct platform_device *device) | ||
493 | { | ||
494 | struct key_entry *key; | ||
495 | |||
496 | /* | ||
497 | * Docking state may have changed while suspended, so trigger | ||
498 | * an input event for the current state. As this is a switch, | ||
499 | * the input layer will only actually pass it on if the state | ||
500 | * changed. | ||
501 | */ | ||
502 | for (key = hp_wmi_keymap; key->type != KE_END; key++) { | ||
503 | switch (key->type) { | ||
504 | case KE_SW: | ||
505 | input_report_switch(hp_wmi_input_dev, key->keycode, | ||
506 | hp_wmi_dock_state()); | ||
507 | input_sync(hp_wmi_input_dev); | ||
508 | break; | ||
509 | } | ||
510 | } | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
490 | static int __init hp_wmi_init(void) | 515 | static int __init hp_wmi_init(void) |
491 | { | 516 | { |
492 | int err; | 517 | int err; |
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 27b7662955bb..29432a50be45 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c | |||
@@ -57,8 +57,8 @@ MODULE_LICENSE("GPL"); | |||
57 | * In that case max_cstate would be n-1 | 57 | * In that case max_cstate would be n-1 |
58 | * GTHS returning '0' would mean that no bandwidth control states are supported | 58 | * GTHS returning '0' would mean that no bandwidth control states are supported |
59 | */ | 59 | */ |
60 | static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | 60 | static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev, |
61 | unsigned long *max_state) | 61 | unsigned long *max_state) |
62 | { | 62 | { |
63 | struct acpi_device *device = cdev->devdata; | 63 | struct acpi_device *device = cdev->devdata; |
64 | acpi_handle handle = device->handle; | 64 | acpi_handle handle = device->handle; |
@@ -83,22 +83,12 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | |||
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev, | ||
87 | char *buf) | ||
88 | { | ||
89 | unsigned long value; | ||
90 | if (memory_get_int_max_bandwidth(cdev, &value)) | ||
91 | return -EINVAL; | ||
92 | |||
93 | return sprintf(buf, "%ld\n", value); | ||
94 | } | ||
95 | |||
96 | static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, | 86 | static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, |
97 | char *buf) | 87 | unsigned long *value) |
98 | { | 88 | { |
99 | struct acpi_device *device = cdev->devdata; | 89 | struct acpi_device *device = cdev->devdata; |
100 | acpi_handle handle = device->handle; | 90 | acpi_handle handle = device->handle; |
101 | unsigned long long value; | 91 | unsigned long long result; |
102 | struct acpi_object_list arg_list; | 92 | struct acpi_object_list arg_list; |
103 | union acpi_object arg; | 93 | union acpi_object arg; |
104 | acpi_status status = AE_OK; | 94 | acpi_status status = AE_OK; |
@@ -108,15 +98,16 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
108 | arg.type = ACPI_TYPE_INTEGER; | 98 | arg.type = ACPI_TYPE_INTEGER; |
109 | arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH; | 99 | arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH; |
110 | status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH, | 100 | status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH, |
111 | &arg_list, &value); | 101 | &arg_list, &result); |
112 | if (ACPI_FAILURE(status)) | 102 | if (ACPI_FAILURE(status)) |
113 | return -EFAULT; | 103 | return -EFAULT; |
114 | 104 | ||
115 | return sprintf(buf, "%llu\n", value); | 105 | *value = result; |
106 | return 0; | ||
116 | } | 107 | } |
117 | 108 | ||
118 | static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | 109 | static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, |
119 | unsigned int state) | 110 | unsigned long state) |
120 | { | 111 | { |
121 | struct acpi_device *device = cdev->devdata; | 112 | struct acpi_device *device = cdev->devdata; |
122 | acpi_handle handle = device->handle; | 113 | acpi_handle handle = device->handle; |
@@ -126,7 +117,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
126 | unsigned long long temp; | 117 | unsigned long long temp; |
127 | unsigned long max_state; | 118 | unsigned long max_state; |
128 | 119 | ||
129 | if (memory_get_int_max_bandwidth(cdev, &max_state)) | 120 | if (memory_get_max_bandwidth(cdev, &max_state)) |
130 | return -EFAULT; | 121 | return -EFAULT; |
131 | 122 | ||
132 | if (state > max_state) | 123 | if (state > max_state) |
@@ -142,7 +133,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
142 | &temp); | 133 | &temp); |
143 | 134 | ||
144 | printk(KERN_INFO | 135 | printk(KERN_INFO |
145 | "Bandwidth value was %d: status is %d\n", state, status); | 136 | "Bandwidth value was %ld: status is %d\n", state, status); |
146 | if (ACPI_FAILURE(status)) | 137 | if (ACPI_FAILURE(status)) |
147 | return -EFAULT; | 138 | return -EFAULT; |
148 | 139 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 537959d07148..e02edf68a68e 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * ACPI Sony Notebook Control Driver (SNC and SPIC) | 2 | * ACPI Sony Notebook Control Driver (SNC and SPIC) |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> | 4 | * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net> |
5 | * Copyright (C) 2007 Mattia Dongili <malattia@linux.it> | 5 | * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it> |
6 | * | 6 | * |
7 | * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c | 7 | * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c |
8 | * which are copyrighted by their respective authors. | 8 | * which are copyrighted by their respective authors. |
@@ -46,7 +46,6 @@ | |||
46 | #include <linux/module.h> | 46 | #include <linux/module.h> |
47 | #include <linux/moduleparam.h> | 47 | #include <linux/moduleparam.h> |
48 | #include <linux/init.h> | 48 | #include <linux/init.h> |
49 | #include <linux/smp_lock.h> | ||
50 | #include <linux/types.h> | 49 | #include <linux/types.h> |
51 | #include <linux/backlight.h> | 50 | #include <linux/backlight.h> |
52 | #include <linux/platform_device.h> | 51 | #include <linux/platform_device.h> |
@@ -64,6 +63,7 @@ | |||
64 | #include <asm/uaccess.h> | 63 | #include <asm/uaccess.h> |
65 | #include <linux/sonypi.h> | 64 | #include <linux/sonypi.h> |
66 | #include <linux/sony-laptop.h> | 65 | #include <linux/sony-laptop.h> |
66 | #include <linux/rfkill.h> | ||
67 | #ifdef CONFIG_SONYPI_COMPAT | 67 | #ifdef CONFIG_SONYPI_COMPAT |
68 | #include <linux/poll.h> | 68 | #include <linux/poll.h> |
69 | #include <linux/miscdevice.h> | 69 | #include <linux/miscdevice.h> |
@@ -123,6 +123,18 @@ MODULE_PARM_DESC(minor, | |||
123 | "default is -1 (automatic)"); | 123 | "default is -1 (automatic)"); |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | enum sony_nc_rfkill { | ||
127 | SONY_WIFI, | ||
128 | SONY_BLUETOOTH, | ||
129 | SONY_WWAN, | ||
130 | SONY_WIMAX, | ||
131 | SONY_RFKILL_MAX, | ||
132 | }; | ||
133 | |||
134 | static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX]; | ||
135 | static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900}; | ||
136 | static void sony_nc_rfkill_update(void); | ||
137 | |||
126 | /*********** Input Devices ***********/ | 138 | /*********** Input Devices ***********/ |
127 | 139 | ||
128 | #define SONY_LAPTOP_BUF_SIZE 128 | 140 | #define SONY_LAPTOP_BUF_SIZE 128 |
@@ -134,6 +146,7 @@ struct sony_laptop_input_s { | |||
134 | spinlock_t fifo_lock; | 146 | spinlock_t fifo_lock; |
135 | struct workqueue_struct *wq; | 147 | struct workqueue_struct *wq; |
136 | }; | 148 | }; |
149 | |||
137 | static struct sony_laptop_input_s sony_laptop_input = { | 150 | static struct sony_laptop_input_s sony_laptop_input = { |
138 | .users = ATOMIC_INIT(0), | 151 | .users = ATOMIC_INIT(0), |
139 | }; | 152 | }; |
@@ -211,6 +224,14 @@ static int sony_laptop_input_index[] = { | |||
211 | 48, /* 61 SONYPI_EVENT_WIRELESS_OFF */ | 224 | 48, /* 61 SONYPI_EVENT_WIRELESS_OFF */ |
212 | 49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */ | 225 | 49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */ |
213 | 50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */ | 226 | 50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */ |
227 | 51, /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */ | ||
228 | 52, /* 65 SONYPI_EVENT_MODEKEY_PRESSED */ | ||
229 | 53, /* 66 SONYPI_EVENT_PKEY_P4 */ | ||
230 | 54, /* 67 SONYPI_EVENT_PKEY_P5 */ | ||
231 | 55, /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */ | ||
232 | 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */ | ||
233 | 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */ | ||
234 | -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */ | ||
214 | }; | 235 | }; |
215 | 236 | ||
216 | static int sony_laptop_input_keycode_map[] = { | 237 | static int sony_laptop_input_keycode_map[] = { |
@@ -264,7 +285,14 @@ static int sony_laptop_input_keycode_map[] = { | |||
264 | KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ | 285 | KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ |
265 | KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ | 286 | KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ |
266 | KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */ | 287 | KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */ |
267 | KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */ | 288 | KEY_ZOOMOUT, /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */ |
289 | KEY_EJECTCD, /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */ | ||
290 | KEY_F13, /* 52 SONYPI_EVENT_MODEKEY_PRESSED */ | ||
291 | KEY_PROG4, /* 53 SONYPI_EVENT_PKEY_P4 */ | ||
292 | KEY_F14, /* 54 SONYPI_EVENT_PKEY_P5 */ | ||
293 | KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */ | ||
294 | KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */ | ||
295 | KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */ | ||
268 | }; | 296 | }; |
269 | 297 | ||
270 | /* release buttons after a short delay if pressed */ | 298 | /* release buttons after a short delay if pressed */ |
@@ -369,7 +397,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device) | |||
369 | sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop"); | 397 | sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop"); |
370 | if (!sony_laptop_input.wq) { | 398 | if (!sony_laptop_input.wq) { |
371 | printk(KERN_ERR DRV_PFX | 399 | printk(KERN_ERR DRV_PFX |
372 | "Unabe to create workqueue.\n"); | 400 | "Unable to create workqueue.\n"); |
373 | error = -ENXIO; | 401 | error = -ENXIO; |
374 | goto err_free_kfifo; | 402 | goto err_free_kfifo; |
375 | } | 403 | } |
@@ -689,6 +717,31 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value, | |||
689 | return -1; | 717 | return -1; |
690 | } | 718 | } |
691 | 719 | ||
720 | static int sony_find_snc_handle(int handle) | ||
721 | { | ||
722 | int i; | ||
723 | int result; | ||
724 | |||
725 | for (i = 0x20; i < 0x30; i++) { | ||
726 | acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result); | ||
727 | if (result == handle) | ||
728 | return i-0x20; | ||
729 | } | ||
730 | |||
731 | return -1; | ||
732 | } | ||
733 | |||
734 | static int sony_call_snc_handle(int handle, int argument, int *result) | ||
735 | { | ||
736 | int offset = sony_find_snc_handle(handle); | ||
737 | |||
738 | if (offset < 0) | ||
739 | return -1; | ||
740 | |||
741 | return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument, | ||
742 | result); | ||
743 | } | ||
744 | |||
692 | /* | 745 | /* |
693 | * sony_nc_values input/output validate functions | 746 | * sony_nc_values input/output validate functions |
694 | */ | 747 | */ |
@@ -809,87 +862,53 @@ struct sony_nc_event { | |||
809 | u8 event; | 862 | u8 event; |
810 | }; | 863 | }; |
811 | 864 | ||
812 | static struct sony_nc_event *sony_nc_events; | 865 | static struct sony_nc_event sony_100_events[] = { |
813 | 866 | { 0x90, SONYPI_EVENT_PKEY_P1 }, | |
814 | /* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence | 867 | { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
815 | * for Fn keys | 868 | { 0x91, SONYPI_EVENT_PKEY_P2 }, |
816 | */ | 869 | { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
817 | static int sony_nc_C_enable(const struct dmi_system_id *id) | ||
818 | { | ||
819 | int result = 0; | ||
820 | |||
821 | printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident); | ||
822 | |||
823 | sony_nc_events = id->driver_data; | ||
824 | |||
825 | if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0 | ||
826 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0 | ||
827 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0 | ||
828 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0 | ||
829 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0 | ||
830 | || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) { | ||
831 | printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some " | ||
832 | "functionalities may be missing\n"); | ||
833 | return 1; | ||
834 | } | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | static struct sony_nc_event sony_C_events[] = { | ||
839 | { 0x81, SONYPI_EVENT_FNKEY_F1 }, | 870 | { 0x81, SONYPI_EVENT_FNKEY_F1 }, |
840 | { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, | 871 | { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, |
872 | { 0x82, SONYPI_EVENT_FNKEY_F2 }, | ||
873 | { 0x02, SONYPI_EVENT_FNKEY_RELEASED }, | ||
874 | { 0x83, SONYPI_EVENT_FNKEY_F3 }, | ||
875 | { 0x03, SONYPI_EVENT_FNKEY_RELEASED }, | ||
876 | { 0x84, SONYPI_EVENT_FNKEY_F4 }, | ||
877 | { 0x04, SONYPI_EVENT_FNKEY_RELEASED }, | ||
841 | { 0x85, SONYPI_EVENT_FNKEY_F5 }, | 878 | { 0x85, SONYPI_EVENT_FNKEY_F5 }, |
842 | { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, | 879 | { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, |
843 | { 0x86, SONYPI_EVENT_FNKEY_F6 }, | 880 | { 0x86, SONYPI_EVENT_FNKEY_F6 }, |
844 | { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, | 881 | { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, |
845 | { 0x87, SONYPI_EVENT_FNKEY_F7 }, | 882 | { 0x87, SONYPI_EVENT_FNKEY_F7 }, |
846 | { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, | 883 | { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, |
884 | { 0x89, SONYPI_EVENT_FNKEY_F9 }, | ||
885 | { 0x09, SONYPI_EVENT_FNKEY_RELEASED }, | ||
847 | { 0x8A, SONYPI_EVENT_FNKEY_F10 }, | 886 | { 0x8A, SONYPI_EVENT_FNKEY_F10 }, |
848 | { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, | 887 | { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, |
849 | { 0x8C, SONYPI_EVENT_FNKEY_F12 }, | 888 | { 0x8C, SONYPI_EVENT_FNKEY_F12 }, |
850 | { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, | 889 | { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, |
890 | { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED }, | ||
891 | { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED }, | ||
851 | { 0, 0 }, | 892 | { 0, 0 }, |
852 | }; | 893 | }; |
853 | 894 | ||
854 | /* SNC-only model map */ | 895 | static struct sony_nc_event sony_127_events[] = { |
855 | static const struct dmi_system_id sony_nc_ids[] = { | 896 | { 0x81, SONYPI_EVENT_MODEKEY_PRESSED }, |
856 | { | 897 | { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
857 | .ident = "Sony Vaio FE Series", | 898 | { 0x82, SONYPI_EVENT_PKEY_P1 }, |
858 | .callback = sony_nc_C_enable, | 899 | { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
859 | .driver_data = sony_C_events, | 900 | { 0x83, SONYPI_EVENT_PKEY_P2 }, |
860 | .matches = { | 901 | { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
861 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 902 | { 0x84, SONYPI_EVENT_PKEY_P3 }, |
862 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"), | 903 | { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
863 | }, | 904 | { 0x85, SONYPI_EVENT_PKEY_P4 }, |
864 | }, | 905 | { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
865 | { | 906 | { 0x86, SONYPI_EVENT_PKEY_P5 }, |
866 | .ident = "Sony Vaio FZ Series", | 907 | { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
867 | .callback = sony_nc_C_enable, | 908 | { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
868 | .driver_data = sony_C_events, | 909 | { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED }, |
869 | .matches = { | 910 | { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED }, |
870 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 911 | { 0, 0 }, |
871 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"), | ||
872 | }, | ||
873 | }, | ||
874 | { | ||
875 | .ident = "Sony Vaio C Series", | ||
876 | .callback = sony_nc_C_enable, | ||
877 | .driver_data = sony_C_events, | ||
878 | .matches = { | ||
879 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
880 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"), | ||
881 | }, | ||
882 | }, | ||
883 | { | ||
884 | .ident = "Sony Vaio N Series", | ||
885 | .callback = sony_nc_C_enable, | ||
886 | .driver_data = sony_C_events, | ||
887 | .matches = { | ||
888 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
889 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"), | ||
890 | }, | ||
891 | }, | ||
892 | { } | ||
893 | }; | 912 | }; |
894 | 913 | ||
895 | /* | 914 | /* |
@@ -897,38 +916,59 @@ static const struct dmi_system_id sony_nc_ids[] = { | |||
897 | */ | 916 | */ |
898 | static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) | 917 | static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) |
899 | { | 918 | { |
900 | struct sony_nc_event *evmap; | ||
901 | u32 ev = event; | 919 | u32 ev = event; |
902 | int result; | ||
903 | 920 | ||
904 | if (ev == 0x92) { | 921 | if (ev >= 0x90) { |
905 | /* read the key pressed from EC.GECR | 922 | /* New-style event */ |
906 | * A call to SN07 with 0x0202 will do it as well respecting | 923 | int result; |
907 | * the current protocol on different OSes | 924 | int key_handle = 0; |
908 | * | 925 | ev -= 0x90; |
909 | * Note: the path for GECR may be | 926 | |
910 | * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends) | 927 | if (sony_find_snc_handle(0x100) == ev) |
911 | * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR) | 928 | key_handle = 0x100; |
912 | * | 929 | if (sony_find_snc_handle(0x127) == ev) |
913 | * TODO: we may want to do the same for the older GHKE -need | 930 | key_handle = 0x127; |
914 | * dmi list- so this snippet may become one more callback. | 931 | |
915 | */ | 932 | if (key_handle) { |
916 | if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0) | 933 | struct sony_nc_event *key_event; |
917 | dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev); | 934 | |
918 | else | 935 | if (sony_call_snc_handle(key_handle, 0x200, &result)) { |
919 | ev = result & 0xFF; | 936 | dprintk("sony_acpi_notify, unable to decode" |
920 | } | 937 | " event 0x%.2x 0x%.2x\n", key_handle, |
938 | ev); | ||
939 | /* restore the original event */ | ||
940 | ev = event; | ||
941 | } else { | ||
942 | ev = result & 0xFF; | ||
943 | |||
944 | if (key_handle == 0x100) | ||
945 | key_event = sony_100_events; | ||
946 | else | ||
947 | key_event = sony_127_events; | ||
948 | |||
949 | for (; key_event->data; key_event++) { | ||
950 | if (key_event->data == ev) { | ||
951 | ev = key_event->event; | ||
952 | break; | ||
953 | } | ||
954 | } | ||
921 | 955 | ||
922 | if (sony_nc_events) | 956 | if (!key_event->data) |
923 | for (evmap = sony_nc_events; evmap->event; evmap++) { | 957 | printk(KERN_INFO DRV_PFX |
924 | if (evmap->data == ev) { | 958 | "Unknown event: 0x%x 0x%x\n", |
925 | ev = evmap->event; | 959 | key_handle, |
926 | break; | 960 | ev); |
961 | else | ||
962 | sony_laptop_report_input_event(ev); | ||
927 | } | 963 | } |
964 | } else if (sony_find_snc_handle(0x124) == ev) { | ||
965 | sony_nc_rfkill_update(); | ||
966 | return; | ||
928 | } | 967 | } |
968 | } else | ||
969 | sony_laptop_report_input_event(ev); | ||
929 | 970 | ||
930 | dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); | 971 | dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); |
931 | sony_laptop_report_input_event(ev); | ||
932 | acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev); | 972 | acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev); |
933 | } | 973 | } |
934 | 974 | ||
@@ -953,9 +993,25 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, | |||
953 | /* | 993 | /* |
954 | * ACPI device | 994 | * ACPI device |
955 | */ | 995 | */ |
996 | static int sony_nc_function_setup(struct acpi_device *device) | ||
997 | { | ||
998 | int result; | ||
999 | |||
1000 | /* Enable all events */ | ||
1001 | acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result); | ||
1002 | |||
1003 | /* Setup hotkeys */ | ||
1004 | sony_call_snc_handle(0x0100, 0, &result); | ||
1005 | sony_call_snc_handle(0x0101, 0, &result); | ||
1006 | sony_call_snc_handle(0x0102, 0x100, &result); | ||
1007 | |||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
956 | static int sony_nc_resume(struct acpi_device *device) | 1011 | static int sony_nc_resume(struct acpi_device *device) |
957 | { | 1012 | { |
958 | struct sony_nc_value *item; | 1013 | struct sony_nc_value *item; |
1014 | acpi_handle handle; | ||
959 | 1015 | ||
960 | for (item = sony_nc_values; item->name; item++) { | 1016 | for (item = sony_nc_values; item->name; item++) { |
961 | int ret; | 1017 | int ret; |
@@ -970,13 +1026,188 @@ static int sony_nc_resume(struct acpi_device *device) | |||
970 | } | 1026 | } |
971 | } | 1027 | } |
972 | 1028 | ||
1029 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", | ||
1030 | &handle))) { | ||
1031 | if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) | ||
1032 | dprintk("ECON Method failed\n"); | ||
1033 | } | ||
1034 | |||
1035 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", | ||
1036 | &handle))) { | ||
1037 | dprintk("Doing SNC setup\n"); | ||
1038 | sony_nc_function_setup(device); | ||
1039 | } | ||
1040 | |||
973 | /* set the last requested brightness level */ | 1041 | /* set the last requested brightness level */ |
974 | if (sony_backlight_device && | 1042 | if (sony_backlight_device && |
975 | !sony_backlight_update_status(sony_backlight_device)) | 1043 | !sony_backlight_update_status(sony_backlight_device)) |
976 | printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); | 1044 | printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); |
977 | 1045 | ||
978 | /* re-initialize models with specific requirements */ | 1046 | return 0; |
979 | dmi_check_system(sony_nc_ids); | 1047 | } |
1048 | |||
1049 | static void sony_nc_rfkill_cleanup(void) | ||
1050 | { | ||
1051 | int i; | ||
1052 | |||
1053 | for (i = 0; i < SONY_RFKILL_MAX; i++) { | ||
1054 | if (sony_rfkill_devices[i]) | ||
1055 | rfkill_unregister(sony_rfkill_devices[i]); | ||
1056 | } | ||
1057 | } | ||
1058 | |||
1059 | static int sony_nc_rfkill_get(void *data, enum rfkill_state *state) | ||
1060 | { | ||
1061 | int result; | ||
1062 | int argument = sony_rfkill_address[(long) data]; | ||
1063 | |||
1064 | sony_call_snc_handle(0x124, 0x200, &result); | ||
1065 | if (result & 0x1) { | ||
1066 | sony_call_snc_handle(0x124, argument, &result); | ||
1067 | if (result & 0xf) | ||
1068 | *state = RFKILL_STATE_UNBLOCKED; | ||
1069 | else | ||
1070 | *state = RFKILL_STATE_SOFT_BLOCKED; | ||
1071 | } else { | ||
1072 | *state = RFKILL_STATE_HARD_BLOCKED; | ||
1073 | } | ||
1074 | |||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | static int sony_nc_rfkill_set(void *data, enum rfkill_state state) | ||
1079 | { | ||
1080 | int result; | ||
1081 | int argument = sony_rfkill_address[(long) data] + 0x100; | ||
1082 | |||
1083 | if (state == RFKILL_STATE_UNBLOCKED) | ||
1084 | argument |= 0xff0000; | ||
1085 | |||
1086 | return sony_call_snc_handle(0x124, argument, &result); | ||
1087 | } | ||
1088 | |||
1089 | static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) | ||
1090 | { | ||
1091 | int err = 0; | ||
1092 | struct rfkill *sony_wifi_rfkill; | ||
1093 | |||
1094 | sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); | ||
1095 | if (!sony_wifi_rfkill) | ||
1096 | return -1; | ||
1097 | sony_wifi_rfkill->name = "sony-wifi"; | ||
1098 | sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set; | ||
1099 | sony_wifi_rfkill->get_state = sony_nc_rfkill_get; | ||
1100 | sony_wifi_rfkill->user_claim_unsupported = 1; | ||
1101 | sony_wifi_rfkill->data = (void *)SONY_WIFI; | ||
1102 | err = rfkill_register(sony_wifi_rfkill); | ||
1103 | if (err) | ||
1104 | rfkill_free(sony_wifi_rfkill); | ||
1105 | else | ||
1106 | sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill; | ||
1107 | return err; | ||
1108 | } | ||
1109 | |||
1110 | static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) | ||
1111 | { | ||
1112 | int err = 0; | ||
1113 | struct rfkill *sony_bluetooth_rfkill; | ||
1114 | |||
1115 | sony_bluetooth_rfkill = rfkill_allocate(&device->dev, | ||
1116 | RFKILL_TYPE_BLUETOOTH); | ||
1117 | if (!sony_bluetooth_rfkill) | ||
1118 | return -1; | ||
1119 | sony_bluetooth_rfkill->name = "sony-bluetooth"; | ||
1120 | sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set; | ||
1121 | sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get; | ||
1122 | sony_bluetooth_rfkill->user_claim_unsupported = 1; | ||
1123 | sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH; | ||
1124 | err = rfkill_register(sony_bluetooth_rfkill); | ||
1125 | if (err) | ||
1126 | rfkill_free(sony_bluetooth_rfkill); | ||
1127 | else | ||
1128 | sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; | ||
1129 | return err; | ||
1130 | } | ||
1131 | |||
1132 | static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) | ||
1133 | { | ||
1134 | int err = 0; | ||
1135 | struct rfkill *sony_wwan_rfkill; | ||
1136 | |||
1137 | sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); | ||
1138 | if (!sony_wwan_rfkill) | ||
1139 | return -1; | ||
1140 | sony_wwan_rfkill->name = "sony-wwan"; | ||
1141 | sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set; | ||
1142 | sony_wwan_rfkill->get_state = sony_nc_rfkill_get; | ||
1143 | sony_wwan_rfkill->user_claim_unsupported = 1; | ||
1144 | sony_wwan_rfkill->data = (void *)SONY_WWAN; | ||
1145 | err = rfkill_register(sony_wwan_rfkill); | ||
1146 | if (err) | ||
1147 | rfkill_free(sony_wwan_rfkill); | ||
1148 | else | ||
1149 | sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill; | ||
1150 | return err; | ||
1151 | } | ||
1152 | |||
1153 | static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) | ||
1154 | { | ||
1155 | int err = 0; | ||
1156 | struct rfkill *sony_wimax_rfkill; | ||
1157 | |||
1158 | sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX); | ||
1159 | if (!sony_wimax_rfkill) | ||
1160 | return -1; | ||
1161 | sony_wimax_rfkill->name = "sony-wimax"; | ||
1162 | sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set; | ||
1163 | sony_wimax_rfkill->get_state = sony_nc_rfkill_get; | ||
1164 | sony_wimax_rfkill->user_claim_unsupported = 1; | ||
1165 | sony_wimax_rfkill->data = (void *)SONY_WIMAX; | ||
1166 | err = rfkill_register(sony_wimax_rfkill); | ||
1167 | if (err) | ||
1168 | rfkill_free(sony_wimax_rfkill); | ||
1169 | else | ||
1170 | sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill; | ||
1171 | return err; | ||
1172 | } | ||
1173 | |||
1174 | static void sony_nc_rfkill_update() | ||
1175 | { | ||
1176 | int i; | ||
1177 | enum rfkill_state state; | ||
1178 | |||
1179 | for (i = 0; i < SONY_RFKILL_MAX; i++) { | ||
1180 | if (sony_rfkill_devices[i]) { | ||
1181 | sony_rfkill_devices[i]-> | ||
1182 | get_state(sony_rfkill_devices[i]->data, | ||
1183 | &state); | ||
1184 | rfkill_force_state(sony_rfkill_devices[i], state); | ||
1185 | } | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | static int sony_nc_rfkill_setup(struct acpi_device *device) | ||
1190 | { | ||
1191 | int result, ret; | ||
1192 | |||
1193 | if (sony_find_snc_handle(0x124) == -1) | ||
1194 | return -1; | ||
1195 | |||
1196 | ret = sony_call_snc_handle(0x124, 0xb00, &result); | ||
1197 | if (ret) { | ||
1198 | printk(KERN_INFO DRV_PFX | ||
1199 | "Unable to enumerate rfkill devices: %x\n", ret); | ||
1200 | return ret; | ||
1201 | } | ||
1202 | |||
1203 | if (result & 0x1) | ||
1204 | sony_nc_setup_wifi_rfkill(device); | ||
1205 | if (result & 0x2) | ||
1206 | sony_nc_setup_bluetooth_rfkill(device); | ||
1207 | if (result & 0x1c) | ||
1208 | sony_nc_setup_wwan_rfkill(device); | ||
1209 | if (result & 0x20) | ||
1210 | sony_nc_setup_wimax_rfkill(device); | ||
980 | 1211 | ||
981 | return 0; | 1212 | return 0; |
982 | } | 1213 | } |
@@ -1024,11 +1255,24 @@ static int sony_nc_add(struct acpi_device *device) | |||
1024 | dprintk("_INI Method failed\n"); | 1255 | dprintk("_INI Method failed\n"); |
1025 | } | 1256 | } |
1026 | 1257 | ||
1258 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", | ||
1259 | &handle))) { | ||
1260 | if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) | ||
1261 | dprintk("ECON Method failed\n"); | ||
1262 | } | ||
1263 | |||
1264 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", | ||
1265 | &handle))) { | ||
1266 | dprintk("Doing SNC setup\n"); | ||
1267 | sony_nc_function_setup(device); | ||
1268 | sony_nc_rfkill_setup(device); | ||
1269 | } | ||
1270 | |||
1027 | /* setup input devices and helper fifo */ | 1271 | /* setup input devices and helper fifo */ |
1028 | result = sony_laptop_setup_input(device); | 1272 | result = sony_laptop_setup_input(device); |
1029 | if (result) { | 1273 | if (result) { |
1030 | printk(KERN_ERR DRV_PFX | 1274 | printk(KERN_ERR DRV_PFX |
1031 | "Unabe to create input devices.\n"); | 1275 | "Unable to create input devices.\n"); |
1032 | goto outwalk; | 1276 | goto outwalk; |
1033 | } | 1277 | } |
1034 | 1278 | ||
@@ -1063,9 +1307,6 @@ static int sony_nc_add(struct acpi_device *device) | |||
1063 | 1307 | ||
1064 | } | 1308 | } |
1065 | 1309 | ||
1066 | /* initialize models with specific requirements */ | ||
1067 | dmi_check_system(sony_nc_ids); | ||
1068 | |||
1069 | result = sony_pf_add(); | 1310 | result = sony_pf_add(); |
1070 | if (result) | 1311 | if (result) |
1071 | goto outbacklight; | 1312 | goto outbacklight; |
@@ -1131,6 +1372,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
1131 | sony_laptop_remove_input(); | 1372 | sony_laptop_remove_input(); |
1132 | 1373 | ||
1133 | outwalk: | 1374 | outwalk: |
1375 | sony_nc_rfkill_cleanup(); | ||
1134 | return result; | 1376 | return result; |
1135 | } | 1377 | } |
1136 | 1378 | ||
@@ -1156,6 +1398,7 @@ static int sony_nc_remove(struct acpi_device *device, int type) | |||
1156 | 1398 | ||
1157 | sony_pf_remove(); | 1399 | sony_pf_remove(); |
1158 | sony_laptop_remove_input(); | 1400 | sony_laptop_remove_input(); |
1401 | sony_nc_rfkill_cleanup(); | ||
1159 | dprintk(SONY_NC_DRIVER_NAME " removed.\n"); | 1402 | dprintk(SONY_NC_DRIVER_NAME " removed.\n"); |
1160 | 1403 | ||
1161 | return 0; | 1404 | return 0; |
@@ -1195,7 +1438,6 @@ static struct acpi_driver sony_nc_driver = { | |||
1195 | #define SONYPI_TYPE1_OFFSET 0x04 | 1438 | #define SONYPI_TYPE1_OFFSET 0x04 |
1196 | #define SONYPI_TYPE2_OFFSET 0x12 | 1439 | #define SONYPI_TYPE2_OFFSET 0x12 |
1197 | #define SONYPI_TYPE3_OFFSET 0x12 | 1440 | #define SONYPI_TYPE3_OFFSET 0x12 |
1198 | #define SONYPI_TYPE4_OFFSET 0x12 | ||
1199 | 1441 | ||
1200 | struct sony_pic_ioport { | 1442 | struct sony_pic_ioport { |
1201 | struct acpi_resource_io io1; | 1443 | struct acpi_resource_io io1; |
@@ -1328,6 +1570,7 @@ static struct sonypi_event sonypi_pkeyev[] = { | |||
1328 | { 0x01, SONYPI_EVENT_PKEY_P1 }, | 1570 | { 0x01, SONYPI_EVENT_PKEY_P1 }, |
1329 | { 0x02, SONYPI_EVENT_PKEY_P2 }, | 1571 | { 0x02, SONYPI_EVENT_PKEY_P2 }, |
1330 | { 0x04, SONYPI_EVENT_PKEY_P3 }, | 1572 | { 0x04, SONYPI_EVENT_PKEY_P3 }, |
1573 | { 0x20, SONYPI_EVENT_PKEY_P1 }, | ||
1331 | { 0, 0 } | 1574 | { 0, 0 } |
1332 | }; | 1575 | }; |
1333 | 1576 | ||
@@ -1371,6 +1614,7 @@ static struct sonypi_event sonypi_zoomev[] = { | |||
1371 | { 0x39, SONYPI_EVENT_ZOOM_PRESSED }, | 1614 | { 0x39, SONYPI_EVENT_ZOOM_PRESSED }, |
1372 | { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED }, | 1615 | { 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED }, |
1373 | { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED }, | 1616 | { 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED }, |
1617 | { 0x04, SONYPI_EVENT_ZOOM_PRESSED }, | ||
1374 | { 0, 0 } | 1618 | { 0, 0 } |
1375 | }; | 1619 | }; |
1376 | 1620 | ||
@@ -1401,6 +1645,19 @@ static struct sonypi_event sonypi_batteryev[] = { | |||
1401 | { 0, 0 } | 1645 | { 0, 0 } |
1402 | }; | 1646 | }; |
1403 | 1647 | ||
1648 | /* The set of possible volume events */ | ||
1649 | static struct sonypi_event sonypi_volumeev[] = { | ||
1650 | { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED }, | ||
1651 | { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED }, | ||
1652 | { 0, 0 } | ||
1653 | }; | ||
1654 | |||
1655 | /* The set of possible brightness events */ | ||
1656 | static struct sonypi_event sonypi_brightnessev[] = { | ||
1657 | { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED }, | ||
1658 | { 0, 0 } | ||
1659 | }; | ||
1660 | |||
1404 | static struct sonypi_eventtypes type1_events[] = { | 1661 | static struct sonypi_eventtypes type1_events[] = { |
1405 | { 0, 0xffffffff, sonypi_releaseev }, | 1662 | { 0, 0xffffffff, sonypi_releaseev }, |
1406 | { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev }, | 1663 | { 0x70, SONYPI_MEYE_MASK, sonypi_meyeev }, |
@@ -1438,17 +1695,11 @@ static struct sonypi_eventtypes type3_events[] = { | |||
1438 | { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, | 1695 | { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, |
1439 | { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, | 1696 | { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, |
1440 | { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, | 1697 | { 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev }, |
1441 | { 0 }, | ||
1442 | }; | ||
1443 | static struct sonypi_eventtypes type4_events[] = { | ||
1444 | { 0, 0xffffffff, sonypi_releaseev }, | ||
1445 | { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev }, | ||
1446 | { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev }, | ||
1447 | { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev }, | ||
1448 | { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev }, | ||
1449 | { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev }, | 1698 | { 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev }, |
1450 | { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev }, | 1699 | { 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev }, |
1451 | { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev }, | 1700 | { 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev }, |
1701 | { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev }, | ||
1702 | { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev }, | ||
1452 | { 0 }, | 1703 | { 0 }, |
1453 | }; | 1704 | }; |
1454 | 1705 | ||
@@ -1511,11 +1762,11 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) | |||
1511 | /* | 1762 | /* |
1512 | * minidrivers for SPIC models | 1763 | * minidrivers for SPIC models |
1513 | */ | 1764 | */ |
1514 | static int type4_handle_irq(const u8 data_mask, const u8 ev) | 1765 | static int type3_handle_irq(const u8 data_mask, const u8 ev) |
1515 | { | 1766 | { |
1516 | /* | 1767 | /* |
1517 | * 0x31 could mean we have to take some extra action and wait for | 1768 | * 0x31 could mean we have to take some extra action and wait for |
1518 | * the next irq for some Type4 models, it will generate a new | 1769 | * the next irq for some Type3 models, it will generate a new |
1519 | * irq and we can read new data from the device: | 1770 | * irq and we can read new data from the device: |
1520 | * - 0x5c and 0x5f requires 0xA0 | 1771 | * - 0x5c and 0x5f requires 0xA0 |
1521 | * - 0x61 requires 0xB3 | 1772 | * - 0x61 requires 0xB3 |
@@ -1545,16 +1796,10 @@ static struct device_ctrl spic_types[] = { | |||
1545 | }, | 1796 | }, |
1546 | { | 1797 | { |
1547 | .model = SONYPI_DEVICE_TYPE3, | 1798 | .model = SONYPI_DEVICE_TYPE3, |
1548 | .handle_irq = NULL, | 1799 | .handle_irq = type3_handle_irq, |
1549 | .evport_offset = SONYPI_TYPE3_OFFSET, | 1800 | .evport_offset = SONYPI_TYPE3_OFFSET, |
1550 | .event_types = type3_events, | 1801 | .event_types = type3_events, |
1551 | }, | 1802 | }, |
1552 | { | ||
1553 | .model = SONYPI_DEVICE_TYPE4, | ||
1554 | .handle_irq = type4_handle_irq, | ||
1555 | .evport_offset = SONYPI_TYPE4_OFFSET, | ||
1556 | .event_types = type4_events, | ||
1557 | }, | ||
1558 | }; | 1803 | }; |
1559 | 1804 | ||
1560 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | 1805 | static void sony_pic_detect_device_type(struct sony_pic_dev *dev) |
@@ -1578,14 +1823,21 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev) | |||
1578 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1823 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1579 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL); | 1824 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL); |
1580 | if (pcidev) { | 1825 | if (pcidev) { |
1581 | dev->control = &spic_types[3]; | 1826 | dev->control = &spic_types[2]; |
1582 | goto out; | 1827 | goto out; |
1583 | } | 1828 | } |
1584 | 1829 | ||
1585 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1830 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1586 | PCI_DEVICE_ID_INTEL_ICH8_4, NULL); | 1831 | PCI_DEVICE_ID_INTEL_ICH8_4, NULL); |
1587 | if (pcidev) { | 1832 | if (pcidev) { |
1588 | dev->control = &spic_types[3]; | 1833 | dev->control = &spic_types[2]; |
1834 | goto out; | ||
1835 | } | ||
1836 | |||
1837 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
1838 | PCI_DEVICE_ID_INTEL_ICH9_1, NULL); | ||
1839 | if (pcidev) { | ||
1840 | dev->control = &spic_types[2]; | ||
1589 | goto out; | 1841 | goto out; |
1590 | } | 1842 | } |
1591 | 1843 | ||
@@ -1598,8 +1850,7 @@ out: | |||
1598 | 1850 | ||
1599 | printk(KERN_INFO DRV_PFX "detected Type%d model\n", | 1851 | printk(KERN_INFO DRV_PFX "detected Type%d model\n", |
1600 | dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : | 1852 | dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : |
1601 | dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : | 1853 | dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); |
1602 | dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4); | ||
1603 | } | 1854 | } |
1604 | 1855 | ||
1605 | /* camera tests and poweron/poweroff */ | 1856 | /* camera tests and poweron/poweroff */ |
@@ -1754,17 +2005,14 @@ int sony_pic_camera_command(int command, u8 value) | |||
1754 | EXPORT_SYMBOL(sony_pic_camera_command); | 2005 | EXPORT_SYMBOL(sony_pic_camera_command); |
1755 | 2006 | ||
1756 | /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */ | 2007 | /* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */ |
1757 | static void sony_pic_set_wwanpower(u8 state) | 2008 | static void __sony_pic_set_wwanpower(u8 state) |
1758 | { | 2009 | { |
1759 | state = !!state; | 2010 | state = !!state; |
1760 | mutex_lock(&spic_dev.lock); | 2011 | if (spic_dev.wwan_power == state) |
1761 | if (spic_dev.wwan_power == state) { | ||
1762 | mutex_unlock(&spic_dev.lock); | ||
1763 | return; | 2012 | return; |
1764 | } | ||
1765 | sony_pic_call2(0xB0, state); | 2013 | sony_pic_call2(0xB0, state); |
2014 | sony_pic_call1(0x82); | ||
1766 | spic_dev.wwan_power = state; | 2015 | spic_dev.wwan_power = state; |
1767 | mutex_unlock(&spic_dev.lock); | ||
1768 | } | 2016 | } |
1769 | 2017 | ||
1770 | static ssize_t sony_pic_wwanpower_store(struct device *dev, | 2018 | static ssize_t sony_pic_wwanpower_store(struct device *dev, |
@@ -1776,7 +2024,9 @@ static ssize_t sony_pic_wwanpower_store(struct device *dev, | |||
1776 | return -EINVAL; | 2024 | return -EINVAL; |
1777 | 2025 | ||
1778 | value = simple_strtoul(buffer, NULL, 10); | 2026 | value = simple_strtoul(buffer, NULL, 10); |
1779 | sony_pic_set_wwanpower(value); | 2027 | mutex_lock(&spic_dev.lock); |
2028 | __sony_pic_set_wwanpower(value); | ||
2029 | mutex_unlock(&spic_dev.lock); | ||
1780 | 2030 | ||
1781 | return count; | 2031 | return count; |
1782 | } | 2032 | } |
@@ -1934,10 +2184,15 @@ static int sonypi_misc_release(struct inode *inode, struct file *file) | |||
1934 | static int sonypi_misc_open(struct inode *inode, struct file *file) | 2184 | static int sonypi_misc_open(struct inode *inode, struct file *file) |
1935 | { | 2185 | { |
1936 | /* Flush input queue on first open */ | 2186 | /* Flush input queue on first open */ |
1937 | lock_kernel(); | 2187 | unsigned long flags; |
2188 | |||
2189 | spin_lock_irqsave(sonypi_compat.fifo->lock, flags); | ||
2190 | |||
1938 | if (atomic_inc_return(&sonypi_compat.open_count) == 1) | 2191 | if (atomic_inc_return(&sonypi_compat.open_count) == 1) |
1939 | kfifo_reset(sonypi_compat.fifo); | 2192 | __kfifo_reset(sonypi_compat.fifo); |
1940 | unlock_kernel(); | 2193 | |
2194 | spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags); | ||
2195 | |||
1941 | return 0; | 2196 | return 0; |
1942 | } | 2197 | } |
1943 | 2198 | ||
@@ -1990,8 +2245,8 @@ static int ec_read16(u8 addr, u16 *value) | |||
1990 | return 0; | 2245 | return 0; |
1991 | } | 2246 | } |
1992 | 2247 | ||
1993 | static int sonypi_misc_ioctl(struct inode *ip, struct file *fp, | 2248 | static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, |
1994 | unsigned int cmd, unsigned long arg) | 2249 | unsigned long arg) |
1995 | { | 2250 | { |
1996 | int ret = 0; | 2251 | int ret = 0; |
1997 | void __user *argp = (void __user *)arg; | 2252 | void __user *argp = (void __user *)arg; |
@@ -2125,7 +2380,7 @@ static const struct file_operations sonypi_misc_fops = { | |||
2125 | .open = sonypi_misc_open, | 2380 | .open = sonypi_misc_open, |
2126 | .release = sonypi_misc_release, | 2381 | .release = sonypi_misc_release, |
2127 | .fasync = sonypi_misc_fasync, | 2382 | .fasync = sonypi_misc_fasync, |
2128 | .ioctl = sonypi_misc_ioctl, | 2383 | .unlocked_ioctl = sonypi_misc_ioctl, |
2129 | }; | 2384 | }; |
2130 | 2385 | ||
2131 | static struct miscdevice sonypi_misc_device = { | 2386 | static struct miscdevice sonypi_misc_device = { |
@@ -2566,7 +2821,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
2566 | result = sony_pic_possible_resources(device); | 2821 | result = sony_pic_possible_resources(device); |
2567 | if (result) { | 2822 | if (result) { |
2568 | printk(KERN_ERR DRV_PFX | 2823 | printk(KERN_ERR DRV_PFX |
2569 | "Unabe to read possible resources.\n"); | 2824 | "Unable to read possible resources.\n"); |
2570 | goto err_free_resources; | 2825 | goto err_free_resources; |
2571 | } | 2826 | } |
2572 | 2827 | ||
@@ -2574,7 +2829,7 @@ static int sony_pic_add(struct acpi_device *device) | |||
2574 | result = sony_laptop_setup_input(device); | 2829 | result = sony_laptop_setup_input(device); |
2575 | if (result) { | 2830 | if (result) { |
2576 | printk(KERN_ERR DRV_PFX | 2831 | printk(KERN_ERR DRV_PFX |
2577 | "Unabe to create input devices.\n"); | 2832 | "Unable to create input devices.\n"); |
2578 | goto err_free_resources; | 2833 | goto err_free_resources; |
2579 | } | 2834 | } |
2580 | 2835 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d2433204a40c..ba3682c5cde0 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * | 4 | * |
5 | * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> | 5 | * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> |
6 | * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 6 | * Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -22,7 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define TPACPI_VERSION "0.22" | 24 | #define TPACPI_VERSION "0.22" |
25 | #define TPACPI_SYSFS_VERSION 0x020200 | 25 | #define TPACPI_SYSFS_VERSION 0x020300 |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * Changelog: | 28 | * Changelog: |
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/string.h> | 54 | #include <linux/string.h> |
55 | #include <linux/list.h> | 55 | #include <linux/list.h> |
56 | #include <linux/mutex.h> | 56 | #include <linux/mutex.h> |
57 | #include <linux/sched.h> | ||
57 | #include <linux/kthread.h> | 58 | #include <linux/kthread.h> |
58 | #include <linux/freezer.h> | 59 | #include <linux/freezer.h> |
59 | #include <linux/delay.h> | 60 | #include <linux/delay.h> |
@@ -172,29 +173,26 @@ enum { | |||
172 | TPACPI_RFK_UWB_SW_ID, | 173 | TPACPI_RFK_UWB_SW_ID, |
173 | }; | 174 | }; |
174 | 175 | ||
175 | /* Debugging */ | 176 | /* printk headers */ |
176 | #define TPACPI_LOG TPACPI_FILE ": " | 177 | #define TPACPI_LOG TPACPI_FILE ": " |
177 | #define TPACPI_ALERT KERN_ALERT TPACPI_LOG | 178 | #define TPACPI_EMERG KERN_EMERG TPACPI_LOG |
178 | #define TPACPI_CRIT KERN_CRIT TPACPI_LOG | 179 | #define TPACPI_ALERT KERN_ALERT TPACPI_LOG |
179 | #define TPACPI_ERR KERN_ERR TPACPI_LOG | 180 | #define TPACPI_CRIT KERN_CRIT TPACPI_LOG |
180 | #define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG | 181 | #define TPACPI_ERR KERN_ERR TPACPI_LOG |
181 | #define TPACPI_INFO KERN_INFO TPACPI_LOG | 182 | #define TPACPI_WARN KERN_WARNING TPACPI_LOG |
182 | #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG | 183 | #define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG |
183 | 184 | #define TPACPI_INFO KERN_INFO TPACPI_LOG | |
185 | #define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG | ||
186 | |||
187 | /* Debugging printk groups */ | ||
184 | #define TPACPI_DBG_ALL 0xffff | 188 | #define TPACPI_DBG_ALL 0xffff |
189 | #define TPACPI_DBG_DISCLOSETASK 0x8000 | ||
185 | #define TPACPI_DBG_INIT 0x0001 | 190 | #define TPACPI_DBG_INIT 0x0001 |
186 | #define TPACPI_DBG_EXIT 0x0002 | 191 | #define TPACPI_DBG_EXIT 0x0002 |
187 | #define dbg_printk(a_dbg_level, format, arg...) \ | 192 | #define TPACPI_DBG_RFKILL 0x0004 |
188 | do { if (dbg_level & a_dbg_level) \ | 193 | #define TPACPI_DBG_HKEY 0x0008 |
189 | printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ | 194 | #define TPACPI_DBG_FAN 0x0010 |
190 | } while (0) | 195 | #define TPACPI_DBG_BRGHT 0x0020 |
191 | #ifdef CONFIG_THINKPAD_ACPI_DEBUG | ||
192 | #define vdbg_printk(a_dbg_level, format, arg...) \ | ||
193 | dbg_printk(a_dbg_level, format, ## arg) | ||
194 | static const char *str_supported(int is_supported); | ||
195 | #else | ||
196 | #define vdbg_printk(a_dbg_level, format, arg...) | ||
197 | #endif | ||
198 | 196 | ||
199 | #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") | 197 | #define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off") |
200 | #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") | 198 | #define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") |
@@ -277,7 +275,6 @@ static struct { | |||
277 | 275 | ||
278 | static struct { | 276 | static struct { |
279 | u16 hotkey_mask_ff:1; | 277 | u16 hotkey_mask_ff:1; |
280 | u16 bright_cmos_ec_unsync:1; | ||
281 | } tp_warned; | 278 | } tp_warned; |
282 | 279 | ||
283 | struct thinkpad_id_data { | 280 | struct thinkpad_id_data { |
@@ -326,6 +323,39 @@ static int tpacpi_uwb_emulstate; | |||
326 | #endif | 323 | #endif |
327 | 324 | ||
328 | 325 | ||
326 | /************************************************************************* | ||
327 | * Debugging helpers | ||
328 | */ | ||
329 | |||
330 | #define dbg_printk(a_dbg_level, format, arg...) \ | ||
331 | do { if (dbg_level & (a_dbg_level)) \ | ||
332 | printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \ | ||
333 | } while (0) | ||
334 | |||
335 | #ifdef CONFIG_THINKPAD_ACPI_DEBUG | ||
336 | #define vdbg_printk dbg_printk | ||
337 | static const char *str_supported(int is_supported); | ||
338 | #else | ||
339 | #define vdbg_printk(a_dbg_level, format, arg...) \ | ||
340 | do { } while (0) | ||
341 | #endif | ||
342 | |||
343 | static void tpacpi_log_usertask(const char * const what) | ||
344 | { | ||
345 | printk(TPACPI_DEBUG "%s: access by process with PID %d\n", | ||
346 | what, task_tgid_vnr(current)); | ||
347 | } | ||
348 | |||
349 | #define tpacpi_disclose_usertask(what, format, arg...) \ | ||
350 | do { \ | ||
351 | if (unlikely( \ | ||
352 | (dbg_level & TPACPI_DBG_DISCLOSETASK) && \ | ||
353 | (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \ | ||
354 | printk(TPACPI_DEBUG "%s: PID %d: " format, \ | ||
355 | what, task_tgid_vnr(current), ## arg); \ | ||
356 | } \ | ||
357 | } while (0) | ||
358 | |||
329 | /**************************************************************************** | 359 | /**************************************************************************** |
330 | **************************************************************************** | 360 | **************************************************************************** |
331 | * | 361 | * |
@@ -989,10 +1019,13 @@ static int __init tpacpi_new_rfkill(const unsigned int id, | |||
989 | /* try to set the initial state as the default for the rfkill | 1019 | /* try to set the initial state as the default for the rfkill |
990 | * type, since we ask the firmware to preserve it across S5 in | 1020 | * type, since we ask the firmware to preserve it across S5 in |
991 | * NVRAM */ | 1021 | * NVRAM */ |
992 | rfkill_set_default(rfktype, | 1022 | if (rfkill_set_default(rfktype, |
993 | (initial_state == RFKILL_STATE_UNBLOCKED) ? | 1023 | (initial_state == RFKILL_STATE_UNBLOCKED) ? |
994 | RFKILL_STATE_UNBLOCKED : | 1024 | RFKILL_STATE_UNBLOCKED : |
995 | RFKILL_STATE_SOFT_BLOCKED); | 1025 | RFKILL_STATE_SOFT_BLOCKED) == -EPERM) |
1026 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
1027 | "Default state for %s cannot be changed\n", | ||
1028 | name); | ||
996 | } | 1029 | } |
997 | 1030 | ||
998 | *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); | 1031 | *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); |
@@ -1020,6 +1053,21 @@ static int __init tpacpi_new_rfkill(const unsigned int id, | |||
1020 | return 0; | 1053 | return 0; |
1021 | } | 1054 | } |
1022 | 1055 | ||
1056 | static void printk_deprecated_attribute(const char * const what, | ||
1057 | const char * const details) | ||
1058 | { | ||
1059 | tpacpi_log_usertask("deprecated sysfs attribute"); | ||
1060 | printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " | ||
1061 | "will be removed. %s\n", | ||
1062 | what, details); | ||
1063 | } | ||
1064 | |||
1065 | static void printk_deprecated_rfkill_attribute(const char * const what) | ||
1066 | { | ||
1067 | printk_deprecated_attribute(what, | ||
1068 | "Please switch to generic rfkill before year 2010"); | ||
1069 | } | ||
1070 | |||
1023 | /************************************************************************* | 1071 | /************************************************************************* |
1024 | * thinkpad-acpi driver attributes | 1072 | * thinkpad-acpi driver attributes |
1025 | */ | 1073 | */ |
@@ -1382,7 +1430,6 @@ static enum { /* Reasons for waking up */ | |||
1382 | 1430 | ||
1383 | static int hotkey_autosleep_ack; | 1431 | static int hotkey_autosleep_ack; |
1384 | 1432 | ||
1385 | static int hotkey_orig_status; | ||
1386 | static u32 hotkey_orig_mask; | 1433 | static u32 hotkey_orig_mask; |
1387 | static u32 hotkey_all_mask; | 1434 | static u32 hotkey_all_mask; |
1388 | static u32 hotkey_reserved_mask; | 1435 | static u32 hotkey_reserved_mask; |
@@ -1529,9 +1576,9 @@ static int hotkey_status_get(int *status) | |||
1529 | return 0; | 1576 | return 0; |
1530 | } | 1577 | } |
1531 | 1578 | ||
1532 | static int hotkey_status_set(int status) | 1579 | static int hotkey_status_set(bool enable) |
1533 | { | 1580 | { |
1534 | if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status)) | 1581 | if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0)) |
1535 | return -EIO; | 1582 | return -EIO; |
1536 | 1583 | ||
1537 | return 0; | 1584 | return 0; |
@@ -1847,6 +1894,9 @@ static ssize_t hotkey_enable_show(struct device *dev, | |||
1847 | { | 1894 | { |
1848 | int res, status; | 1895 | int res, status; |
1849 | 1896 | ||
1897 | printk_deprecated_attribute("hotkey_enable", | ||
1898 | "Hotkey reporting is always enabled"); | ||
1899 | |||
1850 | res = hotkey_status_get(&status); | 1900 | res = hotkey_status_get(&status); |
1851 | if (res) | 1901 | if (res) |
1852 | return res; | 1902 | return res; |
@@ -1859,14 +1909,17 @@ static ssize_t hotkey_enable_store(struct device *dev, | |||
1859 | const char *buf, size_t count) | 1909 | const char *buf, size_t count) |
1860 | { | 1910 | { |
1861 | unsigned long t; | 1911 | unsigned long t; |
1862 | int res; | 1912 | |
1913 | printk_deprecated_attribute("hotkey_enable", | ||
1914 | "Hotkeys can be disabled through hotkey_mask"); | ||
1863 | 1915 | ||
1864 | if (parse_strtoul(buf, 1, &t)) | 1916 | if (parse_strtoul(buf, 1, &t)) |
1865 | return -EINVAL; | 1917 | return -EINVAL; |
1866 | 1918 | ||
1867 | res = hotkey_status_set(t); | 1919 | if (t == 0) |
1920 | return -EPERM; | ||
1868 | 1921 | ||
1869 | return (res) ? res : count; | 1922 | return count; |
1870 | } | 1923 | } |
1871 | 1924 | ||
1872 | static struct device_attribute dev_attr_hotkey_enable = | 1925 | static struct device_attribute dev_attr_hotkey_enable = |
@@ -1910,6 +1963,8 @@ static ssize_t hotkey_mask_store(struct device *dev, | |||
1910 | 1963 | ||
1911 | mutex_unlock(&hotkey_mutex); | 1964 | mutex_unlock(&hotkey_mutex); |
1912 | 1965 | ||
1966 | tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t); | ||
1967 | |||
1913 | return (res) ? res : count; | 1968 | return (res) ? res : count; |
1914 | } | 1969 | } |
1915 | 1970 | ||
@@ -1922,7 +1977,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev, | |||
1922 | struct device_attribute *attr, | 1977 | struct device_attribute *attr, |
1923 | char *buf) | 1978 | char *buf) |
1924 | { | 1979 | { |
1925 | return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status); | 1980 | return sprintf(buf, "0\n"); |
1926 | } | 1981 | } |
1927 | 1982 | ||
1928 | static struct device_attribute dev_attr_hotkey_bios_enabled = | 1983 | static struct device_attribute dev_attr_hotkey_bios_enabled = |
@@ -1996,6 +2051,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev, | |||
1996 | 2051 | ||
1997 | mutex_unlock(&hotkey_mutex); | 2052 | mutex_unlock(&hotkey_mutex); |
1998 | 2053 | ||
2054 | tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); | ||
2055 | |||
1999 | return count; | 2056 | return count; |
2000 | } | 2057 | } |
2001 | 2058 | ||
@@ -2028,6 +2085,8 @@ static ssize_t hotkey_poll_freq_store(struct device *dev, | |||
2028 | hotkey_poll_setup(1); | 2085 | hotkey_poll_setup(1); |
2029 | mutex_unlock(&hotkey_mutex); | 2086 | mutex_unlock(&hotkey_mutex); |
2030 | 2087 | ||
2088 | tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t); | ||
2089 | |||
2031 | return count; | 2090 | return count; |
2032 | } | 2091 | } |
2033 | 2092 | ||
@@ -2197,11 +2256,11 @@ static void hotkey_exit(void) | |||
2197 | kfree(hotkey_keycode_map); | 2256 | kfree(hotkey_keycode_map); |
2198 | 2257 | ||
2199 | if (tp_features.hotkey) { | 2258 | if (tp_features.hotkey) { |
2200 | dbg_printk(TPACPI_DBG_EXIT, | 2259 | dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, |
2201 | "restoring original hot key mask\n"); | 2260 | "restoring original hot key mask\n"); |
2202 | /* no short-circuit boolean operator below! */ | 2261 | /* no short-circuit boolean operator below! */ |
2203 | if ((hotkey_mask_set(hotkey_orig_mask) | | 2262 | if ((hotkey_mask_set(hotkey_orig_mask) | |
2204 | hotkey_status_set(hotkey_orig_status)) != 0) | 2263 | hotkey_status_set(false)) != 0) |
2205 | printk(TPACPI_ERR | 2264 | printk(TPACPI_ERR |
2206 | "failed to restore hot key mask " | 2265 | "failed to restore hot key mask " |
2207 | "to BIOS defaults\n"); | 2266 | "to BIOS defaults\n"); |
@@ -2327,7 +2386,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2327 | int status; | 2386 | int status; |
2328 | int hkeyv; | 2387 | int hkeyv; |
2329 | 2388 | ||
2330 | vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); | 2389 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2390 | "initializing hotkey subdriver\n"); | ||
2331 | 2391 | ||
2332 | BUG_ON(!tpacpi_inputdev); | 2392 | BUG_ON(!tpacpi_inputdev); |
2333 | BUG_ON(tpacpi_inputdev->open != NULL || | 2393 | BUG_ON(tpacpi_inputdev->open != NULL || |
@@ -2344,7 +2404,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2344 | /* hotkey not supported on 570 */ | 2404 | /* hotkey not supported on 570 */ |
2345 | tp_features.hotkey = hkey_handle != NULL; | 2405 | tp_features.hotkey = hkey_handle != NULL; |
2346 | 2406 | ||
2347 | vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", | 2407 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2408 | "hotkeys are %s\n", | ||
2348 | str_supported(tp_features.hotkey)); | 2409 | str_supported(tp_features.hotkey)); |
2349 | 2410 | ||
2350 | if (!tp_features.hotkey) | 2411 | if (!tp_features.hotkey) |
@@ -2376,10 +2437,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2376 | * T4x, X31, and later | 2437 | * T4x, X31, and later |
2377 | */ | 2438 | */ |
2378 | tp_features.hotkey_mask = 1; | 2439 | tp_features.hotkey_mask = 1; |
2440 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | ||
2441 | "firmware HKEY interface version: 0x%x\n", | ||
2442 | hkeyv); | ||
2379 | } | 2443 | } |
2380 | } | 2444 | } |
2381 | 2445 | ||
2382 | vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", | 2446 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2447 | "hotkey masks are %s\n", | ||
2383 | str_supported(tp_features.hotkey_mask)); | 2448 | str_supported(tp_features.hotkey_mask)); |
2384 | 2449 | ||
2385 | if (tp_features.hotkey_mask) { | 2450 | if (tp_features.hotkey_mask) { |
@@ -2396,10 +2461,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2396 | 2461 | ||
2397 | /* hotkey_source_mask *must* be zero for | 2462 | /* hotkey_source_mask *must* be zero for |
2398 | * the first hotkey_mask_get */ | 2463 | * the first hotkey_mask_get */ |
2399 | res = hotkey_status_get(&hotkey_orig_status); | ||
2400 | if (res) | ||
2401 | goto err_exit; | ||
2402 | |||
2403 | if (tp_features.hotkey_mask) { | 2464 | if (tp_features.hotkey_mask) { |
2404 | res = hotkey_mask_get(); | 2465 | res = hotkey_mask_get(); |
2405 | if (res) | 2466 | if (res) |
@@ -2422,7 +2483,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2422 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; | 2483 | hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; |
2423 | } | 2484 | } |
2424 | 2485 | ||
2425 | vdbg_printk(TPACPI_DBG_INIT, | 2486 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2426 | "hotkey source mask 0x%08x, polling freq %d\n", | 2487 | "hotkey source mask 0x%08x, polling freq %d\n", |
2427 | hotkey_source_mask, hotkey_poll_freq); | 2488 | hotkey_source_mask, hotkey_poll_freq); |
2428 | #endif | 2489 | #endif |
@@ -2476,12 +2537,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2476 | } | 2537 | } |
2477 | 2538 | ||
2478 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | 2539 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { |
2479 | dbg_printk(TPACPI_DBG_INIT, | 2540 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2480 | "using Lenovo default hot key map\n"); | 2541 | "using Lenovo default hot key map\n"); |
2481 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | 2542 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, |
2482 | TPACPI_HOTKEY_MAP_SIZE); | 2543 | TPACPI_HOTKEY_MAP_SIZE); |
2483 | } else { | 2544 | } else { |
2484 | dbg_printk(TPACPI_DBG_INIT, | 2545 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2485 | "using IBM default hot key map\n"); | 2546 | "using IBM default hot key map\n"); |
2486 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | 2547 | memcpy(hotkey_keycode_map, &ibm_keycode_map, |
2487 | TPACPI_HOTKEY_MAP_SIZE); | 2548 | TPACPI_HOTKEY_MAP_SIZE); |
@@ -2538,8 +2599,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2538 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); | 2599 | | (1 << TP_ACPI_HOTKEYSCAN_FNEND); |
2539 | } | 2600 | } |
2540 | 2601 | ||
2541 | dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); | 2602 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2542 | res = hotkey_status_set(1); | 2603 | "enabling firmware HKEY event interface...\n"); |
2604 | res = hotkey_status_set(true); | ||
2543 | if (res) { | 2605 | if (res) { |
2544 | hotkey_exit(); | 2606 | hotkey_exit(); |
2545 | return res; | 2607 | return res; |
@@ -2552,8 +2614,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
2552 | return res; | 2614 | return res; |
2553 | } | 2615 | } |
2554 | 2616 | ||
2555 | dbg_printk(TPACPI_DBG_INIT, | 2617 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
2556 | "legacy hot key reporting over procfs %s\n", | 2618 | "legacy ibm/hotkey event reporting over procfs %s\n", |
2557 | (hotkey_report_mode < 2) ? | 2619 | (hotkey_report_mode < 2) ? |
2558 | "enabled" : "disabled"); | 2620 | "enabled" : "disabled"); |
2559 | 2621 | ||
@@ -2884,9 +2946,17 @@ static int hotkey_read(char *p) | |||
2884 | return len; | 2946 | return len; |
2885 | } | 2947 | } |
2886 | 2948 | ||
2949 | static void hotkey_enabledisable_warn(void) | ||
2950 | { | ||
2951 | tpacpi_log_usertask("procfs hotkey enable/disable"); | ||
2952 | WARN(1, TPACPI_WARN | ||
2953 | "hotkey enable/disable functionality has been " | ||
2954 | "removed from the driver. Hotkeys are always enabled.\n"); | ||
2955 | } | ||
2956 | |||
2887 | static int hotkey_write(char *buf) | 2957 | static int hotkey_write(char *buf) |
2888 | { | 2958 | { |
2889 | int res, status; | 2959 | int res; |
2890 | u32 mask; | 2960 | u32 mask; |
2891 | char *cmd; | 2961 | char *cmd; |
2892 | 2962 | ||
@@ -2896,17 +2966,16 @@ static int hotkey_write(char *buf) | |||
2896 | if (mutex_lock_killable(&hotkey_mutex)) | 2966 | if (mutex_lock_killable(&hotkey_mutex)) |
2897 | return -ERESTARTSYS; | 2967 | return -ERESTARTSYS; |
2898 | 2968 | ||
2899 | status = -1; | ||
2900 | mask = hotkey_mask; | 2969 | mask = hotkey_mask; |
2901 | 2970 | ||
2902 | res = 0; | 2971 | res = 0; |
2903 | while ((cmd = next_cmd(&buf))) { | 2972 | while ((cmd = next_cmd(&buf))) { |
2904 | if (strlencmp(cmd, "enable") == 0) { | 2973 | if (strlencmp(cmd, "enable") == 0) { |
2905 | status = 1; | 2974 | hotkey_enabledisable_warn(); |
2906 | } else if (strlencmp(cmd, "disable") == 0) { | 2975 | } else if (strlencmp(cmd, "disable") == 0) { |
2907 | status = 0; | 2976 | hotkey_enabledisable_warn(); |
2977 | res = -EPERM; | ||
2908 | } else if (strlencmp(cmd, "reset") == 0) { | 2978 | } else if (strlencmp(cmd, "reset") == 0) { |
2909 | status = hotkey_orig_status; | ||
2910 | mask = hotkey_orig_mask; | 2979 | mask = hotkey_orig_mask; |
2911 | } else if (sscanf(cmd, "0x%x", &mask) == 1) { | 2980 | } else if (sscanf(cmd, "0x%x", &mask) == 1) { |
2912 | /* mask set */ | 2981 | /* mask set */ |
@@ -2917,8 +2986,10 @@ static int hotkey_write(char *buf) | |||
2917 | goto errexit; | 2986 | goto errexit; |
2918 | } | 2987 | } |
2919 | } | 2988 | } |
2920 | if (status != -1) | 2989 | |
2921 | res = hotkey_status_set(status); | 2990 | if (!res) |
2991 | tpacpi_disclose_usertask("procfs hotkey", | ||
2992 | "set mask to 0x%08x\n", mask); | ||
2922 | 2993 | ||
2923 | if (!res && mask != hotkey_mask) | 2994 | if (!res && mask != hotkey_mask) |
2924 | res = hotkey_mask_set(mask); | 2995 | res = hotkey_mask_set(mask); |
@@ -2971,13 +3042,17 @@ enum { | |||
2971 | TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */ | 3042 | TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */ |
2972 | }; | 3043 | }; |
2973 | 3044 | ||
3045 | #define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" | ||
3046 | |||
2974 | static struct rfkill *tpacpi_bluetooth_rfkill; | 3047 | static struct rfkill *tpacpi_bluetooth_rfkill; |
2975 | 3048 | ||
2976 | static void bluetooth_suspend(pm_message_t state) | 3049 | static void bluetooth_suspend(pm_message_t state) |
2977 | { | 3050 | { |
2978 | /* Try to make sure radio will resume powered off */ | 3051 | /* Try to make sure radio will resume powered off */ |
2979 | acpi_evalf(NULL, NULL, "\\BLTH", "vd", | 3052 | if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd", |
2980 | TP_ACPI_BLTH_PWR_OFF_ON_RESUME); | 3053 | TP_ACPI_BLTH_PWR_OFF_ON_RESUME)) |
3054 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3055 | "bluetooth power down on resume request failed\n"); | ||
2981 | } | 3056 | } |
2982 | 3057 | ||
2983 | static int bluetooth_get_radiosw(void) | 3058 | static int bluetooth_get_radiosw(void) |
@@ -3015,6 +3090,10 @@ static void bluetooth_update_rfk(void) | |||
3015 | if (status < 0) | 3090 | if (status < 0) |
3016 | return; | 3091 | return; |
3017 | rfkill_force_state(tpacpi_bluetooth_rfkill, status); | 3092 | rfkill_force_state(tpacpi_bluetooth_rfkill, status); |
3093 | |||
3094 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3095 | "forced rfkill state to %d\n", | ||
3096 | status); | ||
3018 | } | 3097 | } |
3019 | 3098 | ||
3020 | static int bluetooth_set_radiosw(int radio_on, int update_rfk) | 3099 | static int bluetooth_set_radiosw(int radio_on, int update_rfk) |
@@ -3030,6 +3109,9 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk) | |||
3030 | && radio_on) | 3109 | && radio_on) |
3031 | return -EPERM; | 3110 | return -EPERM; |
3032 | 3111 | ||
3112 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3113 | "will %s bluetooth\n", radio_on ? "enable" : "disable"); | ||
3114 | |||
3033 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 3115 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
3034 | if (dbg_bluetoothemul) { | 3116 | if (dbg_bluetoothemul) { |
3035 | tpacpi_bluetooth_emulstate = !!radio_on; | 3117 | tpacpi_bluetooth_emulstate = !!radio_on; |
@@ -3060,6 +3142,8 @@ static ssize_t bluetooth_enable_show(struct device *dev, | |||
3060 | { | 3142 | { |
3061 | int status; | 3143 | int status; |
3062 | 3144 | ||
3145 | printk_deprecated_rfkill_attribute("bluetooth_enable"); | ||
3146 | |||
3063 | status = bluetooth_get_radiosw(); | 3147 | status = bluetooth_get_radiosw(); |
3064 | if (status < 0) | 3148 | if (status < 0) |
3065 | return status; | 3149 | return status; |
@@ -3075,9 +3159,13 @@ static ssize_t bluetooth_enable_store(struct device *dev, | |||
3075 | unsigned long t; | 3159 | unsigned long t; |
3076 | int res; | 3160 | int res; |
3077 | 3161 | ||
3162 | printk_deprecated_rfkill_attribute("bluetooth_enable"); | ||
3163 | |||
3078 | if (parse_strtoul(buf, 1, &t)) | 3164 | if (parse_strtoul(buf, 1, &t)) |
3079 | return -EINVAL; | 3165 | return -EINVAL; |
3080 | 3166 | ||
3167 | tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t); | ||
3168 | |||
3081 | res = bluetooth_set_radiosw(t, 1); | 3169 | res = bluetooth_set_radiosw(t, 1); |
3082 | 3170 | ||
3083 | return (res) ? res : count; | 3171 | return (res) ? res : count; |
@@ -3111,6 +3199,8 @@ static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) | |||
3111 | 3199 | ||
3112 | static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) | 3200 | static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state) |
3113 | { | 3201 | { |
3202 | dbg_printk(TPACPI_DBG_RFKILL, | ||
3203 | "request to change radio state to %d\n", state); | ||
3114 | return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); | 3204 | return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); |
3115 | } | 3205 | } |
3116 | 3206 | ||
@@ -3121,6 +3211,9 @@ static void bluetooth_shutdown(void) | |||
3121 | TP_ACPI_BLTH_SAVE_STATE)) | 3211 | TP_ACPI_BLTH_SAVE_STATE)) |
3122 | printk(TPACPI_NOTICE | 3212 | printk(TPACPI_NOTICE |
3123 | "failed to save bluetooth state to NVRAM\n"); | 3213 | "failed to save bluetooth state to NVRAM\n"); |
3214 | else | ||
3215 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3216 | "bluestooth state saved to NVRAM\n"); | ||
3124 | } | 3217 | } |
3125 | 3218 | ||
3126 | static void bluetooth_exit(void) | 3219 | static void bluetooth_exit(void) |
@@ -3139,7 +3232,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
3139 | int res; | 3232 | int res; |
3140 | int status = 0; | 3233 | int status = 0; |
3141 | 3234 | ||
3142 | vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n"); | 3235 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3236 | "initializing bluetooth subdriver\n"); | ||
3143 | 3237 | ||
3144 | TPACPI_ACPIHANDLE_INIT(hkey); | 3238 | TPACPI_ACPIHANDLE_INIT(hkey); |
3145 | 3239 | ||
@@ -3148,7 +3242,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
3148 | tp_features.bluetooth = hkey_handle && | 3242 | tp_features.bluetooth = hkey_handle && |
3149 | acpi_evalf(hkey_handle, &status, "GBDC", "qd"); | 3243 | acpi_evalf(hkey_handle, &status, "GBDC", "qd"); |
3150 | 3244 | ||
3151 | vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n", | 3245 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3246 | "bluetooth is %s, status 0x%02x\n", | ||
3152 | str_supported(tp_features.bluetooth), | 3247 | str_supported(tp_features.bluetooth), |
3153 | status); | 3248 | status); |
3154 | 3249 | ||
@@ -3163,7 +3258,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
3163 | !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { | 3258 | !(status & TP_ACPI_BLUETOOTH_HWPRESENT)) { |
3164 | /* no bluetooth hardware present in system */ | 3259 | /* no bluetooth hardware present in system */ |
3165 | tp_features.bluetooth = 0; | 3260 | tp_features.bluetooth = 0; |
3166 | dbg_printk(TPACPI_DBG_INIT, | 3261 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3167 | "bluetooth hardware not installed\n"); | 3262 | "bluetooth hardware not installed\n"); |
3168 | } | 3263 | } |
3169 | 3264 | ||
@@ -3178,7 +3273,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm) | |||
3178 | res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, | 3273 | res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, |
3179 | &tpacpi_bluetooth_rfkill, | 3274 | &tpacpi_bluetooth_rfkill, |
3180 | RFKILL_TYPE_BLUETOOTH, | 3275 | RFKILL_TYPE_BLUETOOTH, |
3181 | "tpacpi_bluetooth_sw", | 3276 | TPACPI_RFK_BLUETOOTH_SW_NAME, |
3182 | true, | 3277 | true, |
3183 | tpacpi_bluetooth_rfk_set, | 3278 | tpacpi_bluetooth_rfk_set, |
3184 | tpacpi_bluetooth_rfk_get); | 3279 | tpacpi_bluetooth_rfk_get); |
@@ -3211,19 +3306,27 @@ static int bluetooth_read(char *p) | |||
3211 | static int bluetooth_write(char *buf) | 3306 | static int bluetooth_write(char *buf) |
3212 | { | 3307 | { |
3213 | char *cmd; | 3308 | char *cmd; |
3309 | int state = -1; | ||
3214 | 3310 | ||
3215 | if (!tp_features.bluetooth) | 3311 | if (!tp_features.bluetooth) |
3216 | return -ENODEV; | 3312 | return -ENODEV; |
3217 | 3313 | ||
3218 | while ((cmd = next_cmd(&buf))) { | 3314 | while ((cmd = next_cmd(&buf))) { |
3219 | if (strlencmp(cmd, "enable") == 0) { | 3315 | if (strlencmp(cmd, "enable") == 0) { |
3220 | bluetooth_set_radiosw(1, 1); | 3316 | state = 1; |
3221 | } else if (strlencmp(cmd, "disable") == 0) { | 3317 | } else if (strlencmp(cmd, "disable") == 0) { |
3222 | bluetooth_set_radiosw(0, 1); | 3318 | state = 0; |
3223 | } else | 3319 | } else |
3224 | return -EINVAL; | 3320 | return -EINVAL; |
3225 | } | 3321 | } |
3226 | 3322 | ||
3323 | if (state != -1) { | ||
3324 | tpacpi_disclose_usertask("procfs bluetooth", | ||
3325 | "attempt to %s\n", | ||
3326 | state ? "enable" : "disable"); | ||
3327 | bluetooth_set_radiosw(state, 1); | ||
3328 | } | ||
3329 | |||
3227 | return 0; | 3330 | return 0; |
3228 | } | 3331 | } |
3229 | 3332 | ||
@@ -3248,13 +3351,17 @@ enum { | |||
3248 | off / last state */ | 3351 | off / last state */ |
3249 | }; | 3352 | }; |
3250 | 3353 | ||
3354 | #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" | ||
3355 | |||
3251 | static struct rfkill *tpacpi_wan_rfkill; | 3356 | static struct rfkill *tpacpi_wan_rfkill; |
3252 | 3357 | ||
3253 | static void wan_suspend(pm_message_t state) | 3358 | static void wan_suspend(pm_message_t state) |
3254 | { | 3359 | { |
3255 | /* Try to make sure radio will resume powered off */ | 3360 | /* Try to make sure radio will resume powered off */ |
3256 | acpi_evalf(NULL, NULL, "\\WGSV", "qvd", | 3361 | if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd", |
3257 | TP_ACPI_WGSV_PWR_OFF_ON_RESUME); | 3362 | TP_ACPI_WGSV_PWR_OFF_ON_RESUME)) |
3363 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3364 | "WWAN power down on resume request failed\n"); | ||
3258 | } | 3365 | } |
3259 | 3366 | ||
3260 | static int wan_get_radiosw(void) | 3367 | static int wan_get_radiosw(void) |
@@ -3292,6 +3399,10 @@ static void wan_update_rfk(void) | |||
3292 | if (status < 0) | 3399 | if (status < 0) |
3293 | return; | 3400 | return; |
3294 | rfkill_force_state(tpacpi_wan_rfkill, status); | 3401 | rfkill_force_state(tpacpi_wan_rfkill, status); |
3402 | |||
3403 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3404 | "forced rfkill state to %d\n", | ||
3405 | status); | ||
3295 | } | 3406 | } |
3296 | 3407 | ||
3297 | static int wan_set_radiosw(int radio_on, int update_rfk) | 3408 | static int wan_set_radiosw(int radio_on, int update_rfk) |
@@ -3307,6 +3418,9 @@ static int wan_set_radiosw(int radio_on, int update_rfk) | |||
3307 | && radio_on) | 3418 | && radio_on) |
3308 | return -EPERM; | 3419 | return -EPERM; |
3309 | 3420 | ||
3421 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3422 | "will %s WWAN\n", radio_on ? "enable" : "disable"); | ||
3423 | |||
3310 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 3424 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
3311 | if (dbg_wwanemul) { | 3425 | if (dbg_wwanemul) { |
3312 | tpacpi_wwan_emulstate = !!radio_on; | 3426 | tpacpi_wwan_emulstate = !!radio_on; |
@@ -3337,6 +3451,8 @@ static ssize_t wan_enable_show(struct device *dev, | |||
3337 | { | 3451 | { |
3338 | int status; | 3452 | int status; |
3339 | 3453 | ||
3454 | printk_deprecated_rfkill_attribute("wwan_enable"); | ||
3455 | |||
3340 | status = wan_get_radiosw(); | 3456 | status = wan_get_radiosw(); |
3341 | if (status < 0) | 3457 | if (status < 0) |
3342 | return status; | 3458 | return status; |
@@ -3352,9 +3468,13 @@ static ssize_t wan_enable_store(struct device *dev, | |||
3352 | unsigned long t; | 3468 | unsigned long t; |
3353 | int res; | 3469 | int res; |
3354 | 3470 | ||
3471 | printk_deprecated_rfkill_attribute("wwan_enable"); | ||
3472 | |||
3355 | if (parse_strtoul(buf, 1, &t)) | 3473 | if (parse_strtoul(buf, 1, &t)) |
3356 | return -EINVAL; | 3474 | return -EINVAL; |
3357 | 3475 | ||
3476 | tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t); | ||
3477 | |||
3358 | res = wan_set_radiosw(t, 1); | 3478 | res = wan_set_radiosw(t, 1); |
3359 | 3479 | ||
3360 | return (res) ? res : count; | 3480 | return (res) ? res : count; |
@@ -3388,6 +3508,8 @@ static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) | |||
3388 | 3508 | ||
3389 | static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) | 3509 | static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state) |
3390 | { | 3510 | { |
3511 | dbg_printk(TPACPI_DBG_RFKILL, | ||
3512 | "request to change radio state to %d\n", state); | ||
3391 | return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); | 3513 | return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); |
3392 | } | 3514 | } |
3393 | 3515 | ||
@@ -3398,6 +3520,9 @@ static void wan_shutdown(void) | |||
3398 | TP_ACPI_WGSV_SAVE_STATE)) | 3520 | TP_ACPI_WGSV_SAVE_STATE)) |
3399 | printk(TPACPI_NOTICE | 3521 | printk(TPACPI_NOTICE |
3400 | "failed to save WWAN state to NVRAM\n"); | 3522 | "failed to save WWAN state to NVRAM\n"); |
3523 | else | ||
3524 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3525 | "WWAN state saved to NVRAM\n"); | ||
3401 | } | 3526 | } |
3402 | 3527 | ||
3403 | static void wan_exit(void) | 3528 | static void wan_exit(void) |
@@ -3416,14 +3541,16 @@ static int __init wan_init(struct ibm_init_struct *iibm) | |||
3416 | int res; | 3541 | int res; |
3417 | int status = 0; | 3542 | int status = 0; |
3418 | 3543 | ||
3419 | vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n"); | 3544 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3545 | "initializing wan subdriver\n"); | ||
3420 | 3546 | ||
3421 | TPACPI_ACPIHANDLE_INIT(hkey); | 3547 | TPACPI_ACPIHANDLE_INIT(hkey); |
3422 | 3548 | ||
3423 | tp_features.wan = hkey_handle && | 3549 | tp_features.wan = hkey_handle && |
3424 | acpi_evalf(hkey_handle, &status, "GWAN", "qd"); | 3550 | acpi_evalf(hkey_handle, &status, "GWAN", "qd"); |
3425 | 3551 | ||
3426 | vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n", | 3552 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3553 | "wan is %s, status 0x%02x\n", | ||
3427 | str_supported(tp_features.wan), | 3554 | str_supported(tp_features.wan), |
3428 | status); | 3555 | status); |
3429 | 3556 | ||
@@ -3438,7 +3565,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) | |||
3438 | !(status & TP_ACPI_WANCARD_HWPRESENT)) { | 3565 | !(status & TP_ACPI_WANCARD_HWPRESENT)) { |
3439 | /* no wan hardware present in system */ | 3566 | /* no wan hardware present in system */ |
3440 | tp_features.wan = 0; | 3567 | tp_features.wan = 0; |
3441 | dbg_printk(TPACPI_DBG_INIT, | 3568 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3442 | "wan hardware not installed\n"); | 3569 | "wan hardware not installed\n"); |
3443 | } | 3570 | } |
3444 | 3571 | ||
@@ -3453,7 +3580,7 @@ static int __init wan_init(struct ibm_init_struct *iibm) | |||
3453 | res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, | 3580 | res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, |
3454 | &tpacpi_wan_rfkill, | 3581 | &tpacpi_wan_rfkill, |
3455 | RFKILL_TYPE_WWAN, | 3582 | RFKILL_TYPE_WWAN, |
3456 | "tpacpi_wwan_sw", | 3583 | TPACPI_RFK_WWAN_SW_NAME, |
3457 | true, | 3584 | true, |
3458 | tpacpi_wan_rfk_set, | 3585 | tpacpi_wan_rfk_set, |
3459 | tpacpi_wan_rfk_get); | 3586 | tpacpi_wan_rfk_get); |
@@ -3471,6 +3598,8 @@ static int wan_read(char *p) | |||
3471 | int len = 0; | 3598 | int len = 0; |
3472 | int status = wan_get_radiosw(); | 3599 | int status = wan_get_radiosw(); |
3473 | 3600 | ||
3601 | tpacpi_disclose_usertask("procfs wan", "read"); | ||
3602 | |||
3474 | if (!tp_features.wan) | 3603 | if (!tp_features.wan) |
3475 | len += sprintf(p + len, "status:\t\tnot supported\n"); | 3604 | len += sprintf(p + len, "status:\t\tnot supported\n"); |
3476 | else { | 3605 | else { |
@@ -3486,19 +3615,27 @@ static int wan_read(char *p) | |||
3486 | static int wan_write(char *buf) | 3615 | static int wan_write(char *buf) |
3487 | { | 3616 | { |
3488 | char *cmd; | 3617 | char *cmd; |
3618 | int state = -1; | ||
3489 | 3619 | ||
3490 | if (!tp_features.wan) | 3620 | if (!tp_features.wan) |
3491 | return -ENODEV; | 3621 | return -ENODEV; |
3492 | 3622 | ||
3493 | while ((cmd = next_cmd(&buf))) { | 3623 | while ((cmd = next_cmd(&buf))) { |
3494 | if (strlencmp(cmd, "enable") == 0) { | 3624 | if (strlencmp(cmd, "enable") == 0) { |
3495 | wan_set_radiosw(1, 1); | 3625 | state = 1; |
3496 | } else if (strlencmp(cmd, "disable") == 0) { | 3626 | } else if (strlencmp(cmd, "disable") == 0) { |
3497 | wan_set_radiosw(0, 1); | 3627 | state = 0; |
3498 | } else | 3628 | } else |
3499 | return -EINVAL; | 3629 | return -EINVAL; |
3500 | } | 3630 | } |
3501 | 3631 | ||
3632 | if (state != -1) { | ||
3633 | tpacpi_disclose_usertask("procfs wan", | ||
3634 | "attempt to %s\n", | ||
3635 | state ? "enable" : "disable"); | ||
3636 | wan_set_radiosw(state, 1); | ||
3637 | } | ||
3638 | |||
3502 | return 0; | 3639 | return 0; |
3503 | } | 3640 | } |
3504 | 3641 | ||
@@ -3521,6 +3658,8 @@ enum { | |||
3521 | TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */ | 3658 | TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */ |
3522 | }; | 3659 | }; |
3523 | 3660 | ||
3661 | #define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" | ||
3662 | |||
3524 | static struct rfkill *tpacpi_uwb_rfkill; | 3663 | static struct rfkill *tpacpi_uwb_rfkill; |
3525 | 3664 | ||
3526 | static int uwb_get_radiosw(void) | 3665 | static int uwb_get_radiosw(void) |
@@ -3558,6 +3697,10 @@ static void uwb_update_rfk(void) | |||
3558 | if (status < 0) | 3697 | if (status < 0) |
3559 | return; | 3698 | return; |
3560 | rfkill_force_state(tpacpi_uwb_rfkill, status); | 3699 | rfkill_force_state(tpacpi_uwb_rfkill, status); |
3700 | |||
3701 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3702 | "forced rfkill state to %d\n", | ||
3703 | status); | ||
3561 | } | 3704 | } |
3562 | 3705 | ||
3563 | static int uwb_set_radiosw(int radio_on, int update_rfk) | 3706 | static int uwb_set_radiosw(int radio_on, int update_rfk) |
@@ -3573,6 +3716,9 @@ static int uwb_set_radiosw(int radio_on, int update_rfk) | |||
3573 | && radio_on) | 3716 | && radio_on) |
3574 | return -EPERM; | 3717 | return -EPERM; |
3575 | 3718 | ||
3719 | vdbg_printk(TPACPI_DBG_RFKILL, | ||
3720 | "will %s UWB\n", radio_on ? "enable" : "disable"); | ||
3721 | |||
3576 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES | 3722 | #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES |
3577 | if (dbg_uwbemul) { | 3723 | if (dbg_uwbemul) { |
3578 | tpacpi_uwb_emulstate = !!radio_on; | 3724 | tpacpi_uwb_emulstate = !!radio_on; |
@@ -3607,6 +3753,8 @@ static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) | |||
3607 | 3753 | ||
3608 | static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) | 3754 | static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state) |
3609 | { | 3755 | { |
3756 | dbg_printk(TPACPI_DBG_RFKILL, | ||
3757 | "request to change radio state to %d\n", state); | ||
3610 | return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); | 3758 | return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0); |
3611 | } | 3759 | } |
3612 | 3760 | ||
@@ -3621,14 +3769,16 @@ static int __init uwb_init(struct ibm_init_struct *iibm) | |||
3621 | int res; | 3769 | int res; |
3622 | int status = 0; | 3770 | int status = 0; |
3623 | 3771 | ||
3624 | vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n"); | 3772 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3773 | "initializing uwb subdriver\n"); | ||
3625 | 3774 | ||
3626 | TPACPI_ACPIHANDLE_INIT(hkey); | 3775 | TPACPI_ACPIHANDLE_INIT(hkey); |
3627 | 3776 | ||
3628 | tp_features.uwb = hkey_handle && | 3777 | tp_features.uwb = hkey_handle && |
3629 | acpi_evalf(hkey_handle, &status, "GUWB", "qd"); | 3778 | acpi_evalf(hkey_handle, &status, "GUWB", "qd"); |
3630 | 3779 | ||
3631 | vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n", | 3780 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
3781 | "uwb is %s, status 0x%02x\n", | ||
3632 | str_supported(tp_features.uwb), | 3782 | str_supported(tp_features.uwb), |
3633 | status); | 3783 | status); |
3634 | 3784 | ||
@@ -3653,7 +3803,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm) | |||
3653 | res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, | 3803 | res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, |
3654 | &tpacpi_uwb_rfkill, | 3804 | &tpacpi_uwb_rfkill, |
3655 | RFKILL_TYPE_UWB, | 3805 | RFKILL_TYPE_UWB, |
3656 | "tpacpi_uwb_sw", | 3806 | TPACPI_RFK_UWB_SW_NAME, |
3657 | false, | 3807 | false, |
3658 | tpacpi_uwb_rfk_set, | 3808 | tpacpi_uwb_rfk_set, |
3659 | tpacpi_uwb_rfk_get); | 3809 | tpacpi_uwb_rfk_get); |
@@ -4602,6 +4752,16 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { | |||
4602 | "tpacpi::unknown_led", | 4752 | "tpacpi::unknown_led", |
4603 | "tpacpi::standby", | 4753 | "tpacpi::standby", |
4604 | }; | 4754 | }; |
4755 | #define TPACPI_SAFE_LEDS 0x0081U | ||
4756 | |||
4757 | static inline bool tpacpi_is_led_restricted(const unsigned int led) | ||
4758 | { | ||
4759 | #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS | ||
4760 | return false; | ||
4761 | #else | ||
4762 | return (TPACPI_SAFE_LEDS & (1 << led)) == 0; | ||
4763 | #endif | ||
4764 | } | ||
4605 | 4765 | ||
4606 | static int led_get_status(const unsigned int led) | 4766 | static int led_get_status(const unsigned int led) |
4607 | { | 4767 | { |
@@ -4639,16 +4799,20 @@ static int led_set_status(const unsigned int led, | |||
4639 | switch (led_supported) { | 4799 | switch (led_supported) { |
4640 | case TPACPI_LED_570: | 4800 | case TPACPI_LED_570: |
4641 | /* 570 */ | 4801 | /* 570 */ |
4642 | if (led > 7) | 4802 | if (unlikely(led > 7)) |
4643 | return -EINVAL; | 4803 | return -EINVAL; |
4804 | if (unlikely(tpacpi_is_led_restricted(led))) | ||
4805 | return -EPERM; | ||
4644 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 4806 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
4645 | (1 << led), led_sled_arg1[ledstatus])) | 4807 | (1 << led), led_sled_arg1[ledstatus])) |
4646 | rc = -EIO; | 4808 | rc = -EIO; |
4647 | break; | 4809 | break; |
4648 | case TPACPI_LED_OLD: | 4810 | case TPACPI_LED_OLD: |
4649 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ | 4811 | /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ |
4650 | if (led > 7) | 4812 | if (unlikely(led > 7)) |
4651 | return -EINVAL; | 4813 | return -EINVAL; |
4814 | if (unlikely(tpacpi_is_led_restricted(led))) | ||
4815 | return -EPERM; | ||
4652 | rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); | 4816 | rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); |
4653 | if (rc >= 0) | 4817 | if (rc >= 0) |
4654 | rc = ec_write(TPACPI_LED_EC_HLBL, | 4818 | rc = ec_write(TPACPI_LED_EC_HLBL, |
@@ -4659,6 +4823,10 @@ static int led_set_status(const unsigned int led, | |||
4659 | break; | 4823 | break; |
4660 | case TPACPI_LED_NEW: | 4824 | case TPACPI_LED_NEW: |
4661 | /* all others */ | 4825 | /* all others */ |
4826 | if (unlikely(led >= TPACPI_LED_NUMLEDS)) | ||
4827 | return -EINVAL; | ||
4828 | if (unlikely(tpacpi_is_led_restricted(led))) | ||
4829 | return -EPERM; | ||
4662 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", | 4830 | if (!acpi_evalf(led_handle, NULL, NULL, "vdd", |
4663 | led, led_led_arg1[ledstatus])) | 4831 | led, led_led_arg1[ledstatus])) |
4664 | rc = -EIO; | 4832 | rc = -EIO; |
@@ -4751,6 +4919,30 @@ static void led_exit(void) | |||
4751 | kfree(tpacpi_leds); | 4919 | kfree(tpacpi_leds); |
4752 | } | 4920 | } |
4753 | 4921 | ||
4922 | static int __init tpacpi_init_led(unsigned int led) | ||
4923 | { | ||
4924 | int rc; | ||
4925 | |||
4926 | tpacpi_leds[led].led = led; | ||
4927 | |||
4928 | tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set; | ||
4929 | tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set; | ||
4930 | if (led_supported == TPACPI_LED_570) | ||
4931 | tpacpi_leds[led].led_classdev.brightness_get = | ||
4932 | &led_sysfs_get; | ||
4933 | |||
4934 | tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led]; | ||
4935 | |||
4936 | INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker); | ||
4937 | |||
4938 | rc = led_classdev_register(&tpacpi_pdev->dev, | ||
4939 | &tpacpi_leds[led].led_classdev); | ||
4940 | if (rc < 0) | ||
4941 | tpacpi_leds[led].led_classdev.name = NULL; | ||
4942 | |||
4943 | return rc; | ||
4944 | } | ||
4945 | |||
4754 | static int __init led_init(struct ibm_init_struct *iibm) | 4946 | static int __init led_init(struct ibm_init_struct *iibm) |
4755 | { | 4947 | { |
4756 | unsigned int i; | 4948 | unsigned int i; |
@@ -4784,27 +4976,21 @@ static int __init led_init(struct ibm_init_struct *iibm) | |||
4784 | } | 4976 | } |
4785 | 4977 | ||
4786 | for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { | 4978 | for (i = 0; i < TPACPI_LED_NUMLEDS; i++) { |
4787 | tpacpi_leds[i].led = i; | 4979 | if (!tpacpi_is_led_restricted(i)) { |
4788 | 4980 | rc = tpacpi_init_led(i); | |
4789 | tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set; | 4981 | if (rc < 0) { |
4790 | tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set; | 4982 | led_exit(); |
4791 | if (led_supported == TPACPI_LED_570) | 4983 | return rc; |
4792 | tpacpi_leds[i].led_classdev.brightness_get = | 4984 | } |
4793 | &led_sysfs_get; | ||
4794 | |||
4795 | tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i]; | ||
4796 | |||
4797 | INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker); | ||
4798 | |||
4799 | rc = led_classdev_register(&tpacpi_pdev->dev, | ||
4800 | &tpacpi_leds[i].led_classdev); | ||
4801 | if (rc < 0) { | ||
4802 | tpacpi_leds[i].led_classdev.name = NULL; | ||
4803 | led_exit(); | ||
4804 | return rc; | ||
4805 | } | 4985 | } |
4806 | } | 4986 | } |
4807 | 4987 | ||
4988 | #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS | ||
4989 | if (led_supported != TPACPI_LED_NONE) | ||
4990 | printk(TPACPI_NOTICE | ||
4991 | "warning: userspace override of important " | ||
4992 | "firmware LEDs is enabled\n"); | ||
4993 | #endif | ||
4808 | return (led_supported != TPACPI_LED_NONE)? 0 : 1; | 4994 | return (led_supported != TPACPI_LED_NONE)? 0 : 1; |
4809 | } | 4995 | } |
4810 | 4996 | ||
@@ -5340,6 +5526,20 @@ static struct ibm_struct ecdump_driver_data = { | |||
5340 | 5526 | ||
5341 | #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" | 5527 | #define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen" |
5342 | 5528 | ||
5529 | /* | ||
5530 | * ThinkPads can read brightness from two places: EC HBRV (0x31), or | ||
5531 | * CMOS NVRAM byte 0x5E, bits 0-3. | ||
5532 | * | ||
5533 | * EC HBRV (0x31) has the following layout | ||
5534 | * Bit 7: unknown function | ||
5535 | * Bit 6: unknown function | ||
5536 | * Bit 5: Z: honour scale changes, NZ: ignore scale changes | ||
5537 | * Bit 4: must be set to zero to avoid problems | ||
5538 | * Bit 3-0: backlight brightness level | ||
5539 | * | ||
5540 | * brightness_get_raw returns status data in the HBRV layout | ||
5541 | */ | ||
5542 | |||
5343 | enum { | 5543 | enum { |
5344 | TP_EC_BACKLIGHT = 0x31, | 5544 | TP_EC_BACKLIGHT = 0x31, |
5345 | 5545 | ||
@@ -5349,108 +5549,164 @@ enum { | |||
5349 | TP_EC_BACKLIGHT_MAPSW = 0x20, | 5549 | TP_EC_BACKLIGHT_MAPSW = 0x20, |
5350 | }; | 5550 | }; |
5351 | 5551 | ||
5552 | enum tpacpi_brightness_access_mode { | ||
5553 | TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */ | ||
5554 | TPACPI_BRGHT_MODE_EC, /* EC control */ | ||
5555 | TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */ | ||
5556 | TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */ | ||
5557 | TPACPI_BRGHT_MODE_MAX | ||
5558 | }; | ||
5559 | |||
5352 | static struct backlight_device *ibm_backlight_device; | 5560 | static struct backlight_device *ibm_backlight_device; |
5353 | static int brightness_mode; | 5561 | |
5562 | static enum tpacpi_brightness_access_mode brightness_mode = | ||
5563 | TPACPI_BRGHT_MODE_MAX; | ||
5564 | |||
5354 | static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ | 5565 | static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */ |
5355 | 5566 | ||
5356 | static struct mutex brightness_mutex; | 5567 | static struct mutex brightness_mutex; |
5357 | 5568 | ||
5358 | /* | 5569 | /* NVRAM brightness access, |
5359 | * ThinkPads can read brightness from two places: EC 0x31, or | 5570 | * call with brightness_mutex held! */ |
5360 | * CMOS NVRAM byte 0x5E, bits 0-3. | 5571 | static unsigned int tpacpi_brightness_nvram_get(void) |
5361 | * | ||
5362 | * EC 0x31 has the following layout | ||
5363 | * Bit 7: unknown function | ||
5364 | * Bit 6: unknown function | ||
5365 | * Bit 5: Z: honour scale changes, NZ: ignore scale changes | ||
5366 | * Bit 4: must be set to zero to avoid problems | ||
5367 | * Bit 3-0: backlight brightness level | ||
5368 | * | ||
5369 | * brightness_get_raw returns status data in the EC 0x31 layout | ||
5370 | */ | ||
5371 | static int brightness_get_raw(int *status) | ||
5372 | { | 5572 | { |
5373 | u8 lec = 0, lcmos = 0, level = 0; | 5573 | u8 lnvram; |
5374 | 5574 | ||
5375 | if (brightness_mode & 1) { | 5575 | lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) |
5376 | if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec)) | 5576 | & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) |
5377 | return -EIO; | 5577 | >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; |
5378 | level = lec & TP_EC_BACKLIGHT_LVLMSK; | 5578 | lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07; |
5379 | }; | 5579 | |
5380 | if (brightness_mode & 2) { | 5580 | return lnvram; |
5381 | lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) | 5581 | } |
5382 | & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) | 5582 | |
5383 | >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; | 5583 | static void tpacpi_brightness_checkpoint_nvram(void) |
5384 | lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07; | 5584 | { |
5385 | level = lcmos; | 5585 | u8 lec = 0; |
5386 | } | 5586 | u8 b_nvram; |
5387 | 5587 | ||
5388 | if (brightness_mode == 3) { | 5588 | if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM) |
5389 | *status = lec; /* Prefer EC, CMOS is just a backing store */ | 5589 | return; |
5390 | lec &= TP_EC_BACKLIGHT_LVLMSK; | 5590 | |
5391 | if (lec == lcmos) | 5591 | vdbg_printk(TPACPI_DBG_BRGHT, |
5392 | tp_warned.bright_cmos_ec_unsync = 0; | 5592 | "trying to checkpoint backlight level to NVRAM...\n"); |
5393 | else { | 5593 | |
5394 | if (!tp_warned.bright_cmos_ec_unsync) { | 5594 | if (mutex_lock_killable(&brightness_mutex) < 0) |
5395 | printk(TPACPI_ERR | 5595 | return; |
5396 | "CMOS NVRAM (%u) and EC (%u) do not " | 5596 | |
5397 | "agree on display brightness level\n", | 5597 | if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec))) |
5398 | (unsigned int) lcmos, | 5598 | goto unlock; |
5399 | (unsigned int) lec); | 5599 | lec &= TP_EC_BACKLIGHT_LVLMSK; |
5400 | tp_warned.bright_cmos_ec_unsync = 1; | 5600 | b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS); |
5401 | } | 5601 | |
5602 | if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) | ||
5603 | >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) { | ||
5604 | /* NVRAM needs update */ | ||
5605 | b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS << | ||
5606 | TP_NVRAM_POS_LEVEL_BRIGHTNESS); | ||
5607 | b_nvram |= lec; | ||
5608 | nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS); | ||
5609 | dbg_printk(TPACPI_DBG_BRGHT, | ||
5610 | "updated NVRAM backlight level to %u (0x%02x)\n", | ||
5611 | (unsigned int) lec, (unsigned int) b_nvram); | ||
5612 | } else | ||
5613 | vdbg_printk(TPACPI_DBG_BRGHT, | ||
5614 | "NVRAM backlight level already is %u (0x%02x)\n", | ||
5615 | (unsigned int) lec, (unsigned int) b_nvram); | ||
5616 | |||
5617 | unlock: | ||
5618 | mutex_unlock(&brightness_mutex); | ||
5619 | } | ||
5620 | |||
5621 | |||
5622 | /* call with brightness_mutex held! */ | ||
5623 | static int tpacpi_brightness_get_raw(int *status) | ||
5624 | { | ||
5625 | u8 lec = 0; | ||
5626 | |||
5627 | switch (brightness_mode) { | ||
5628 | case TPACPI_BRGHT_MODE_UCMS_STEP: | ||
5629 | *status = tpacpi_brightness_nvram_get(); | ||
5630 | return 0; | ||
5631 | case TPACPI_BRGHT_MODE_EC: | ||
5632 | case TPACPI_BRGHT_MODE_ECNVRAM: | ||
5633 | if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec))) | ||
5402 | return -EIO; | 5634 | return -EIO; |
5403 | } | 5635 | *status = lec; |
5404 | } else { | 5636 | return 0; |
5405 | *status = level; | 5637 | default: |
5638 | return -ENXIO; | ||
5406 | } | 5639 | } |
5640 | } | ||
5641 | |||
5642 | /* call with brightness_mutex held! */ | ||
5643 | /* do NOT call with illegal backlight level value */ | ||
5644 | static int tpacpi_brightness_set_ec(unsigned int value) | ||
5645 | { | ||
5646 | u8 lec = 0; | ||
5647 | |||
5648 | if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec))) | ||
5649 | return -EIO; | ||
5650 | |||
5651 | if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT, | ||
5652 | (lec & TP_EC_BACKLIGHT_CMDMSK) | | ||
5653 | (value & TP_EC_BACKLIGHT_LVLMSK)))) | ||
5654 | return -EIO; | ||
5655 | |||
5656 | return 0; | ||
5657 | } | ||
5658 | |||
5659 | /* call with brightness_mutex held! */ | ||
5660 | static int tpacpi_brightness_set_ucmsstep(unsigned int value) | ||
5661 | { | ||
5662 | int cmos_cmd, inc; | ||
5663 | unsigned int current_value, i; | ||
5664 | |||
5665 | current_value = tpacpi_brightness_nvram_get(); | ||
5666 | |||
5667 | if (value == current_value) | ||
5668 | return 0; | ||
5669 | |||
5670 | cmos_cmd = (value > current_value) ? | ||
5671 | TP_CMOS_BRIGHTNESS_UP : | ||
5672 | TP_CMOS_BRIGHTNESS_DOWN; | ||
5673 | inc = (value > current_value) ? 1 : -1; | ||
5674 | |||
5675 | for (i = current_value; i != value; i += inc) | ||
5676 | if (issue_thinkpad_cmos_command(cmos_cmd)) | ||
5677 | return -EIO; | ||
5407 | 5678 | ||
5408 | return 0; | 5679 | return 0; |
5409 | } | 5680 | } |
5410 | 5681 | ||
5411 | /* May return EINTR which can always be mapped to ERESTARTSYS */ | 5682 | /* May return EINTR which can always be mapped to ERESTARTSYS */ |
5412 | static int brightness_set(int value) | 5683 | static int brightness_set(unsigned int value) |
5413 | { | 5684 | { |
5414 | int cmos_cmd, inc, i, res; | 5685 | int res; |
5415 | int current_value; | ||
5416 | int command_bits; | ||
5417 | 5686 | ||
5418 | if (value > ((tp_features.bright_16levels)? 15 : 7) || | 5687 | if (value > ((tp_features.bright_16levels)? 15 : 7) || |
5419 | value < 0) | 5688 | value < 0) |
5420 | return -EINVAL; | 5689 | return -EINVAL; |
5421 | 5690 | ||
5691 | vdbg_printk(TPACPI_DBG_BRGHT, | ||
5692 | "set backlight level to %d\n", value); | ||
5693 | |||
5422 | res = mutex_lock_killable(&brightness_mutex); | 5694 | res = mutex_lock_killable(&brightness_mutex); |
5423 | if (res < 0) | 5695 | if (res < 0) |
5424 | return res; | 5696 | return res; |
5425 | 5697 | ||
5426 | res = brightness_get_raw(¤t_value); | 5698 | switch (brightness_mode) { |
5427 | if (res < 0) | 5699 | case TPACPI_BRGHT_MODE_EC: |
5428 | goto errout; | 5700 | case TPACPI_BRGHT_MODE_ECNVRAM: |
5429 | 5701 | res = tpacpi_brightness_set_ec(value); | |
5430 | command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK; | 5702 | break; |
5431 | current_value &= TP_EC_BACKLIGHT_LVLMSK; | 5703 | case TPACPI_BRGHT_MODE_UCMS_STEP: |
5432 | 5704 | res = tpacpi_brightness_set_ucmsstep(value); | |
5433 | cmos_cmd = value > current_value ? | 5705 | break; |
5434 | TP_CMOS_BRIGHTNESS_UP : | 5706 | default: |
5435 | TP_CMOS_BRIGHTNESS_DOWN; | 5707 | res = -ENXIO; |
5436 | inc = (value > current_value)? 1 : -1; | ||
5437 | |||
5438 | res = 0; | ||
5439 | for (i = current_value; i != value; i += inc) { | ||
5440 | if ((brightness_mode & 2) && | ||
5441 | issue_thinkpad_cmos_command(cmos_cmd)) { | ||
5442 | res = -EIO; | ||
5443 | goto errout; | ||
5444 | } | ||
5445 | if ((brightness_mode & 1) && | ||
5446 | !acpi_ec_write(TP_EC_BACKLIGHT, | ||
5447 | (i + inc) | command_bits)) { | ||
5448 | res = -EIO; | ||
5449 | goto errout;; | ||
5450 | } | ||
5451 | } | 5708 | } |
5452 | 5709 | ||
5453 | errout: | ||
5454 | mutex_unlock(&brightness_mutex); | 5710 | mutex_unlock(&brightness_mutex); |
5455 | return res; | 5711 | return res; |
5456 | } | 5712 | } |
@@ -5459,21 +5715,34 @@ errout: | |||
5459 | 5715 | ||
5460 | static int brightness_update_status(struct backlight_device *bd) | 5716 | static int brightness_update_status(struct backlight_device *bd) |
5461 | { | 5717 | { |
5462 | /* it is the backlight class's job (caller) to handle | 5718 | unsigned int level = |
5463 | * EINTR and other errors properly */ | ||
5464 | return brightness_set( | ||
5465 | (bd->props.fb_blank == FB_BLANK_UNBLANK && | 5719 | (bd->props.fb_blank == FB_BLANK_UNBLANK && |
5466 | bd->props.power == FB_BLANK_UNBLANK) ? | 5720 | bd->props.power == FB_BLANK_UNBLANK) ? |
5467 | bd->props.brightness : 0); | 5721 | bd->props.brightness : 0; |
5722 | |||
5723 | dbg_printk(TPACPI_DBG_BRGHT, | ||
5724 | "backlight: attempt to set level to %d\n", | ||
5725 | level); | ||
5726 | |||
5727 | /* it is the backlight class's job (caller) to handle | ||
5728 | * EINTR and other errors properly */ | ||
5729 | return brightness_set(level); | ||
5468 | } | 5730 | } |
5469 | 5731 | ||
5470 | static int brightness_get(struct backlight_device *bd) | 5732 | static int brightness_get(struct backlight_device *bd) |
5471 | { | 5733 | { |
5472 | int status, res; | 5734 | int status, res; |
5473 | 5735 | ||
5474 | res = brightness_get_raw(&status); | 5736 | res = mutex_lock_killable(&brightness_mutex); |
5475 | if (res < 0) | 5737 | if (res < 0) |
5476 | return 0; /* FIXME: teach backlight about error handling */ | 5738 | return 0; |
5739 | |||
5740 | res = tpacpi_brightness_get_raw(&status); | ||
5741 | |||
5742 | mutex_unlock(&brightness_mutex); | ||
5743 | |||
5744 | if (res < 0) | ||
5745 | return 0; | ||
5477 | 5746 | ||
5478 | return status & TP_EC_BACKLIGHT_LVLMSK; | 5747 | return status & TP_EC_BACKLIGHT_LVLMSK; |
5479 | } | 5748 | } |
@@ -5523,7 +5792,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
5523 | } | 5792 | } |
5524 | 5793 | ||
5525 | if (!brightness_enable) { | 5794 | if (!brightness_enable) { |
5526 | dbg_printk(TPACPI_DBG_INIT, | 5795 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, |
5527 | "brightness support disabled by " | 5796 | "brightness support disabled by " |
5528 | "module parameter\n"); | 5797 | "module parameter\n"); |
5529 | return 1; | 5798 | return 1; |
@@ -5538,20 +5807,38 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
5538 | if (b == 16) | 5807 | if (b == 16) |
5539 | tp_features.bright_16levels = 1; | 5808 | tp_features.bright_16levels = 1; |
5540 | 5809 | ||
5541 | if (!brightness_mode) { | 5810 | /* |
5542 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) | 5811 | * Check for module parameter bogosity, note that we |
5543 | brightness_mode = 2; | 5812 | * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be |
5544 | else | 5813 | * able to detect "unspecified" |
5545 | brightness_mode = 3; | 5814 | */ |
5815 | if (brightness_mode > TPACPI_BRGHT_MODE_MAX) | ||
5816 | return -EINVAL; | ||
5546 | 5817 | ||
5547 | dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", | 5818 | /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */ |
5548 | brightness_mode); | 5819 | if (brightness_mode == TPACPI_BRGHT_MODE_AUTO || |
5549 | } | 5820 | brightness_mode == TPACPI_BRGHT_MODE_MAX) { |
5821 | if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) { | ||
5822 | /* | ||
5823 | * IBM models that define HBRV probably have | ||
5824 | * EC-based backlight level control | ||
5825 | */ | ||
5826 | if (acpi_evalf(ec_handle, NULL, "HBRV", "qd")) | ||
5827 | /* T40-T43, R50-R52, R50e, R51e, X31-X41 */ | ||
5828 | brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM; | ||
5829 | else | ||
5830 | /* all other IBM ThinkPads */ | ||
5831 | brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; | ||
5832 | } else | ||
5833 | /* All Lenovo ThinkPads */ | ||
5834 | brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP; | ||
5550 | 5835 | ||
5551 | if (brightness_mode > 3) | 5836 | dbg_printk(TPACPI_DBG_BRGHT, |
5552 | return -EINVAL; | 5837 | "selected brightness_mode=%d\n", |
5838 | brightness_mode); | ||
5839 | } | ||
5553 | 5840 | ||
5554 | if (brightness_get_raw(&b) < 0) | 5841 | if (tpacpi_brightness_get_raw(&b) < 0) |
5555 | return 1; | 5842 | return 1; |
5556 | 5843 | ||
5557 | if (tp_features.bright_16levels) | 5844 | if (tp_features.bright_16levels) |
@@ -5565,7 +5852,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
5565 | printk(TPACPI_ERR "Could not register backlight device\n"); | 5852 | printk(TPACPI_ERR "Could not register backlight device\n"); |
5566 | return PTR_ERR(ibm_backlight_device); | 5853 | return PTR_ERR(ibm_backlight_device); |
5567 | } | 5854 | } |
5568 | vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n"); | 5855 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, |
5856 | "brightness is supported\n"); | ||
5569 | 5857 | ||
5570 | ibm_backlight_device->props.max_brightness = | 5858 | ibm_backlight_device->props.max_brightness = |
5571 | (tp_features.bright_16levels)? 15 : 7; | 5859 | (tp_features.bright_16levels)? 15 : 7; |
@@ -5575,13 +5863,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
5575 | return 0; | 5863 | return 0; |
5576 | } | 5864 | } |
5577 | 5865 | ||
5866 | static void brightness_suspend(pm_message_t state) | ||
5867 | { | ||
5868 | tpacpi_brightness_checkpoint_nvram(); | ||
5869 | } | ||
5870 | |||
5871 | static void brightness_shutdown(void) | ||
5872 | { | ||
5873 | tpacpi_brightness_checkpoint_nvram(); | ||
5874 | } | ||
5875 | |||
5578 | static void brightness_exit(void) | 5876 | static void brightness_exit(void) |
5579 | { | 5877 | { |
5580 | if (ibm_backlight_device) { | 5878 | if (ibm_backlight_device) { |
5581 | vdbg_printk(TPACPI_DBG_EXIT, | 5879 | vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT, |
5582 | "calling backlight_device_unregister()\n"); | 5880 | "calling backlight_device_unregister()\n"); |
5583 | backlight_device_unregister(ibm_backlight_device); | 5881 | backlight_device_unregister(ibm_backlight_device); |
5584 | } | 5882 | } |
5883 | |||
5884 | tpacpi_brightness_checkpoint_nvram(); | ||
5585 | } | 5885 | } |
5586 | 5886 | ||
5587 | static int brightness_read(char *p) | 5887 | static int brightness_read(char *p) |
@@ -5628,6 +5928,9 @@ static int brightness_write(char *buf) | |||
5628 | return -EINVAL; | 5928 | return -EINVAL; |
5629 | } | 5929 | } |
5630 | 5930 | ||
5931 | tpacpi_disclose_usertask("procfs brightness", | ||
5932 | "set level to %d\n", level); | ||
5933 | |||
5631 | /* | 5934 | /* |
5632 | * Now we know what the final level should be, so we try to set it. | 5935 | * Now we know what the final level should be, so we try to set it. |
5633 | * Doing it this way makes the syscall restartable in case of EINTR | 5936 | * Doing it this way makes the syscall restartable in case of EINTR |
@@ -5641,6 +5944,8 @@ static struct ibm_struct brightness_driver_data = { | |||
5641 | .read = brightness_read, | 5944 | .read = brightness_read, |
5642 | .write = brightness_write, | 5945 | .write = brightness_write, |
5643 | .exit = brightness_exit, | 5946 | .exit = brightness_exit, |
5947 | .suspend = brightness_suspend, | ||
5948 | .shutdown = brightness_shutdown, | ||
5644 | }; | 5949 | }; |
5645 | 5950 | ||
5646 | /************************************************************************* | 5951 | /************************************************************************* |
@@ -6086,6 +6391,9 @@ static int fan_set_level(int level) | |||
6086 | default: | 6391 | default: |
6087 | return -ENXIO; | 6392 | return -ENXIO; |
6088 | } | 6393 | } |
6394 | |||
6395 | vdbg_printk(TPACPI_DBG_FAN, | ||
6396 | "fan control: set fan control register to 0x%02x\n", level); | ||
6089 | return 0; | 6397 | return 0; |
6090 | } | 6398 | } |
6091 | 6399 | ||
@@ -6163,6 +6471,11 @@ static int fan_set_enable(void) | |||
6163 | } | 6471 | } |
6164 | 6472 | ||
6165 | mutex_unlock(&fan_mutex); | 6473 | mutex_unlock(&fan_mutex); |
6474 | |||
6475 | if (!rc) | ||
6476 | vdbg_printk(TPACPI_DBG_FAN, | ||
6477 | "fan control: set fan control register to 0x%02x\n", | ||
6478 | s); | ||
6166 | return rc; | 6479 | return rc; |
6167 | } | 6480 | } |
6168 | 6481 | ||
@@ -6199,6 +6512,9 @@ static int fan_set_disable(void) | |||
6199 | rc = -ENXIO; | 6512 | rc = -ENXIO; |
6200 | } | 6513 | } |
6201 | 6514 | ||
6515 | if (!rc) | ||
6516 | vdbg_printk(TPACPI_DBG_FAN, | ||
6517 | "fan control: set fan control register to 0\n"); | ||
6202 | 6518 | ||
6203 | mutex_unlock(&fan_mutex); | 6519 | mutex_unlock(&fan_mutex); |
6204 | return rc; | 6520 | return rc; |
@@ -6327,6 +6643,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev, | |||
6327 | if (parse_strtoul(buf, 2, &t)) | 6643 | if (parse_strtoul(buf, 2, &t)) |
6328 | return -EINVAL; | 6644 | return -EINVAL; |
6329 | 6645 | ||
6646 | tpacpi_disclose_usertask("hwmon pwm1_enable", | ||
6647 | "set fan mode to %lu\n", t); | ||
6648 | |||
6330 | switch (t) { | 6649 | switch (t) { |
6331 | case 0: | 6650 | case 0: |
6332 | level = TP_EC_FAN_FULLSPEED; | 6651 | level = TP_EC_FAN_FULLSPEED; |
@@ -6392,6 +6711,9 @@ static ssize_t fan_pwm1_store(struct device *dev, | |||
6392 | if (parse_strtoul(buf, 255, &s)) | 6711 | if (parse_strtoul(buf, 255, &s)) |
6393 | return -EINVAL; | 6712 | return -EINVAL; |
6394 | 6713 | ||
6714 | tpacpi_disclose_usertask("hwmon pwm1", | ||
6715 | "set fan speed to %lu\n", s); | ||
6716 | |||
6395 | /* scale down from 0-255 to 0-7 */ | 6717 | /* scale down from 0-255 to 0-7 */ |
6396 | newlevel = (s >> 5) & 0x07; | 6718 | newlevel = (s >> 5) & 0x07; |
6397 | 6719 | ||
@@ -6458,6 +6780,8 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv, | |||
6458 | fan_watchdog_maxinterval = t; | 6780 | fan_watchdog_maxinterval = t; |
6459 | fan_watchdog_reset(); | 6781 | fan_watchdog_reset(); |
6460 | 6782 | ||
6783 | tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t); | ||
6784 | |||
6461 | return count; | 6785 | return count; |
6462 | } | 6786 | } |
6463 | 6787 | ||
@@ -6479,7 +6803,8 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
6479 | { | 6803 | { |
6480 | int rc; | 6804 | int rc; |
6481 | 6805 | ||
6482 | vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n"); | 6806 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, |
6807 | "initializing fan subdriver\n"); | ||
6483 | 6808 | ||
6484 | mutex_init(&fan_mutex); | 6809 | mutex_init(&fan_mutex); |
6485 | fan_status_access_mode = TPACPI_FAN_NONE; | 6810 | fan_status_access_mode = TPACPI_FAN_NONE; |
@@ -6538,7 +6863,8 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
6538 | } | 6863 | } |
6539 | } | 6864 | } |
6540 | 6865 | ||
6541 | vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n", | 6866 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, |
6867 | "fan is %s, modes %d, %d\n", | ||
6542 | str_supported(fan_status_access_mode != TPACPI_FAN_NONE || | 6868 | str_supported(fan_status_access_mode != TPACPI_FAN_NONE || |
6543 | fan_control_access_mode != TPACPI_FAN_WR_NONE), | 6869 | fan_control_access_mode != TPACPI_FAN_WR_NONE), |
6544 | fan_status_access_mode, fan_control_access_mode); | 6870 | fan_status_access_mode, fan_control_access_mode); |
@@ -6547,7 +6873,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
6547 | if (!fan_control_allowed) { | 6873 | if (!fan_control_allowed) { |
6548 | fan_control_access_mode = TPACPI_FAN_WR_NONE; | 6874 | fan_control_access_mode = TPACPI_FAN_WR_NONE; |
6549 | fan_control_commands = 0; | 6875 | fan_control_commands = 0; |
6550 | dbg_printk(TPACPI_DBG_INIT, | 6876 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN, |
6551 | "fan control features disabled by parameter\n"); | 6877 | "fan control features disabled by parameter\n"); |
6552 | } | 6878 | } |
6553 | 6879 | ||
@@ -6576,7 +6902,7 @@ static int __init fan_init(struct ibm_init_struct *iibm) | |||
6576 | 6902 | ||
6577 | static void fan_exit(void) | 6903 | static void fan_exit(void) |
6578 | { | 6904 | { |
6579 | vdbg_printk(TPACPI_DBG_EXIT, | 6905 | vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN, |
6580 | "cancelling any pending fan watchdog tasks\n"); | 6906 | "cancelling any pending fan watchdog tasks\n"); |
6581 | 6907 | ||
6582 | /* FIXME: can we really do this unconditionally? */ | 6908 | /* FIXME: can we really do this unconditionally? */ |
@@ -6757,6 +7083,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc) | |||
6757 | if (*rc == -ENXIO) | 7083 | if (*rc == -ENXIO) |
6758 | printk(TPACPI_ERR "level command accepted for unsupported " | 7084 | printk(TPACPI_ERR "level command accepted for unsupported " |
6759 | "access mode %d", fan_control_access_mode); | 7085 | "access mode %d", fan_control_access_mode); |
7086 | else if (!*rc) | ||
7087 | tpacpi_disclose_usertask("procfs fan", | ||
7088 | "set level to %d\n", level); | ||
6760 | 7089 | ||
6761 | return 1; | 7090 | return 1; |
6762 | } | 7091 | } |
@@ -6770,6 +7099,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc) | |||
6770 | if (*rc == -ENXIO) | 7099 | if (*rc == -ENXIO) |
6771 | printk(TPACPI_ERR "enable command accepted for unsupported " | 7100 | printk(TPACPI_ERR "enable command accepted for unsupported " |
6772 | "access mode %d", fan_control_access_mode); | 7101 | "access mode %d", fan_control_access_mode); |
7102 | else if (!*rc) | ||
7103 | tpacpi_disclose_usertask("procfs fan", "enable\n"); | ||
6773 | 7104 | ||
6774 | return 1; | 7105 | return 1; |
6775 | } | 7106 | } |
@@ -6783,6 +7114,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc) | |||
6783 | if (*rc == -ENXIO) | 7114 | if (*rc == -ENXIO) |
6784 | printk(TPACPI_ERR "disable command accepted for unsupported " | 7115 | printk(TPACPI_ERR "disable command accepted for unsupported " |
6785 | "access mode %d", fan_control_access_mode); | 7116 | "access mode %d", fan_control_access_mode); |
7117 | else if (!*rc) | ||
7118 | tpacpi_disclose_usertask("procfs fan", "disable\n"); | ||
6786 | 7119 | ||
6787 | return 1; | 7120 | return 1; |
6788 | } | 7121 | } |
@@ -6801,6 +7134,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc) | |||
6801 | if (*rc == -ENXIO) | 7134 | if (*rc == -ENXIO) |
6802 | printk(TPACPI_ERR "speed command accepted for unsupported " | 7135 | printk(TPACPI_ERR "speed command accepted for unsupported " |
6803 | "access mode %d", fan_control_access_mode); | 7136 | "access mode %d", fan_control_access_mode); |
7137 | else if (!*rc) | ||
7138 | tpacpi_disclose_usertask("procfs fan", | ||
7139 | "set speed to %d\n", speed); | ||
6804 | 7140 | ||
6805 | return 1; | 7141 | return 1; |
6806 | } | 7142 | } |
@@ -6814,8 +7150,12 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc) | |||
6814 | 7150 | ||
6815 | if (interval < 0 || interval > 120) | 7151 | if (interval < 0 || interval > 120) |
6816 | *rc = -EINVAL; | 7152 | *rc = -EINVAL; |
6817 | else | 7153 | else { |
6818 | fan_watchdog_maxinterval = interval; | 7154 | fan_watchdog_maxinterval = interval; |
7155 | tpacpi_disclose_usertask("procfs fan", | ||
7156 | "set watchdog timer to %d\n", | ||
7157 | interval); | ||
7158 | } | ||
6819 | 7159 | ||
6820 | return 1; | 7160 | return 1; |
6821 | } | 7161 | } |
@@ -7244,10 +7584,10 @@ module_param_named(fan_control, fan_control_allowed, bool, 0); | |||
7244 | MODULE_PARM_DESC(fan_control, | 7584 | MODULE_PARM_DESC(fan_control, |
7245 | "Enables setting fan parameters features when true"); | 7585 | "Enables setting fan parameters features when true"); |
7246 | 7586 | ||
7247 | module_param_named(brightness_mode, brightness_mode, int, 0); | 7587 | module_param_named(brightness_mode, brightness_mode, uint, 0); |
7248 | MODULE_PARM_DESC(brightness_mode, | 7588 | MODULE_PARM_DESC(brightness_mode, |
7249 | "Selects brightness control strategy: " | 7589 | "Selects brightness control strategy: " |
7250 | "0=auto, 1=EC, 2=CMOS, 3=both"); | 7590 | "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM"); |
7251 | 7591 | ||
7252 | module_param(brightness_enable, uint, 0); | 7592 | module_param(brightness_enable, uint, 0); |
7253 | MODULE_PARM_DESC(brightness_enable, | 7593 | MODULE_PARM_DESC(brightness_enable, |
@@ -7517,9 +7857,6 @@ static int __init thinkpad_acpi_module_init(void) | |||
7517 | return 0; | 7857 | return 0; |
7518 | } | 7858 | } |
7519 | 7859 | ||
7520 | /* Please remove this in year 2009 */ | ||
7521 | MODULE_ALIAS("ibm_acpi"); | ||
7522 | |||
7523 | MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); | 7860 | MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); |
7524 | 7861 | ||
7525 | /* | 7862 | /* |
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index ac01e06817fb..da73591017f9 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
@@ -93,6 +93,8 @@ static struct device_attribute power_supply_attrs[] = { | |||
93 | POWER_SUPPLY_ATTR(voltage_avg), | 93 | POWER_SUPPLY_ATTR(voltage_avg), |
94 | POWER_SUPPLY_ATTR(current_now), | 94 | POWER_SUPPLY_ATTR(current_now), |
95 | POWER_SUPPLY_ATTR(current_avg), | 95 | POWER_SUPPLY_ATTR(current_avg), |
96 | POWER_SUPPLY_ATTR(power_now), | ||
97 | POWER_SUPPLY_ATTR(power_avg), | ||
96 | POWER_SUPPLY_ATTR(charge_full_design), | 98 | POWER_SUPPLY_ATTR(charge_full_design), |
97 | POWER_SUPPLY_ATTR(charge_empty_design), | 99 | POWER_SUPPLY_ATTR(charge_empty_design), |
98 | POWER_SUPPLY_ATTR(charge_full), | 100 | POWER_SUPPLY_ATTR(charge_full), |
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 8171ca17b936..d0b093b66adc 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/idr.h> | 30 | #include <linux/idr.h> |
31 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/reboot.h> | ||
33 | 34 | ||
34 | MODULE_AUTHOR("Zhang Rui"); | 35 | MODULE_AUTHOR("Zhang Rui"); |
35 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); | 36 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); |
@@ -104,22 +105,36 @@ static ssize_t | |||
104 | temp_show(struct device *dev, struct device_attribute *attr, char *buf) | 105 | temp_show(struct device *dev, struct device_attribute *attr, char *buf) |
105 | { | 106 | { |
106 | struct thermal_zone_device *tz = to_thermal_zone(dev); | 107 | struct thermal_zone_device *tz = to_thermal_zone(dev); |
108 | long temperature; | ||
109 | int ret; | ||
107 | 110 | ||
108 | if (!tz->ops->get_temp) | 111 | if (!tz->ops->get_temp) |
109 | return -EPERM; | 112 | return -EPERM; |
110 | 113 | ||
111 | return tz->ops->get_temp(tz, buf); | 114 | ret = tz->ops->get_temp(tz, &temperature); |
115 | |||
116 | if (ret) | ||
117 | return ret; | ||
118 | |||
119 | return sprintf(buf, "%ld\n", temperature); | ||
112 | } | 120 | } |
113 | 121 | ||
114 | static ssize_t | 122 | static ssize_t |
115 | mode_show(struct device *dev, struct device_attribute *attr, char *buf) | 123 | mode_show(struct device *dev, struct device_attribute *attr, char *buf) |
116 | { | 124 | { |
117 | struct thermal_zone_device *tz = to_thermal_zone(dev); | 125 | struct thermal_zone_device *tz = to_thermal_zone(dev); |
126 | enum thermal_device_mode mode; | ||
127 | int result; | ||
118 | 128 | ||
119 | if (!tz->ops->get_mode) | 129 | if (!tz->ops->get_mode) |
120 | return -EPERM; | 130 | return -EPERM; |
121 | 131 | ||
122 | return tz->ops->get_mode(tz, buf); | 132 | result = tz->ops->get_mode(tz, &mode); |
133 | if (result) | ||
134 | return result; | ||
135 | |||
136 | return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled" | ||
137 | : "disabled"); | ||
123 | } | 138 | } |
124 | 139 | ||
125 | static ssize_t | 140 | static ssize_t |
@@ -132,7 +147,13 @@ mode_store(struct device *dev, struct device_attribute *attr, | |||
132 | if (!tz->ops->set_mode) | 147 | if (!tz->ops->set_mode) |
133 | return -EPERM; | 148 | return -EPERM; |
134 | 149 | ||
135 | result = tz->ops->set_mode(tz, buf); | 150 | if (!strncmp(buf, "enabled", sizeof("enabled"))) |
151 | result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); | ||
152 | else if (!strncmp(buf, "disabled", sizeof("disabled"))) | ||
153 | result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); | ||
154 | else | ||
155 | result = -EINVAL; | ||
156 | |||
136 | if (result) | 157 | if (result) |
137 | return result; | 158 | return result; |
138 | 159 | ||
@@ -144,7 +165,8 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, | |||
144 | char *buf) | 165 | char *buf) |
145 | { | 166 | { |
146 | struct thermal_zone_device *tz = to_thermal_zone(dev); | 167 | struct thermal_zone_device *tz = to_thermal_zone(dev); |
147 | int trip; | 168 | enum thermal_trip_type type; |
169 | int trip, result; | ||
148 | 170 | ||
149 | if (!tz->ops->get_trip_type) | 171 | if (!tz->ops->get_trip_type) |
150 | return -EPERM; | 172 | return -EPERM; |
@@ -152,7 +174,22 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr, | |||
152 | if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip)) | 174 | if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip)) |
153 | return -EINVAL; | 175 | return -EINVAL; |
154 | 176 | ||
155 | return tz->ops->get_trip_type(tz, trip, buf); | 177 | result = tz->ops->get_trip_type(tz, trip, &type); |
178 | if (result) | ||
179 | return result; | ||
180 | |||
181 | switch (type) { | ||
182 | case THERMAL_TRIP_CRITICAL: | ||
183 | return sprintf(buf, "critical"); | ||
184 | case THERMAL_TRIP_HOT: | ||
185 | return sprintf(buf, "hot"); | ||
186 | case THERMAL_TRIP_PASSIVE: | ||
187 | return sprintf(buf, "passive"); | ||
188 | case THERMAL_TRIP_ACTIVE: | ||
189 | return sprintf(buf, "active"); | ||
190 | default: | ||
191 | return sprintf(buf, "unknown"); | ||
192 | } | ||
156 | } | 193 | } |
157 | 194 | ||
158 | static ssize_t | 195 | static ssize_t |
@@ -160,7 +197,8 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, | |||
160 | char *buf) | 197 | char *buf) |
161 | { | 198 | { |
162 | struct thermal_zone_device *tz = to_thermal_zone(dev); | 199 | struct thermal_zone_device *tz = to_thermal_zone(dev); |
163 | int trip; | 200 | int trip, ret; |
201 | long temperature; | ||
164 | 202 | ||
165 | if (!tz->ops->get_trip_temp) | 203 | if (!tz->ops->get_trip_temp) |
166 | return -EPERM; | 204 | return -EPERM; |
@@ -168,12 +206,77 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, | |||
168 | if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) | 206 | if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip)) |
169 | return -EINVAL; | 207 | return -EINVAL; |
170 | 208 | ||
171 | return tz->ops->get_trip_temp(tz, trip, buf); | 209 | ret = tz->ops->get_trip_temp(tz, trip, &temperature); |
210 | |||
211 | if (ret) | ||
212 | return ret; | ||
213 | |||
214 | return sprintf(buf, "%ld\n", temperature); | ||
215 | } | ||
216 | |||
217 | static ssize_t | ||
218 | passive_store(struct device *dev, struct device_attribute *attr, | ||
219 | const char *buf, size_t count) | ||
220 | { | ||
221 | struct thermal_zone_device *tz = to_thermal_zone(dev); | ||
222 | struct thermal_cooling_device *cdev = NULL; | ||
223 | int state; | ||
224 | |||
225 | if (!sscanf(buf, "%d\n", &state)) | ||
226 | return -EINVAL; | ||
227 | |||
228 | if (state && !tz->forced_passive) { | ||
229 | mutex_lock(&thermal_list_lock); | ||
230 | list_for_each_entry(cdev, &thermal_cdev_list, node) { | ||
231 | if (!strncmp("Processor", cdev->type, | ||
232 | sizeof("Processor"))) | ||
233 | thermal_zone_bind_cooling_device(tz, | ||
234 | THERMAL_TRIPS_NONE, | ||
235 | cdev); | ||
236 | } | ||
237 | mutex_unlock(&thermal_list_lock); | ||
238 | } else if (!state && tz->forced_passive) { | ||
239 | mutex_lock(&thermal_list_lock); | ||
240 | list_for_each_entry(cdev, &thermal_cdev_list, node) { | ||
241 | if (!strncmp("Processor", cdev->type, | ||
242 | sizeof("Processor"))) | ||
243 | thermal_zone_unbind_cooling_device(tz, | ||
244 | THERMAL_TRIPS_NONE, | ||
245 | cdev); | ||
246 | } | ||
247 | mutex_unlock(&thermal_list_lock); | ||
248 | } | ||
249 | |||
250 | tz->tc1 = 1; | ||
251 | tz->tc2 = 1; | ||
252 | |||
253 | if (!tz->passive_delay) | ||
254 | tz->passive_delay = 1000; | ||
255 | |||
256 | if (!tz->polling_delay) | ||
257 | tz->polling_delay = 10000; | ||
258 | |||
259 | tz->forced_passive = state; | ||
260 | |||
261 | thermal_zone_device_update(tz); | ||
262 | |||
263 | return count; | ||
264 | } | ||
265 | |||
266 | static ssize_t | ||
267 | passive_show(struct device *dev, struct device_attribute *attr, | ||
268 | char *buf) | ||
269 | { | ||
270 | struct thermal_zone_device *tz = to_thermal_zone(dev); | ||
271 | |||
272 | return sprintf(buf, "%d\n", tz->forced_passive); | ||
172 | } | 273 | } |
173 | 274 | ||
174 | static DEVICE_ATTR(type, 0444, type_show, NULL); | 275 | static DEVICE_ATTR(type, 0444, type_show, NULL); |
175 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); | 276 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); |
176 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); | 277 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); |
278 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ | ||
279 | passive_store); | ||
177 | 280 | ||
178 | static struct device_attribute trip_point_attrs[] = { | 281 | static struct device_attribute trip_point_attrs[] = { |
179 | __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), | 282 | __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), |
@@ -236,8 +339,13 @@ thermal_cooling_device_max_state_show(struct device *dev, | |||
236 | struct device_attribute *attr, char *buf) | 339 | struct device_attribute *attr, char *buf) |
237 | { | 340 | { |
238 | struct thermal_cooling_device *cdev = to_cooling_device(dev); | 341 | struct thermal_cooling_device *cdev = to_cooling_device(dev); |
342 | unsigned long state; | ||
343 | int ret; | ||
239 | 344 | ||
240 | return cdev->ops->get_max_state(cdev, buf); | 345 | ret = cdev->ops->get_max_state(cdev, &state); |
346 | if (ret) | ||
347 | return ret; | ||
348 | return sprintf(buf, "%ld\n", state); | ||
241 | } | 349 | } |
242 | 350 | ||
243 | static ssize_t | 351 | static ssize_t |
@@ -245,8 +353,13 @@ thermal_cooling_device_cur_state_show(struct device *dev, | |||
245 | struct device_attribute *attr, char *buf) | 353 | struct device_attribute *attr, char *buf) |
246 | { | 354 | { |
247 | struct thermal_cooling_device *cdev = to_cooling_device(dev); | 355 | struct thermal_cooling_device *cdev = to_cooling_device(dev); |
356 | unsigned long state; | ||
357 | int ret; | ||
248 | 358 | ||
249 | return cdev->ops->get_cur_state(cdev, buf); | 359 | ret = cdev->ops->get_cur_state(cdev, &state); |
360 | if (ret) | ||
361 | return ret; | ||
362 | return sprintf(buf, "%ld\n", state); | ||
250 | } | 363 | } |
251 | 364 | ||
252 | static ssize_t | 365 | static ssize_t |
@@ -255,10 +368,10 @@ thermal_cooling_device_cur_state_store(struct device *dev, | |||
255 | const char *buf, size_t count) | 368 | const char *buf, size_t count) |
256 | { | 369 | { |
257 | struct thermal_cooling_device *cdev = to_cooling_device(dev); | 370 | struct thermal_cooling_device *cdev = to_cooling_device(dev); |
258 | int state; | 371 | unsigned long state; |
259 | int result; | 372 | int result; |
260 | 373 | ||
261 | if (!sscanf(buf, "%d\n", &state)) | 374 | if (!sscanf(buf, "%ld\n", &state)) |
262 | return -EINVAL; | 375 | return -EINVAL; |
263 | 376 | ||
264 | if (state < 0) | 377 | if (state < 0) |
@@ -312,13 +425,20 @@ static DEVICE_ATTR(name, 0444, name_show, NULL); | |||
312 | static ssize_t | 425 | static ssize_t |
313 | temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) | 426 | temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) |
314 | { | 427 | { |
428 | long temperature; | ||
429 | int ret; | ||
315 | struct thermal_hwmon_attr *hwmon_attr | 430 | struct thermal_hwmon_attr *hwmon_attr |
316 | = container_of(attr, struct thermal_hwmon_attr, attr); | 431 | = container_of(attr, struct thermal_hwmon_attr, attr); |
317 | struct thermal_zone_device *tz | 432 | struct thermal_zone_device *tz |
318 | = container_of(hwmon_attr, struct thermal_zone_device, | 433 | = container_of(hwmon_attr, struct thermal_zone_device, |
319 | temp_input); | 434 | temp_input); |
320 | 435 | ||
321 | return tz->ops->get_temp(tz, buf); | 436 | ret = tz->ops->get_temp(tz, &temperature); |
437 | |||
438 | if (ret) | ||
439 | return ret; | ||
440 | |||
441 | return sprintf(buf, "%ld\n", temperature); | ||
322 | } | 442 | } |
323 | 443 | ||
324 | static ssize_t | 444 | static ssize_t |
@@ -330,8 +450,14 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, | |||
330 | struct thermal_zone_device *tz | 450 | struct thermal_zone_device *tz |
331 | = container_of(hwmon_attr, struct thermal_zone_device, | 451 | = container_of(hwmon_attr, struct thermal_zone_device, |
332 | temp_crit); | 452 | temp_crit); |
453 | long temperature; | ||
454 | int ret; | ||
455 | |||
456 | ret = tz->ops->get_trip_temp(tz, 0, &temperature); | ||
457 | if (ret) | ||
458 | return ret; | ||
333 | 459 | ||
334 | return tz->ops->get_trip_temp(tz, 0, buf); | 460 | return sprintf(buf, "%ld\n", temperature); |
335 | } | 461 | } |
336 | 462 | ||
337 | 463 | ||
@@ -452,6 +578,97 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) | |||
452 | } | 578 | } |
453 | #endif | 579 | #endif |
454 | 580 | ||
581 | static void thermal_zone_device_set_polling(struct thermal_zone_device *tz, | ||
582 | int delay) | ||
583 | { | ||
584 | cancel_delayed_work(&(tz->poll_queue)); | ||
585 | |||
586 | if (!delay) | ||
587 | return; | ||
588 | |||
589 | if (delay > 1000) | ||
590 | schedule_delayed_work(&(tz->poll_queue), | ||
591 | round_jiffies(msecs_to_jiffies(delay))); | ||
592 | else | ||
593 | schedule_delayed_work(&(tz->poll_queue), | ||
594 | msecs_to_jiffies(delay)); | ||
595 | } | ||
596 | |||
597 | static void thermal_zone_device_passive(struct thermal_zone_device *tz, | ||
598 | int temp, int trip_temp, int trip) | ||
599 | { | ||
600 | int trend = 0; | ||
601 | struct thermal_cooling_device_instance *instance; | ||
602 | struct thermal_cooling_device *cdev; | ||
603 | long state, max_state; | ||
604 | |||
605 | /* | ||
606 | * Above Trip? | ||
607 | * ----------- | ||
608 | * Calculate the thermal trend (using the passive cooling equation) | ||
609 | * and modify the performance limit for all passive cooling devices | ||
610 | * accordingly. Note that we assume symmetry. | ||
611 | */ | ||
612 | if (temp >= trip_temp) { | ||
613 | tz->passive = true; | ||
614 | |||
615 | trend = (tz->tc1 * (temp - tz->last_temperature)) + | ||
616 | (tz->tc2 * (temp - trip_temp)); | ||
617 | |||
618 | /* Heating up? */ | ||
619 | if (trend > 0) { | ||
620 | list_for_each_entry(instance, &tz->cooling_devices, | ||
621 | node) { | ||
622 | if (instance->trip != trip) | ||
623 | continue; | ||
624 | cdev = instance->cdev; | ||
625 | cdev->ops->get_cur_state(cdev, &state); | ||
626 | cdev->ops->get_max_state(cdev, &max_state); | ||
627 | if (state++ < max_state) | ||
628 | cdev->ops->set_cur_state(cdev, state); | ||
629 | } | ||
630 | } else if (trend < 0) { /* Cooling off? */ | ||
631 | list_for_each_entry(instance, &tz->cooling_devices, | ||
632 | node) { | ||
633 | if (instance->trip != trip) | ||
634 | continue; | ||
635 | cdev = instance->cdev; | ||
636 | cdev->ops->get_cur_state(cdev, &state); | ||
637 | cdev->ops->get_max_state(cdev, &max_state); | ||
638 | if (state > 0) | ||
639 | cdev->ops->set_cur_state(cdev, --state); | ||
640 | } | ||
641 | } | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * Below Trip? | ||
647 | * ----------- | ||
648 | * Implement passive cooling hysteresis to slowly increase performance | ||
649 | * and avoid thrashing around the passive trip point. Note that we | ||
650 | * assume symmetry. | ||
651 | */ | ||
652 | list_for_each_entry(instance, &tz->cooling_devices, node) { | ||
653 | if (instance->trip != trip) | ||
654 | continue; | ||
655 | cdev = instance->cdev; | ||
656 | cdev->ops->get_cur_state(cdev, &state); | ||
657 | cdev->ops->get_max_state(cdev, &max_state); | ||
658 | if (state > 0) | ||
659 | cdev->ops->set_cur_state(cdev, --state); | ||
660 | if (state == 0) | ||
661 | tz->passive = false; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | static void thermal_zone_device_check(struct work_struct *work) | ||
666 | { | ||
667 | struct thermal_zone_device *tz = container_of(work, struct | ||
668 | thermal_zone_device, | ||
669 | poll_queue.work); | ||
670 | thermal_zone_device_update(tz); | ||
671 | } | ||
455 | 672 | ||
456 | /** | 673 | /** |
457 | * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone | 674 | * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone |
@@ -722,25 +939,113 @@ void thermal_cooling_device_unregister(struct | |||
722 | EXPORT_SYMBOL(thermal_cooling_device_unregister); | 939 | EXPORT_SYMBOL(thermal_cooling_device_unregister); |
723 | 940 | ||
724 | /** | 941 | /** |
942 | * thermal_zone_device_update - force an update of a thermal zone's state | ||
943 | * @ttz: the thermal zone to update | ||
944 | */ | ||
945 | |||
946 | void thermal_zone_device_update(struct thermal_zone_device *tz) | ||
947 | { | ||
948 | int count, ret = 0; | ||
949 | long temp, trip_temp; | ||
950 | enum thermal_trip_type trip_type; | ||
951 | struct thermal_cooling_device_instance *instance; | ||
952 | struct thermal_cooling_device *cdev; | ||
953 | |||
954 | mutex_lock(&tz->lock); | ||
955 | |||
956 | tz->ops->get_temp(tz, &temp); | ||
957 | |||
958 | for (count = 0; count < tz->trips; count++) { | ||
959 | tz->ops->get_trip_type(tz, count, &trip_type); | ||
960 | tz->ops->get_trip_temp(tz, count, &trip_temp); | ||
961 | |||
962 | switch (trip_type) { | ||
963 | case THERMAL_TRIP_CRITICAL: | ||
964 | if (temp > trip_temp) { | ||
965 | if (tz->ops->notify) | ||
966 | ret = tz->ops->notify(tz, count, | ||
967 | trip_type); | ||
968 | if (!ret) { | ||
969 | printk(KERN_EMERG | ||
970 | "Critical temperature reached (%ld C), shutting down.\n", | ||
971 | temp/1000); | ||
972 | orderly_poweroff(true); | ||
973 | } | ||
974 | } | ||
975 | break; | ||
976 | case THERMAL_TRIP_HOT: | ||
977 | if (temp > trip_temp) | ||
978 | if (tz->ops->notify) | ||
979 | tz->ops->notify(tz, count, trip_type); | ||
980 | break; | ||
981 | case THERMAL_TRIP_ACTIVE: | ||
982 | list_for_each_entry(instance, &tz->cooling_devices, | ||
983 | node) { | ||
984 | if (instance->trip != count) | ||
985 | continue; | ||
986 | |||
987 | cdev = instance->cdev; | ||
988 | |||
989 | if (temp > trip_temp) | ||
990 | cdev->ops->set_cur_state(cdev, 1); | ||
991 | else | ||
992 | cdev->ops->set_cur_state(cdev, 0); | ||
993 | } | ||
994 | break; | ||
995 | case THERMAL_TRIP_PASSIVE: | ||
996 | if (temp > trip_temp || tz->passive) | ||
997 | thermal_zone_device_passive(tz, temp, | ||
998 | trip_temp, count); | ||
999 | break; | ||
1000 | } | ||
1001 | } | ||
1002 | |||
1003 | if (tz->forced_passive) | ||
1004 | thermal_zone_device_passive(tz, temp, tz->forced_passive, | ||
1005 | THERMAL_TRIPS_NONE); | ||
1006 | |||
1007 | tz->last_temperature = temp; | ||
1008 | if (tz->passive) | ||
1009 | thermal_zone_device_set_polling(tz, tz->passive_delay); | ||
1010 | else if (tz->polling_delay) | ||
1011 | thermal_zone_device_set_polling(tz, tz->polling_delay); | ||
1012 | mutex_unlock(&tz->lock); | ||
1013 | } | ||
1014 | EXPORT_SYMBOL(thermal_zone_device_update); | ||
1015 | |||
1016 | /** | ||
725 | * thermal_zone_device_register - register a new thermal zone device | 1017 | * thermal_zone_device_register - register a new thermal zone device |
726 | * @type: the thermal zone device type | 1018 | * @type: the thermal zone device type |
727 | * @trips: the number of trip points the thermal zone support | 1019 | * @trips: the number of trip points the thermal zone support |
728 | * @devdata: private device data | 1020 | * @devdata: private device data |
729 | * @ops: standard thermal zone device callbacks | 1021 | * @ops: standard thermal zone device callbacks |
1022 | * @tc1: thermal coefficient 1 for passive calculations | ||
1023 | * @tc2: thermal coefficient 2 for passive calculations | ||
1024 | * @passive_delay: number of milliseconds to wait between polls when | ||
1025 | * performing passive cooling | ||
1026 | * @polling_delay: number of milliseconds to wait between polls when checking | ||
1027 | * whether trip points have been crossed (0 for interrupt | ||
1028 | * driven systems) | ||
730 | * | 1029 | * |
731 | * thermal_zone_device_unregister() must be called when the device is no | 1030 | * thermal_zone_device_unregister() must be called when the device is no |
732 | * longer needed. | 1031 | * longer needed. The passive cooling formula uses tc1 and tc2 as described in |
1032 | * section 11.1.5.1 of the ACPI specification 3.0. | ||
733 | */ | 1033 | */ |
734 | struct thermal_zone_device *thermal_zone_device_register(char *type, | 1034 | struct thermal_zone_device *thermal_zone_device_register(char *type, |
735 | int trips, | 1035 | int trips, |
736 | void *devdata, struct | 1036 | void *devdata, struct |
737 | thermal_zone_device_ops | 1037 | thermal_zone_device_ops |
738 | *ops) | 1038 | *ops, int tc1, int |
1039 | tc2, | ||
1040 | int passive_delay, | ||
1041 | int polling_delay) | ||
739 | { | 1042 | { |
740 | struct thermal_zone_device *tz; | 1043 | struct thermal_zone_device *tz; |
741 | struct thermal_cooling_device *pos; | 1044 | struct thermal_cooling_device *pos; |
1045 | enum thermal_trip_type trip_type; | ||
742 | int result; | 1046 | int result; |
743 | int count; | 1047 | int count; |
1048 | int passive = 0; | ||
744 | 1049 | ||
745 | if (strlen(type) >= THERMAL_NAME_LENGTH) | 1050 | if (strlen(type) >= THERMAL_NAME_LENGTH) |
746 | return ERR_PTR(-EINVAL); | 1051 | return ERR_PTR(-EINVAL); |
@@ -769,6 +1074,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
769 | tz->device.class = &thermal_class; | 1074 | tz->device.class = &thermal_class; |
770 | tz->devdata = devdata; | 1075 | tz->devdata = devdata; |
771 | tz->trips = trips; | 1076 | tz->trips = trips; |
1077 | tz->tc1 = tc1; | ||
1078 | tz->tc2 = tc2; | ||
1079 | tz->passive_delay = passive_delay; | ||
1080 | tz->polling_delay = polling_delay; | ||
1081 | |||
772 | dev_set_name(&tz->device, "thermal_zone%d", tz->id); | 1082 | dev_set_name(&tz->device, "thermal_zone%d", tz->id); |
773 | result = device_register(&tz->device); | 1083 | result = device_register(&tz->device); |
774 | if (result) { | 1084 | if (result) { |
@@ -798,8 +1108,18 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
798 | TRIP_POINT_ATTR_ADD(&tz->device, count, result); | 1108 | TRIP_POINT_ATTR_ADD(&tz->device, count, result); |
799 | if (result) | 1109 | if (result) |
800 | goto unregister; | 1110 | goto unregister; |
1111 | tz->ops->get_trip_type(tz, count, &trip_type); | ||
1112 | if (trip_type == THERMAL_TRIP_PASSIVE) | ||
1113 | passive = 1; | ||
801 | } | 1114 | } |
802 | 1115 | ||
1116 | if (!passive) | ||
1117 | result = device_create_file(&tz->device, | ||
1118 | &dev_attr_passive); | ||
1119 | |||
1120 | if (result) | ||
1121 | goto unregister; | ||
1122 | |||
803 | result = thermal_add_hwmon_sysfs(tz); | 1123 | result = thermal_add_hwmon_sysfs(tz); |
804 | if (result) | 1124 | if (result) |
805 | goto unregister; | 1125 | goto unregister; |
@@ -814,6 +1134,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
814 | } | 1134 | } |
815 | mutex_unlock(&thermal_list_lock); | 1135 | mutex_unlock(&thermal_list_lock); |
816 | 1136 | ||
1137 | INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); | ||
1138 | |||
1139 | thermal_zone_device_update(tz); | ||
1140 | |||
817 | if (!result) | 1141 | if (!result) |
818 | return tz; | 1142 | return tz; |
819 | 1143 | ||
@@ -853,6 +1177,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
853 | tz->ops->unbind(tz, cdev); | 1177 | tz->ops->unbind(tz, cdev); |
854 | mutex_unlock(&thermal_list_lock); | 1178 | mutex_unlock(&thermal_list_lock); |
855 | 1179 | ||
1180 | thermal_zone_device_set_polling(tz, 0); | ||
1181 | |||
856 | if (tz->type[0]) | 1182 | if (tz->type[0]) |
857 | device_remove_file(&tz->device, &dev_attr_type); | 1183 | device_remove_file(&tz->device, &dev_attr_type); |
858 | device_remove_file(&tz->device, &dev_attr_temp); | 1184 | device_remove_file(&tz->device, &dev_attr_temp); |