aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt21
-rw-r--r--Documentation/thinkpad-acpi.txt353
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/i386/kernel/acpi/boot.c8
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c4
-rw-r--r--drivers/acpi/Kconfig23
-rw-r--r--drivers/acpi/battery.c673
-rw-r--r--drivers/acpi/bay.c19
-rw-r--r--drivers/acpi/bus.c4
-rw-r--r--drivers/acpi/dock.c127
-rw-r--r--drivers/acpi/ec.c247
-rw-r--r--drivers/acpi/event.c153
-rw-r--r--drivers/acpi/events/evgpeblk.c4
-rw-r--r--drivers/acpi/events/evrgnini.c1
-rw-r--r--drivers/acpi/glue.c2
-rw-r--r--drivers/acpi/osl.c40
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_core.c6
-rw-r--r--drivers/acpi/processor_idle.c20
-rw-r--r--drivers/acpi/processor_throttling.c410
-rw-r--r--drivers/acpi/sbs.c33
-rw-r--r--drivers/acpi/sleep/main.c5
-rw-r--r--drivers/acpi/system.c165
-rw-r--r--drivers/acpi/tables/tbfadt.c44
-rw-r--r--drivers/acpi/utilities/uteval.c17
-rw-r--r--drivers/acpi/video.c120
-rw-r--r--drivers/misc/Kconfig14
-rw-r--r--drivers/misc/sony-laptop.c368
-rw-r--r--drivers/misc/thinkpad_acpi.c602
-rw-r--r--drivers/misc/thinkpad_acpi.h42
-rw-r--r--drivers/video/Kconfig7
-rw-r--r--drivers/video/Makefile3
-rw-r--r--include/acpi/acmacros.h63
-rw-r--r--include/acpi/acoutput.h4
-rw-r--r--include/acpi/acpi_bus.h3
-rw-r--r--include/acpi/platform/acenv.h2
-rw-r--r--include/acpi/platform/aclinux.h3
-rw-r--r--include/acpi/processor.h47
-rw-r--r--include/linux/pci_ids.h2
39 files changed, 2818 insertions, 849 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a5cb7839a679..c175eedadb5f 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -180,24 +180,11 @@ Who: Adrian Bunk <bunk@stusta.de>
180 180
181--------------------------- 181---------------------------
182 182
183What: /sys/firmware/acpi/namespace
184When: 2.6.21
185Why: The ACPI namespace is effectively the symbol list for
186 the BIOS. The device names are completely arbitrary
187 and have no place being exposed to user-space.
188
189 For those interested in the BIOS ACPI namespace,
190 the BIOS can be extracted and disassembled with acpidump
191 and iasl as documented in the pmtools package here:
192 http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils
193Who: Len Brown <len.brown@intel.com>
194
195---------------------------
196
197What: ACPI procfs interface 183What: ACPI procfs interface
198When: July 2007 184When: July 2008
199Why: After ACPI sysfs conversion, ACPI attributes will be duplicated 185Why: ACPI sysfs conversion should be finished by January 2008.
200 in sysfs and the ACPI procfs interface should be removed. 186 ACPI procfs interface will be removed in July 2008 so that
187 there is enough time for the user space to catch up.
201Who: Zhang Rui <rui.zhang@intel.com> 188Who: Zhang Rui <rui.zhang@intel.com>
202 189
203--------------------------- 190---------------------------
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 9e6b94face4b..6711fbcf4080 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -1,11 +1,11 @@
1 ThinkPad ACPI Extras Driver 1 ThinkPad ACPI Extras Driver
2 2
3 Version 0.14 3 Version 0.15
4 April 21st, 2007 4 July 1st, 2007
5 5
6 Borislav Deianov <borislav@users.sf.net> 6 Borislav Deianov <borislav@users.sf.net>
7 Henrique de Moraes Holschuh <hmh@hmh.eng.br> 7 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
8 http://ibm-acpi.sf.net/ 8 http://ibm-acpi.sf.net/
9 9
10 10
11This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It 11This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It
@@ -134,54 +134,68 @@ end of this document. Changes to the sysfs interface done by the kernel
134subsystems are not documented here, nor are they tracked by this 134subsystems are not documented here, nor are they tracked by this
135attribute. 135attribute.
136 136
137Changes to the thinkpad-acpi sysfs interface are only considered
138non-experimental when they are submitted to Linux mainline, at which
139point the changes in this interface are documented and interface_version
140may be updated. If you are using any thinkpad-acpi features not yet
141sent to mainline for merging, you do so on your own risk: these features
142may disappear, or be implemented in a different and incompatible way by
143the time they are merged in Linux mainline.
144
145Changes that are backwards-compatible by nature (e.g. the addition of
146attributes that do not change the way the other attributes work) do not
147always warrant an update of interface_version. Therefore, one must
148expect that an attribute might not be there, and deal with it properly
149(an attribute not being there *is* a valid way to make it clear that a
150feature is not available in sysfs).
151
137Hot keys 152Hot keys
138-------- 153--------
139 154
140procfs: /proc/acpi/ibm/hotkey 155procfs: /proc/acpi/ibm/hotkey
141sysfs device attribute: hotkey_* 156sysfs device attribute: hotkey_*
142 157
143Without this driver, only the Fn-F4 key (sleep button) generates an 158In a ThinkPad, the ACPI HKEY handler is responsible for comunicating
144ACPI event. With the driver loaded, the hotkey feature enabled and the 159some important events and also keyboard hot key presses to the operating
145mask set (see below), the various hot keys generate ACPI events in the 160system. Enabling the hotkey functionality of thinkpad-acpi signals the
161firmware that such a driver is present, and modifies how the ThinkPad
162firmware will behave in many situations.
163
164When the hotkey feature is enabled and the hot key mask is set (see
165below), the various hot keys either generate ACPI events in the
146following format: 166following format:
147 167
148 ibm/hotkey HKEY 00000080 0000xxxx 168 ibm/hotkey HKEY 00000080 0000xxxx
149 169
150The last four digits vary depending on the key combination pressed. 170or events over the input layer. The input layer support accepts the
151All labeled Fn-Fx key combinations generate distinct events. In 171standard IOCTLs to remap the keycodes assigned to each hotkey.
152addition, the lid microswitch and some docking station buttons may 172
153also generate such events. 173When the input device is open, the driver will suppress any ACPI hot key
154 174events that get translated into a meaningful input layer event, in order
155The bit mask allows some control over which hot keys generate ACPI 175to avoid sending duplicate events to userspace. Hot keys that are
156events. Not all bits in the mask can be modified. Not all bits that 176mapped to KEY_RESERVED in the keymap are not translated, and will always
157can be modified do anything. Not all hot keys can be individually 177generate an ACPI ibm/hotkey HKEY event, and no input layer events.
158controlled by the mask. Most recent ThinkPad models honor the 178
159following bits (assuming the hot keys feature has been enabled): 179The hot key bit mask allows some control over which hot keys generate
160 180events. If a key is "masked" (bit set to 0 in the mask), the firmware
161 key bit behavior when set behavior when unset 181will handle it. If it is "unmasked", it signals the firmware that
162 182thinkpad-acpi would prefer to handle it, if the firmware would be so
163 Fn-F3 always generates ACPI event 183kind to allow it (and it often doesn't!).
164 Fn-F4 always generates ACPI event 184
165 Fn-F5 0010 generate ACPI event enable/disable Bluetooth 185Not all bits in the mask can be modified. Not all bits that can be
166 Fn-F7 0040 generate ACPI event switch LCD and external display 186modified do anything. Not all hot keys can be individually controlled
167 Fn-F8 0080 generate ACPI event expand screen or none 187by the mask. Some models do not support the mask at all, and in those
168 Fn-F9 0100 generate ACPI event none 188models, hot keys cannot be controlled individually. The behaviour of
169 Fn-F12 always generates ACPI event 189the mask is, therefore, higly dependent on the ThinkPad model.
170 190
171Some models do not support all of the above. For example, the T30 does 191Note that unmasking some keys prevents their default behavior. For
172not support Fn-F5 and Fn-F9. Other models do not support the mask at 192example, if Fn+F5 is unmasked, that key will no longer enable/disable
173all. On those models, hot keys cannot be controlled individually. 193Bluetooth by itself.
174 194
175Note that enabling ACPI events for some keys prevents their default 195Note also that not all Fn key combinations are supported through ACPI.
176behavior. For example, if events for Fn-F5 are enabled, that key will 196For example, on the X40, the brightness, volume and "Access IBM" buttons
177no longer enable/disable Bluetooth by itself. This can still be done 197do not generate ACPI events even with this driver. They *can* be used
178from an acpid handler for the ibm/hotkey event. 198through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/
179
180Note also that not all Fn key combinations are supported through
181ACPI. For example, on the X40, the brightness, volume and "Access IBM"
182buttons do not generate ACPI events even with this driver. They *can*
183be used through the "ThinkPad Buttons" utility, see
184http://www.nongnu.org/tpb/
185 199
186procfs notes: 200procfs notes:
187 201
@@ -189,9 +203,9 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file:
189 203
190 echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature 204 echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature
191 echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature 205 echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature
192 echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys 206 echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys
193 echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys 207 echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys
194 ... any other 4-hex-digit mask ... 208 ... any other 8-hex-digit mask ...
195 echo reset > /proc/acpi/ibm/hotkey -- restore the original mask 209 echo reset > /proc/acpi/ibm/hotkey -- restore the original mask
196 210
197sysfs notes: 211sysfs notes:
@@ -202,7 +216,7 @@ sysfs notes:
202 key feature status will be restored to this value. 216 key feature status will be restored to this value.
203 217
204 0: hot keys were disabled 218 0: hot keys were disabled
205 1: hot keys were enabled 219 1: hot keys were enabled (unusual)
206 220
207 hotkey_bios_mask: 221 hotkey_bios_mask:
208 Returns the hot keys mask when thinkpad-acpi was loaded. 222 Returns the hot keys mask when thinkpad-acpi was loaded.
@@ -217,9 +231,182 @@ sysfs notes:
217 1: enables the hot keys feature / feature enabled 231 1: enables the hot keys feature / feature enabled
218 232
219 hotkey_mask: 233 hotkey_mask:
220 bit mask to enable ACPI event generation for each hot 234 bit mask to enable driver-handling and ACPI event
221 key (see above). Returns the current status of the hot 235 generation for each hot key (see above). Returns the
222 keys mask, and allows one to modify it. 236 current status of the hot keys mask, and allows one to
237 modify it.
238
239 hotkey_all_mask:
240 bit mask that should enable event reporting for all
241 supported hot keys, when echoed to hotkey_mask above.
242 Unless you know which events need to be handled
243 passively (because the firmware *will* handle them
244 anyway), do *not* use hotkey_all_mask. Use
245 hotkey_recommended_mask, instead. You have been warned.
246
247 hotkey_recommended_mask:
248 bit mask that should enable event reporting for all
249 supported hot keys, except those which are always
250 handled by the firmware anyway. Echo it to
251 hotkey_mask above, to use.
252
253 hotkey_radio_sw:
254 if the ThinkPad has a hardware radio switch, this
255 attribute will read 0 if the switch is in the "radios
256 disabled" postition, and 1 if the switch is in the
257 "radios enabled" position.
258
259input layer notes:
260
261A Hot key is mapped to a single input layer EV_KEY event, possibly
262followed by an EV_MSC MSC_SCAN event that shall contain that key's scan
263code. An EV_SYN event will always be generated to mark the end of the
264event block.
265
266Do not use the EV_MSC MSC_SCAN events to process keys. They are to be
267used as a helper to remap keys, only. They are particularly useful when
268remapping KEY_UNKNOWN keys.
269
270The events are available in an input device, with the following id:
271
272 Bus: BUS_HOST
273 vendor: 0x1014 (PCI_VENDOR_ID_IBM) or
274 0x17aa (PCI_VENDOR_ID_LENOVO)
275 product: 0x5054 ("TP")
276 version: 0x4101
277
278The version will have its LSB incremented if the keymap changes in a
279backwards-compatible way. The MSB shall always be 0x41 for this input
280device. If the MSB is not 0x41, do not use the device as described in
281this section, as it is either something else (e.g. another input device
282exported by a thinkpad driver, such as HDAPS) or its functionality has
283been changed in a non-backwards compatible way.
284
285Adding other event types for other functionalities shall be considered a
286backwards-compatible change for this input device.
287
288Thinkpad-acpi Hot Key event map (version 0x4101):
289
290ACPI Scan
291event code Key Notes
292
2930x1001 0x00 FN+F1 -
2940x1002 0x01 FN+F2 IBM: battery (rare)
295 Lenovo: Screen lock
296
2970x1003 0x02 FN+F3 Many IBM models always report
298 this hot key, even with hot keys
299 disabled or with Fn+F3 masked
300 off
301 IBM: screen lock
302 Lenovo: battery
303
3040x1004 0x03 FN+F4 Sleep button (ACPI sleep button
305 semanthics, i.e. sleep-to-RAM).
306 It is always generate some kind
307 of event, either the hot key
308 event or a ACPI sleep button
309 event. The firmware may
310 refuse to generate further FN+F4
311 key presses until a S3 or S4 ACPI
312 sleep cycle is performed or some
313 time passes.
314
3150x1005 0x04 FN+F5 Radio. Enables/disables
316 the internal BlueTooth hardware
317 and W-WAN card if left in control
318 of the firmware. Does not affect
319 the WLAN card.
320 Should be used to turn on/off all
321 radios (bluetooth+W-WAN+WLAN),
322 really.
323
3240x1006 0x05 FN+F6 -
325
3260x1007 0x06 FN+F7 Video output cycle.
327 Do you feel lucky today?
328
3290x1008 0x07 FN+F8 IBM: toggle screen expand
330 Lenovo: configure ultranav
331
3320x1009 0x08 FN+F9 -
333 .. .. ..
3340x100B 0x0A FN+F11 -
335
3360x100C 0x0B FN+F12 Sleep to disk. You are always
337 supposed to handle it yourself,
338 either through the ACPI event,
339 or through a hotkey event.
340 The firmware may refuse to
341 generate further FN+F4 key
342 press events until a S3 or S4
343 ACPI sleep cycle is performed,
344 or some time passes.
345
3460x100D 0x0C FN+BACKSPACE -
3470x100E 0x0D FN+INSERT -
3480x100F 0x0E FN+DELETE -
349
3500x1010 0x0F FN+HOME Brightness up. This key is
351 always handled by the firmware
352 in IBM ThinkPads, even when
353 unmasked. Just leave it alone.
354 For Lenovo ThinkPads with a new
355 BIOS, it has to be handled either
356 by the ACPI OSI, or by userspace.
3570x1011 0x10 FN+END Brightness down. See brightness
358 up for details.
359
3600x1012 0x11 FN+PGUP Thinklight toggle. This key is
361 always handled by the firmware,
362 even when unmasked.
363
3640x1013 0x12 FN+PGDOWN -
365
3660x1014 0x13 FN+SPACE Zoom key
367
3680x1015 0x14 VOLUME UP Internal mixer volume up. This
369 key is always handled by the
370 firmware, even when unmasked.
371 NOTE: Lenovo seems to be changing
372 this.
3730x1016 0x15 VOLUME DOWN Internal mixer volume up. This
374 key is always handled by the
375 firmware, even when unmasked.
376 NOTE: Lenovo seems to be changing
377 this.
3780x1017 0x16 MUTE Mute internal mixer. This
379 key is always handled by the
380 firmware, even when unmasked.
381
3820x1018 0x17 THINKPAD Thinkpad/Access IBM/Lenovo key
383
3840x1019 0x18 unknown
385.. .. ..
3860x1020 0x1F unknown
387
388The ThinkPad firmware does not allow one to differentiate when most hot
389keys are pressed or released (either that, or we don't know how to, yet).
390For these keys, the driver generates a set of events for a key press and
391immediately issues the same set of events for a key release. It is
392unknown by the driver if the ThinkPad firmware triggered these events on
393hot key press or release, but the firmware will do it for either one, not
394both.
395
396If a key is mapped to KEY_RESERVED, it generates no input events at all,
397and it may generate a legacy thinkpad-acpi ACPI hotkey event.
398
399If a key is mapped to KEY_UNKNOWN, it generates an input event that
400includes an scan code, and it may also generate a legacy thinkpad-acpi
401ACPI hotkey event.
402
403If a key is mapped to anything else, it will only generate legacy
404thinkpad-acpi ACPI hotkey events if nobody has opened the input device.
405
406Non hot-key ACPI HKEY event map:
4070x5001 Lid closed
4080x5002 Lid opened
4090x7000 Radio Switch may have changed state
223 410
224 411
225Bluetooth 412Bluetooth
@@ -437,27 +624,34 @@ CMOS control
437procfs: /proc/acpi/ibm/cmos 624procfs: /proc/acpi/ibm/cmos
438sysfs device attribute: cmos_command 625sysfs device attribute: cmos_command
439 626
440This feature is used internally by the ACPI firmware to control the 627This feature is mostly used internally by the ACPI firmware to keep the legacy
441ThinkLight on most newer ThinkPad models. It may also control LCD 628CMOS NVRAM bits in sync with the current machine state, and to record this
442brightness, sounds volume and more, but only on some models. 629state so that the ThinkPad will retain such settings across reboots.
630
631Some of these commands actually perform actions in some ThinkPad models, but
632this is expected to disappear more and more in newer models. As an example, in
633a T43 and in a X40, commands 12 and 13 still control the ThinkLight state for
634real, but commands 0 to 2 don't control the mixer anymore (they have been
635phased out) and just update the NVRAM.
443 636
444The range of valid cmos command numbers is 0 to 21, but not all have an 637The range of valid cmos command numbers is 0 to 21, but not all have an
445effect and the behavior varies from model to model. Here is the behavior 638effect and the behavior varies from model to model. Here is the behavior
446on the X40 (tpb is the ThinkPad Buttons utility): 639on the X40 (tpb is the ThinkPad Buttons utility):
447 640
448 0 - no effect but tpb reports "Volume down" 641 0 - Related to "Volume down" key press
449 1 - no effect but tpb reports "Volume up" 642 1 - Related to "Volume up" key press
450 2 - no effect but tpb reports "Mute on" 643 2 - Related to "Mute on" key press
451 3 - simulate pressing the "Access IBM" button 644 3 - Related to "Access IBM" key press
452 4 - LCD brightness up 645 4 - Related to "LCD brightness up" key pess
453 5 - LCD brightness down 646 5 - Related to "LCD brightness down" key press
454 11 - toggle screen expansion 647 11 - Related to "toggle screen expansion" key press/function
455 12 - ThinkLight on 648 12 - Related to "ThinkLight on"
456 13 - ThinkLight off 649 13 - Related to "ThinkLight off"
457 14 - no effect but tpb reports ThinkLight status change 650 14 - Related to "ThinkLight" key press (toggle thinklight)
458 651
459The cmos command interface is prone to firmware split-brain problems, as 652The cmos command interface is prone to firmware split-brain problems, as
460in newer ThinkPads it is just a compatibility layer. 653in newer ThinkPads it is just a compatibility layer. Do not use it, it is
654exported just as a debug tool.
461 655
462LED control -- /proc/acpi/ibm/led 656LED control -- /proc/acpi/ibm/led
463--------------------------------- 657---------------------------------
@@ -516,23 +710,15 @@ Temperature sensors
516procfs: /proc/acpi/ibm/thermal 710procfs: /proc/acpi/ibm/thermal
517sysfs device attributes: (hwmon) temp*_input 711sysfs device attributes: (hwmon) temp*_input
518 712
519Most ThinkPads include six or more separate temperature sensors but 713Most ThinkPads include six or more separate temperature sensors but only
520only expose the CPU temperature through the standard ACPI methods. 714expose the CPU temperature through the standard ACPI methods. This
521This feature shows readings from up to eight different sensors on older 715feature shows readings from up to eight different sensors on older
522ThinkPads, and it has experimental support for up to sixteen different 716ThinkPads, and up to sixteen different sensors on newer ThinkPads.
523sensors on newer ThinkPads.
524
525EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
526implementation directly accesses hardware registers and may not work as
527expected. USE WITH CAUTION! To use this feature, you need to supply the
528experimental=1 parameter when loading the module. When EXPERIMENTAL
529mode is enabled, reading the first 8 sensors on newer ThinkPads will
530also use an new experimental thermal sensor access mode.
531 717
532For example, on the X40, a typical output may be: 718For example, on the X40, a typical output may be:
533temperatures: 42 42 45 41 36 -128 33 -128 719temperatures: 42 42 45 41 36 -128 33 -128
534 720
535EXPERIMENTAL: On the T43/p, a typical output may be: 721On the T43/p, a typical output may be:
536temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128 722temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
537 723
538The mapping of thermal sensors to physical locations varies depending on 724The mapping of thermal sensors to physical locations varies depending on
@@ -562,7 +748,8 @@ http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p
5622: System board, left side (near PCMCIA slot), reported as HDAPS temp 7482: System board, left side (near PCMCIA slot), reported as HDAPS temp
5633: PCMCIA slot 7493: PCMCIA slot
5649: MCH (northbridge) to DRAM Bus 7509: MCH (northbridge) to DRAM Bus
56510: ICH (southbridge), under Mini-PCI card, under touchpad 75110: Clock-generator, mini-pci card and ICH (southbridge), under Mini-PCI
752 card, under touchpad
56611: Power regulator, underside of system board, below F2 key 75311: Power regulator, underside of system board, below F2 key
567 754
568The A31 has a very atypical layout for the thermal sensors 755The A31 has a very atypical layout for the thermal sensors
@@ -681,6 +868,12 @@ cannot be controlled.
681The backlight control has eight levels, ranging from 0 to 7. Some of the 868The backlight control has eight levels, ranging from 0 to 7. Some of the
682levels may not be distinct. 869levels may not be distinct.
683 870
871There are two interfaces to the firmware for brightness control, EC and CMOS.
872To select which one should be used, use the brightness_mode module parameter:
873brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode,
874brightness_mode=3 selects both EC and CMOS. The driver tries to autodetect
875which interface to use.
876
684Procfs notes: 877Procfs notes:
685 878
686 The available commands are: 879 The available commands are:
@@ -976,3 +1169,9 @@ Sysfs interface changelog:
976 1169
9770x000100: Initial sysfs support, as a single platform driver and 11700x000100: Initial sysfs support, as a single platform driver and
978 device. 1171 device.
11720x000200: Hot key support for 32 hot keys, and radio slider switch
1173 support.
11740x010000: Hot keys are now handled by default over the input
1175 layer, the radio switch generates input event EV_RADIO,
1176 and the driver enables hot key handling by default in
1177 the firmware.
diff --git a/MAINTAINERS b/MAINTAINERS
index 773c732b4177..a9b9ef614ae7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -225,15 +225,15 @@ T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
225S: Supported 225S: Supported
226 226
227ACPI BATTERY DRIVERS 227ACPI BATTERY DRIVERS
228P: Vladimir P. Lebedev 228P: Alexey Starikovskiy
229M: vladimir.p.lebedev@intel.com 229M: astarikovskiy@suse.de
230L: linux-acpi@vger.kernel.org 230L: linux-acpi@vger.kernel.org
231W: http://acpi.sourceforge.net/ 231W: http://acpi.sourceforge.net/
232S: Supported 232S: Supported
233 233
234ACPI EC DRIVER 234ACPI EC DRIVER
235P: Alexey Starikovskiy 235P: Alexey Starikovskiy
236M: alexey.y.starikovskiy@linux.intel.com 236M: astarikovskiy@suse.de
237L: linux-acpi@vger.kernel.org 237L: linux-acpi@vger.kernel.org
238W: http://acpi.sourceforge.net/ 238W: http://acpi.sourceforge.net/
239S: Supported 239S: Supported
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index b87cedeaf59b..cacdd883bf2b 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -986,14 +986,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
986 }, 986 },
987 { 987 {
988 .callback = force_acpi_ht, 988 .callback = force_acpi_ht,
989 .ident = "DELL GX240",
990 .matches = {
991 DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
992 DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
993 },
994 },
995 {
996 .callback = force_acpi_ht,
997 .ident = "HP VISUALIZE NT Workstation", 989 .ident = "HP VISUALIZE NT Workstation",
998 .matches = { 990 .matches = {
999 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), 991 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 18c8b67ea3a7..6f846bee2103 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -665,8 +665,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
665 data->max_freq = perf->states[0].core_frequency * 1000; 665 data->max_freq = perf->states[0].core_frequency * 1000;
666 /* table init */ 666 /* table init */
667 for (i=0; i<perf->state_count; i++) { 667 for (i=0; i<perf->state_count; i++) {
668 if (i>0 && perf->states[i].core_frequency == 668 if (i>0 && perf->states[i].core_frequency >=
669 perf->states[i-1].core_frequency) 669 data->freq_table[valid_states-1].frequency / 1000)
670 continue; 670 continue;
671 671
672 data->freq_table[valid_states].index = i; 672 data->freq_table[valid_states].index = i;
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 139f41f033d8..408b45168aba 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -2,16 +2,12 @@
2# ACPI Configuration 2# ACPI Configuration
3# 3#
4 4
5menu "ACPI (Advanced Configuration and Power Interface) Support" 5menuconfig ACPI
6 bool "ACPI Support (Advanced Configuration and Power Interface) Support"
6 depends on !X86_NUMAQ 7 depends on !X86_NUMAQ
7 depends on !X86_VISWS 8 depends on !X86_VISWS
8 depends on !IA64_HP_SIM 9 depends on !IA64_HP_SIM
9 depends on IA64 || X86 10 depends on IA64 || X86
10 depends on PM
11
12config ACPI
13 bool "ACPI Support"
14 depends on IA64 || X86
15 depends on PCI 11 depends on PCI
16 depends on PM 12 depends on PM
17 select PNP 13 select PNP
@@ -49,7 +45,6 @@ if ACPI
49config ACPI_SLEEP 45config ACPI_SLEEP
50 bool "Sleep States" 46 bool "Sleep States"
51 depends on X86 && (!SMP || SUSPEND_SMP) 47 depends on X86 && (!SMP || SUSPEND_SMP)
52 depends on PM
53 default y 48 default y
54 ---help--- 49 ---help---
55 This option adds support for ACPI suspend states. 50 This option adds support for ACPI suspend states.
@@ -82,7 +77,6 @@ config ACPI_SLEEP_PROC_SLEEP
82 77
83config ACPI_PROCFS 78config ACPI_PROCFS
84 bool "Procfs interface (deprecated)" 79 bool "Procfs interface (deprecated)"
85 depends on ACPI
86 default y 80 default y
87 ---help--- 81 ---help---
88 The Procfs interface for ACPI is made optional for backward compatibility. 82 The Procfs interface for ACPI is made optional for backward compatibility.
@@ -124,7 +118,7 @@ config ACPI_BUTTON
124 118
125config ACPI_VIDEO 119config ACPI_VIDEO
126 tristate "Video" 120 tristate "Video"
127 depends on X86 && BACKLIGHT_CLASS_DEVICE 121 depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
128 help 122 help
129 This driver implement the ACPI Extensions For Display Adapters 123 This driver implement the ACPI Extensions For Display Adapters
130 for integrated graphics devices on motherboard, as specified in 124 for integrated graphics devices on motherboard, as specified in
@@ -280,6 +274,14 @@ config ACPI_DEBUG
280 of verbosity. Saying Y enables these statements. This will increase 274 of verbosity. Saying Y enables these statements. This will increase
281 your kernel size by around 50K. 275 your kernel size by around 50K.
282 276
277config ACPI_DEBUG_FUNC_TRACE
278 bool "Additionally enable ACPI function tracing"
279 default n
280 depends on ACPI_DEBUG
281 help
282 ACPI Debug Statements slow down ACPI processing. Function trace
283 is about half of the penalty and is rarely useful.
284
283config ACPI_EC 285config ACPI_EC
284 bool 286 bool
285 default y 287 default y
@@ -330,7 +332,6 @@ config ACPI_CONTAINER
330 332
331config ACPI_HOTPLUG_MEMORY 333config ACPI_HOTPLUG_MEMORY
332 tristate "Memory Hotplug" 334 tristate "Memory Hotplug"
333 depends on ACPI
334 depends on MEMORY_HOTPLUG 335 depends on MEMORY_HOTPLUG
335 default n 336 default n
336 help 337 help
@@ -359,5 +360,3 @@ config ACPI_SBS
359 to today's ACPI "Control Method" battery. 360 to today's ACPI "Control Method" battery.
360 361
361endif # ACPI 362endif # ACPI
362
363endmenu
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index e64c76c8b726..cad932de383d 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -43,21 +43,30 @@
43#define ACPI_BATTERY_CLASS "battery" 43#define ACPI_BATTERY_CLASS "battery"
44#define ACPI_BATTERY_HID "PNP0C0A" 44#define ACPI_BATTERY_HID "PNP0C0A"
45#define ACPI_BATTERY_DEVICE_NAME "Battery" 45#define ACPI_BATTERY_DEVICE_NAME "Battery"
46#define ACPI_BATTERY_FILE_INFO "info"
47#define ACPI_BATTERY_FILE_STATUS "state"
48#define ACPI_BATTERY_FILE_ALARM "alarm"
49#define ACPI_BATTERY_NOTIFY_STATUS 0x80 46#define ACPI_BATTERY_NOTIFY_STATUS 0x80
50#define ACPI_BATTERY_NOTIFY_INFO 0x81 47#define ACPI_BATTERY_NOTIFY_INFO 0x81
51#define ACPI_BATTERY_UNITS_WATTS "mW" 48#define ACPI_BATTERY_UNITS_WATTS "mW"
52#define ACPI_BATTERY_UNITS_AMPS "mA" 49#define ACPI_BATTERY_UNITS_AMPS "mA"
53 50
54#define _COMPONENT ACPI_BATTERY_COMPONENT 51#define _COMPONENT ACPI_BATTERY_COMPONENT
52
53#define ACPI_BATTERY_UPDATE_TIME 0
54
55#define ACPI_BATTERY_NONE_UPDATE 0
56#define ACPI_BATTERY_EASY_UPDATE 1
57#define ACPI_BATTERY_INIT_UPDATE 2
58
55ACPI_MODULE_NAME("battery"); 59ACPI_MODULE_NAME("battery");
56 60
57MODULE_AUTHOR("Paul Diefenbaugh"); 61MODULE_AUTHOR("Paul Diefenbaugh");
58MODULE_DESCRIPTION("ACPI Battery Driver"); 62MODULE_DESCRIPTION("ACPI Battery Driver");
59MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
60 64
65static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
66
67/* 0 - every time, > 0 - by update_time */
68module_param(update_time, uint, 0644);
69
61extern struct proc_dir_entry *acpi_lock_battery_dir(void); 70extern struct proc_dir_entry *acpi_lock_battery_dir(void);
62extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); 71extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
63 72
@@ -76,7 +85,7 @@ static struct acpi_driver acpi_battery_driver = {
76 }, 85 },
77}; 86};
78 87
79struct acpi_battery_status { 88struct acpi_battery_state {
80 acpi_integer state; 89 acpi_integer state;
81 acpi_integer present_rate; 90 acpi_integer present_rate;
82 acpi_integer remaining_capacity; 91 acpi_integer remaining_capacity;
@@ -99,33 +108,111 @@ struct acpi_battery_info {
99 acpi_string oem_info; 108 acpi_string oem_info;
100}; 109};
101 110
102struct acpi_battery_flags { 111enum acpi_battery_files{
103 u8 present:1; /* Bay occupied? */ 112 ACPI_BATTERY_INFO = 0,
104 u8 power_unit:1; /* 0=watts, 1=apms */ 113 ACPI_BATTERY_STATE,
105 u8 alarm:1; /* _BTP present? */ 114 ACPI_BATTERY_ALARM,
106 u8 reserved:5; 115 ACPI_BATTERY_NUMFILES,
107}; 116};
108 117
109struct acpi_battery_trips { 118struct acpi_battery_flags {
110 unsigned long warning; 119 u8 battery_present_prev;
111 unsigned long low; 120 u8 alarm_present;
121 u8 init_update;
122 u8 update[ACPI_BATTERY_NUMFILES];
123 u8 power_unit;
112}; 124};
113 125
114struct acpi_battery { 126struct acpi_battery {
115 struct acpi_device * device; 127 struct mutex mutex;
128 struct acpi_device *device;
116 struct acpi_battery_flags flags; 129 struct acpi_battery_flags flags;
117 struct acpi_battery_trips trips; 130 struct acpi_buffer bif_data;
131 struct acpi_buffer bst_data;
118 unsigned long alarm; 132 unsigned long alarm;
119 struct acpi_battery_info *info; 133 unsigned long update_time[ACPI_BATTERY_NUMFILES];
120}; 134};
121 135
136inline int acpi_battery_present(struct acpi_battery *battery)
137{
138 return battery->device->status.battery_present;
139}
140inline char *acpi_battery_power_units(struct acpi_battery *battery)
141{
142 if (battery->flags.power_unit)
143 return ACPI_BATTERY_UNITS_AMPS;
144 else
145 return ACPI_BATTERY_UNITS_WATTS;
146}
147
148inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
149{
150 return battery->device->handle;
151}
152
122/* -------------------------------------------------------------------------- 153/* --------------------------------------------------------------------------
123 Battery Management 154 Battery Management
124 -------------------------------------------------------------------------- */ 155 -------------------------------------------------------------------------- */
125 156
126static int 157static void acpi_battery_check_result(struct acpi_battery *battery, int result)
127acpi_battery_get_info(struct acpi_battery *battery, 158{
128 struct acpi_battery_info **bif) 159 if (!battery)
160 return;
161
162 if (result) {
163 battery->flags.init_update = 1;
164 }
165}
166
167static int acpi_battery_extract_package(struct acpi_battery *battery,
168 union acpi_object *package,
169 struct acpi_buffer *format,
170 struct acpi_buffer *data,
171 char *package_name)
172{
173 acpi_status status = AE_OK;
174 struct acpi_buffer data_null = { 0, NULL };
175
176 status = acpi_extract_package(package, format, &data_null);
177 if (status != AE_BUFFER_OVERFLOW) {
178 ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
179 package_name));
180 return -ENODEV;
181 }
182
183 if (data_null.length != data->length) {
184 kfree(data->pointer);
185 data->pointer = kzalloc(data_null.length, GFP_KERNEL);
186 if (!data->pointer) {
187 ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
188 return -ENOMEM;
189 }
190 data->length = data_null.length;
191 }
192
193 status = acpi_extract_package(package, format, data);
194 if (ACPI_FAILURE(status)) {
195 ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
196 package_name));
197 return -ENODEV;
198 }
199
200 return 0;
201}
202
203static int acpi_battery_get_status(struct acpi_battery *battery)
204{
205 int result = 0;
206
207 result = acpi_bus_get_status(battery->device);
208 if (result) {
209 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
210 return -ENODEV;
211 }
212 return result;
213}
214
215static int acpi_battery_get_info(struct acpi_battery *battery)
129{ 216{
130 int result = 0; 217 int result = 0;
131 acpi_status status = 0; 218 acpi_status status = 0;
@@ -133,16 +220,20 @@ acpi_battery_get_info(struct acpi_battery *battery,
133 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), 220 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
134 ACPI_BATTERY_FORMAT_BIF 221 ACPI_BATTERY_FORMAT_BIF
135 }; 222 };
136 struct acpi_buffer data = { 0, NULL };
137 union acpi_object *package = NULL; 223 union acpi_object *package = NULL;
224 struct acpi_buffer *data = NULL;
225 struct acpi_battery_info *bif = NULL;
138 226
227 battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
139 228
140 if (!battery || !bif) 229 if (!acpi_battery_present(battery))
141 return -EINVAL; 230 return 0;
142 231
143 /* Evalute _BIF */ 232 /* Evaluate _BIF */
144 233
145 status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); 234 status =
235 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
236 &buffer);
146 if (ACPI_FAILURE(status)) { 237 if (ACPI_FAILURE(status)) {
147 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 238 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
148 return -ENODEV; 239 return -ENODEV;
@@ -150,41 +241,29 @@ acpi_battery_get_info(struct acpi_battery *battery,
150 241
151 package = buffer.pointer; 242 package = buffer.pointer;
152 243
153 /* Extract Package Data */ 244 data = &battery->bif_data;
154
155 status = acpi_extract_package(package, &format, &data);
156 if (status != AE_BUFFER_OVERFLOW) {
157 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF"));
158 result = -ENODEV;
159 goto end;
160 }
161 245
162 data.pointer = kzalloc(data.length, GFP_KERNEL); 246 /* Extract Package Data */
163 if (!data.pointer) {
164 result = -ENOMEM;
165 goto end;
166 }
167 247
168 status = acpi_extract_package(package, &format, &data); 248 result =
169 if (ACPI_FAILURE(status)) { 249 acpi_battery_extract_package(battery, package, &format, data,
170 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); 250 "_BIF");
171 kfree(data.pointer); 251 if (result)
172 result = -ENODEV;
173 goto end; 252 goto end;
174 }
175 253
176 end: 254 end:
255
177 kfree(buffer.pointer); 256 kfree(buffer.pointer);
178 257
179 if (!result) 258 if (!result) {
180 (*bif) = data.pointer; 259 bif = data->pointer;
260 battery->flags.power_unit = bif->power_unit;
261 }
181 262
182 return result; 263 return result;
183} 264}
184 265
185static int 266static int acpi_battery_get_state(struct acpi_battery *battery)
186acpi_battery_get_status(struct acpi_battery *battery,
187 struct acpi_battery_status **bst)
188{ 267{
189 int result = 0; 268 int result = 0;
190 acpi_status status = 0; 269 acpi_status status = 0;
@@ -192,16 +271,19 @@ acpi_battery_get_status(struct acpi_battery *battery,
192 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), 271 struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
193 ACPI_BATTERY_FORMAT_BST 272 ACPI_BATTERY_FORMAT_BST
194 }; 273 };
195 struct acpi_buffer data = { 0, NULL };
196 union acpi_object *package = NULL; 274 union acpi_object *package = NULL;
275 struct acpi_buffer *data = NULL;
197 276
277 battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
198 278
199 if (!battery || !bst) 279 if (!acpi_battery_present(battery))
200 return -EINVAL; 280 return 0;
201 281
202 /* Evalute _BST */ 282 /* Evaluate _BST */
203 283
204 status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); 284 status =
285 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
286 &buffer);
205 if (ACPI_FAILURE(status)) { 287 if (ACPI_FAILURE(status)) {
206 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 288 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
207 return -ENODEV; 289 return -ENODEV;
@@ -209,55 +291,49 @@ acpi_battery_get_status(struct acpi_battery *battery,
209 291
210 package = buffer.pointer; 292 package = buffer.pointer;
211 293
212 /* Extract Package Data */ 294 data = &battery->bst_data;
213
214 status = acpi_extract_package(package, &format, &data);
215 if (status != AE_BUFFER_OVERFLOW) {
216 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST"));
217 result = -ENODEV;
218 goto end;
219 }
220 295
221 data.pointer = kzalloc(data.length, GFP_KERNEL); 296 /* Extract Package Data */
222 if (!data.pointer) {
223 result = -ENOMEM;
224 goto end;
225 }
226 297
227 status = acpi_extract_package(package, &format, &data); 298 result =
228 if (ACPI_FAILURE(status)) { 299 acpi_battery_extract_package(battery, package, &format, data,
229 ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); 300 "_BST");
230 kfree(data.pointer); 301 if (result)
231 result = -ENODEV;
232 goto end; 302 goto end;
233 }
234 303
235 end: 304 end:
236 kfree(buffer.pointer); 305 kfree(buffer.pointer);
237 306
238 if (!result)
239 (*bst) = data.pointer;
240
241 return result; 307 return result;
242} 308}
243 309
244static int 310static int acpi_battery_get_alarm(struct acpi_battery *battery)
245acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) 311{
312 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
313
314 return 0;
315}
316
317static int acpi_battery_set_alarm(struct acpi_battery *battery,
318 unsigned long alarm)
246{ 319{
247 acpi_status status = 0; 320 acpi_status status = 0;
248 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 321 union acpi_object arg0 = { ACPI_TYPE_INTEGER };
249 struct acpi_object_list arg_list = { 1, &arg0 }; 322 struct acpi_object_list arg_list = { 1, &arg0 };
250 323
324 battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
251 325
252 if (!battery) 326 if (!acpi_battery_present(battery))
253 return -EINVAL; 327 return -ENODEV;
254 328
255 if (!battery->flags.alarm) 329 if (!battery->flags.alarm_present)
256 return -ENODEV; 330 return -ENODEV;
257 331
258 arg0.integer.value = alarm; 332 arg0.integer.value = alarm;
259 333
260 status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); 334 status =
335 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
336 &arg_list, NULL);
261 if (ACPI_FAILURE(status)) 337 if (ACPI_FAILURE(status))
262 return -ENODEV; 338 return -ENODEV;
263 339
@@ -268,65 +344,114 @@ acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm)
268 return 0; 344 return 0;
269} 345}
270 346
271static int acpi_battery_check(struct acpi_battery *battery) 347static int acpi_battery_init_alarm(struct acpi_battery *battery)
272{ 348{
273 int result = 0; 349 int result = 0;
274 acpi_status status = AE_OK; 350 acpi_status status = AE_OK;
275 acpi_handle handle = NULL; 351 acpi_handle handle = NULL;
276 struct acpi_device *device = NULL; 352 struct acpi_battery_info *bif = battery->bif_data.pointer;
277 struct acpi_battery_info *bif = NULL; 353 unsigned long alarm = battery->alarm;
278 354
355 /* See if alarms are supported, and if so, set default */
279 356
280 if (!battery) 357 status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
281 return -EINVAL; 358 if (ACPI_SUCCESS(status)) {
282 359 battery->flags.alarm_present = 1;
283 device = battery->device; 360 if (!alarm && bif) {
361 alarm = bif->design_capacity_warning;
362 }
363 result = acpi_battery_set_alarm(battery, alarm);
364 if (result)
365 goto end;
366 } else {
367 battery->flags.alarm_present = 0;
368 }
284 369
285 result = acpi_bus_get_status(device); 370 end:
286 if (result)
287 return result;
288 371
289 /* Insertion? */ 372 return result;
373}
290 374
291 if (!battery->flags.present && device->status.battery_present) { 375static int acpi_battery_init_update(struct acpi_battery *battery)
376{
377 int result = 0;
292 378
293 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); 379 result = acpi_battery_get_status(battery);
380 if (result)
381 return result;
294 382
295 /* Evalute _BIF to get certain static information */ 383 battery->flags.battery_present_prev = acpi_battery_present(battery);
296 384
297 result = acpi_battery_get_info(battery, &bif); 385 if (acpi_battery_present(battery)) {
386 result = acpi_battery_get_info(battery);
387 if (result)
388 return result;
389 result = acpi_battery_get_state(battery);
298 if (result) 390 if (result)
299 return result; 391 return result;
300 392
301 battery->flags.power_unit = bif->power_unit; 393 acpi_battery_init_alarm(battery);
302 battery->trips.warning = bif->design_capacity_warning; 394 }
303 battery->trips.low = bif->design_capacity_low; 395
304 kfree(bif); 396 return result;
397}
305 398
306 /* See if alarms are supported, and if so, set default */ 399static int acpi_battery_update(struct acpi_battery *battery,
400 int update, int *update_result_ptr)
401{
402 int result = 0;
403 int update_result = ACPI_BATTERY_NONE_UPDATE;
404
405 if (!acpi_battery_present(battery)) {
406 update = 1;
407 }
307 408
308 status = acpi_get_handle(battery->device->handle, "_BTP", &handle); 409 if (battery->flags.init_update) {
309 if (ACPI_SUCCESS(status)) { 410 result = acpi_battery_init_update(battery);
310 battery->flags.alarm = 1; 411 if (result)
311 acpi_battery_set_alarm(battery, battery->trips.warning); 412 goto end;
413 update_result = ACPI_BATTERY_INIT_UPDATE;
414 } else if (update) {
415 result = acpi_battery_get_status(battery);
416 if (result)
417 goto end;
418 if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
419 || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
420 result = acpi_battery_init_update(battery);
421 if (result)
422 goto end;
423 update_result = ACPI_BATTERY_INIT_UPDATE;
424 } else {
425 update_result = ACPI_BATTERY_EASY_UPDATE;
312 } 426 }
313 } 427 }
314 428
315 /* Removal? */ 429 end:
316 430
317 else if (battery->flags.present && !device->status.battery_present) { 431 battery->flags.init_update = (result != 0);
318 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n"));
319 }
320 432
321 battery->flags.present = device->status.battery_present; 433 *update_result_ptr = update_result;
322 434
323 return result; 435 return result;
324} 436}
325 437
326static void acpi_battery_check_present(struct acpi_battery *battery) 438static void acpi_battery_notify_update(struct acpi_battery *battery)
327{ 439{
328 if (!battery->flags.present) { 440 acpi_battery_get_status(battery);
329 acpi_battery_check(battery); 441
442 if (battery->flags.init_update) {
443 return;
444 }
445
446 if ((!battery->flags.battery_present_prev &
447 acpi_battery_present(battery)) ||
448 (battery->flags.battery_present_prev &
449 !acpi_battery_present(battery))) {
450 battery->flags.init_update = 1;
451 } else {
452 battery->flags.update[ACPI_BATTERY_INFO] = 1;
453 battery->flags.update[ACPI_BATTERY_STATE] = 1;
454 battery->flags.update[ACPI_BATTERY_ALARM] = 1;
330 } 455 }
331} 456}
332 457
@@ -335,37 +460,33 @@ static void acpi_battery_check_present(struct acpi_battery *battery)
335 -------------------------------------------------------------------------- */ 460 -------------------------------------------------------------------------- */
336 461
337static struct proc_dir_entry *acpi_battery_dir; 462static struct proc_dir_entry *acpi_battery_dir;
338static int acpi_battery_read_info(struct seq_file *seq, void *offset) 463
464static int acpi_battery_print_info(struct seq_file *seq, int result)
339{ 465{
340 int result = 0;
341 struct acpi_battery *battery = seq->private; 466 struct acpi_battery *battery = seq->private;
342 struct acpi_battery_info *bif = NULL; 467 struct acpi_battery_info *bif = NULL;
343 char *units = "?"; 468 char *units = "?";
344 469
345 470 if (result)
346 if (!battery)
347 goto end; 471 goto end;
348 472
349 acpi_battery_check_present(battery); 473 if (acpi_battery_present(battery))
350
351 if (battery->flags.present)
352 seq_printf(seq, "present: yes\n"); 474 seq_printf(seq, "present: yes\n");
353 else { 475 else {
354 seq_printf(seq, "present: no\n"); 476 seq_printf(seq, "present: no\n");
355 goto end; 477 goto end;
356 } 478 }
357 479
358 /* Battery Info (_BIF) */ 480 bif = battery->bif_data.pointer;
359 481 if (!bif) {
360 result = acpi_battery_get_info(battery, &bif); 482 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
361 if (result || !bif) { 483 result = -ENODEV;
362 seq_printf(seq, "ERROR: Unable to read battery information\n");
363 goto end; 484 goto end;
364 } 485 }
365 486
366 units = 487 /* Battery Units */
367 bif-> 488
368 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; 489 units = acpi_battery_power_units(battery);
369 490
370 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) 491 if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
371 seq_printf(seq, "design capacity: unknown\n"); 492 seq_printf(seq, "design capacity: unknown\n");
@@ -396,7 +517,6 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
396 else 517 else
397 seq_printf(seq, "design voltage: %d mV\n", 518 seq_printf(seq, "design voltage: %d mV\n",
398 (u32) bif->design_voltage); 519 (u32) bif->design_voltage);
399
400 seq_printf(seq, "design capacity warning: %d %sh\n", 520 seq_printf(seq, "design capacity warning: %d %sh\n",
401 (u32) bif->design_capacity_warning, units); 521 (u32) bif->design_capacity_warning, units);
402 seq_printf(seq, "design capacity low: %d %sh\n", 522 seq_printf(seq, "design capacity low: %d %sh\n",
@@ -411,50 +531,40 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
411 seq_printf(seq, "OEM info: %s\n", bif->oem_info); 531 seq_printf(seq, "OEM info: %s\n", bif->oem_info);
412 532
413 end: 533 end:
414 kfree(bif);
415 534
416 return 0; 535 if (result)
417} 536 seq_printf(seq, "ERROR: Unable to read battery info\n");
418 537
419static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) 538 return result;
420{
421 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
422} 539}
423 540
424static int acpi_battery_read_state(struct seq_file *seq, void *offset) 541static int acpi_battery_print_state(struct seq_file *seq, int result)
425{ 542{
426 int result = 0;
427 struct acpi_battery *battery = seq->private; 543 struct acpi_battery *battery = seq->private;
428 struct acpi_battery_status *bst = NULL; 544 struct acpi_battery_state *bst = NULL;
429 char *units = "?"; 545 char *units = "?";
430 546
431 547 if (result)
432 if (!battery)
433 goto end; 548 goto end;
434 549
435 acpi_battery_check_present(battery); 550 if (acpi_battery_present(battery))
436
437 if (battery->flags.present)
438 seq_printf(seq, "present: yes\n"); 551 seq_printf(seq, "present: yes\n");
439 else { 552 else {
440 seq_printf(seq, "present: no\n"); 553 seq_printf(seq, "present: no\n");
441 goto end; 554 goto end;
442 } 555 }
443 556
444 /* Battery Units */ 557 bst = battery->bst_data.pointer;
445 558 if (!bst) {
446 units = 559 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
447 battery->flags. 560 result = -ENODEV;
448 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
449
450 /* Battery Status (_BST) */
451
452 result = acpi_battery_get_status(battery, &bst);
453 if (result || !bst) {
454 seq_printf(seq, "ERROR: Unable to read battery status\n");
455 goto end; 561 goto end;
456 } 562 }
457 563
564 /* Battery Units */
565
566 units = acpi_battery_power_units(battery);
567
458 if (!(bst->state & 0x04)) 568 if (!(bst->state & 0x04))
459 seq_printf(seq, "capacity state: ok\n"); 569 seq_printf(seq, "capacity state: ok\n");
460 else 570 else
@@ -490,48 +600,43 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
490 (u32) bst->present_voltage); 600 (u32) bst->present_voltage);
491 601
492 end: 602 end:
493 kfree(bst);
494 603
495 return 0; 604 if (result) {
496} 605 seq_printf(seq, "ERROR: Unable to read battery state\n");
606 }
497 607
498static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) 608 return result;
499{
500 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
501} 609}
502 610
503static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 611static int acpi_battery_print_alarm(struct seq_file *seq, int result)
504{ 612{
505 struct acpi_battery *battery = seq->private; 613 struct acpi_battery *battery = seq->private;
506 char *units = "?"; 614 char *units = "?";
507 615
508 616 if (result)
509 if (!battery)
510 goto end; 617 goto end;
511 618
512 acpi_battery_check_present(battery); 619 if (!acpi_battery_present(battery)) {
513
514 if (!battery->flags.present) {
515 seq_printf(seq, "present: no\n"); 620 seq_printf(seq, "present: no\n");
516 goto end; 621 goto end;
517 } 622 }
518 623
519 /* Battery Units */ 624 /* Battery Units */
520 625
521 units = 626 units = acpi_battery_power_units(battery);
522 battery->flags.
523 power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS;
524
525 /* Battery Alarm */
526 627
527 seq_printf(seq, "alarm: "); 628 seq_printf(seq, "alarm: ");
528 if (!battery->alarm) 629 if (!battery->alarm)
529 seq_printf(seq, "unsupported\n"); 630 seq_printf(seq, "unsupported\n");
530 else 631 else
531 seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); 632 seq_printf(seq, "%lu %sh\n", battery->alarm, units);
532 633
533 end: 634 end:
534 return 0; 635
636 if (result)
637 seq_printf(seq, "ERROR: Unable to read battery alarm\n");
638
639 return result;
535} 640}
536 641
537static ssize_t 642static ssize_t
@@ -543,27 +648,113 @@ acpi_battery_write_alarm(struct file *file,
543 char alarm_string[12] = { '\0' }; 648 char alarm_string[12] = { '\0' };
544 struct seq_file *m = file->private_data; 649 struct seq_file *m = file->private_data;
545 struct acpi_battery *battery = m->private; 650 struct acpi_battery *battery = m->private;
546 651 int update_result = ACPI_BATTERY_NONE_UPDATE;
547 652
548 if (!battery || (count > sizeof(alarm_string) - 1)) 653 if (!battery || (count > sizeof(alarm_string) - 1))
549 return -EINVAL; 654 return -EINVAL;
550 655
551 acpi_battery_check_present(battery); 656 mutex_lock(&battery->mutex);
552 657
553 if (!battery->flags.present) 658 result = acpi_battery_update(battery, 1, &update_result);
554 return -ENODEV; 659 if (result) {
660 result = -ENODEV;
661 goto end;
662 }
663
664 if (!acpi_battery_present(battery)) {
665 result = -ENODEV;
666 goto end;
667 }
555 668
556 if (copy_from_user(alarm_string, buffer, count)) 669 if (copy_from_user(alarm_string, buffer, count)) {
557 return -EFAULT; 670 result = -EFAULT;
671 goto end;
672 }
558 673
559 alarm_string[count] = '\0'; 674 alarm_string[count] = '\0';
560 675
561 result = acpi_battery_set_alarm(battery, 676 result = acpi_battery_set_alarm(battery,
562 simple_strtoul(alarm_string, NULL, 0)); 677 simple_strtoul(alarm_string, NULL, 0));
563 if (result) 678 if (result)
564 return result; 679 goto end;
680
681 end:
565 682
566 return count; 683 acpi_battery_check_result(battery, result);
684
685 if (!result)
686 result = count;
687
688 mutex_unlock(&battery->mutex);
689
690 return result;
691}
692
693typedef int(*print_func)(struct seq_file *seq, int result);
694typedef int(*get_func)(struct acpi_battery *battery);
695
696static struct acpi_read_mux {
697 print_func print;
698 get_func get;
699} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
700 {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
701 {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
702 {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
703};
704
705static int acpi_battery_read(int fid, struct seq_file *seq)
706{
707 struct acpi_battery *battery = seq->private;
708 int result = 0;
709 int update_result = ACPI_BATTERY_NONE_UPDATE;
710 int update = 0;
711
712 mutex_lock(&battery->mutex);
713
714 update = (get_seconds() - battery->update_time[fid] >= update_time);
715 update = (update | battery->flags.update[fid]);
716
717 result = acpi_battery_update(battery, update, &update_result);
718 if (result)
719 goto end;
720
721 if (update_result == ACPI_BATTERY_EASY_UPDATE) {
722 result = acpi_read_funcs[fid].get(battery);
723 if (result)
724 goto end;
725 }
726
727 end:
728 result = acpi_read_funcs[fid].print(seq, result);
729 acpi_battery_check_result(battery, result);
730 battery->flags.update[fid] = result;
731 mutex_unlock(&battery->mutex);
732 return result;
733}
734
735static int acpi_battery_read_info(struct seq_file *seq, void *offset)
736{
737 return acpi_battery_read(ACPI_BATTERY_INFO, seq);
738}
739
740static int acpi_battery_read_state(struct seq_file *seq, void *offset)
741{
742 return acpi_battery_read(ACPI_BATTERY_STATE, seq);
743}
744
745static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
746{
747 return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
748}
749
750static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
751{
752 return single_open(file, acpi_battery_read_info, PDE(inode)->data);
753}
754
755static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
756{
757 return single_open(file, acpi_battery_read_state, PDE(inode)->data);
567} 758}
568 759
569static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) 760static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -571,35 +762,51 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
571 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); 762 return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
572} 763}
573 764
574static const struct file_operations acpi_battery_info_ops = { 765static struct battery_file {
766 struct file_operations ops;
767 mode_t mode;
768 char *name;
769} acpi_battery_file[] = {
770 {
771 .name = "info",
772 .mode = S_IRUGO,
773 .ops = {
575 .open = acpi_battery_info_open_fs, 774 .open = acpi_battery_info_open_fs,
576 .read = seq_read, 775 .read = seq_read,
577 .llseek = seq_lseek, 776 .llseek = seq_lseek,
578 .release = single_release, 777 .release = single_release,
579 .owner = THIS_MODULE, 778 .owner = THIS_MODULE,
580}; 779 },
581 780 },
582static const struct file_operations acpi_battery_state_ops = { 781 {
782 .name = "state",
783 .mode = S_IRUGO,
784 .ops = {
583 .open = acpi_battery_state_open_fs, 785 .open = acpi_battery_state_open_fs,
584 .read = seq_read, 786 .read = seq_read,
585 .llseek = seq_lseek, 787 .llseek = seq_lseek,
586 .release = single_release, 788 .release = single_release,
587 .owner = THIS_MODULE, 789 .owner = THIS_MODULE,
588}; 790 },
589 791 },
590static const struct file_operations acpi_battery_alarm_ops = { 792 {
793 .name = "alarm",
794 .mode = S_IFREG | S_IRUGO | S_IWUSR,
795 .ops = {
591 .open = acpi_battery_alarm_open_fs, 796 .open = acpi_battery_alarm_open_fs,
592 .read = seq_read, 797 .read = seq_read,
593 .write = acpi_battery_write_alarm, 798 .write = acpi_battery_write_alarm,
594 .llseek = seq_lseek, 799 .llseek = seq_lseek,
595 .release = single_release, 800 .release = single_release,
596 .owner = THIS_MODULE, 801 .owner = THIS_MODULE,
802 },
803 },
597}; 804};
598 805
599static int acpi_battery_add_fs(struct acpi_device *device) 806static int acpi_battery_add_fs(struct acpi_device *device)
600{ 807{
601 struct proc_dir_entry *entry = NULL; 808 struct proc_dir_entry *entry = NULL;
602 809 int i;
603 810
604 if (!acpi_device_dir(device)) { 811 if (!acpi_device_dir(device)) {
605 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 812 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -609,38 +816,16 @@ static int acpi_battery_add_fs(struct acpi_device *device)
609 acpi_device_dir(device)->owner = THIS_MODULE; 816 acpi_device_dir(device)->owner = THIS_MODULE;
610 } 817 }
611 818
612 /* 'info' [R] */ 819 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
613 entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, 820 entry = create_proc_entry(acpi_battery_file[i].name,
614 S_IRUGO, acpi_device_dir(device)); 821 acpi_battery_file[i].mode, acpi_device_dir(device));
615 if (!entry) 822 if (!entry)
616 return -ENODEV; 823 return -ENODEV;
617 else { 824 else {
618 entry->proc_fops = &acpi_battery_info_ops; 825 entry->proc_fops = &acpi_battery_file[i].ops;
619 entry->data = acpi_driver_data(device); 826 entry->data = acpi_driver_data(device);
620 entry->owner = THIS_MODULE; 827 entry->owner = THIS_MODULE;
621 } 828 }
622
623 /* 'status' [R] */
624 entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS,
625 S_IRUGO, acpi_device_dir(device));
626 if (!entry)
627 return -ENODEV;
628 else {
629 entry->proc_fops = &acpi_battery_state_ops;
630 entry->data = acpi_driver_data(device);
631 entry->owner = THIS_MODULE;
632 }
633
634 /* 'alarm' [R/W] */
635 entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM,
636 S_IFREG | S_IRUGO | S_IWUSR,
637 acpi_device_dir(device));
638 if (!entry)
639 return -ENODEV;
640 else {
641 entry->proc_fops = &acpi_battery_alarm_ops;
642 entry->data = acpi_driver_data(device);
643 entry->owner = THIS_MODULE;
644 } 829 }
645 830
646 return 0; 831 return 0;
@@ -648,15 +833,12 @@ static int acpi_battery_add_fs(struct acpi_device *device)
648 833
649static int acpi_battery_remove_fs(struct acpi_device *device) 834static int acpi_battery_remove_fs(struct acpi_device *device)
650{ 835{
651 836 int i;
652 if (acpi_device_dir(device)) { 837 if (acpi_device_dir(device)) {
653 remove_proc_entry(ACPI_BATTERY_FILE_ALARM, 838 for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
839 remove_proc_entry(acpi_battery_file[i].name,
654 acpi_device_dir(device)); 840 acpi_device_dir(device));
655 remove_proc_entry(ACPI_BATTERY_FILE_STATUS, 841 }
656 acpi_device_dir(device));
657 remove_proc_entry(ACPI_BATTERY_FILE_INFO,
658 acpi_device_dir(device));
659
660 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); 842 remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
661 acpi_device_dir(device) = NULL; 843 acpi_device_dir(device) = NULL;
662 } 844 }
@@ -673,7 +855,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
673 struct acpi_battery *battery = data; 855 struct acpi_battery *battery = data;
674 struct acpi_device *device = NULL; 856 struct acpi_device *device = NULL;
675 857
676
677 if (!battery) 858 if (!battery)
678 return; 859 return;
679 860
@@ -684,8 +865,10 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
684 case ACPI_BATTERY_NOTIFY_INFO: 865 case ACPI_BATTERY_NOTIFY_INFO:
685 case ACPI_NOTIFY_BUS_CHECK: 866 case ACPI_NOTIFY_BUS_CHECK:
686 case ACPI_NOTIFY_DEVICE_CHECK: 867 case ACPI_NOTIFY_DEVICE_CHECK:
687 acpi_battery_check(battery); 868 device = battery->device;
688 acpi_bus_generate_event(device, event, battery->flags.present); 869 acpi_battery_notify_update(battery);
870 acpi_bus_generate_event(device, event,
871 acpi_battery_present(battery));
689 break; 872 break;
690 default: 873 default:
691 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 874 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -702,7 +885,6 @@ static int acpi_battery_add(struct acpi_device *device)
702 acpi_status status = 0; 885 acpi_status status = 0;
703 struct acpi_battery *battery = NULL; 886 struct acpi_battery *battery = NULL;
704 887
705
706 if (!device) 888 if (!device)
707 return -EINVAL; 889 return -EINVAL;
708 890
@@ -710,15 +892,21 @@ static int acpi_battery_add(struct acpi_device *device)
710 if (!battery) 892 if (!battery)
711 return -ENOMEM; 893 return -ENOMEM;
712 894
895 mutex_init(&battery->mutex);
896
897 mutex_lock(&battery->mutex);
898
713 battery->device = device; 899 battery->device = device;
714 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 900 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
715 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 901 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
716 acpi_driver_data(device) = battery; 902 acpi_driver_data(device) = battery;
717 903
718 result = acpi_battery_check(battery); 904 result = acpi_battery_get_status(battery);
719 if (result) 905 if (result)
720 goto end; 906 goto end;
721 907
908 battery->flags.init_update = 1;
909
722 result = acpi_battery_add_fs(device); 910 result = acpi_battery_add_fs(device);
723 if (result) 911 if (result)
724 goto end; 912 goto end;
@@ -727,6 +915,7 @@ static int acpi_battery_add(struct acpi_device *device)
727 ACPI_ALL_NOTIFY, 915 ACPI_ALL_NOTIFY,
728 acpi_battery_notify, battery); 916 acpi_battery_notify, battery);
729 if (ACPI_FAILURE(status)) { 917 if (ACPI_FAILURE(status)) {
918 ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler"));
730 result = -ENODEV; 919 result = -ENODEV;
731 goto end; 920 goto end;
732 } 921 }
@@ -736,11 +925,14 @@ static int acpi_battery_add(struct acpi_device *device)
736 device->status.battery_present ? "present" : "absent"); 925 device->status.battery_present ? "present" : "absent");
737 926
738 end: 927 end:
928
739 if (result) { 929 if (result) {
740 acpi_battery_remove_fs(device); 930 acpi_battery_remove_fs(device);
741 kfree(battery); 931 kfree(battery);
742 } 932 }
743 933
934 mutex_unlock(&battery->mutex);
935
744 return result; 936 return result;
745} 937}
746 938
@@ -749,18 +941,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
749 acpi_status status = 0; 941 acpi_status status = 0;
750 struct acpi_battery *battery = NULL; 942 struct acpi_battery *battery = NULL;
751 943
752
753 if (!device || !acpi_driver_data(device)) 944 if (!device || !acpi_driver_data(device))
754 return -EINVAL; 945 return -EINVAL;
755 946
756 battery = acpi_driver_data(device); 947 battery = acpi_driver_data(device);
757 948
949 mutex_lock(&battery->mutex);
950
758 status = acpi_remove_notify_handler(device->handle, 951 status = acpi_remove_notify_handler(device->handle,
759 ACPI_ALL_NOTIFY, 952 ACPI_ALL_NOTIFY,
760 acpi_battery_notify); 953 acpi_battery_notify);
761 954
762 acpi_battery_remove_fs(device); 955 acpi_battery_remove_fs(device);
763 956
957 kfree(battery->bif_data.pointer);
958
959 kfree(battery->bst_data.pointer);
960
961 mutex_unlock(&battery->mutex);
962
963 mutex_destroy(&battery->mutex);
964
764 kfree(battery); 965 kfree(battery);
765 966
766 return 0; 967 return 0;
@@ -775,7 +976,10 @@ static int acpi_battery_resume(struct acpi_device *device)
775 return -EINVAL; 976 return -EINVAL;
776 977
777 battery = device->driver_data; 978 battery = device->driver_data;
778 return acpi_battery_check(battery); 979
980 battery->flags.init_update = 1;
981
982 return 0;
779} 983}
780 984
781static int __init acpi_battery_init(void) 985static int __init acpi_battery_init(void)
@@ -800,7 +1004,6 @@ static int __init acpi_battery_init(void)
800 1004
801static void __exit acpi_battery_exit(void) 1005static void __exit acpi_battery_exit(void)
802{ 1006{
803
804 acpi_bus_unregister_driver(&acpi_battery_driver); 1007 acpi_bus_unregister_driver(&acpi_battery_driver);
805 1008
806 acpi_unlock_battery_dir(acpi_battery_dir); 1009 acpi_unlock_battery_dir(acpi_battery_dir);
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index fb3f31b5e69f..56a5b3fffeb3 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -288,6 +288,11 @@ static int bay_add(acpi_handle handle, int id)
288 new_bay->pdev = pdev; 288 new_bay->pdev = pdev;
289 platform_set_drvdata(pdev, new_bay); 289 platform_set_drvdata(pdev, new_bay);
290 290
291 /*
292 * we want the bay driver to be able to send uevents
293 */
294 pdev->dev.uevent_suppress = 0;
295
291 if (acpi_bay_add_fs(new_bay)) { 296 if (acpi_bay_add_fs(new_bay)) {
292 platform_device_unregister(new_bay->pdev); 297 platform_device_unregister(new_bay->pdev);
293 goto bay_add_err; 298 goto bay_add_err;
@@ -328,18 +333,12 @@ static void bay_notify(acpi_handle handle, u32 event, void *data)
328{ 333{
329 struct bay *bay_dev = (struct bay *)data; 334 struct bay *bay_dev = (struct bay *)data;
330 struct device *dev = &bay_dev->pdev->dev; 335 struct device *dev = &bay_dev->pdev->dev;
336 char event_string[12];
337 char *envp[] = { event_string, NULL };
331 338
332 bay_dprintk(handle, "Bay event"); 339 bay_dprintk(handle, "Bay event");
333 340 sprintf(event_string, "BAY_EVENT=%d\n", event);
334 switch(event) { 341 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
335 case ACPI_NOTIFY_BUS_CHECK:
336 case ACPI_NOTIFY_DEVICE_CHECK:
337 case ACPI_NOTIFY_EJECT_REQUEST:
338 kobject_uevent(&dev->kobj, KOBJ_CHANGE);
339 break;
340 default:
341 printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event);
342 }
343} 342}
344 343
345static acpi_status 344static acpi_status
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e5084ececb6f..6b2658c96242 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -292,6 +292,10 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
292 if (!device) 292 if (!device)
293 return -EINVAL; 293 return -EINVAL;
294 294
295 if (acpi_bus_generate_genetlink_event(device, type, data))
296 printk(KERN_WARNING PREFIX
297 "Failed to generate an ACPI event via genetlink!\n");
298
295 /* drop event on the floor if no one's listening */ 299 /* drop event on the floor if no one's listening */
296 if (!event_is_open) 300 if (!event_is_open)
297 return 0; 301 return 0;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 4546bf873aea..6192c8be66df 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -40,8 +40,15 @@ MODULE_AUTHOR("Kristen Carlson Accardi");
40MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); 40MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
41MODULE_LICENSE("GPL"); 41MODULE_LICENSE("GPL");
42 42
43static int immediate_undock = 1;
44module_param(immediate_undock, bool, 0644);
45MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
46 "undock immediately when the undock button is pressed, 0 will cause"
47 " the driver to wait for userspace to write the undock sysfs file "
48 " before undocking");
49
43static struct atomic_notifier_head dock_notifier_list; 50static struct atomic_notifier_head dock_notifier_list;
44static struct platform_device dock_device; 51static struct platform_device *dock_device;
45static char dock_device_name[] = "dock"; 52static char dock_device_name[] = "dock";
46 53
47struct dock_station { 54struct dock_station {
@@ -63,6 +70,7 @@ struct dock_dependent_device {
63}; 70};
64 71
65#define DOCK_DOCKING 0x00000001 72#define DOCK_DOCKING 0x00000001
73#define DOCK_UNDOCKING 0x00000002
66#define DOCK_EVENT 3 74#define DOCK_EVENT 3
67#define UNDOCK_EVENT 2 75#define UNDOCK_EVENT 2
68 76
@@ -327,12 +335,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
327 335
328static void dock_event(struct dock_station *ds, u32 event, int num) 336static void dock_event(struct dock_station *ds, u32 event, int num)
329{ 337{
330 struct device *dev = &dock_device.dev; 338 struct device *dev = &dock_device->dev;
339 char event_string[7];
340 char *envp[] = { event_string, NULL };
341
342 if (num == UNDOCK_EVENT)
343 sprintf(event_string, "UNDOCK");
344 else
345 sprintf(event_string, "DOCK");
346
331 /* 347 /*
332 * Indicate that the status of the dock station has 348 * Indicate that the status of the dock station has
333 * changed. 349 * changed.
334 */ 350 */
335 kobject_uevent(&dev->kobj, KOBJ_CHANGE); 351 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
336} 352}
337 353
338/** 354/**
@@ -380,12 +396,11 @@ static void handle_dock(struct dock_station *ds, int dock)
380 union acpi_object arg; 396 union acpi_object arg;
381 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 397 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
382 struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 398 struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
383 union acpi_object *obj;
384 399
385 acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); 400 acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer);
386 obj = name_buffer.pointer;
387 401
388 printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking"); 402 printk(KERN_INFO PREFIX "%s - %s\n",
403 (char *)name_buffer.pointer, dock ? "docking" : "undocking");
389 404
390 /* _DCK method has one argument */ 405 /* _DCK method has one argument */
391 arg_list.count = 1; 406 arg_list.count = 1;
@@ -394,7 +409,8 @@ static void handle_dock(struct dock_station *ds, int dock)
394 arg.integer.value = dock; 409 arg.integer.value = dock;
395 status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); 410 status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer);
396 if (ACPI_FAILURE(status)) 411 if (ACPI_FAILURE(status))
397 pr_debug("%s: failed to execute _DCK\n", obj->string.pointer); 412 printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n",
413 (char *)name_buffer.pointer);
398 kfree(buffer.pointer); 414 kfree(buffer.pointer);
399 kfree(name_buffer.pointer); 415 kfree(name_buffer.pointer);
400} 416}
@@ -420,6 +436,16 @@ static inline void complete_dock(struct dock_station *ds)
420 ds->last_dock_time = jiffies; 436 ds->last_dock_time = jiffies;
421} 437}
422 438
439static inline void begin_undock(struct dock_station *ds)
440{
441 ds->flags |= DOCK_UNDOCKING;
442}
443
444static inline void complete_undock(struct dock_station *ds)
445{
446 ds->flags &= ~(DOCK_UNDOCKING);
447}
448
423/** 449/**
424 * dock_in_progress - see if we are in the middle of handling a dock event 450 * dock_in_progress - see if we are in the middle of handling a dock event
425 * @ds: the dock station 451 * @ds: the dock station
@@ -550,7 +576,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
550 printk(KERN_ERR PREFIX "Unable to undock!\n"); 576 printk(KERN_ERR PREFIX "Unable to undock!\n");
551 return -EBUSY; 577 return -EBUSY;
552 } 578 }
553 579 complete_undock(ds);
554 return 0; 580 return 0;
555} 581}
556 582
@@ -594,7 +620,11 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
594 * to the driver who wish to hotplug. 620 * to the driver who wish to hotplug.
595 */ 621 */
596 case ACPI_NOTIFY_EJECT_REQUEST: 622 case ACPI_NOTIFY_EJECT_REQUEST:
597 handle_eject_request(ds, event); 623 begin_undock(ds);
624 if (immediate_undock)
625 handle_eject_request(ds, event);
626 else
627 dock_event(ds, event, UNDOCK_EVENT);
598 break; 628 break;
599 default: 629 default:
600 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); 630 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -653,6 +683,17 @@ static ssize_t show_docked(struct device *dev,
653DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 683DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
654 684
655/* 685/*
686 * show_flags - read method for flags file in sysfs
687 */
688static ssize_t show_flags(struct device *dev,
689 struct device_attribute *attr, char *buf)
690{
691 return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
692
693}
694DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL);
695
696/*
656 * write_undock - write method for "undock" file in sysfs 697 * write_undock - write method for "undock" file in sysfs
657 */ 698 */
658static ssize_t write_undock(struct device *dev, struct device_attribute *attr, 699static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
@@ -675,16 +716,15 @@ static ssize_t show_dock_uid(struct device *dev,
675 struct device_attribute *attr, char *buf) 716 struct device_attribute *attr, char *buf)
676{ 717{
677 unsigned long lbuf; 718 unsigned long lbuf;
678 acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf); 719 acpi_status status = acpi_evaluate_integer(dock_station->handle,
679 if(ACPI_FAILURE(status)) { 720 "_UID", NULL, &lbuf);
721 if (ACPI_FAILURE(status))
680 return 0; 722 return 0;
681 } 723
682 return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); 724 return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf);
683} 725}
684DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); 726DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
685 727
686
687
688/** 728/**
689 * dock_add - add a new dock station 729 * dock_add - add a new dock station
690 * @handle: the dock station handle 730 * @handle: the dock station handle
@@ -711,33 +751,53 @@ static int dock_add(acpi_handle handle)
711 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 751 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
712 752
713 /* initialize platform device stuff */ 753 /* initialize platform device stuff */
714 dock_device.name = dock_device_name; 754 dock_device =
715 ret = platform_device_register(&dock_device); 755 platform_device_register_simple(dock_device_name, 0, NULL, 0);
756 if (IS_ERR(dock_device)) {
757 kfree(dock_station);
758 dock_station = NULL;
759 return PTR_ERR(dock_device);
760 }
761
762 /* we want the dock device to send uevents */
763 dock_device->dev.uevent_suppress = 0;
764
765 ret = device_create_file(&dock_device->dev, &dev_attr_docked);
716 if (ret) { 766 if (ret) {
717 printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); 767 printk("Error %d adding sysfs file\n", ret);
768 platform_device_unregister(dock_device);
718 kfree(dock_station); 769 kfree(dock_station);
770 dock_station = NULL;
719 return ret; 771 return ret;
720 } 772 }
721 ret = device_create_file(&dock_device.dev, &dev_attr_docked); 773 ret = device_create_file(&dock_device->dev, &dev_attr_undock);
722 if (ret) { 774 if (ret) {
723 printk("Error %d adding sysfs file\n", ret); 775 printk("Error %d adding sysfs file\n", ret);
724 platform_device_unregister(&dock_device); 776 device_remove_file(&dock_device->dev, &dev_attr_docked);
777 platform_device_unregister(dock_device);
725 kfree(dock_station); 778 kfree(dock_station);
779 dock_station = NULL;
726 return ret; 780 return ret;
727 } 781 }
728 ret = device_create_file(&dock_device.dev, &dev_attr_undock); 782 ret = device_create_file(&dock_device->dev, &dev_attr_uid);
729 if (ret) { 783 if (ret) {
730 printk("Error %d adding sysfs file\n", ret); 784 printk("Error %d adding sysfs file\n", ret);
731 device_remove_file(&dock_device.dev, &dev_attr_docked); 785 device_remove_file(&dock_device->dev, &dev_attr_docked);
732 platform_device_unregister(&dock_device); 786 device_remove_file(&dock_device->dev, &dev_attr_undock);
787 platform_device_unregister(dock_device);
733 kfree(dock_station); 788 kfree(dock_station);
789 dock_station = NULL;
734 return ret; 790 return ret;
735 } 791 }
736 ret = device_create_file(&dock_device.dev, &dev_attr_uid); 792 ret = device_create_file(&dock_device->dev, &dev_attr_flags);
737 if (ret) { 793 if (ret) {
738 printk("Error %d adding sysfs file\n", ret); 794 printk("Error %d adding sysfs file\n", ret);
739 platform_device_unregister(&dock_device); 795 device_remove_file(&dock_device->dev, &dev_attr_docked);
796 device_remove_file(&dock_device->dev, &dev_attr_undock);
797 device_remove_file(&dock_device->dev, &dev_attr_uid);
798 platform_device_unregister(dock_device);
740 kfree(dock_station); 799 kfree(dock_station);
800 dock_station = NULL;
741 return ret; 801 return ret;
742 } 802 }
743 803
@@ -750,6 +810,7 @@ static int dock_add(acpi_handle handle)
750 dd = alloc_dock_dependent_device(handle); 810 dd = alloc_dock_dependent_device(handle);
751 if (!dd) { 811 if (!dd) {
752 kfree(dock_station); 812 kfree(dock_station);
813 dock_station = NULL;
753 ret = -ENOMEM; 814 ret = -ENOMEM;
754 goto dock_add_err_unregister; 815 goto dock_add_err_unregister;
755 } 816 }
@@ -773,10 +834,13 @@ static int dock_add(acpi_handle handle)
773dock_add_err: 834dock_add_err:
774 kfree(dd); 835 kfree(dd);
775dock_add_err_unregister: 836dock_add_err_unregister:
776 device_remove_file(&dock_device.dev, &dev_attr_docked); 837 device_remove_file(&dock_device->dev, &dev_attr_docked);
777 device_remove_file(&dock_device.dev, &dev_attr_undock); 838 device_remove_file(&dock_device->dev, &dev_attr_undock);
778 platform_device_unregister(&dock_device); 839 device_remove_file(&dock_device->dev, &dev_attr_uid);
840 device_remove_file(&dock_device->dev, &dev_attr_flags);
841 platform_device_unregister(dock_device);
779 kfree(dock_station); 842 kfree(dock_station);
843 dock_station = NULL;
780 return ret; 844 return ret;
781} 845}
782 846
@@ -804,12 +868,15 @@ static int dock_remove(void)
804 printk(KERN_ERR "Error removing notify handler\n"); 868 printk(KERN_ERR "Error removing notify handler\n");
805 869
806 /* cleanup sysfs */ 870 /* cleanup sysfs */
807 device_remove_file(&dock_device.dev, &dev_attr_docked); 871 device_remove_file(&dock_device->dev, &dev_attr_docked);
808 device_remove_file(&dock_device.dev, &dev_attr_undock); 872 device_remove_file(&dock_device->dev, &dev_attr_undock);
809 platform_device_unregister(&dock_device); 873 device_remove_file(&dock_device->dev, &dev_attr_uid);
874 device_remove_file(&dock_device->dev, &dev_attr_flags);
875 platform_device_unregister(dock_device);
810 876
811 /* free dock station memory */ 877 /* free dock station memory */
812 kfree(dock_station); 878 kfree(dock_station);
879 dock_station = NULL;
813 return 0; 880 return 0;
814} 881}
815 882
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 82f496c07675..10e851021eca 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -34,25 +34,26 @@
34#include <linux/proc_fs.h> 34#include <linux/proc_fs.h>
35#include <linux/seq_file.h> 35#include <linux/seq_file.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/list.h>
37#include <asm/io.h> 38#include <asm/io.h>
38#include <acpi/acpi_bus.h> 39#include <acpi/acpi_bus.h>
39#include <acpi/acpi_drivers.h> 40#include <acpi/acpi_drivers.h>
40#include <acpi/actypes.h> 41#include <acpi/actypes.h>
41 42
42#define _COMPONENT ACPI_EC_COMPONENT
43ACPI_MODULE_NAME("ec");
44#define ACPI_EC_COMPONENT 0x00100000
45#define ACPI_EC_CLASS "embedded_controller" 43#define ACPI_EC_CLASS "embedded_controller"
46#define ACPI_EC_HID "PNP0C09" 44#define ACPI_EC_HID "PNP0C09"
47#define ACPI_EC_DEVICE_NAME "Embedded Controller" 45#define ACPI_EC_DEVICE_NAME "Embedded Controller"
48#define ACPI_EC_FILE_INFO "info" 46#define ACPI_EC_FILE_INFO "info"
47
49#undef PREFIX 48#undef PREFIX
50#define PREFIX "ACPI: EC: " 49#define PREFIX "ACPI: EC: "
50
51/* EC status register */ 51/* EC status register */
52#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 52#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
53#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 53#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
54#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ 54#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
55#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 55#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
56
56/* EC commands */ 57/* EC commands */
57enum ec_command { 58enum ec_command {
58 ACPI_EC_COMMAND_READ = 0x80, 59 ACPI_EC_COMMAND_READ = 0x80,
@@ -61,6 +62,7 @@ enum ec_command {
61 ACPI_EC_BURST_DISABLE = 0x83, 62 ACPI_EC_BURST_DISABLE = 0x83,
62 ACPI_EC_COMMAND_QUERY = 0x84, 63 ACPI_EC_COMMAND_QUERY = 0x84,
63}; 64};
65
64/* EC events */ 66/* EC events */
65enum ec_event { 67enum ec_event {
66 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ 68 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
@@ -94,6 +96,16 @@ static struct acpi_driver acpi_ec_driver = {
94 96
95/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 97/* If we find an EC via the ECDT, we need to keep a ptr to its context */
96/* External interfaces use first EC only, so remember */ 98/* External interfaces use first EC only, so remember */
99typedef int (*acpi_ec_query_func) (void *data);
100
101struct acpi_ec_query_handler {
102 struct list_head node;
103 acpi_ec_query_func func;
104 acpi_handle handle;
105 void *data;
106 u8 query_bit;
107};
108
97static struct acpi_ec { 109static struct acpi_ec {
98 acpi_handle handle; 110 acpi_handle handle;
99 unsigned long gpe; 111 unsigned long gpe;
@@ -104,6 +116,7 @@ static struct acpi_ec {
104 atomic_t query_pending; 116 atomic_t query_pending;
105 atomic_t event_count; 117 atomic_t event_count;
106 wait_queue_head_t wait; 118 wait_queue_head_t wait;
119 struct list_head list;
107} *boot_ec, *first_ec; 120} *boot_ec, *first_ec;
108 121
109/* -------------------------------------------------------------------------- 122/* --------------------------------------------------------------------------
@@ -245,7 +258,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
245 258
246 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); 259 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
247 if (status) { 260 if (status) {
248 printk(KERN_DEBUG PREFIX 261 printk(KERN_ERR PREFIX
249 "input buffer is not empty, aborting transaction\n"); 262 "input buffer is not empty, aborting transaction\n");
250 goto end; 263 goto end;
251 } 264 }
@@ -394,21 +407,67 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
394/* -------------------------------------------------------------------------- 407/* --------------------------------------------------------------------------
395 Event Management 408 Event Management
396 -------------------------------------------------------------------------- */ 409 -------------------------------------------------------------------------- */
410int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
411 acpi_handle handle, acpi_ec_query_func func,
412 void *data)
413{
414 struct acpi_ec_query_handler *handler =
415 kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL);
416 if (!handler)
417 return -ENOMEM;
418
419 handler->query_bit = query_bit;
420 handler->handle = handle;
421 handler->func = func;
422 handler->data = data;
423 mutex_lock(&ec->lock);
424 list_add_tail(&handler->node, &ec->list);
425 mutex_unlock(&ec->lock);
426 return 0;
427}
428
429EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
430
431void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
432{
433 struct acpi_ec_query_handler *handler;
434 mutex_lock(&ec->lock);
435 list_for_each_entry(handler, &ec->list, node) {
436 if (query_bit == handler->query_bit) {
437 list_del(&handler->node);
438 kfree(handler);
439 break;
440 }
441 }
442 mutex_unlock(&ec->lock);
443}
444
445EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler);
397 446
398static void acpi_ec_gpe_query(void *ec_cxt) 447static void acpi_ec_gpe_query(void *ec_cxt)
399{ 448{
400 struct acpi_ec *ec = ec_cxt; 449 struct acpi_ec *ec = ec_cxt;
401 u8 value = 0; 450 u8 value = 0;
402 char object_name[8]; 451 struct acpi_ec_query_handler *handler, copy;
403 452
404 if (!ec || acpi_ec_query(ec, &value)) 453 if (!ec || acpi_ec_query(ec, &value))
405 return; 454 return;
406 455 mutex_lock(&ec->lock);
407 snprintf(object_name, 8, "_Q%2.2X", value); 456 list_for_each_entry(handler, &ec->list, node) {
408 457 if (value == handler->query_bit) {
409 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); 458 /* have custom handler for this bit */
410 459 memcpy(&copy, handler, sizeof(copy));
411 acpi_evaluate_object(ec->handle, object_name, NULL, NULL); 460 mutex_unlock(&ec->lock);
461 if (copy.func) {
462 copy.func(copy.data);
463 } else if (copy.handle) {
464 acpi_evaluate_object(copy.handle, NULL, NULL, NULL);
465 }
466 return;
467 }
468 }
469 mutex_unlock(&ec->lock);
470 printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
412} 471}
413 472
414static u32 acpi_ec_gpe_handler(void *data) 473static u32 acpi_ec_gpe_handler(void *data)
@@ -427,8 +486,7 @@ static u32 acpi_ec_gpe_handler(void *data)
427 if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { 486 if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
428 atomic_set(&ec->query_pending, 1); 487 atomic_set(&ec->query_pending, 1);
429 status = 488 status =
430 acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, 489 acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
431 ec);
432 } 490 }
433 491
434 return status == AE_OK ? 492 return status == AE_OK ?
@@ -454,57 +512,35 @@ acpi_ec_space_setup(acpi_handle region_handle,
454} 512}
455 513
456static acpi_status 514static acpi_status
457acpi_ec_space_handler(u32 function, 515acpi_ec_space_handler(u32 function, acpi_physical_address address,
458 acpi_physical_address address, 516 u32 bits, acpi_integer *value,
459 u32 bit_width,
460 acpi_integer * value,
461 void *handler_context, void *region_context) 517 void *handler_context, void *region_context)
462{ 518{
463 int result = 0;
464 struct acpi_ec *ec = handler_context; 519 struct acpi_ec *ec = handler_context;
465 u64 temp = *value; 520 int result = 0, i = 0;
466 acpi_integer f_v = 0; 521 u8 temp = 0;
467 int i = 0;
468 522
469 if ((address > 0xFF) || !value || !handler_context) 523 if ((address > 0xFF) || !value || !handler_context)
470 return AE_BAD_PARAMETER; 524 return AE_BAD_PARAMETER;
471 525
472 if (bit_width != 8 && acpi_strict) { 526 if (function != ACPI_READ && function != ACPI_WRITE)
473 return AE_BAD_PARAMETER; 527 return AE_BAD_PARAMETER;
474 }
475
476 next_byte:
477 switch (function) {
478 case ACPI_READ:
479 temp = 0;
480 result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
481 break;
482 case ACPI_WRITE:
483 result = acpi_ec_write(ec, (u8) address, (u8) temp);
484 break;
485 default:
486 result = -EINVAL;
487 goto out;
488 break;
489 }
490 528
491 bit_width -= 8; 529 if (bits != 8 && acpi_strict)
492 if (bit_width) { 530 return AE_BAD_PARAMETER;
493 if (function == ACPI_READ)
494 f_v |= temp << 8 * i;
495 if (function == ACPI_WRITE)
496 temp >>= 8;
497 i++;
498 address++;
499 goto next_byte;
500 }
501 531
502 if (function == ACPI_READ) { 532 while (bits - i > 0) {
503 f_v |= temp << 8 * i; 533 if (function == ACPI_READ) {
504 *value = f_v; 534 result = acpi_ec_read(ec, address, &temp);
535 (*value) |= ((acpi_integer)temp) << i;
536 } else {
537 temp = 0xff & ((*value) >> i);
538 result = acpi_ec_write(ec, address, temp);
539 }
540 i += 8;
541 ++address;
505 } 542 }
506 543
507 out:
508 switch (result) { 544 switch (result) {
509 case -EINVAL: 545 case -EINVAL:
510 return AE_BAD_PARAMETER; 546 return AE_BAD_PARAMETER;
@@ -597,9 +633,6 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
597static acpi_status 633static acpi_status
598ec_parse_io_ports(struct acpi_resource *resource, void *context); 634ec_parse_io_ports(struct acpi_resource *resource, void *context);
599 635
600static acpi_status
601ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval);
602
603static struct acpi_ec *make_acpi_ec(void) 636static struct acpi_ec *make_acpi_ec(void)
604{ 637{
605 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); 638 struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
@@ -610,13 +643,52 @@ static struct acpi_ec *make_acpi_ec(void)
610 atomic_set(&ec->event_count, 1); 643 atomic_set(&ec->event_count, 1);
611 mutex_init(&ec->lock); 644 mutex_init(&ec->lock);
612 init_waitqueue_head(&ec->wait); 645 init_waitqueue_head(&ec->wait);
646 INIT_LIST_HEAD(&ec->list);
613 647
614 return ec; 648 return ec;
615} 649}
616 650
651static acpi_status
652acpi_ec_register_query_methods(acpi_handle handle, u32 level,
653 void *context, void **return_value)
654{
655 struct acpi_namespace_node *node = handle;
656 struct acpi_ec *ec = context;
657 int value = 0;
658 if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
659 acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
660 }
661 return AE_OK;
662}
663
664static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
665{
666 if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
667 ec_parse_io_ports, ec)))
668 return -EINVAL;
669
670 /* Get GPE bit assignment (EC events). */
671 /* TODO: Add support for _GPE returning a package */
672 if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
673 return -EINVAL;
674
675 /* Use the global lock for all EC transactions? */
676 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
677
678 /* Find and register all query methods */
679 acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
680 acpi_ec_register_query_methods, ec, NULL);
681
682 ec->handle = handle;
683
684 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
685 ec->gpe, ec->command_addr, ec->data_addr);
686
687 return 0;
688}
689
617static int acpi_ec_add(struct acpi_device *device) 690static int acpi_ec_add(struct acpi_device *device)
618{ 691{
619 acpi_status status = AE_OK;
620 struct acpi_ec *ec = NULL; 692 struct acpi_ec *ec = NULL;
621 693
622 if (!device) 694 if (!device)
@@ -629,8 +701,7 @@ static int acpi_ec_add(struct acpi_device *device)
629 if (!ec) 701 if (!ec)
630 return -ENOMEM; 702 return -ENOMEM;
631 703
632 status = ec_parse_device(device->handle, 0, ec, NULL); 704 if (ec_parse_device(ec, device->handle)) {
633 if (status != AE_CTRL_TERMINATE) {
634 kfree(ec); 705 kfree(ec);
635 return -EINVAL; 706 return -EINVAL;
636 } 707 }
@@ -641,6 +712,8 @@ static int acpi_ec_add(struct acpi_device *device)
641 /* We might have incorrect info for GL at boot time */ 712 /* We might have incorrect info for GL at boot time */
642 mutex_lock(&boot_ec->lock); 713 mutex_lock(&boot_ec->lock);
643 boot_ec->global_lock = ec->global_lock; 714 boot_ec->global_lock = ec->global_lock;
715 /* Copy handlers from new ec into boot ec */
716 list_splice(&ec->list, &boot_ec->list);
644 mutex_unlock(&boot_ec->lock); 717 mutex_unlock(&boot_ec->lock);
645 kfree(ec); 718 kfree(ec);
646 ec = boot_ec; 719 ec = boot_ec;
@@ -651,22 +724,24 @@ static int acpi_ec_add(struct acpi_device *device)
651 acpi_driver_data(device) = ec; 724 acpi_driver_data(device) = ec;
652 725
653 acpi_ec_add_fs(device); 726 acpi_ec_add_fs(device);
654
655 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
656 acpi_device_name(device), acpi_device_bid(device),
657 (u32) ec->gpe));
658
659 return 0; 727 return 0;
660} 728}
661 729
662static int acpi_ec_remove(struct acpi_device *device, int type) 730static int acpi_ec_remove(struct acpi_device *device, int type)
663{ 731{
664 struct acpi_ec *ec; 732 struct acpi_ec *ec;
733 struct acpi_ec_query_handler *handler;
665 734
666 if (!device) 735 if (!device)
667 return -EINVAL; 736 return -EINVAL;
668 737
669 ec = acpi_driver_data(device); 738 ec = acpi_driver_data(device);
739 mutex_lock(&ec->lock);
740 list_for_each_entry(handler, &ec->list, node) {
741 list_del(&handler->node);
742 kfree(handler);
743 }
744 mutex_unlock(&ec->lock);
670 acpi_ec_remove_fs(device); 745 acpi_ec_remove_fs(device);
671 acpi_driver_data(device) = NULL; 746 acpi_driver_data(device) = NULL;
672 if (ec == first_ec) 747 if (ec == first_ec)
@@ -722,15 +797,13 @@ static int ec_install_handlers(struct acpi_ec *ec)
722 return -ENODEV; 797 return -ENODEV;
723 } 798 }
724 799
725 /* EC is fully operational, allow queries */
726 atomic_set(&ec->query_pending, 0);
727
728 return 0; 800 return 0;
729} 801}
730 802
731static int acpi_ec_start(struct acpi_device *device) 803static int acpi_ec_start(struct acpi_device *device)
732{ 804{
733 struct acpi_ec *ec; 805 struct acpi_ec *ec;
806 int ret = 0;
734 807
735 if (!device) 808 if (!device)
736 return -EINVAL; 809 return -EINVAL;
@@ -740,14 +813,14 @@ static int acpi_ec_start(struct acpi_device *device)
740 if (!ec) 813 if (!ec)
741 return -EINVAL; 814 return -EINVAL;
742 815
743 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
744 ec->gpe, ec->command_addr, ec->data_addr));
745
746 /* Boot EC is already working */ 816 /* Boot EC is already working */
747 if (ec == boot_ec) 817 if (ec != boot_ec)
748 return 0; 818 ret = ec_install_handlers(ec);
819
820 /* EC is fully operational, allow queries */
821 atomic_set(&ec->query_pending, 0);
749 822
750 return ec_install_handlers(ec); 823 return ret;
751} 824}
752 825
753static int acpi_ec_stop(struct acpi_device *device, int type) 826static int acpi_ec_stop(struct acpi_device *device, int type)
@@ -779,34 +852,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
779 return 0; 852 return 0;
780} 853}
781 854
782static acpi_status
783ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
784{
785 acpi_status status;
786
787 struct acpi_ec *ec = context;
788 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
789 ec_parse_io_ports, ec);
790 if (ACPI_FAILURE(status))
791 return status;
792
793 /* Get GPE bit assignment (EC events). */
794 /* TODO: Add support for _GPE returning a package */
795 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
796 if (ACPI_FAILURE(status))
797 return status;
798
799 /* Use the global lock for all EC transactions? */
800 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
801
802 ec->handle = handle;
803
804 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
805 ec->gpe, ec->command_addr, ec->data_addr));
806
807 return AE_CTRL_TERMINATE;
808}
809
810int __init acpi_ec_ecdt_probe(void) 855int __init acpi_ec_ecdt_probe(void)
811{ 856{
812 int ret; 857 int ret;
@@ -825,7 +870,7 @@ int __init acpi_ec_ecdt_probe(void)
825 if (ACPI_FAILURE(status)) 870 if (ACPI_FAILURE(status))
826 goto error; 871 goto error;
827 872
828 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); 873 printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
829 874
830 boot_ec->command_addr = ecdt_ptr->control.address; 875 boot_ec->command_addr = ecdt_ptr->control.address;
831 boot_ec->data_addr = ecdt_ptr->data.address; 876 boot_ec->data_addr = ecdt_ptr->data.address;
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 3b23562e6f92..dfa5853b17f0 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -11,6 +11,8 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/poll.h> 12#include <linux/poll.h>
13#include <acpi/acpi_drivers.h> 13#include <acpi/acpi_drivers.h>
14#include <net/netlink.h>
15#include <net/genetlink.h>
14 16
15#define _COMPONENT ACPI_SYSTEM_COMPONENT 17#define _COMPONENT ACPI_SYSTEM_COMPONENT
16ACPI_MODULE_NAME("event"); 18ACPI_MODULE_NAME("event");
@@ -48,7 +50,6 @@ acpi_system_read_event(struct file *file, char __user * buffer, size_t count,
48 static int chars_remaining = 0; 50 static int chars_remaining = 0;
49 static char *ptr; 51 static char *ptr;
50 52
51
52 if (!chars_remaining) { 53 if (!chars_remaining) {
53 memset(&event, 0, sizeof(struct acpi_bus_event)); 54 memset(&event, 0, sizeof(struct acpi_bus_event));
54 55
@@ -106,23 +107,161 @@ static const struct file_operations acpi_system_event_ops = {
106 .poll = acpi_system_poll_event, 107 .poll = acpi_system_poll_event,
107}; 108};
108 109
110#ifdef CONFIG_NET
111unsigned int acpi_event_seqnum;
112struct acpi_genl_event {
113 acpi_device_class device_class;
114 char bus_id[15];
115 u32 type;
116 u32 data;
117};
118
119/* attributes of acpi_genl_family */
120enum {
121 ACPI_GENL_ATTR_UNSPEC,
122 ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */
123 __ACPI_GENL_ATTR_MAX,
124};
125#define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1)
126
127/* commands supported by the acpi_genl_family */
128enum {
129 ACPI_GENL_CMD_UNSPEC,
130 ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */
131 __ACPI_GENL_CMD_MAX,
132};
133#define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1)
134
135#define ACPI_GENL_FAMILY_NAME "acpi_event"
136#define ACPI_GENL_VERSION 0x01
137#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group"
138
139static struct genl_family acpi_event_genl_family = {
140 .id = GENL_ID_GENERATE,
141 .name = ACPI_GENL_FAMILY_NAME,
142 .version = ACPI_GENL_VERSION,
143 .maxattr = ACPI_GENL_ATTR_MAX,
144};
145
146static struct genl_multicast_group acpi_event_mcgrp = {
147 .name = ACPI_GENL_MCAST_GROUP_NAME,
148};
149
150int acpi_bus_generate_genetlink_event(struct acpi_device *device,
151 u8 type, int data)
152{
153 struct sk_buff *skb;
154 struct nlattr *attr;
155 struct acpi_genl_event *event;
156 void *msg_header;
157 int size;
158 int result;
159
160 /* allocate memory */
161 size = nla_total_size(sizeof(struct acpi_genl_event)) +
162 nla_total_size(0);
163
164 skb = genlmsg_new(size, GFP_ATOMIC);
165 if (!skb)
166 return -ENOMEM;
167
168 /* add the genetlink message header */
169 msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++,
170 &acpi_event_genl_family, 0,
171 ACPI_GENL_CMD_EVENT);
172 if (!msg_header) {
173 nlmsg_free(skb);
174 return -ENOMEM;
175 }
176
177 /* fill the data */
178 attr =
179 nla_reserve(skb, ACPI_GENL_ATTR_EVENT,
180 sizeof(struct acpi_genl_event));
181 if (!attr) {
182 nlmsg_free(skb);
183 return -EINVAL;
184 }
185
186 event = nla_data(attr);
187 if (!event) {
188 nlmsg_free(skb);
189 return -EINVAL;
190 }
191
192 memset(event, 0, sizeof(struct acpi_genl_event));
193
194 strcpy(event->device_class, device->pnp.device_class);
195 strcpy(event->bus_id, device->dev.bus_id);
196 event->type = type;
197 event->data = data;
198
199 /* send multicast genetlink message */
200 result = genlmsg_end(skb, msg_header);
201 if (result < 0) {
202 nlmsg_free(skb);
203 return result;
204 }
205
206 result =
207 genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
208 if (result)
209 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
210 "Failed to send a Genetlink message!\n"));
211 return 0;
212}
213
214static int acpi_event_genetlink_init(void)
215{
216 int result;
217
218 result = genl_register_family(&acpi_event_genl_family);
219 if (result)
220 return result;
221
222 result = genl_register_mc_group(&acpi_event_genl_family,
223 &acpi_event_mcgrp);
224 if (result)
225 genl_unregister_family(&acpi_event_genl_family);
226
227 return result;
228}
229
230#else
231int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type,
232 int data)
233{
234 return 0;
235}
236
237static int acpi_event_genetlink_init(void)
238{
239 return -ENODEV;
240}
241#endif
242
109static int __init acpi_event_init(void) 243static int __init acpi_event_init(void)
110{ 244{
111 struct proc_dir_entry *entry; 245 struct proc_dir_entry *entry;
112 int error = 0; 246 int error = 0;
113 247
114
115 if (acpi_disabled) 248 if (acpi_disabled)
116 return 0; 249 return 0;
117 250
251 /* create genetlink for acpi event */
252 error = acpi_event_genetlink_init();
253 if (error)
254 printk(KERN_WARNING PREFIX
255 "Failed to create genetlink family for ACPI event\n");
256
118 /* 'event' [R] */ 257 /* 'event' [R] */
119 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); 258 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
120 if (entry) 259 if (entry)
121 entry->proc_fops = &acpi_system_event_ops; 260 entry->proc_fops = &acpi_system_event_ops;
122 else { 261 else
123 error = -ENODEV; 262 return -ENODEV;
124 } 263
125 return error; 264 return 0;
126} 265}
127 266
128subsys_initcall(acpi_event_init); 267fs_initcall(acpi_event_init);
diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c
index 902c287b3a4f..361ebe6c4a6f 100644
--- a/drivers/acpi/events/evgpeblk.c
+++ b/drivers/acpi/events/evgpeblk.c
@@ -586,6 +586,10 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt)
586 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); 586 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
587 if (gpe_xrupt->previous) { 587 if (gpe_xrupt->previous) {
588 gpe_xrupt->previous->next = gpe_xrupt->next; 588 gpe_xrupt->previous->next = gpe_xrupt->next;
589 } else {
590 /* No previous, update list head */
591
592 acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next;
589 } 593 }
590 594
591 if (gpe_xrupt->next) { 595 if (gpe_xrupt->next) {
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 400d90fca966..23ee7bc4a705 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -284,6 +284,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
284 } 284 }
285 285
286 if (!pci_device_node) { 286 if (!pci_device_node) {
287 ACPI_FREE(pci_id);
287 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 288 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
288 } 289 }
289 290
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 41427a41f620..4893e256e399 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -16,7 +16,7 @@
16#if ACPI_GLUE_DEBUG 16#if ACPI_GLUE_DEBUG
17#define DBG(x...) printk(PREFIX x) 17#define DBG(x...) printk(PREFIX x)
18#else 18#else
19#define DBG(x...) 19#define DBG(x...) do { } while(0)
20#endif 20#endif
21static LIST_HEAD(bus_type_list); 21static LIST_HEAD(bus_type_list);
22static DECLARE_RWSEM(bus_type_sem); 22static DECLARE_RWSEM(bus_type_sem);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 00d53c2fd1e8..12c09fafce9a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -77,13 +77,7 @@ static struct workqueue_struct *kacpi_notify_wq;
77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ 77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
78static char osi_additional_string[OSI_STRING_LENGTH_MAX]; 78static char osi_additional_string[OSI_STRING_LENGTH_MAX];
79 79
80#define OSI_LINUX_ENABLED 80static int osi_linux; /* disable _OSI(Linux) by default */
81#ifdef OSI_LINUX_ENABLED
82int osi_linux = 1; /* enable _OSI(Linux) by default */
83#else
84int osi_linux; /* disable _OSI(Linux) by default */
85#endif
86
87 81
88#ifdef CONFIG_DMI 82#ifdef CONFIG_DMI
89static struct __initdata dmi_system_id acpi_osl_dmi_table[]; 83static struct __initdata dmi_system_id acpi_osl_dmi_table[];
@@ -1183,17 +1177,10 @@ acpi_os_validate_interface (char *interface)
1183 if (!strcmp("Linux", interface)) { 1177 if (!strcmp("Linux", interface)) {
1184 printk(KERN_WARNING PREFIX 1178 printk(KERN_WARNING PREFIX
1185 "System BIOS is requesting _OSI(Linux)\n"); 1179 "System BIOS is requesting _OSI(Linux)\n");
1186#ifdef OSI_LINUX_ENABLED
1187 printk(KERN_WARNING PREFIX
1188 "Please test with \"acpi_osi=!Linux\"\n"
1189 "Please send dmidecode "
1190 "to linux-acpi@vger.kernel.org\n");
1191#else
1192 printk(KERN_WARNING PREFIX 1180 printk(KERN_WARNING PREFIX
1193 "If \"acpi_osi=Linux\" works better,\n" 1181 "If \"acpi_osi=Linux\" works better,\n"
1194 "Please send dmidecode " 1182 "Please send dmidecode "
1195 "to linux-acpi@vger.kernel.org\n"); 1183 "to linux-acpi@vger.kernel.org\n");
1196#endif
1197 if(osi_linux) 1184 if(osi_linux)
1198 return AE_OK; 1185 return AE_OK;
1199 } 1186 }
@@ -1227,36 +1214,14 @@ acpi_os_validate_address (
1227} 1214}
1228 1215
1229#ifdef CONFIG_DMI 1216#ifdef CONFIG_DMI
1230#ifdef OSI_LINUX_ENABLED
1231static int dmi_osi_not_linux(struct dmi_system_id *d)
1232{
1233 printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident);
1234 enable_osi_linux(0);
1235 return 0;
1236}
1237#else
1238static int dmi_osi_linux(struct dmi_system_id *d) 1217static int dmi_osi_linux(struct dmi_system_id *d)
1239{ 1218{
1240 printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident); 1219 printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident);
1241 enable_osi_linux(1); 1220 enable_osi_linux(1);
1242 return 0; 1221 return 0;
1243} 1222}
1244#endif
1245 1223
1246static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { 1224static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
1247#ifdef OSI_LINUX_ENABLED
1248 /*
1249 * Boxes that need NOT _OSI(Linux)
1250 */
1251 {
1252 .callback = dmi_osi_not_linux,
1253 .ident = "Toshiba Satellite P100",
1254 .matches = {
1255 DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"),
1256 DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"),
1257 },
1258 },
1259#else
1260 /* 1225 /*
1261 * Boxes that need _OSI(Linux) 1226 * Boxes that need _OSI(Linux)
1262 */ 1227 */
@@ -1268,7 +1233,6 @@ static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
1268 DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), 1233 DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
1269 }, 1234 },
1270 }, 1235 },
1271#endif
1272 {} 1236 {}
1273}; 1237};
1274#endif /* CONFIG_DMI */ 1238#endif /* CONFIG_DMI */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index acc594771379..3448edd61dc4 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -733,7 +733,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
733 /* query and set link->irq.active */ 733 /* query and set link->irq.active */
734 acpi_pci_link_get_current(link); 734 acpi_pci_link_get_current(link);
735 735
736 printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), 736 printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device),
737 acpi_device_bid(device)); 737 acpi_device_bid(device));
738 for (i = 0; i < link->irq.possible_count; i++) { 738 for (i = 0; i < link->irq.possible_count; i++) {
739 if (link->irq.active == link->irq.possible[i]) { 739 if (link->irq.active == link->irq.possible[i]) {
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e1ca86dfdd66..81aceb5da7c7 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -66,6 +66,7 @@
66#define ACPI_PROCESSOR_FILE_LIMIT "limit" 66#define ACPI_PROCESSOR_FILE_LIMIT "limit"
67#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 67#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
68#define ACPI_PROCESSOR_NOTIFY_POWER 0x81 68#define ACPI_PROCESSOR_NOTIFY_POWER 0x81
69#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82
69 70
70#define ACPI_PROCESSOR_LIMIT_USER 0 71#define ACPI_PROCESSOR_LIMIT_USER 0
71#define ACPI_PROCESSOR_LIMIT_THERMAL 1 72#define ACPI_PROCESSOR_LIMIT_THERMAL 1
@@ -84,6 +85,8 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
84static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); 85static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
85static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); 86static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
86static int acpi_processor_handle_eject(struct acpi_processor *pr); 87static int acpi_processor_handle_eject(struct acpi_processor *pr);
88extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
89
87 90
88static struct acpi_driver acpi_processor_driver = { 91static struct acpi_driver acpi_processor_driver = {
89 .name = "processor", 92 .name = "processor",
@@ -696,6 +699,9 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
696 acpi_processor_cst_has_changed(pr); 699 acpi_processor_cst_has_changed(pr);
697 acpi_bus_generate_event(device, event, 0); 700 acpi_bus_generate_event(device, event, 0);
698 break; 701 break;
702 case ACPI_PROCESSOR_NOTIFY_THROTTLING:
703 acpi_processor_tstate_has_changed(pr);
704 acpi_bus_generate_event(device, event, 0);
699 default: 705 default:
700 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 706 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
701 "Unsupported event [0x%x]\n", event)); 707 "Unsupported event [0x%x]\n", event));
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index bb5d23be4260..a898991f77cb 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -490,7 +490,17 @@ static void acpi_processor_idle(void)
490 490
491 case ACPI_STATE_C3: 491 case ACPI_STATE_C3:
492 492
493 if (pr->flags.bm_check) { 493 /*
494 * disable bus master
495 * bm_check implies we need ARB_DIS
496 * !bm_check implies we need cache flush
497 * bm_control implies whether we can do ARB_DIS
498 *
499 * That leaves a case where bm_check is set and bm_control is
500 * not set. In that case we cannot do much, we enter C3
501 * without doing anything.
502 */
503 if (pr->flags.bm_check && pr->flags.bm_control) {
494 if (atomic_inc_return(&c3_cpu_count) == 504 if (atomic_inc_return(&c3_cpu_count) ==
495 num_online_cpus()) { 505 num_online_cpus()) {
496 /* 506 /*
@@ -499,7 +509,7 @@ static void acpi_processor_idle(void)
499 */ 509 */
500 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); 510 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
501 } 511 }
502 } else { 512 } else if (!pr->flags.bm_check) {
503 /* SMP with no shared cache... Invalidate cache */ 513 /* SMP with no shared cache... Invalidate cache */
504 ACPI_FLUSH_CPU_CACHE(); 514 ACPI_FLUSH_CPU_CACHE();
505 } 515 }
@@ -511,7 +521,7 @@ static void acpi_processor_idle(void)
511 acpi_cstate_enter(cx); 521 acpi_cstate_enter(cx);
512 /* Get end time (ticks) */ 522 /* Get end time (ticks) */
513 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 523 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
514 if (pr->flags.bm_check) { 524 if (pr->flags.bm_check && pr->flags.bm_control) {
515 /* Enable bus master arbitration */ 525 /* Enable bus master arbitration */
516 atomic_dec(&c3_cpu_count); 526 atomic_dec(&c3_cpu_count);
517 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); 527 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
@@ -961,9 +971,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
961 if (pr->flags.bm_check) { 971 if (pr->flags.bm_check) {
962 /* bus mastering control is necessary */ 972 /* bus mastering control is necessary */
963 if (!pr->flags.bm_control) { 973 if (!pr->flags.bm_control) {
974 /* In this case we enter C3 without bus mastering */
964 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 975 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
965 "C3 support requires bus mastering control\n")); 976 "C3 support without bus mastering control\n"));
966 return;
967 } 977 }
968 } else { 978 } else {
969 /* 979 /*
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index b33486009f41..3f55d1f90c11 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -44,17 +44,231 @@
44#define _COMPONENT ACPI_PROCESSOR_COMPONENT 44#define _COMPONENT ACPI_PROCESSOR_COMPONENT
45ACPI_MODULE_NAME("processor_throttling"); 45ACPI_MODULE_NAME("processor_throttling");
46 46
47static int acpi_processor_get_throttling(struct acpi_processor *pr);
48int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
49
50static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
51{
52 acpi_status status = 0;
53 unsigned long tpc = 0;
54
55 if (!pr)
56 return -EINVAL;
57 status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc);
58 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
59 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC"));
60 return -ENODEV;
61 }
62 pr->throttling_platform_limit = (int)tpc;
63 return 0;
64}
65
66int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
67{
68 return acpi_processor_get_platform_limit(pr);
69}
70
71/* --------------------------------------------------------------------------
72 _PTC, _TSS, _TSD support
73 -------------------------------------------------------------------------- */
74static int acpi_processor_get_throttling_control(struct acpi_processor *pr)
75{
76 int result = 0;
77 acpi_status status = 0;
78 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
79 union acpi_object *ptc = NULL;
80 union acpi_object obj = { 0 };
81
82 status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer);
83 if (ACPI_FAILURE(status)) {
84 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC"));
85 return -ENODEV;
86 }
87
88 ptc = (union acpi_object *)buffer.pointer;
89 if (!ptc || (ptc->type != ACPI_TYPE_PACKAGE)
90 || (ptc->package.count != 2)) {
91 printk(KERN_ERR PREFIX "Invalid _PTC data\n");
92 result = -EFAULT;
93 goto end;
94 }
95
96 /*
97 * control_register
98 */
99
100 obj = ptc->package.elements[0];
101
102 if ((obj.type != ACPI_TYPE_BUFFER)
103 || (obj.buffer.length < sizeof(struct acpi_ptc_register))
104 || (obj.buffer.pointer == NULL)) {
105 printk(KERN_ERR PREFIX
106 "Invalid _PTC data (control_register)\n");
107 result = -EFAULT;
108 goto end;
109 }
110 memcpy(&pr->throttling.control_register, obj.buffer.pointer,
111 sizeof(struct acpi_ptc_register));
112
113 /*
114 * status_register
115 */
116
117 obj = ptc->package.elements[1];
118
119 if ((obj.type != ACPI_TYPE_BUFFER)
120 || (obj.buffer.length < sizeof(struct acpi_ptc_register))
121 || (obj.buffer.pointer == NULL)) {
122 printk(KERN_ERR PREFIX "Invalid _PTC data (status_register)\n");
123 result = -EFAULT;
124 goto end;
125 }
126
127 memcpy(&pr->throttling.status_register, obj.buffer.pointer,
128 sizeof(struct acpi_ptc_register));
129
130 end:
131 kfree(buffer.pointer);
132
133 return result;
134}
135static int acpi_processor_get_throttling_states(struct acpi_processor *pr)
136{
137 int result = 0;
138 acpi_status status = AE_OK;
139 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
140 struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
141 struct acpi_buffer state = { 0, NULL };
142 union acpi_object *tss = NULL;
143 int i;
144
145 status = acpi_evaluate_object(pr->handle, "_TSS", NULL, &buffer);
146 if (ACPI_FAILURE(status)) {
147 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS"));
148 return -ENODEV;
149 }
150
151 tss = buffer.pointer;
152 if (!tss || (tss->type != ACPI_TYPE_PACKAGE)) {
153 printk(KERN_ERR PREFIX "Invalid _TSS data\n");
154 result = -EFAULT;
155 goto end;
156 }
157
158 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
159 tss->package.count));
160
161 pr->throttling.state_count = tss->package.count;
162 pr->throttling.states_tss =
163 kmalloc(sizeof(struct acpi_processor_tx_tss) * tss->package.count,
164 GFP_KERNEL);
165 if (!pr->throttling.states_tss) {
166 result = -ENOMEM;
167 goto end;
168 }
169
170 for (i = 0; i < pr->throttling.state_count; i++) {
171
172 struct acpi_processor_tx_tss *tx =
173 (struct acpi_processor_tx_tss *)&(pr->throttling.
174 states_tss[i]);
175
176 state.length = sizeof(struct acpi_processor_tx_tss);
177 state.pointer = tx;
178
179 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
180
181 status = acpi_extract_package(&(tss->package.elements[i]),
182 &format, &state);
183 if (ACPI_FAILURE(status)) {
184 ACPI_EXCEPTION((AE_INFO, status, "Invalid _TSS data"));
185 result = -EFAULT;
186 kfree(pr->throttling.states_tss);
187 goto end;
188 }
189
190 if (!tx->freqpercentage) {
191 printk(KERN_ERR PREFIX
192 "Invalid _TSS data: freq is zero\n");
193 result = -EFAULT;
194 kfree(pr->throttling.states_tss);
195 goto end;
196 }
197 }
198
199 end:
200 kfree(buffer.pointer);
201
202 return result;
203}
204static int acpi_processor_get_tsd(struct acpi_processor *pr)
205{
206 int result = 0;
207 acpi_status status = AE_OK;
208 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
209 struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" };
210 struct acpi_buffer state = { 0, NULL };
211 union acpi_object *tsd = NULL;
212 struct acpi_tsd_package *pdomain;
213
214 status = acpi_evaluate_object(pr->handle, "_TSD", NULL, &buffer);
215 if (ACPI_FAILURE(status)) {
216 return -ENODEV;
217 }
218
219 tsd = buffer.pointer;
220 if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) {
221 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
222 result = -EFAULT;
223 goto end;
224 }
225
226 if (tsd->package.count != 1) {
227 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
228 result = -EFAULT;
229 goto end;
230 }
231
232 pdomain = &(pr->throttling.domain_info);
233
234 state.length = sizeof(struct acpi_tsd_package);
235 state.pointer = pdomain;
236
237 status = acpi_extract_package(&(tsd->package.elements[0]),
238 &format, &state);
239 if (ACPI_FAILURE(status)) {
240 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n"));
241 result = -EFAULT;
242 goto end;
243 }
244
245 if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) {
246 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n"));
247 result = -EFAULT;
248 goto end;
249 }
250
251 if (pdomain->revision != ACPI_TSD_REV0_REVISION) {
252 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n"));
253 result = -EFAULT;
254 goto end;
255 }
256
257 end:
258 kfree(buffer.pointer);
259 return result;
260}
261
47/* -------------------------------------------------------------------------- 262/* --------------------------------------------------------------------------
48 Throttling Control 263 Throttling Control
49 -------------------------------------------------------------------------- */ 264 -------------------------------------------------------------------------- */
50static int acpi_processor_get_throttling(struct acpi_processor *pr) 265static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr)
51{ 266{
52 int state = 0; 267 int state = 0;
53 u32 value = 0; 268 u32 value = 0;
54 u32 duty_mask = 0; 269 u32 duty_mask = 0;
55 u32 duty_value = 0; 270 u32 duty_value = 0;
56 271
57
58 if (!pr) 272 if (!pr)
59 return -EINVAL; 273 return -EINVAL;
60 274
@@ -94,13 +308,115 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
94 return 0; 308 return 0;
95} 309}
96 310
97int acpi_processor_set_throttling(struct acpi_processor *pr, int state) 311static int acpi_read_throttling_status(struct acpi_processor_throttling
312 *throttling)
313{
314 int value = -1;
315 switch (throttling->status_register.space_id) {
316 case ACPI_ADR_SPACE_SYSTEM_IO:
317 acpi_os_read_port((acpi_io_address) throttling->status_register.
318 address, &value,
319 (u32) throttling->status_register.bit_width *
320 8);
321 break;
322 case ACPI_ADR_SPACE_FIXED_HARDWARE:
323 printk(KERN_ERR PREFIX
324 "HARDWARE addr space,NOT supported yet\n");
325 break;
326 default:
327 printk(KERN_ERR PREFIX "Unknown addr space %d\n",
328 (u32) (throttling->status_register.space_id));
329 }
330 return value;
331}
332
333static int acpi_write_throttling_state(struct acpi_processor_throttling
334 *throttling, int value)
335{
336 int ret = -1;
337
338 switch (throttling->control_register.space_id) {
339 case ACPI_ADR_SPACE_SYSTEM_IO:
340 acpi_os_write_port((acpi_io_address) throttling->
341 control_register.address, value,
342 (u32) throttling->control_register.
343 bit_width * 8);
344 ret = 0;
345 break;
346 case ACPI_ADR_SPACE_FIXED_HARDWARE:
347 printk(KERN_ERR PREFIX
348 "HARDWARE addr space,NOT supported yet\n");
349 break;
350 default:
351 printk(KERN_ERR PREFIX "Unknown addr space %d\n",
352 (u32) (throttling->control_register.space_id));
353 }
354 return ret;
355}
356
357static int acpi_get_throttling_state(struct acpi_processor *pr, int value)
358{
359 int i;
360
361 for (i = 0; i < pr->throttling.state_count; i++) {
362 struct acpi_processor_tx_tss *tx =
363 (struct acpi_processor_tx_tss *)&(pr->throttling.
364 states_tss[i]);
365 if (tx->control == value)
366 break;
367 }
368 if (i > pr->throttling.state_count)
369 i = -1;
370 return i;
371}
372
373static int acpi_get_throttling_value(struct acpi_processor *pr, int state)
374{
375 int value = -1;
376 if (state >= 0 && state <= pr->throttling.state_count) {
377 struct acpi_processor_tx_tss *tx =
378 (struct acpi_processor_tx_tss *)&(pr->throttling.
379 states_tss[state]);
380 value = tx->control;
381 }
382 return value;
383}
384
385static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr)
386{
387 int state = 0;
388 u32 value = 0;
389
390 if (!pr)
391 return -EINVAL;
392
393 if (!pr->flags.throttling)
394 return -ENODEV;
395
396 pr->throttling.state = 0;
397 local_irq_disable();
398 value = acpi_read_throttling_status(&pr->throttling);
399 if (value >= 0) {
400 state = acpi_get_throttling_state(pr, value);
401 pr->throttling.state = state;
402 }
403 local_irq_enable();
404
405 return 0;
406}
407
408static int acpi_processor_get_throttling(struct acpi_processor *pr)
409{
410 return pr->throttling.acpi_processor_get_throttling(pr);
411}
412
413static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
414 int state)
98{ 415{
99 u32 value = 0; 416 u32 value = 0;
100 u32 duty_mask = 0; 417 u32 duty_mask = 0;
101 u32 duty_value = 0; 418 u32 duty_value = 0;
102 419
103
104 if (!pr) 420 if (!pr)
105 return -EINVAL; 421 return -EINVAL;
106 422
@@ -113,6 +429,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
113 if (state == pr->throttling.state) 429 if (state == pr->throttling.state)
114 return 0; 430 return 0;
115 431
432 if (state < pr->throttling_platform_limit)
433 return -EPERM;
116 /* 434 /*
117 * Calculate the duty_value and duty_mask. 435 * Calculate the duty_value and duty_mask.
118 */ 436 */
@@ -165,12 +483,51 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
165 return 0; 483 return 0;
166} 484}
167 485
486static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
487 int state)
488{
489 u32 value = 0;
490
491 if (!pr)
492 return -EINVAL;
493
494 if ((state < 0) || (state > (pr->throttling.state_count - 1)))
495 return -EINVAL;
496
497 if (!pr->flags.throttling)
498 return -ENODEV;
499
500 if (state == pr->throttling.state)
501 return 0;
502
503 if (state < pr->throttling_platform_limit)
504 return -EPERM;
505
506 local_irq_disable();
507
508 value = acpi_get_throttling_value(pr, state);
509 if (value >= 0) {
510 acpi_write_throttling_state(&pr->throttling, value);
511 pr->throttling.state = state;
512 }
513 local_irq_enable();
514
515 return 0;
516}
517
518int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
519{
520 return pr->throttling.acpi_processor_set_throttling(pr, state);
521}
522
168int acpi_processor_get_throttling_info(struct acpi_processor *pr) 523int acpi_processor_get_throttling_info(struct acpi_processor *pr)
169{ 524{
170 int result = 0; 525 int result = 0;
171 int step = 0; 526 int step = 0;
172 int i = 0; 527 int i = 0;
173 528 int no_ptc = 0;
529 int no_tss = 0;
530 int no_tsd = 0;
174 531
175 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 532 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
176 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", 533 "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
@@ -182,6 +539,21 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
182 return -EINVAL; 539 return -EINVAL;
183 540
184 /* TBD: Support ACPI 2.0 objects */ 541 /* TBD: Support ACPI 2.0 objects */
542 no_ptc = acpi_processor_get_throttling_control(pr);
543 no_tss = acpi_processor_get_throttling_states(pr);
544 no_tsd = acpi_processor_get_tsd(pr);
545
546 if (no_ptc || no_tss) {
547 pr->throttling.acpi_processor_get_throttling =
548 &acpi_processor_get_throttling_fadt;
549 pr->throttling.acpi_processor_set_throttling =
550 &acpi_processor_set_throttling_fadt;
551 } else {
552 pr->throttling.acpi_processor_get_throttling =
553 &acpi_processor_get_throttling_ptc;
554 pr->throttling.acpi_processor_set_throttling =
555 &acpi_processor_set_throttling_ptc;
556 }
185 557
186 if (!pr->throttling.address) { 558 if (!pr->throttling.address) {
187 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); 559 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
@@ -262,7 +634,6 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
262 int i = 0; 634 int i = 0;
263 int result = 0; 635 int result = 0;
264 636
265
266 if (!pr) 637 if (!pr)
267 goto end; 638 goto end;
268 639
@@ -280,15 +651,25 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq,
280 } 651 }
281 652
282 seq_printf(seq, "state count: %d\n" 653 seq_printf(seq, "state count: %d\n"
283 "active state: T%d\n", 654 "active state: T%d\n"
284 pr->throttling.state_count, pr->throttling.state); 655 "state available: T%d to T%d\n",
656 pr->throttling.state_count, pr->throttling.state,
657 pr->throttling_platform_limit,
658 pr->throttling.state_count - 1);
285 659
286 seq_puts(seq, "states:\n"); 660 seq_puts(seq, "states:\n");
287 for (i = 0; i < pr->throttling.state_count; i++) 661 if (acpi_processor_get_throttling == acpi_processor_get_throttling_fadt)
288 seq_printf(seq, " %cT%d: %02d%%\n", 662 for (i = 0; i < pr->throttling.state_count; i++)
289 (i == pr->throttling.state ? '*' : ' '), i, 663 seq_printf(seq, " %cT%d: %02d%%\n",
290 (pr->throttling.states[i].performance ? pr-> 664 (i == pr->throttling.state ? '*' : ' '), i,
291 throttling.states[i].performance / 10 : 0)); 665 (pr->throttling.states[i].performance ? pr->
666 throttling.states[i].performance / 10 : 0));
667 else
668 for (i = 0; i < pr->throttling.state_count; i++)
669 seq_printf(seq, " %cT%d: %02d%%\n",
670 (i == pr->throttling.state ? '*' : ' '), i,
671 (int)pr->throttling.states_tss[i].
672 freqpercentage);
292 673
293 end: 674 end:
294 return 0; 675 return 0;
@@ -301,7 +682,7 @@ static int acpi_processor_throttling_open_fs(struct inode *inode,
301 PDE(inode)->data); 682 PDE(inode)->data);
302} 683}
303 684
304static ssize_t acpi_processor_write_throttling(struct file * file, 685static ssize_t acpi_processor_write_throttling(struct file *file,
305 const char __user * buffer, 686 const char __user * buffer,
306 size_t count, loff_t * data) 687 size_t count, loff_t * data)
307{ 688{
@@ -310,7 +691,6 @@ static ssize_t acpi_processor_write_throttling(struct file * file,
310 struct acpi_processor *pr = m->private; 691 struct acpi_processor *pr = m->private;
311 char state_string[12] = { '\0' }; 692 char state_string[12] = { '\0' };
312 693
313
314 if (!pr || (count > sizeof(state_string) - 1)) 694 if (!pr || (count > sizeof(state_string) - 1))
315 return -EINVAL; 695 return -EINVAL;
316 696
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index c1bae106833c..974d00ccfe84 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -127,7 +127,7 @@ static int acpi_sbs_resume(struct acpi_device *device);
127static struct acpi_driver acpi_sbs_driver = { 127static struct acpi_driver acpi_sbs_driver = {
128 .name = "sbs", 128 .name = "sbs",
129 .class = ACPI_SBS_CLASS, 129 .class = ACPI_SBS_CLASS,
130 .ids = ACPI_SBS_HID, 130 .ids = "ACPI0001,ACPI0005",
131 .ops = { 131 .ops = {
132 .add = acpi_sbs_add, 132 .add = acpi_sbs_add,
133 .remove = acpi_sbs_remove, 133 .remove = acpi_sbs_remove,
@@ -176,10 +176,8 @@ struct acpi_battery {
176}; 176};
177 177
178struct acpi_sbs { 178struct acpi_sbs {
179 acpi_handle handle;
180 int base; 179 int base;
181 struct acpi_device *device; 180 struct acpi_device *device;
182 struct acpi_ec_smbus *smbus;
183 struct mutex mutex; 181 struct mutex mutex;
184 int sbsm_present; 182 int sbsm_present;
185 int sbsm_batteries_supported; 183 int sbsm_batteries_supported;
@@ -511,7 +509,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
511 "acpi_sbs_read_word() failed")); 509 "acpi_sbs_read_word() failed"));
512 goto end; 510 goto end;
513 } 511 }
514 512 sbs->sbsm_present = 1;
515 sbs->sbsm_batteries_supported = battery_system_info & 0x000f; 513 sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
516 514
517 end: 515 end:
@@ -1630,13 +1628,12 @@ static int acpi_sbs_add(struct acpi_device *device)
1630{ 1628{
1631 struct acpi_sbs *sbs = NULL; 1629 struct acpi_sbs *sbs = NULL;
1632 int result = 0, remove_result = 0; 1630 int result = 0, remove_result = 0;
1633 unsigned long sbs_obj;
1634 int id; 1631 int id;
1635 acpi_status status = AE_OK; 1632 acpi_status status = AE_OK;
1636 unsigned long val; 1633 unsigned long val;
1637 1634
1638 status = 1635 status =
1639 acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val); 1636 acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
1640 if (ACPI_FAILURE(status)) { 1637 if (ACPI_FAILURE(status)) {
1641 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); 1638 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
1642 return -EIO; 1639 return -EIO;
@@ -1653,7 +1650,7 @@ static int acpi_sbs_add(struct acpi_device *device)
1653 1650
1654 sbs_mutex_lock(sbs); 1651 sbs_mutex_lock(sbs);
1655 1652
1656 sbs->base = (val & 0xff00ull) >> 8; 1653 sbs->base = 0xff & (val >> 8);
1657 sbs->device = device; 1654 sbs->device = device;
1658 1655
1659 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); 1656 strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
@@ -1665,24 +1662,10 @@ static int acpi_sbs_add(struct acpi_device *device)
1665 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); 1662 ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
1666 goto end; 1663 goto end;
1667 } 1664 }
1668 status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj);
1669 if (status) {
1670 ACPI_EXCEPTION((AE_INFO, status,
1671 "acpi_evaluate_integer() failed"));
1672 result = -EIO;
1673 goto end;
1674 }
1675 if (sbs_obj > 0) {
1676 result = acpi_sbsm_get_info(sbs);
1677 if (result) {
1678 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
1679 "acpi_sbsm_get_info() failed"));
1680 goto end;
1681 }
1682 sbs->sbsm_present = 1;
1683 }
1684 1665
1685 if (sbs->sbsm_present == 0) { 1666 acpi_sbsm_get_info(sbs);
1667
1668 if (!sbs->sbsm_present) {
1686 result = acpi_battery_add(sbs, 0); 1669 result = acpi_battery_add(sbs, 0);
1687 if (result) { 1670 if (result) {
1688 ACPI_EXCEPTION((AE_INFO, AE_ERROR, 1671 ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1702,8 +1685,6 @@ static int acpi_sbs_add(struct acpi_device *device)
1702 } 1685 }
1703 } 1686 }
1704 1687
1705 sbs->handle = device->handle;
1706
1707 init_timer(&sbs->update_timer); 1688 init_timer(&sbs->update_timer);
1708 result = acpi_check_update_proc(sbs); 1689 result = acpi_check_update_proc(sbs);
1709 if (result) 1690 if (result)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 42127c0d612c..3279e72a94f8 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -210,11 +210,6 @@ static void acpi_hibernation_finish(void)
210 210
211 /* reset firmware waking vector */ 211 /* reset firmware waking vector */
212 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 212 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
213
214 if (init_8259A_after_S1) {
215 printk("Broken toshiba laptop -> kicking interrupts\n");
216 init_8259A(0);
217 }
218} 213}
219 214
220static int acpi_hibernation_pre_restore(void) 215static int acpi_hibernation_pre_restore(void)
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 83a8d3097904..edee2806e37b 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system");
39 39
40#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
41#define ACPI_SYSTEM_DEVICE_NAME "System" 41#define ACPI_SYSTEM_DEVICE_NAME "System"
42#define ACPI_SYSTEM_FILE_INFO "info"
43#define ACPI_SYSTEM_FILE_EVENT "event"
44#define ACPI_SYSTEM_FILE_DSDT "dsdt"
45#define ACPI_SYSTEM_FILE_FADT "fadt"
46 42
47/* 43/*
48 * Make ACPICA version work as module param 44 * Make ACPICA version work as module param
49 */ 45 */
50static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { 46static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
47{
51 int result; 48 int result;
52 49
53 result = sprintf(buffer, "%x", ACPI_CA_VERSION); 50 result = sprintf(buffer, "%x", ACPI_CA_VERSION);
@@ -58,9 +55,126 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) {
58module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); 55module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
59 56
60/* -------------------------------------------------------------------------- 57/* --------------------------------------------------------------------------
58 FS Interface (/sys)
59 -------------------------------------------------------------------------- */
60static LIST_HEAD(acpi_table_attr_list);
61static struct kobject tables_kobj;
62
63struct acpi_table_attr {
64 struct bin_attribute attr;
65 char name[8];
66 int instance;
67 struct list_head node;
68};
69
70static ssize_t acpi_table_show(struct kobject *kobj,
71 struct bin_attribute *bin_attr, char *buf,
72 loff_t offset, size_t count)
73{
74 struct acpi_table_attr *table_attr =
75 container_of(bin_attr, struct acpi_table_attr, attr);
76 struct acpi_table_header *table_header = NULL;
77 acpi_status status;
78 ssize_t ret_count = count;
79
80 status =
81 acpi_get_table(table_attr->name, table_attr->instance,
82 &table_header);
83 if (ACPI_FAILURE(status))
84 return -ENODEV;
85
86 if (offset >= table_header->length) {
87 ret_count = 0;
88 goto end;
89 }
90
91 if (offset + ret_count > table_header->length)
92 ret_count = table_header->length - offset;
93
94 memcpy(buf, ((char *)table_header) + offset, ret_count);
95
96 end:
97 return ret_count;
98}
99
100static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
101 struct acpi_table_header *table_header)
102{
103 struct acpi_table_header *header = NULL;
104 struct acpi_table_attr *attr = NULL;
105
106 memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
107
108 list_for_each_entry(attr, &acpi_table_attr_list, node) {
109 if (!memcmp(table_header->signature, attr->name,
110 ACPI_NAME_SIZE))
111 if (table_attr->instance < attr->instance)
112 table_attr->instance = attr->instance;
113 }
114 table_attr->instance++;
115
116 if (table_attr->instance > 1 || (table_attr->instance == 1 &&
117 !acpi_get_table(table_header->
118 signature, 2,
119 &header)))
120 sprintf(table_attr->name + 4, "%d", table_attr->instance);
121
122 table_attr->attr.size = 0;
123 table_attr->attr.read = acpi_table_show;
124 table_attr->attr.attr.name = table_attr->name;
125 table_attr->attr.attr.mode = 0444;
126 table_attr->attr.attr.owner = THIS_MODULE;
127
128 return;
129}
130
131static int acpi_system_sysfs_init(void)
132{
133 struct acpi_table_attr *table_attr;
134 struct acpi_table_header *table_header = NULL;
135 int table_index = 0;
136 int result;
137
138 tables_kobj.parent = &acpi_subsys.kobj;
139 kobject_set_name(&tables_kobj, "tables");
140 result = kobject_register(&tables_kobj);
141 if (result)
142 return result;
143
144 do {
145 result = acpi_get_table_by_index(table_index, &table_header);
146 if (!result) {
147 table_index++;
148 table_attr = NULL;
149 table_attr =
150 kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
151 if (!table_attr)
152 return -ENOMEM;
153
154 acpi_table_attr_init(table_attr, table_header);
155 result =
156 sysfs_create_bin_file(&tables_kobj,
157 &table_attr->attr);
158 if (result) {
159 kfree(table_attr);
160 return result;
161 } else
162 list_add_tail(&table_attr->node,
163 &acpi_table_attr_list);
164 }
165 } while (!result);
166
167 return 0;
168}
169
170/* --------------------------------------------------------------------------
61 FS Interface (/proc) 171 FS Interface (/proc)
62 -------------------------------------------------------------------------- */ 172 -------------------------------------------------------------------------- */
63#ifdef CONFIG_ACPI_PROCFS 173#ifdef CONFIG_ACPI_PROCFS
174#define ACPI_SYSTEM_FILE_INFO "info"
175#define ACPI_SYSTEM_FILE_EVENT "event"
176#define ACPI_SYSTEM_FILE_DSDT "dsdt"
177#define ACPI_SYSTEM_FILE_FADT "fadt"
64 178
65static int acpi_system_read_info(struct seq_file *seq, void *offset) 179static int acpi_system_read_info(struct seq_file *seq, void *offset)
66{ 180{
@@ -80,7 +194,6 @@ static const struct file_operations acpi_system_info_ops = {
80 .llseek = seq_lseek, 194 .llseek = seq_lseek,
81 .release = single_release, 195 .release = single_release,
82}; 196};
83#endif
84 197
85static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, 198static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t,
86 loff_t *); 199 loff_t *);
@@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file,
97 struct acpi_table_header *dsdt = NULL; 210 struct acpi_table_header *dsdt = NULL;
98 ssize_t res; 211 ssize_t res;
99 212
100
101 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); 213 status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt);
102 if (ACPI_FAILURE(status)) 214 if (ACPI_FAILURE(status))
103 return -ENODEV; 215 return -ENODEV;
104 216
105 res = simple_read_from_buffer(buffer, count, ppos, 217 res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length);
106 dsdt, dsdt->length);
107 218
108 return res; 219 return res;
109} 220}
@@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file,
123 struct acpi_table_header *fadt = NULL; 234 struct acpi_table_header *fadt = NULL;
124 ssize_t res; 235 ssize_t res;
125 236
126
127 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); 237 status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt);
128 if (ACPI_FAILURE(status)) 238 if (ACPI_FAILURE(status))
129 return -ENODEV; 239 return -ENODEV;
130 240
131 res = simple_read_from_buffer(buffer, count, ppos, 241 res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length);
132 fadt, fadt->length);
133 242
134 return res; 243 return res;
135} 244}
136 245
137static int __init acpi_system_init(void) 246static int acpi_system_procfs_init(void)
138{ 247{
139 struct proc_dir_entry *entry; 248 struct proc_dir_entry *entry;
140 int error = 0; 249 int error = 0;
141 char *name; 250 char *name;
142 251
143
144 if (acpi_disabled)
145 return 0;
146
147#ifdef CONFIG_ACPI_PROCFS
148 /* 'info' [R] */ 252 /* 'info' [R] */
149 name = ACPI_SYSTEM_FILE_INFO; 253 name = ACPI_SYSTEM_FILE_INFO;
150 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); 254 entry = create_proc_entry(name, S_IRUGO, acpi_root_dir);
@@ -153,7 +257,6 @@ static int __init acpi_system_init(void)
153 else { 257 else {
154 entry->proc_fops = &acpi_system_info_ops; 258 entry->proc_fops = &acpi_system_info_ops;
155 } 259 }
156#endif
157 260
158 /* 'dsdt' [R] */ 261 /* 'dsdt' [R] */
159 name = ACPI_SYSTEM_FILE_DSDT; 262 name = ACPI_SYSTEM_FILE_DSDT;
@@ -177,12 +280,32 @@ static int __init acpi_system_init(void)
177 Error: 280 Error:
178 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); 281 remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir);
179 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); 282 remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir);
180#ifdef CONFIG_ACPI_PROCFS
181 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); 283 remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir);
182#endif
183 284
184 error = -EFAULT; 285 error = -EFAULT;
185 goto Done; 286 goto Done;
186} 287}
288#else
289static int acpi_system_procfs_init(void)
290{
291 return 0;
292}
293#endif
294
295static int __init acpi_system_init(void)
296{
297 int result = 0;
298
299 if (acpi_disabled)
300 return 0;
301
302 result = acpi_system_procfs_init();
303 if (result)
304 return result;
305
306 result = acpi_system_sysfs_init();
307
308 return result;
309}
187 310
188subsys_initcall(acpi_system_init); 311subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index 1285e91474fb..002bb33003af 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -211,14 +211,17 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags)
211 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. 211 * DESCRIPTION: Get a local copy of the FADT and convert it to a common format.
212 * Performs validation on some important FADT fields. 212 * Performs validation on some important FADT fields.
213 * 213 *
214 * NOTE: We create a local copy of the FADT regardless of the version.
215 *
214 ******************************************************************************/ 216 ******************************************************************************/
215 217
216void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) 218void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
217{ 219{
218 220
219 /* 221 /*
220 * Check if the FADT is larger than what we know about (ACPI 2.0 version). 222 * Check if the FADT is larger than the largest table that we expect
221 * Truncate the table, but make some noise. 223 * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue
224 * a warning.
222 */ 225 */
223 if (length > sizeof(struct acpi_table_fadt)) { 226 if (length > sizeof(struct acpi_table_fadt)) {
224 ACPI_WARNING((AE_INFO, 227 ACPI_WARNING((AE_INFO,
@@ -227,10 +230,12 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
227 sizeof(struct acpi_table_fadt))); 230 sizeof(struct acpi_table_fadt)));
228 } 231 }
229 232
230 /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ 233 /* Clear the entire local FADT */
231 234
232 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); 235 ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt));
233 236
237 /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */
238
234 ACPI_MEMCPY(&acpi_gbl_FADT, table, 239 ACPI_MEMCPY(&acpi_gbl_FADT, table,
235 ACPI_MIN(length, sizeof(struct acpi_table_fadt))); 240 ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
236 241
@@ -251,7 +256,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
251 * RETURN: None 256 * RETURN: None
252 * 257 *
253 * DESCRIPTION: Converts all versions of the FADT to a common internal format. 258 * DESCRIPTION: Converts all versions of the FADT to a common internal format.
254 * -> Expand all 32-bit addresses to 64-bit. 259 * Expand all 32-bit addresses to 64-bit.
255 * 260 *
256 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), 261 * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
257 * and must contain a copy of the actual FADT. 262 * and must contain a copy of the actual FADT.
@@ -292,8 +297,23 @@ static void acpi_tb_convert_fadt(void)
292 } 297 }
293 298
294 /* 299 /*
295 * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address 300 * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
296 * structures as necessary. 301 * should be zero are indeed zero. This will workaround BIOSs that
302 * inadvertently place values in these fields.
303 *
304 * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at
305 * offset 45, 55, 95, and the word located at offset 109, 110.
306 */
307 if (acpi_gbl_FADT.header.revision < 3) {
308 acpi_gbl_FADT.preferred_profile = 0;
309 acpi_gbl_FADT.pstate_control = 0;
310 acpi_gbl_FADT.cst_control = 0;
311 acpi_gbl_FADT.boot_flags = 0;
312 }
313
314 /*
315 * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X"
316 * generic address structures as necessary.
297 */ 317 */
298 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 318 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
299 target = 319 target =
@@ -349,18 +369,6 @@ static void acpi_tb_convert_fadt(void)
349 acpi_gbl_FADT.xpm1a_event_block.space_id; 369 acpi_gbl_FADT.xpm1a_event_block.space_id;
350 370
351 } 371 }
352
353 /*
354 * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero)
355 * are indeed zero. This will workaround BIOSs that inadvertently placed
356 * values in these fields.
357 */
358 if (acpi_gbl_FADT.header.revision < 3) {
359 acpi_gbl_FADT.preferred_profile = 0;
360 acpi_gbl_FADT.pstate_control = 0;
361 acpi_gbl_FADT.cst_control = 0;
362 acpi_gbl_FADT.boot_flags = 0;
363 }
364} 372}
365 373
366/****************************************************************************** 374/******************************************************************************
diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
index 8ec6f8e48138..f112af433e36 100644
--- a/drivers/acpi/utilities/uteval.c
+++ b/drivers/acpi/utilities/uteval.c
@@ -62,16 +62,13 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
62static char *acpi_interfaces_supported[] = { 62static char *acpi_interfaces_supported[] = {
63 /* Operating System Vendor Strings */ 63 /* Operating System Vendor Strings */
64 64
65 "Windows 2000", 65 "Windows 2000", /* Windows 2000 */
66 "Windows 2001", 66 "Windows 2001", /* Windows XP */
67 "Windows 2001 SP0", 67 "Windows 2001 SP1", /* Windows XP SP1 */
68 "Windows 2001 SP1", 68 "Windows 2001 SP2", /* Windows XP SP2 */
69 "Windows 2001 SP2", 69 "Windows 2001.1", /* Windows Server 2003 */
70 "Windows 2001 SP3", 70 "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
71 "Windows 2001 SP4", 71 "Windows 2006", /* Windows Vista - Added 03/2006 */
72 "Windows 2001.1",
73 "Windows 2001.1 SP1", /* Added 03/2006 */
74 "Windows 2006", /* Added 03/2006 */
75 72
76 /* Feature Group Strings */ 73 /* Feature Group Strings */
77 74
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 00d25b347255..5f014d3764c8 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -33,6 +33,7 @@
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/backlight.h> 35#include <linux/backlight.h>
36#include <linux/video_output.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37 38
38#include <acpi/acpi_bus.h> 39#include <acpi/acpi_bus.h>
@@ -169,6 +170,7 @@ struct acpi_video_device {
169 struct acpi_device *dev; 170 struct acpi_device *dev;
170 struct acpi_video_device_brightness *brightness; 171 struct acpi_video_device_brightness *brightness;
171 struct backlight_device *backlight; 172 struct backlight_device *backlight;
173 struct output_device *output_dev;
172}; 174};
173 175
174/* bus */ 176/* bus */
@@ -272,6 +274,10 @@ static int acpi_video_get_next_level(struct acpi_video_device *device,
272 u32 level_current, u32 event); 274 u32 level_current, u32 event);
273static void acpi_video_switch_brightness(struct acpi_video_device *device, 275static void acpi_video_switch_brightness(struct acpi_video_device *device,
274 int event); 276 int event);
277static int acpi_video_device_get_state(struct acpi_video_device *device,
278 unsigned long *state);
279static int acpi_video_output_get(struct output_device *od);
280static int acpi_video_device_set_state(struct acpi_video_device *device, int state);
275 281
276/*backlight device sysfs support*/ 282/*backlight device sysfs support*/
277static int acpi_video_get_brightness(struct backlight_device *bd) 283static int acpi_video_get_brightness(struct backlight_device *bd)
@@ -297,6 +303,28 @@ static struct backlight_ops acpi_backlight_ops = {
297 .update_status = acpi_video_set_brightness, 303 .update_status = acpi_video_set_brightness,
298}; 304};
299 305
306/*video output device sysfs support*/
307static int acpi_video_output_get(struct output_device *od)
308{
309 unsigned long state;
310 struct acpi_video_device *vd =
311 (struct acpi_video_device *)class_get_devdata(&od->class_dev);
312 acpi_video_device_get_state(vd, &state);
313 return (int)state;
314}
315
316static int acpi_video_output_set(struct output_device *od)
317{
318 unsigned long state = od->request_state;
319 struct acpi_video_device *vd=
320 (struct acpi_video_device *)class_get_devdata(&od->class_dev);
321 return acpi_video_device_set_state(vd, state);
322}
323
324static struct output_properties acpi_output_properties = {
325 .set_state = acpi_video_output_set,
326 .get_status = acpi_video_output_get,
327};
300/* -------------------------------------------------------------------------- 328/* --------------------------------------------------------------------------
301 Video Management 329 Video Management
302 -------------------------------------------------------------------------- */ 330 -------------------------------------------------------------------------- */
@@ -531,7 +559,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
531 559
532static void acpi_video_device_find_cap(struct acpi_video_device *device) 560static void acpi_video_device_find_cap(struct acpi_video_device *device)
533{ 561{
534 acpi_integer status;
535 acpi_handle h_dummy1; 562 acpi_handle h_dummy1;
536 int i; 563 int i;
537 u32 max_level = 0; 564 u32 max_level = 0;
@@ -565,50 +592,55 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
565 device->cap._DSS = 1; 592 device->cap._DSS = 1;
566 } 593 }
567 594
568 status = acpi_video_device_lcd_query_levels(device, &obj); 595 if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
569 596
570 if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { 597 if (obj->package.count >= 2) {
571 int count = 0; 598 int count = 0;
572 union acpi_object *o; 599 union acpi_object *o;
573 600
574 br = kzalloc(sizeof(*br), GFP_KERNEL); 601 br = kzalloc(sizeof(*br), GFP_KERNEL);
575 if (!br) { 602 if (!br) {
576 printk(KERN_ERR "can't allocate memory\n"); 603 printk(KERN_ERR "can't allocate memory\n");
577 } else {
578 br->levels = kmalloc(obj->package.count *
579 sizeof *(br->levels), GFP_KERNEL);
580 if (!br->levels)
581 goto out;
582
583 for (i = 0; i < obj->package.count; i++) {
584 o = (union acpi_object *)&obj->package.
585 elements[i];
586 if (o->type != ACPI_TYPE_INTEGER) {
587 printk(KERN_ERR PREFIX "Invalid data\n");
588 continue;
589 }
590 br->levels[count] = (u32) o->integer.value;
591 if (br->levels[count] > max_level)
592 max_level = br->levels[count];
593 count++;
594 }
595 out:
596 if (count < 2) {
597 kfree(br->levels);
598 kfree(br);
599 } else { 604 } else {
600 br->count = count; 605 br->levels = kmalloc(obj->package.count *
601 device->brightness = br; 606 sizeof *(br->levels), GFP_KERNEL);
602 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 607 if (!br->levels)
603 "found %d brightness levels\n", 608 goto out;
604 count)); 609
610 for (i = 0; i < obj->package.count; i++) {
611 o = (union acpi_object *)&obj->package.
612 elements[i];
613 if (o->type != ACPI_TYPE_INTEGER) {
614 printk(KERN_ERR PREFIX "Invalid data\n");
615 continue;
616 }
617 br->levels[count] = (u32) o->integer.value;
618
619 if (br->levels[count] > max_level)
620 max_level = br->levels[count];
621 count++;
622 }
623 out:
624 if (count < 2) {
625 kfree(br->levels);
626 kfree(br);
627 } else {
628 br->count = count;
629 device->brightness = br;
630 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
631 "found %d brightness levels\n",
632 count));
633 }
605 } 634 }
606 } 635 }
636
637 } else {
638 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
607 } 639 }
608 640
609 kfree(obj); 641 kfree(obj);
610 642
611 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ 643 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
612 unsigned long tmp; 644 unsigned long tmp;
613 static int count = 0; 645 static int count = 0;
614 char *name; 646 char *name;
@@ -626,6 +658,17 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
626 658
627 kfree(name); 659 kfree(name);
628 } 660 }
661 if (device->cap._DCS && device->cap._DSS){
662 static int count = 0;
663 char *name;
664 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
665 if (!name)
666 return;
667 sprintf(name, "acpi_video%d", count++);
668 device->output_dev = video_output_register(name,
669 NULL, device, &acpi_output_properties);
670 kfree(name);
671 }
629 return; 672 return;
630} 673}
631 674
@@ -1669,6 +1712,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1669 ACPI_DEVICE_NOTIFY, 1712 ACPI_DEVICE_NOTIFY,
1670 acpi_video_device_notify); 1713 acpi_video_device_notify);
1671 backlight_device_unregister(device->backlight); 1714 backlight_device_unregister(device->backlight);
1715 video_output_unregister(device->output_dev);
1672 return 0; 1716 return 0;
1673} 1717}
1674 1718
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1d516f24ba53..aaaa61ea4217 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -150,6 +150,7 @@ config THINKPAD_ACPI
150 depends on X86 && ACPI 150 depends on X86 && ACPI
151 select BACKLIGHT_CLASS_DEVICE 151 select BACKLIGHT_CLASS_DEVICE
152 select HWMON 152 select HWMON
153 select NVRAM
153 ---help--- 154 ---help---
154 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds 155 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
155 support for Fn-Fx key combinations, Bluetooth control, video 156 support for Fn-Fx key combinations, Bluetooth control, video
@@ -196,4 +197,17 @@ config THINKPAD_ACPI_BAY
196 197
197 If you are not sure, say Y here. 198 If you are not sure, say Y here.
198 199
200config THINKPAD_ACPI_INPUT_ENABLED
201 bool "Enable input layer support by default"
202 depends on THINKPAD_ACPI
203 default y
204 ---help---
205 Enables hot key handling over the input layer by default. If unset,
206 the driver does not enable any hot key handling by default, and also
207 starts up with a mostly empty keymap.
208
209 If you are not sure, say Y here. Say N to retain the deprecated
210 behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21.
211
212
199endif # MISC_DEVICES 213endif # MISC_DEVICES
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 9623eaf4f89f..303e48ca0e8a 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -142,43 +142,124 @@ struct sony_laptop_keypress {
142 int key; 142 int key;
143}; 143};
144 144
145/* Correspondance table between sonypi events and input layer events */ 145/* Correspondance table between sonypi events
146static struct { 146 * and input layer indexes in the keymap
147 int sonypiev; 147 */
148 int inputev; 148static int sony_laptop_input_index[] = {
149} sony_laptop_inputkeys[] = { 149 -1, /* no event */
150 { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA }, 150 -1, /* SONYPI_EVENT_JOGDIAL_DOWN */
151 { SONYPI_EVENT_FNKEY_ONLY, KEY_FN }, 151 -1, /* SONYPI_EVENT_JOGDIAL_UP */
152 { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC }, 152 -1, /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */
153 { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 }, 153 -1, /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */
154 { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 }, 154 -1, /* SONYPI_EVENT_JOGDIAL_PRESSED */
155 { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 }, 155 -1, /* SONYPI_EVENT_JOGDIAL_RELEASED */
156 { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 }, 156 0, /* SONYPI_EVENT_CAPTURE_PRESSED */
157 { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 }, 157 1, /* SONYPI_EVENT_CAPTURE_RELEASED */
158 { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 }, 158 2, /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
159 { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 }, 159 3, /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
160 { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 }, 160 4, /* SONYPI_EVENT_FNKEY_ESC */
161 { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 }, 161 5, /* SONYPI_EVENT_FNKEY_F1 */
162 { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 }, 162 6, /* SONYPI_EVENT_FNKEY_F2 */
163 { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 }, 163 7, /* SONYPI_EVENT_FNKEY_F3 */
164 { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 }, 164 8, /* SONYPI_EVENT_FNKEY_F4 */
165 { SONYPI_EVENT_FNKEY_1, KEY_FN_1 }, 165 9, /* SONYPI_EVENT_FNKEY_F5 */
166 { SONYPI_EVENT_FNKEY_2, KEY_FN_2 }, 166 10, /* SONYPI_EVENT_FNKEY_F6 */
167 { SONYPI_EVENT_FNKEY_D, KEY_FN_D }, 167 11, /* SONYPI_EVENT_FNKEY_F7 */
168 { SONYPI_EVENT_FNKEY_E, KEY_FN_E }, 168 12, /* SONYPI_EVENT_FNKEY_F8 */
169 { SONYPI_EVENT_FNKEY_F, KEY_FN_F }, 169 13, /* SONYPI_EVENT_FNKEY_F9 */
170 { SONYPI_EVENT_FNKEY_S, KEY_FN_S }, 170 14, /* SONYPI_EVENT_FNKEY_F10 */
171 { SONYPI_EVENT_FNKEY_B, KEY_FN_B }, 171 15, /* SONYPI_EVENT_FNKEY_F11 */
172 { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE }, 172 16, /* SONYPI_EVENT_FNKEY_F12 */
173 { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE }, 173 17, /* SONYPI_EVENT_FNKEY_1 */
174 { SONYPI_EVENT_PKEY_P1, KEY_PROG1 }, 174 18, /* SONYPI_EVENT_FNKEY_2 */
175 { SONYPI_EVENT_PKEY_P2, KEY_PROG2 }, 175 19, /* SONYPI_EVENT_FNKEY_D */
176 { SONYPI_EVENT_PKEY_P3, KEY_PROG3 }, 176 20, /* SONYPI_EVENT_FNKEY_E */
177 { SONYPI_EVENT_BACK_PRESSED, KEY_BACK }, 177 21, /* SONYPI_EVENT_FNKEY_F */
178 { SONYPI_EVENT_HELP_PRESSED, KEY_HELP }, 178 22, /* SONYPI_EVENT_FNKEY_S */
179 { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM }, 179 23, /* SONYPI_EVENT_FNKEY_B */
180 { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB }, 180 24, /* SONYPI_EVENT_BLUETOOTH_PRESSED */
181 { 0, 0 }, 181 25, /* SONYPI_EVENT_PKEY_P1 */
182 26, /* SONYPI_EVENT_PKEY_P2 */
183 27, /* SONYPI_EVENT_PKEY_P3 */
184 28, /* SONYPI_EVENT_BACK_PRESSED */
185 -1, /* SONYPI_EVENT_LID_CLOSED */
186 -1, /* SONYPI_EVENT_LID_OPENED */
187 29, /* SONYPI_EVENT_BLUETOOTH_ON */
188 30, /* SONYPI_EVENT_BLUETOOTH_OFF */
189 31, /* SONYPI_EVENT_HELP_PRESSED */
190 32, /* SONYPI_EVENT_FNKEY_ONLY */
191 33, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */
192 34, /* SONYPI_EVENT_JOGDIAL_FAST_UP */
193 35, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
194 36, /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
195 37, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
196 38, /* SONYPI_EVENT_JOGDIAL_VFAST_UP */
197 39, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
198 40, /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
199 41, /* SONYPI_EVENT_ZOOM_PRESSED */
200 42, /* SONYPI_EVENT_THUMBPHRASE_PRESSED */
201 43, /* SONYPI_EVENT_MEYE_FACE */
202 44, /* SONYPI_EVENT_MEYE_OPPOSITE */
203 45, /* SONYPI_EVENT_MEMORYSTICK_INSERT */
204 46, /* SONYPI_EVENT_MEMORYSTICK_EJECT */
205 -1, /* SONYPI_EVENT_ANYBUTTON_RELEASED */
206 -1, /* SONYPI_EVENT_BATTERY_INSERT */
207 -1, /* SONYPI_EVENT_BATTERY_REMOVE */
208 -1, /* SONYPI_EVENT_FNKEY_RELEASED */
209 47, /* SONYPI_EVENT_WIRELESS_ON */
210 48, /* SONYPI_EVENT_WIRELESS_OFF */
211};
212
213static int sony_laptop_input_keycode_map[] = {
214 KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */
215 KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */
216 KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */
217 KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */
218 KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */
219 KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */
220 KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */
221 KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */
222 KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */
223 KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */
224 KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */
225 KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */
226 KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */
227 KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */
228 KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */
229 KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */
230 KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */
231 KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */
232 KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */
233 KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */
234 KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */
235 KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */
236 KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */
237 KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */
238 KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */
239 KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */
240 KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */
241 KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */
242 KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */
243 KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */
244 KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */
245 KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */
246 KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */
247 KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */
248 KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */
249 KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */
250 KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */
251 KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */
252 KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */
253 KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */
254 KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */
255 KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */
256 BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */
257 KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */
258 KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */
259 KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */
260 KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */
261 KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */
262 KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */
182}; 263};
183 264
184/* release buttons after a short delay if pressed */ 265/* release buttons after a short delay if pressed */
@@ -202,7 +283,6 @@ static void sony_laptop_report_input_event(u8 event)
202 struct input_dev *jog_dev = sony_laptop_input.jog_dev; 283 struct input_dev *jog_dev = sony_laptop_input.jog_dev;
203 struct input_dev *key_dev = sony_laptop_input.key_dev; 284 struct input_dev *key_dev = sony_laptop_input.key_dev;
204 struct sony_laptop_keypress kp = { NULL }; 285 struct sony_laptop_keypress kp = { NULL };
205 int i;
206 286
207 if (event == SONYPI_EVENT_FNKEY_RELEASED) { 287 if (event == SONYPI_EVENT_FNKEY_RELEASED) {
208 /* Nothing, not all VAIOs generate this event */ 288 /* Nothing, not all VAIOs generate this event */
@@ -231,17 +311,22 @@ static void sony_laptop_report_input_event(u8 event)
231 break; 311 break;
232 312
233 default: 313 default:
234 for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) 314 if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) {
235 if (event == sony_laptop_inputkeys[i].sonypiev) { 315 dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
316 break;
317 }
318 if (sony_laptop_input_index[event] != -1) {
319 kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]];
320 if (kp.key != KEY_UNKNOWN)
236 kp.dev = key_dev; 321 kp.dev = key_dev;
237 kp.key = sony_laptop_inputkeys[i].inputev; 322 }
238 break;
239 }
240 break; 323 break;
241 } 324 }
242 325
243 if (kp.dev) { 326 if (kp.dev) {
244 input_report_key(kp.dev, kp.key, 1); 327 input_report_key(kp.dev, kp.key, 1);
328 /* we emit the scancode so we can always remap the key */
329 input_event(kp.dev, EV_MSC, MSC_SCAN, event);
245 input_sync(kp.dev); 330 input_sync(kp.dev);
246 kfifo_put(sony_laptop_input.fifo, 331 kfifo_put(sony_laptop_input.fifo,
247 (unsigned char *)&kp, sizeof(kp)); 332 (unsigned char *)&kp, sizeof(kp));
@@ -296,11 +381,18 @@ static int sony_laptop_setup_input(void)
296 key_dev->id.vendor = PCI_VENDOR_ID_SONY; 381 key_dev->id.vendor = PCI_VENDOR_ID_SONY;
297 382
298 /* Initialize the Input Drivers: special keys */ 383 /* Initialize the Input Drivers: special keys */
299 key_dev->evbit[0] = BIT(EV_KEY); 384 set_bit(EV_KEY, key_dev->evbit);
300 for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) 385 set_bit(EV_MSC, key_dev->evbit);
301 if (sony_laptop_inputkeys[i].inputev) 386 set_bit(MSC_SCAN, key_dev->mscbit);
302 set_bit(sony_laptop_inputkeys[i].inputev, 387 key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]);
303 key_dev->keybit); 388 key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map);
389 key_dev->keycode = &sony_laptop_input_keycode_map;
390 for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) {
391 if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) {
392 set_bit(sony_laptop_input_keycode_map[i],
393 key_dev->keybit);
394 }
395 }
304 396
305 error = input_register_device(key_dev); 397 error = input_register_device(key_dev);
306 if (error) 398 if (error)
@@ -487,6 +579,14 @@ SNC_HANDLE_NAMES(audiopower_set, "AZPW");
487SNC_HANDLE_NAMES(lanpower_get, "GLNP"); 579SNC_HANDLE_NAMES(lanpower_get, "GLNP");
488SNC_HANDLE_NAMES(lanpower_set, "LNPW"); 580SNC_HANDLE_NAMES(lanpower_set, "LNPW");
489 581
582SNC_HANDLE_NAMES(lidstate_get, "GLID");
583
584SNC_HANDLE_NAMES(indicatorlamp_get, "GILS");
585SNC_HANDLE_NAMES(indicatorlamp_set, "SILS");
586
587SNC_HANDLE_NAMES(gainbass_get, "GMGB");
588SNC_HANDLE_NAMES(gainbass_set, "CMGB");
589
490SNC_HANDLE_NAMES(PID_get, "GPID"); 590SNC_HANDLE_NAMES(PID_get, "GPID");
491 591
492SNC_HANDLE_NAMES(CTR_get, "GCTR"); 592SNC_HANDLE_NAMES(CTR_get, "GCTR");
@@ -507,6 +607,12 @@ static struct sony_nc_value sony_nc_values[] = {
507 boolean_validate, 0), 607 boolean_validate, 0),
508 SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, 608 SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set,
509 boolean_validate, 1), 609 boolean_validate, 1),
610 SNC_HANDLE(lidstate, snc_lidstate_get, NULL,
611 boolean_validate, 0),
612 SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set,
613 boolean_validate, 0),
614 SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set,
615 boolean_validate, 0),
510 /* unknown methods */ 616 /* unknown methods */
511 SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), 617 SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1),
512 SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), 618 SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
@@ -689,13 +795,116 @@ static struct backlight_ops sony_backlight_ops = {
689}; 795};
690 796
691/* 797/*
798 * New SNC-only Vaios event mapping to driver known keys
799 */
800struct sony_nc_event {
801 u8 data;
802 u8 event;
803};
804
805static struct sony_nc_event *sony_nc_events;
806
807/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
808 * for Fn keys
809 */
810static int sony_nc_C_enable(struct dmi_system_id *id)
811{
812 int result = 0;
813
814 printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
815
816 sony_nc_events = id->driver_data;
817
818 if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
819 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
820 || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
821 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
822 || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
823 || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
824 printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
825 "functionalities may be missing\n");
826 return 1;
827 }
828 return 0;
829}
830
831static struct sony_nc_event sony_C_events[] = {
832 { 0x81, SONYPI_EVENT_FNKEY_F1 },
833 { 0x01, SONYPI_EVENT_FNKEY_RELEASED },
834 { 0x85, SONYPI_EVENT_FNKEY_F5 },
835 { 0x05, SONYPI_EVENT_FNKEY_RELEASED },
836 { 0x86, SONYPI_EVENT_FNKEY_F6 },
837 { 0x06, SONYPI_EVENT_FNKEY_RELEASED },
838 { 0x87, SONYPI_EVENT_FNKEY_F7 },
839 { 0x07, SONYPI_EVENT_FNKEY_RELEASED },
840 { 0x8A, SONYPI_EVENT_FNKEY_F10 },
841 { 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
842 { 0x8C, SONYPI_EVENT_FNKEY_F12 },
843 { 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
844 { 0, 0 },
845};
846
847/* SNC-only model map */
848struct dmi_system_id sony_nc_ids[] = {
849 {
850 .ident = "Sony Vaio FE Series",
851 .callback = sony_nc_C_enable,
852 .driver_data = sony_C_events,
853 .matches = {
854 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
855 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
856 },
857 },
858 {
859 .ident = "Sony Vaio C Series",
860 .callback = sony_nc_C_enable,
861 .driver_data = sony_C_events,
862 .matches = {
863 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
864 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
865 },
866 },
867 { }
868};
869
870/*
692 * ACPI callbacks 871 * ACPI callbacks
693 */ 872 */
694static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) 873static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
695{ 874{
696 dprintk("sony_acpi_notify, event: %d\n", event); 875 struct sony_nc_event *evmap;
697 sony_laptop_report_input_event(event); 876 u32 ev = event;
698 acpi_bus_generate_event(sony_nc_acpi_device, 1, event); 877 int result;
878
879 if (ev == 0x92) {
880 /* read the key pressed from EC.GECR
881 * A call to SN07 with 0x0202 will do it as well respecting
882 * the current protocol on different OSes
883 *
884 * Note: the path for GECR may be
885 * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
886 * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
887 *
888 * TODO: we may want to do the same for the older GHKE -need
889 * dmi list- so this snippet may become one more callback.
890 */
891 if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
892 dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
893 else
894 ev = result & 0xFF;
895 }
896
897 if (sony_nc_events)
898 for (evmap = sony_nc_events; evmap->event; evmap++) {
899 if (evmap->data == ev) {
900 ev = evmap->event;
901 break;
902 }
903 }
904
905 dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
906 sony_laptop_report_input_event(ev);
907 acpi_bus_generate_event(sony_nc_acpi_device, 1, ev);
699} 908}
700 909
701static acpi_status sony_walk_callback(acpi_handle handle, u32 level, 910static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
@@ -732,6 +941,10 @@ static int sony_nc_resume(struct acpi_device *device)
732 break; 941 break;
733 } 942 }
734 } 943 }
944
945 /* re-initialize models with specific requirements */
946 dmi_check_system(sony_nc_ids);
947
735 return 0; 948 return 0;
736} 949}
737 950
@@ -750,6 +963,15 @@ static int sony_nc_add(struct acpi_device *device)
750 963
751 sony_nc_acpi_handle = device->handle; 964 sony_nc_acpi_handle = device->handle;
752 965
966 /* read device status */
967 result = acpi_bus_get_status(device);
968 /* bail IFF the above call was successful and the device is not present */
969 if (!result && !device->status.present) {
970 dprintk("Device not present\n");
971 result = -ENODEV;
972 goto outwalk;
973 }
974
753 if (debug) { 975 if (debug) {
754 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, 976 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
755 1, sony_walk_callback, NULL, NULL); 977 1, sony_walk_callback, NULL, NULL);
@@ -760,6 +982,15 @@ static int sony_nc_add(struct acpi_device *device)
760 } 982 }
761 } 983 }
762 984
985 /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1
986 * should be respected as we already checked for the device presence above */
987 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) {
988 dprintk("Invoking _INI\n");
989 if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI,
990 NULL, NULL)))
991 dprintk("_INI Method failed\n");
992 }
993
763 /* setup input devices and helper fifo */ 994 /* setup input devices and helper fifo */
764 result = sony_laptop_setup_input(); 995 result = sony_laptop_setup_input();
765 if (result) { 996 if (result) {
@@ -772,7 +1003,7 @@ static int sony_nc_add(struct acpi_device *device)
772 ACPI_DEVICE_NOTIFY, 1003 ACPI_DEVICE_NOTIFY,
773 sony_acpi_notify, NULL); 1004 sony_acpi_notify, NULL);
774 if (ACPI_FAILURE(status)) { 1005 if (ACPI_FAILURE(status)) {
775 printk(KERN_WARNING DRV_PFX "unable to install notify handler\n"); 1006 printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
776 result = -ENODEV; 1007 result = -ENODEV;
777 goto outinput; 1008 goto outinput;
778 } 1009 }
@@ -795,6 +1026,9 @@ static int sony_nc_add(struct acpi_device *device)
795 1026
796 } 1027 }
797 1028
1029 /* initialize models with specific requirements */
1030 dmi_check_system(sony_nc_ids);
1031
798 result = sony_pf_add(); 1032 result = sony_pf_add();
799 if (result) 1033 if (result)
800 goto outbacklight; 1034 goto outbacklight;
@@ -908,7 +1142,9 @@ static struct acpi_driver sony_nc_driver = {
908#define SONYPI_DEVICE_TYPE2 0x00000002 1142#define SONYPI_DEVICE_TYPE2 0x00000002
909#define SONYPI_DEVICE_TYPE3 0x00000004 1143#define SONYPI_DEVICE_TYPE3 0x00000004
910 1144
911#define SONY_PIC_EV_MASK 0xff 1145#define SONYPI_TYPE1_OFFSET 0x04
1146#define SONYPI_TYPE2_OFFSET 0x12
1147#define SONYPI_TYPE3_OFFSET 0x12
912 1148
913struct sony_pic_ioport { 1149struct sony_pic_ioport {
914 struct acpi_resource_io io; 1150 struct acpi_resource_io io;
@@ -922,6 +1158,7 @@ struct sony_pic_irq {
922 1158
923struct sony_pic_dev { 1159struct sony_pic_dev {
924 int model; 1160 int model;
1161 u16 evport_offset;
925 u8 camera_power; 1162 u8 camera_power;
926 u8 bluetooth_power; 1163 u8 bluetooth_power;
927 u8 wwan_power; 1164 u8 wwan_power;
@@ -1999,20 +2236,17 @@ end:
1999static irqreturn_t sony_pic_irq(int irq, void *dev_id) 2236static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2000{ 2237{
2001 int i, j; 2238 int i, j;
2002 u32 port_val = 0;
2003 u8 ev = 0; 2239 u8 ev = 0;
2004 u8 data_mask = 0; 2240 u8 data_mask = 0;
2005 u8 device_event = 0; 2241 u8 device_event = 0;
2006 2242
2007 struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; 2243 struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
2008 2244
2009 acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val, 2245 ev = inb_p(dev->cur_ioport->io.minimum);
2010 dev->cur_ioport->io.address_length); 2246 data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
2011 ev = port_val & SONY_PIC_EV_MASK;
2012 data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8));
2013 2247
2014 dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n", 2248 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2015 port_val, ev, data_mask, dev->cur_ioport->io.minimum); 2249 ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
2016 2250
2017 if (ev == 0x00 || ev == 0xff) 2251 if (ev == 0x00 || ev == 0xff)
2018 return IRQ_HANDLED; 2252 return IRQ_HANDLED;
@@ -2103,6 +2337,20 @@ static int sony_pic_add(struct acpi_device *device)
2103 spic_dev.model = sony_pic_detect_device_type(); 2337 spic_dev.model = sony_pic_detect_device_type();
2104 mutex_init(&spic_dev.lock); 2338 mutex_init(&spic_dev.lock);
2105 2339
2340 /* model specific characteristics */
2341 switch(spic_dev.model) {
2342 case SONYPI_DEVICE_TYPE1:
2343 spic_dev.evport_offset = SONYPI_TYPE1_OFFSET;
2344 break;
2345 case SONYPI_DEVICE_TYPE3:
2346 spic_dev.evport_offset = SONYPI_TYPE3_OFFSET;
2347 break;
2348 case SONYPI_DEVICE_TYPE2:
2349 default:
2350 spic_dev.evport_offset = SONYPI_TYPE2_OFFSET;
2351 break;
2352 }
2353
2106 /* read _PRS resources */ 2354 /* read _PRS resources */
2107 result = sony_pic_possible_resources(device); 2355 result = sony_pic_possible_resources(device);
2108 if (result) { 2356 if (result) {
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 95c0b96e83f2..f15a58f7403f 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -21,8 +21,8 @@
21 * 02110-1301, USA. 21 * 02110-1301, USA.
22 */ 22 */
23 23
24#define IBM_VERSION "0.14" 24#define IBM_VERSION "0.15"
25#define TPACPI_SYSFS_VERSION 0x000100 25#define TPACPI_SYSFS_VERSION 0x010000
26 26
27/* 27/*
28 * Changelog: 28 * Changelog:
@@ -92,6 +92,29 @@ MODULE_LICENSE("GPL");
92/* Please remove this in year 2009 */ 92/* Please remove this in year 2009 */
93MODULE_ALIAS("ibm_acpi"); 93MODULE_ALIAS("ibm_acpi");
94 94
95/*
96 * DMI matching for module autoloading
97 *
98 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
99 * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads
100 *
101 * Only models listed in thinkwiki will be supported, so add yours
102 * if it is not there yet.
103 */
104#define IBM_BIOS_MODULE_ALIAS(__type) \
105 MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW")
106
107/* Non-ancient thinkpads */
108MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*");
109MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*");
110
111/* Ancient thinkpad BIOSes have to be identified by
112 * BIOS type or model number, and there are far less
113 * BIOS types than model numbers... */
114IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]");
115IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]");
116IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
117
95#define __unused __attribute__ ((unused)) 118#define __unused __attribute__ ((unused))
96 119
97/**************************************************************************** 120/****************************************************************************
@@ -106,7 +129,7 @@ MODULE_ALIAS("ibm_acpi");
106 * ACPI basic handles 129 * ACPI basic handles
107 */ 130 */
108 131
109static acpi_handle root_handle = NULL; 132static acpi_handle root_handle;
110 133
111#define IBM_HANDLE(object, parent, paths...) \ 134#define IBM_HANDLE(object, parent, paths...) \
112 static acpi_handle object##_handle; \ 135 static acpi_handle object##_handle; \
@@ -487,19 +510,36 @@ static char *next_cmd(char **cmds)
487/**************************************************************************** 510/****************************************************************************
488 **************************************************************************** 511 ****************************************************************************
489 * 512 *
490 * Device model: hwmon and platform 513 * Device model: input, hwmon and platform
491 * 514 *
492 **************************************************************************** 515 ****************************************************************************
493 ****************************************************************************/ 516 ****************************************************************************/
494 517
495static struct platform_device *tpacpi_pdev = NULL; 518static struct platform_device *tpacpi_pdev;
496static struct class_device *tpacpi_hwmon = NULL; 519static struct class_device *tpacpi_hwmon;
520static struct input_dev *tpacpi_inputdev;
521
522
523static int tpacpi_resume_handler(struct platform_device *pdev)
524{
525 struct ibm_struct *ibm, *itmp;
526
527 list_for_each_entry_safe(ibm, itmp,
528 &tpacpi_all_drivers,
529 all_drivers) {
530 if (ibm->resume)
531 (ibm->resume)();
532 }
533
534 return 0;
535}
497 536
498static struct platform_driver tpacpi_pdriver = { 537static struct platform_driver tpacpi_pdriver = {
499 .driver = { 538 .driver = {
500 .name = IBM_DRVR_NAME, 539 .name = IBM_DRVR_NAME,
501 .owner = THIS_MODULE, 540 .owner = THIS_MODULE,
502 }, 541 },
542 .resume = tpacpi_resume_handler,
503}; 543};
504 544
505 545
@@ -677,9 +717,19 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm)
677 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); 717 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
678 printk(IBM_INFO "%s\n", IBM_URL); 718 printk(IBM_INFO "%s\n", IBM_URL);
679 719
680 if (ibm_thinkpad_ec_found) 720 printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n",
681 printk(IBM_INFO "ThinkPad EC firmware %s\n", 721 (thinkpad_id.bios_version_str) ?
682 ibm_thinkpad_ec_found); 722 thinkpad_id.bios_version_str : "unknown",
723 (thinkpad_id.ec_version_str) ?
724 thinkpad_id.ec_version_str : "unknown");
725
726 if (thinkpad_id.vendor && thinkpad_id.model_str)
727 printk(IBM_INFO "%s %s\n",
728 (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
729 "IBM" : ((thinkpad_id.vendor ==
730 PCI_VENDOR_ID_LENOVO) ?
731 "Lenovo" : "Unknown vendor"),
732 thinkpad_id.model_str);
683 733
684 return 0; 734 return 0;
685} 735}
@@ -704,16 +754,28 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
704 */ 754 */
705 755
706static int hotkey_orig_status; 756static int hotkey_orig_status;
707static int hotkey_orig_mask; 757static u32 hotkey_orig_mask;
758static u32 hotkey_all_mask;
759static u32 hotkey_reserved_mask;
760
761static u16 *hotkey_keycode_map;
708 762
709static struct attribute_set *hotkey_dev_attributes = NULL; 763static struct attribute_set *hotkey_dev_attributes;
764
765static int hotkey_get_wlsw(int *status)
766{
767 if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
768 return -EIO;
769 return 0;
770}
710 771
711/* sysfs hotkey enable ------------------------------------------------- */ 772/* sysfs hotkey enable ------------------------------------------------- */
712static ssize_t hotkey_enable_show(struct device *dev, 773static ssize_t hotkey_enable_show(struct device *dev,
713 struct device_attribute *attr, 774 struct device_attribute *attr,
714 char *buf) 775 char *buf)
715{ 776{
716 int res, status, mask; 777 int res, status;
778 u32 mask;
717 779
718 res = hotkey_get(&status, &mask); 780 res = hotkey_get(&status, &mask);
719 if (res) 781 if (res)
@@ -727,7 +789,8 @@ static ssize_t hotkey_enable_store(struct device *dev,
727 const char *buf, size_t count) 789 const char *buf, size_t count)
728{ 790{
729 unsigned long t; 791 unsigned long t;
730 int res, status, mask; 792 int res, status;
793 u32 mask;
731 794
732 if (parse_strtoul(buf, 1, &t)) 795 if (parse_strtoul(buf, 1, &t))
733 return -EINVAL; 796 return -EINVAL;
@@ -748,13 +811,14 @@ static ssize_t hotkey_mask_show(struct device *dev,
748 struct device_attribute *attr, 811 struct device_attribute *attr,
749 char *buf) 812 char *buf)
750{ 813{
751 int res, status, mask; 814 int res, status;
815 u32 mask;
752 816
753 res = hotkey_get(&status, &mask); 817 res = hotkey_get(&status, &mask);
754 if (res) 818 if (res)
755 return res; 819 return res;
756 820
757 return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask); 821 return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask);
758} 822}
759 823
760static ssize_t hotkey_mask_store(struct device *dev, 824static ssize_t hotkey_mask_store(struct device *dev,
@@ -762,9 +826,10 @@ static ssize_t hotkey_mask_store(struct device *dev,
762 const char *buf, size_t count) 826 const char *buf, size_t count)
763{ 827{
764 unsigned long t; 828 unsigned long t;
765 int res, status, mask; 829 int res, status;
830 u32 mask;
766 831
767 if (parse_strtoul(buf, 0xffff, &t)) 832 if (parse_strtoul(buf, 0xffffffffUL, &t))
768 return -EINVAL; 833 return -EINVAL;
769 834
770 res = hotkey_get(&status, &mask); 835 res = hotkey_get(&status, &mask);
@@ -794,26 +859,123 @@ static ssize_t hotkey_bios_mask_show(struct device *dev,
794 struct device_attribute *attr, 859 struct device_attribute *attr,
795 char *buf) 860 char *buf)
796{ 861{
797 return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask); 862 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask);
798} 863}
799 864
800static struct device_attribute dev_attr_hotkey_bios_mask = 865static struct device_attribute dev_attr_hotkey_bios_mask =
801 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); 866 __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL);
802 867
868/* sysfs hotkey all_mask ----------------------------------------------- */
869static ssize_t hotkey_all_mask_show(struct device *dev,
870 struct device_attribute *attr,
871 char *buf)
872{
873 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_all_mask);
874}
875
876static struct device_attribute dev_attr_hotkey_all_mask =
877 __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL);
878
879/* sysfs hotkey recommended_mask --------------------------------------- */
880static ssize_t hotkey_recommended_mask_show(struct device *dev,
881 struct device_attribute *attr,
882 char *buf)
883{
884 return snprintf(buf, PAGE_SIZE, "0x%08x\n",
885 hotkey_all_mask & ~hotkey_reserved_mask);
886}
887
888static struct device_attribute dev_attr_hotkey_recommended_mask =
889 __ATTR(hotkey_recommended_mask, S_IRUGO,
890 hotkey_recommended_mask_show, NULL);
891
892/* sysfs hotkey radio_sw ----------------------------------------------- */
893static ssize_t hotkey_radio_sw_show(struct device *dev,
894 struct device_attribute *attr,
895 char *buf)
896{
897 int res, s;
898 res = hotkey_get_wlsw(&s);
899 if (res < 0)
900 return res;
901
902 return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
903}
904
905static struct device_attribute dev_attr_hotkey_radio_sw =
906 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
907
803/* --------------------------------------------------------------------- */ 908/* --------------------------------------------------------------------- */
804 909
805static struct attribute *hotkey_mask_attributes[] = { 910static struct attribute *hotkey_mask_attributes[] = {
806 &dev_attr_hotkey_mask.attr, 911 &dev_attr_hotkey_mask.attr,
807 &dev_attr_hotkey_bios_enabled.attr, 912 &dev_attr_hotkey_bios_enabled.attr,
808 &dev_attr_hotkey_bios_mask.attr, 913 &dev_attr_hotkey_bios_mask.attr,
914 &dev_attr_hotkey_all_mask.attr,
915 &dev_attr_hotkey_recommended_mask.attr,
809}; 916};
810 917
811static int __init hotkey_init(struct ibm_init_struct *iibm) 918static int __init hotkey_init(struct ibm_init_struct *iibm)
812{ 919{
813 int res; 920
921 static u16 ibm_keycode_map[] __initdata = {
922 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
923 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP,
924 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
925 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
926 /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
927 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
928 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
929 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
930 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
931 /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
932 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
933 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
934 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
935 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
936 KEY_RESERVED, /* 0x14: VOLUME UP */
937 KEY_RESERVED, /* 0x15: VOLUME DOWN */
938 KEY_RESERVED, /* 0x16: MUTE */
939 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
940 /* (assignments unknown, please report if found) */
941 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
942 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
943 };
944 static u16 lenovo_keycode_map[] __initdata = {
945 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
946 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
947 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
948 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
949 /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
950 KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
951 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
952 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
953 KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */
954 /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
955 KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */
956 KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
957 KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
958 KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
959 KEY_RESERVED, /* 0x14: VOLUME UP */
960 KEY_RESERVED, /* 0x15: VOLUME DOWN */
961 KEY_RESERVED, /* 0x16: MUTE */
962 KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
963 /* (assignments unknown, please report if found) */
964 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
965 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
966 };
967
968#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map)
969#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map)
970#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0])
971
972 int res, i;
973 int status;
814 974
815 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); 975 vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
816 976
977 BUG_ON(!tpacpi_inputdev);
978
817 IBM_ACPIHANDLE_INIT(hkey); 979 IBM_ACPIHANDLE_INIT(hkey);
818 mutex_init(&hotkey_mutex); 980 mutex_init(&hotkey_mutex);
819 981
@@ -824,7 +986,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
824 str_supported(tp_features.hotkey)); 986 str_supported(tp_features.hotkey));
825 987
826 if (tp_features.hotkey) { 988 if (tp_features.hotkey) {
827 hotkey_dev_attributes = create_attr_set(4, NULL); 989 hotkey_dev_attributes = create_attr_set(7, NULL);
828 if (!hotkey_dev_attributes) 990 if (!hotkey_dev_attributes)
829 return -ENOMEM; 991 return -ENOMEM;
830 res = add_to_attr_set(hotkey_dev_attributes, 992 res = add_to_attr_set(hotkey_dev_attributes,
@@ -840,19 +1002,92 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
840 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", 1002 vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
841 str_supported(tp_features.hotkey_mask)); 1003 str_supported(tp_features.hotkey_mask));
842 1004
1005 if (tp_features.hotkey_mask) {
1006 /* MHKA available in A31, R40, R40e, T4x, X31, and later */
1007 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
1008 "MHKA", "qd"))
1009 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
1010 }
1011
843 res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); 1012 res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
844 if (!res && tp_features.hotkey_mask) { 1013 if (!res && tp_features.hotkey_mask) {
845 res = add_many_to_attr_set(hotkey_dev_attributes, 1014 res = add_many_to_attr_set(hotkey_dev_attributes,
846 hotkey_mask_attributes, 1015 hotkey_mask_attributes,
847 ARRAY_SIZE(hotkey_mask_attributes)); 1016 ARRAY_SIZE(hotkey_mask_attributes));
848 } 1017 }
1018
1019 /* Not all thinkpads have a hardware radio switch */
1020 if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
1021 tp_features.hotkey_wlsw = 1;
1022 printk(IBM_INFO
1023 "radio switch found; radios are %s\n",
1024 enabled(status, 0));
1025 res = add_to_attr_set(hotkey_dev_attributes,
1026 &dev_attr_hotkey_radio_sw.attr);
1027 }
1028
849 if (!res) 1029 if (!res)
850 res = register_attr_set_with_sysfs( 1030 res = register_attr_set_with_sysfs(
851 hotkey_dev_attributes, 1031 hotkey_dev_attributes,
852 &tpacpi_pdev->dev.kobj); 1032 &tpacpi_pdev->dev.kobj);
1033 if (res)
1034 return res;
1035
1036 /* Set up key map */
1037
1038 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
1039 GFP_KERNEL);
1040 if (!hotkey_keycode_map) {
1041 printk(IBM_ERR "failed to allocate memory for key map\n");
1042 return -ENOMEM;
1043 }
1044
1045 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
1046 dbg_printk(TPACPI_DBG_INIT,
1047 "using Lenovo default hot key map\n");
1048 memcpy(hotkey_keycode_map, &lenovo_keycode_map,
1049 TPACPI_HOTKEY_MAP_SIZE);
1050 } else {
1051 dbg_printk(TPACPI_DBG_INIT,
1052 "using IBM default hot key map\n");
1053 memcpy(hotkey_keycode_map, &ibm_keycode_map,
1054 TPACPI_HOTKEY_MAP_SIZE);
1055 }
853 1056
1057#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
1058 for (i = 0; i < 12; i++)
1059 hotkey_keycode_map[i] = KEY_UNKNOWN;
1060#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
1061
1062 set_bit(EV_KEY, tpacpi_inputdev->evbit);
1063 set_bit(EV_MSC, tpacpi_inputdev->evbit);
1064 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
1065 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
1066 tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
1067 tpacpi_inputdev->keycode = hotkey_keycode_map;
1068 for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
1069 if (hotkey_keycode_map[i] != KEY_RESERVED) {
1070 set_bit(hotkey_keycode_map[i],
1071 tpacpi_inputdev->keybit);
1072 } else {
1073 if (i < sizeof(hotkey_reserved_mask)*8)
1074 hotkey_reserved_mask |= 1 << i;
1075 }
1076 }
1077
1078 if (tp_features.hotkey_wlsw) {
1079 set_bit(EV_SW, tpacpi_inputdev->evbit);
1080 set_bit(SW_RADIO, tpacpi_inputdev->swbit);
1081 }
1082
1083#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
1084 dbg_printk(TPACPI_DBG_INIT,
1085 "enabling hot key handling\n");
1086 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
1087 | hotkey_orig_mask);
854 if (res) 1088 if (res)
855 return res; 1089 return res;
1090#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
856 } 1091 }
857 1092
858 return (tp_features.hotkey)? 0 : 1; 1093 return (tp_features.hotkey)? 0 : 1;
@@ -875,22 +1110,101 @@ static void hotkey_exit(void)
875 } 1110 }
876} 1111}
877 1112
1113static void tpacpi_input_send_key(unsigned int scancode,
1114 unsigned int keycode)
1115{
1116 if (keycode != KEY_RESERVED) {
1117 input_report_key(tpacpi_inputdev, keycode, 1);
1118 if (keycode == KEY_UNKNOWN)
1119 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
1120 scancode);
1121 input_sync(tpacpi_inputdev);
1122
1123 input_report_key(tpacpi_inputdev, keycode, 0);
1124 if (keycode == KEY_UNKNOWN)
1125 input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
1126 scancode);
1127 input_sync(tpacpi_inputdev);
1128 }
1129}
1130
1131static void tpacpi_input_send_radiosw(void)
1132{
1133 int wlsw;
1134
1135 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw))
1136 input_report_switch(tpacpi_inputdev,
1137 SW_RADIO, !!wlsw);
1138}
1139
878static void hotkey_notify(struct ibm_struct *ibm, u32 event) 1140static void hotkey_notify(struct ibm_struct *ibm, u32 event)
879{ 1141{
880 int hkey; 1142 u32 hkey;
1143 unsigned int keycode, scancode;
1144 int sendacpi = 1;
1145
1146 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
1147 if (tpacpi_inputdev->users > 0) {
1148 switch (hkey >> 12) {
1149 case 1:
1150 /* 0x1000-0x1FFF: key presses */
1151 scancode = hkey & 0xfff;
1152 if (scancode > 0 && scancode < 0x21) {
1153 scancode--;
1154 keycode = hotkey_keycode_map[scancode];
1155 tpacpi_input_send_key(scancode, keycode);
1156 sendacpi = (keycode == KEY_RESERVED
1157 || keycode == KEY_UNKNOWN);
1158 } else {
1159 printk(IBM_ERR
1160 "hotkey 0x%04x out of range for keyboard map\n",
1161 hkey);
1162 }
1163 break;
1164 case 5:
1165 /* 0x5000-0x5FFF: LID */
1166 /* we don't handle it through this path, just
1167 * eat up known LID events */
1168 if (hkey != 0x5001 && hkey != 0x5002) {
1169 printk(IBM_ERR
1170 "unknown LID-related hotkey event: 0x%04x\n",
1171 hkey);
1172 }
1173 break;
1174 case 7:
1175 /* 0x7000-0x7FFF: misc */
1176 if (tp_features.hotkey_wlsw && hkey == 0x7000) {
1177 tpacpi_input_send_radiosw();
1178 sendacpi = 0;
1179 break;
1180 }
1181 /* fallthrough to default */
1182 default:
1183 /* case 2: dock-related */
1184 /* 0x2305 - T43 waking up due to bay lever eject while aslept */
1185 /* case 3: ultra-bay related. maybe bay in dock? */
1186 /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
1187 printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);
1188 }
1189 }
881 1190
882 if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) 1191 if (sendacpi)
883 acpi_bus_generate_event(ibm->acpi->device, event, hkey); 1192 acpi_bus_generate_event(ibm->acpi->device, event, hkey);
884 else { 1193 } else {
885 printk(IBM_ERR "unknown hotkey event %d\n", event); 1194 printk(IBM_ERR "unknown hotkey notification event %d\n", event);
886 acpi_bus_generate_event(ibm->acpi->device, event, 0); 1195 acpi_bus_generate_event(ibm->acpi->device, event, 0);
887 } 1196 }
888} 1197}
889 1198
1199static void hotkey_resume(void)
1200{
1201 tpacpi_input_send_radiosw();
1202}
1203
890/* 1204/*
891 * Call with hotkey_mutex held 1205 * Call with hotkey_mutex held
892 */ 1206 */
893static int hotkey_get(int *status, int *mask) 1207static int hotkey_get(int *status, u32 *mask)
894{ 1208{
895 if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) 1209 if (!acpi_evalf(hkey_handle, status, "DHKC", "d"))
896 return -EIO; 1210 return -EIO;
@@ -905,7 +1219,7 @@ static int hotkey_get(int *status, int *mask)
905/* 1219/*
906 * Call with hotkey_mutex held 1220 * Call with hotkey_mutex held
907 */ 1221 */
908static int hotkey_set(int status, int mask) 1222static int hotkey_set(int status, u32 mask)
909{ 1223{
910 int i; 1224 int i;
911 1225
@@ -926,7 +1240,8 @@ static int hotkey_set(int status, int mask)
926/* procfs -------------------------------------------------------------- */ 1240/* procfs -------------------------------------------------------------- */
927static int hotkey_read(char *p) 1241static int hotkey_read(char *p)
928{ 1242{
929 int res, status, mask; 1243 int res, status;
1244 u32 mask;
930 int len = 0; 1245 int len = 0;
931 1246
932 if (!tp_features.hotkey) { 1247 if (!tp_features.hotkey) {
@@ -944,7 +1259,7 @@ static int hotkey_read(char *p)
944 1259
945 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 1260 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
946 if (tp_features.hotkey_mask) { 1261 if (tp_features.hotkey_mask) {
947 len += sprintf(p + len, "mask:\t\t0x%04x\n", mask); 1262 len += sprintf(p + len, "mask:\t\t0x%08x\n", mask);
948 len += sprintf(p + len, 1263 len += sprintf(p + len,
949 "commands:\tenable, disable, reset, <mask>\n"); 1264 "commands:\tenable, disable, reset, <mask>\n");
950 } else { 1265 } else {
@@ -957,7 +1272,8 @@ static int hotkey_read(char *p)
957 1272
958static int hotkey_write(char *buf) 1273static int hotkey_write(char *buf)
959{ 1274{
960 int res, status, mask; 1275 int res, status;
1276 u32 mask;
961 char *cmd; 1277 char *cmd;
962 int do_cmd = 0; 1278 int do_cmd = 0;
963 1279
@@ -1012,6 +1328,7 @@ static struct ibm_struct hotkey_driver_data = {
1012 .read = hotkey_read, 1328 .read = hotkey_read,
1013 .write = hotkey_write, 1329 .write = hotkey_write,
1014 .exit = hotkey_exit, 1330 .exit = hotkey_exit,
1331 .resume = hotkey_resume,
1015 .acpi = &ibm_hotkey_acpidriver, 1332 .acpi = &ibm_hotkey_acpidriver,
1016}; 1333};
1017 1334
@@ -1770,7 +2087,10 @@ static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = {
1770 .type = ACPI_SYSTEM_NOTIFY, 2087 .type = ACPI_SYSTEM_NOTIFY,
1771 }, 2088 },
1772 { 2089 {
1773 .hid = IBM_PCI_HID, 2090 /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING.
2091 * We just use it to get notifications of dock hotplug
2092 * in very old thinkpads */
2093 .hid = PCI_ROOT_HID_STRING,
1774 .notify = dock_notify, 2094 .notify = dock_notify,
1775 .handle = &pci_handle, 2095 .handle = &pci_handle,
1776 .type = ACPI_SYSTEM_NOTIFY, 2096 .type = ACPI_SYSTEM_NOTIFY,
@@ -1829,7 +2149,7 @@ static int __init dock_init2(struct ibm_init_struct *iibm)
1829static void dock_notify(struct ibm_struct *ibm, u32 event) 2149static void dock_notify(struct ibm_struct *ibm, u32 event)
1830{ 2150{
1831 int docked = dock_docked(); 2151 int docked = dock_docked();
1832 int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, IBM_PCI_HID); 2152 int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, PCI_ROOT_HID_STRING);
1833 2153
1834 if (event == 1 && !pci) /* 570 */ 2154 if (event == 1 && !pci) /* 570 */
1835 acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ 2155 acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */
@@ -2389,7 +2709,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
2389 2709
2390 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 2710 acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
2391 2711
2392 if (ibm_thinkpad_ec_found && experimental) { 2712 if (thinkpad_id.ec_model) {
2393 /* 2713 /*
2394 * Direct EC access mode: sensors at registers 2714 * Direct EC access mode: sensors at registers
2395 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for 2715 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
@@ -2533,6 +2853,8 @@ static int thermal_get_sensor(int idx, s32 *value)
2533 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); 2853 snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx);
2534 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 2854 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
2535 return -EIO; 2855 return -EIO;
2856 if (t > 127 || t < -127)
2857 t = TP_EC_THERMAL_TMP_NA;
2536 *value = t * 1000; 2858 *value = t * 1000;
2537 return 0; 2859 return 0;
2538 } 2860 }
@@ -2671,22 +2993,39 @@ static struct ibm_struct ecdump_driver_data = {
2671 * Backlight/brightness subdriver 2993 * Backlight/brightness subdriver
2672 */ 2994 */
2673 2995
2674static struct backlight_device *ibm_backlight_device = NULL; 2996static struct backlight_device *ibm_backlight_device;
2675 2997
2676static struct backlight_ops ibm_backlight_data = { 2998static struct backlight_ops ibm_backlight_data = {
2677 .get_brightness = brightness_get, 2999 .get_brightness = brightness_get,
2678 .update_status = brightness_update_status, 3000 .update_status = brightness_update_status,
2679}; 3001};
2680 3002
3003static struct mutex brightness_mutex;
3004
2681static int __init brightness_init(struct ibm_init_struct *iibm) 3005static int __init brightness_init(struct ibm_init_struct *iibm)
2682{ 3006{
2683 int b; 3007 int b;
2684 3008
2685 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); 3009 vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
2686 3010
3011 mutex_init(&brightness_mutex);
3012
3013 if (!brightness_mode) {
3014 if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
3015 brightness_mode = 2;
3016 else
3017 brightness_mode = 3;
3018
3019 dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
3020 brightness_mode);
3021 }
3022
3023 if (brightness_mode > 3)
3024 return -EINVAL;
3025
2687 b = brightness_get(NULL); 3026 b = brightness_get(NULL);
2688 if (b < 0) 3027 if (b < 0)
2689 return b; 3028 return 1;
2690 3029
2691 ibm_backlight_device = backlight_device_register( 3030 ibm_backlight_device = backlight_device_register(
2692 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 3031 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
@@ -2722,34 +3061,79 @@ static int brightness_update_status(struct backlight_device *bd)
2722 bd->props.brightness : 0); 3061 bd->props.brightness : 0);
2723} 3062}
2724 3063
3064/*
3065 * ThinkPads can read brightness from two places: EC 0x31, or
3066 * CMOS NVRAM byte 0x5E, bits 0-3.
3067 */
2725static int brightness_get(struct backlight_device *bd) 3068static int brightness_get(struct backlight_device *bd)
2726{ 3069{
2727 u8 level; 3070 u8 lec = 0, lcmos = 0, level = 0;
2728 if (!acpi_ec_read(brightness_offset, &level))
2729 return -EIO;
2730 3071
2731 level &= 0x7; 3072 if (brightness_mode & 1) {
3073 if (!acpi_ec_read(brightness_offset, &lec))
3074 return -EIO;
3075 lec &= 7;
3076 level = lec;
3077 };
3078 if (brightness_mode & 2) {
3079 lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
3080 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
3081 >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
3082 level = lcmos;
3083 }
3084
3085 if (brightness_mode == 3 && lec != lcmos) {
3086 printk(IBM_ERR
3087 "CMOS NVRAM (%u) and EC (%u) do not agree "
3088 "on display brightness level\n",
3089 (unsigned int) lcmos,
3090 (unsigned int) lec);
3091 return -EIO;
3092 }
2732 3093
2733 return level; 3094 return level;
2734} 3095}
2735 3096
2736static int brightness_set(int value) 3097static int brightness_set(int value)
2737{ 3098{
2738 int cmos_cmd, inc, i; 3099 int cmos_cmd, inc, i, res;
2739 int current_value = brightness_get(NULL); 3100 int current_value;
3101
3102 if (value > 7)
3103 return -EINVAL;
2740 3104
2741 value &= 7; 3105 res = mutex_lock_interruptible(&brightness_mutex);
3106 if (res < 0)
3107 return res;
3108
3109 current_value = brightness_get(NULL);
3110 if (current_value < 0) {
3111 res = current_value;
3112 goto errout;
3113 }
2742 3114
2743 cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN; 3115 cmos_cmd = value > current_value ?
3116 TP_CMOS_BRIGHTNESS_UP :
3117 TP_CMOS_BRIGHTNESS_DOWN;
2744 inc = value > current_value ? 1 : -1; 3118 inc = value > current_value ? 1 : -1;
3119
3120 res = 0;
2745 for (i = current_value; i != value; i += inc) { 3121 for (i = current_value; i != value; i += inc) {
2746 if (issue_thinkpad_cmos_command(cmos_cmd)) 3122 if ((brightness_mode & 2) &&
2747 return -EIO; 3123 issue_thinkpad_cmos_command(cmos_cmd)) {
2748 if (!acpi_ec_write(brightness_offset, i + inc)) 3124 res = -EIO;
2749 return -EIO; 3125 goto errout;
3126 }
3127 if ((brightness_mode & 1) &&
3128 !acpi_ec_write(brightness_offset, i + inc)) {
3129 res = -EIO;
3130 goto errout;;
3131 }
2750 } 3132 }
2751 3133
2752 return 0; 3134errout:
3135 mutex_unlock(&brightness_mutex);
3136 return res;
2753} 3137}
2754 3138
2755static int brightness_read(char *p) 3139static int brightness_read(char *p)
@@ -3273,20 +3657,19 @@ static int __init fan_init(struct ibm_init_struct *iibm)
3273 * Enable for TP-1Y (T43), TP-78 (R51e), 3657 * Enable for TP-1Y (T43), TP-78 (R51e),
3274 * TP-76 (R52), TP-70 (T43, R52), which are known 3658 * TP-76 (R52), TP-70 (T43, R52), which are known
3275 * to be buggy. */ 3659 * to be buggy. */
3276 if (fan_control_initial_status == 0x07 && 3660 if (fan_control_initial_status == 0x07) {
3277 ibm_thinkpad_ec_found && 3661 switch (thinkpad_id.ec_model) {
3278 ((ibm_thinkpad_ec_found[0] == '1' && 3662 case 0x5931: /* TP-1Y */
3279 ibm_thinkpad_ec_found[1] == 'Y') || 3663 case 0x3837: /* TP-78 */
3280 (ibm_thinkpad_ec_found[0] == '7' && 3664 case 0x3637: /* TP-76 */
3281 (ibm_thinkpad_ec_found[1] == '6' || 3665 case 0x3037: /* TP-70 */
3282 ibm_thinkpad_ec_found[1] == '8' || 3666 printk(IBM_NOTICE
3283 ibm_thinkpad_ec_found[1] == '0')) 3667 "fan_init: initial fan status is "
3284 )) { 3668 "unknown, assuming it is in auto "
3285 printk(IBM_NOTICE 3669 "mode\n");
3286 "fan_init: initial fan status is " 3670 tp_features.fan_ctrl_status_undef = 1;
3287 "unknown, assuming it is in auto " 3671 ;;
3288 "mode\n"); 3672 }
3289 tp_features.fan_ctrl_status_undef = 1;
3290 } 3673 }
3291 } else { 3674 } else {
3292 printk(IBM_ERR 3675 printk(IBM_ERR
@@ -3474,7 +3857,7 @@ static void fan_watchdog_fire(struct work_struct *ignored)
3474 3857
3475static void fan_watchdog_reset(void) 3858static void fan_watchdog_reset(void)
3476{ 3859{
3477 static int fan_watchdog_active = 0; 3860 static int fan_watchdog_active;
3478 3861
3479 if (fan_control_access_mode == TPACPI_FAN_WR_NONE) 3862 if (fan_control_access_mode == TPACPI_FAN_WR_NONE)
3480 return; 3863 return;
@@ -3877,7 +4260,7 @@ static struct ibm_struct fan_driver_data = {
3877 ****************************************************************************/ 4260 ****************************************************************************/
3878 4261
3879/* /proc support */ 4262/* /proc support */
3880static struct proc_dir_entry *proc_dir = NULL; 4263static struct proc_dir_entry *proc_dir;
3881 4264
3882/* Subdriver registry */ 4265/* Subdriver registry */
3883static LIST_HEAD(tpacpi_all_drivers); 4266static LIST_HEAD(tpacpi_all_drivers);
@@ -4020,13 +4403,30 @@ static void ibm_exit(struct ibm_struct *ibm)
4020 4403
4021/* Probing */ 4404/* Probing */
4022 4405
4023static char *ibm_thinkpad_ec_found = NULL; 4406static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp)
4024
4025static char* __init check_dmi_for_ec(void)
4026{ 4407{
4027 struct dmi_device *dev = NULL; 4408 struct dmi_device *dev = NULL;
4028 char ec_fw_string[18]; 4409 char ec_fw_string[18];
4029 4410
4411 if (!tp)
4412 return;
4413
4414 memset(tp, 0, sizeof(*tp));
4415
4416 if (dmi_name_in_vendors("IBM"))
4417 tp->vendor = PCI_VENDOR_ID_IBM;
4418 else if (dmi_name_in_vendors("LENOVO"))
4419 tp->vendor = PCI_VENDOR_ID_LENOVO;
4420 else
4421 return;
4422
4423 tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION),
4424 GFP_KERNEL);
4425 if (!tp->bios_version_str)
4426 return;
4427 tp->bios_model = tp->bios_version_str[0]
4428 | (tp->bios_version_str[1] << 8);
4429
4030 /* 4430 /*
4031 * ThinkPad T23 or newer, A31 or newer, R50e or newer, 4431 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
4032 * X32 or newer, all Z series; Some models must have an 4432 * X32 or newer, all Z series; Some models must have an
@@ -4040,10 +4440,20 @@ static char* __init check_dmi_for_ec(void)
4040 ec_fw_string) == 1) { 4440 ec_fw_string) == 1) {
4041 ec_fw_string[sizeof(ec_fw_string) - 1] = 0; 4441 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
4042 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; 4442 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
4043 return kstrdup(ec_fw_string, GFP_KERNEL); 4443
4444 tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL);
4445 tp->ec_model = ec_fw_string[0]
4446 | (ec_fw_string[1] << 8);
4447 break;
4044 } 4448 }
4045 } 4449 }
4046 return NULL; 4450
4451 tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION),
4452 GFP_KERNEL);
4453 if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) {
4454 kfree(tp->model_str);
4455 tp->model_str = NULL;
4456 }
4047} 4457}
4048 4458
4049static int __init probe_for_thinkpad(void) 4459static int __init probe_for_thinkpad(void)
@@ -4057,7 +4467,7 @@ static int __init probe_for_thinkpad(void)
4057 * Non-ancient models have better DMI tagging, but very old models 4467 * Non-ancient models have better DMI tagging, but very old models
4058 * don't. 4468 * don't.
4059 */ 4469 */
4060 is_thinkpad = dmi_name_in_vendors("ThinkPad"); 4470 is_thinkpad = (thinkpad_id.model_str != NULL);
4061 4471
4062 /* ec is required because many other handles are relative to it */ 4472 /* ec is required because many other handles are relative to it */
4063 IBM_ACPIHANDLE_INIT(ec); 4473 IBM_ACPIHANDLE_INIT(ec);
@@ -4073,7 +4483,7 @@ static int __init probe_for_thinkpad(void)
4073 * false positives a damn great deal 4483 * false positives a damn great deal
4074 */ 4484 */
4075 if (!is_thinkpad) 4485 if (!is_thinkpad)
4076 is_thinkpad = dmi_name_in_vendors("IBM"); 4486 is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM);
4077 4487
4078 if (!is_thinkpad && !force_load) 4488 if (!is_thinkpad && !force_load)
4079 return -ENODEV; 4489 return -ENODEV;
@@ -4185,10 +4595,13 @@ static u32 dbg_level;
4185module_param_named(debug, dbg_level, uint, 0); 4595module_param_named(debug, dbg_level, uint, 0);
4186 4596
4187static int force_load; 4597static int force_load;
4188module_param(force_load, int, 0); 4598module_param(force_load, bool, 0);
4189 4599
4190static int fan_control_allowed; 4600static int fan_control_allowed;
4191module_param_named(fan_control, fan_control_allowed, int, 0); 4601module_param_named(fan_control, fan_control_allowed, bool, 0);
4602
4603static int brightness_mode;
4604module_param_named(brightness_mode, brightness_mode, int, 0);
4192 4605
4193#define IBM_PARAM(feature) \ 4606#define IBM_PARAM(feature) \
4194 module_param_call(feature, set_ibm_param, NULL, NULL, 0) 4607 module_param_call(feature, set_ibm_param, NULL, NULL, 0)
@@ -4216,12 +4629,16 @@ static int __init thinkpad_acpi_module_init(void)
4216 int ret, i; 4629 int ret, i;
4217 4630
4218 /* Driver-level probe */ 4631 /* Driver-level probe */
4632
4633 get_thinkpad_model_data(&thinkpad_id);
4219 ret = probe_for_thinkpad(); 4634 ret = probe_for_thinkpad();
4220 if (ret) 4635 if (ret) {
4636 thinkpad_acpi_module_exit();
4221 return ret; 4637 return ret;
4638 }
4222 4639
4223 /* Driver initialization */ 4640 /* Driver initialization */
4224 ibm_thinkpad_ec_found = check_dmi_for_ec(); 4641
4225 IBM_ACPIHANDLE_INIT(ecrd); 4642 IBM_ACPIHANDLE_INIT(ecrd);
4226 IBM_ACPIHANDLE_INIT(ecwr); 4643 IBM_ACPIHANDLE_INIT(ecwr);
4227 4644
@@ -4265,6 +4682,22 @@ static int __init thinkpad_acpi_module_init(void)
4265 thinkpad_acpi_module_exit(); 4682 thinkpad_acpi_module_exit();
4266 return ret; 4683 return ret;
4267 } 4684 }
4685 tpacpi_inputdev = input_allocate_device();
4686 if (!tpacpi_inputdev) {
4687 printk(IBM_ERR "unable to allocate input device\n");
4688 thinkpad_acpi_module_exit();
4689 return -ENOMEM;
4690 } else {
4691 /* Prepare input device, but don't register */
4692 tpacpi_inputdev->name = "ThinkPad Extra Buttons";
4693 tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0";
4694 tpacpi_inputdev->id.bustype = BUS_HOST;
4695 tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ?
4696 thinkpad_id.vendor :
4697 PCI_VENDOR_ID_IBM;
4698 tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
4699 tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
4700 }
4268 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { 4701 for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
4269 ret = ibm_init(&ibms_init[i]); 4702 ret = ibm_init(&ibms_init[i]);
4270 if (ret >= 0 && *ibms_init[i].param) 4703 if (ret >= 0 && *ibms_init[i].param)
@@ -4274,6 +4707,14 @@ static int __init thinkpad_acpi_module_init(void)
4274 return ret; 4707 return ret;
4275 } 4708 }
4276 } 4709 }
4710 ret = input_register_device(tpacpi_inputdev);
4711 if (ret < 0) {
4712 printk(IBM_ERR "unable to register input device\n");
4713 thinkpad_acpi_module_exit();
4714 return ret;
4715 } else {
4716 tp_features.input_device_registered = 1;
4717 }
4277 4718
4278 return 0; 4719 return 0;
4279} 4720}
@@ -4290,6 +4731,13 @@ static void thinkpad_acpi_module_exit(void)
4290 4731
4291 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); 4732 dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n");
4292 4733
4734 if (tpacpi_inputdev) {
4735 if (tp_features.input_device_registered)
4736 input_unregister_device(tpacpi_inputdev);
4737 else
4738 input_free_device(tpacpi_inputdev);
4739 }
4740
4293 if (tpacpi_hwmon) 4741 if (tpacpi_hwmon)
4294 hwmon_device_unregister(tpacpi_hwmon); 4742 hwmon_device_unregister(tpacpi_hwmon);
4295 4743
@@ -4302,7 +4750,9 @@ static void thinkpad_acpi_module_exit(void)
4302 if (proc_dir) 4750 if (proc_dir)
4303 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); 4751 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
4304 4752
4305 kfree(ibm_thinkpad_ec_found); 4753 kfree(thinkpad_id.bios_version_str);
4754 kfree(thinkpad_id.ec_version_str);
4755 kfree(thinkpad_id.model_str);
4306} 4756}
4307 4757
4308module_init(thinkpad_acpi_module_init); 4758module_init(thinkpad_acpi_module_init);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 72d62f2dabb9..b7a4a888cc8b 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -32,6 +32,7 @@
32#include <linux/list.h> 32#include <linux/list.h>
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34 34
35#include <linux/nvram.h>
35#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
36#include <linux/sysfs.h> 37#include <linux/sysfs.h>
37#include <linux/backlight.h> 38#include <linux/backlight.h>
@@ -39,6 +40,7 @@
39#include <linux/platform_device.h> 40#include <linux/platform_device.h>
40#include <linux/hwmon.h> 41#include <linux/hwmon.h>
41#include <linux/hwmon-sysfs.h> 42#include <linux/hwmon-sysfs.h>
43#include <linux/input.h>
42#include <asm/uaccess.h> 44#include <asm/uaccess.h>
43 45
44#include <linux/dmi.h> 46#include <linux/dmi.h>
@@ -48,6 +50,7 @@
48#include <acpi/acpi_drivers.h> 50#include <acpi/acpi_drivers.h>
49#include <acpi/acnamesp.h> 51#include <acpi/acnamesp.h>
50 52
53#include <linux/pci_ids.h>
51 54
52/**************************************************************************** 55/****************************************************************************
53 * Main driver 56 * Main driver
@@ -78,6 +81,11 @@
78#define TP_CMOS_BRIGHTNESS_UP 4 81#define TP_CMOS_BRIGHTNESS_UP 4
79#define TP_CMOS_BRIGHTNESS_DOWN 5 82#define TP_CMOS_BRIGHTNESS_DOWN 5
80 83
84/* ThinkPad CMOS NVRAM constants */
85#define TP_NVRAM_ADDR_BRIGHTNESS 0x5e
86#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07
87#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0
88
81#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") 89#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
82#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 90#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
83#define strlencmp(a,b) (strncmp((a), (b), strlen(b))) 91#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
@@ -98,9 +106,13 @@ static const char *str_supported(int is_supported);
98#define vdbg_printk(a_dbg_level, format, arg...) 106#define vdbg_printk(a_dbg_level, format, arg...)
99#endif 107#endif
100 108
109/* Input IDs */
110#define TPACPI_HKEY_INPUT_VENDOR PCI_VENDOR_ID_IBM
111#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */
112#define TPACPI_HKEY_INPUT_VERSION 0x4101
113
101/* ACPI HIDs */ 114/* ACPI HIDs */
102#define IBM_HKEY_HID "IBM0068" 115#define IBM_HKEY_HID "IBM0068"
103#define IBM_PCI_HID "PNP0A03"
104 116
105/* ACPI helpers */ 117/* ACPI helpers */
106static int __must_check acpi_evalf(acpi_handle handle, 118static int __must_check acpi_evalf(acpi_handle handle,
@@ -161,6 +173,7 @@ static int parse_strtoul(const char *buf, unsigned long max,
161static struct platform_device *tpacpi_pdev; 173static struct platform_device *tpacpi_pdev;
162static struct class_device *tpacpi_hwmon; 174static struct class_device *tpacpi_hwmon;
163static struct platform_driver tpacpi_pdriver; 175static struct platform_driver tpacpi_pdriver;
176static struct input_dev *tpacpi_inputdev;
164static int tpacpi_create_driver_attributes(struct device_driver *drv); 177static int tpacpi_create_driver_attributes(struct device_driver *drv);
165static void tpacpi_remove_driver_attributes(struct device_driver *drv); 178static void tpacpi_remove_driver_attributes(struct device_driver *drv);
166 179
@@ -168,9 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
168static int experimental; 181static int experimental;
169static u32 dbg_level; 182static u32 dbg_level;
170static int force_load; 183static int force_load;
171static char *ibm_thinkpad_ec_found;
172 184
173static char* check_dmi_for_ec(void);
174static int thinkpad_acpi_module_init(void); 185static int thinkpad_acpi_module_init(void);
175static void thinkpad_acpi_module_exit(void); 186static void thinkpad_acpi_module_exit(void);
176 187
@@ -197,6 +208,7 @@ struct ibm_struct {
197 int (*read) (char *); 208 int (*read) (char *);
198 int (*write) (char *); 209 int (*write) (char *);
199 void (*exit) (void); 210 void (*exit) (void);
211 void (*resume) (void);
200 212
201 struct list_head all_drivers; 213 struct list_head all_drivers;
202 214
@@ -228,12 +240,29 @@ static struct {
228 u16 bluetooth:1; 240 u16 bluetooth:1;
229 u16 hotkey:1; 241 u16 hotkey:1;
230 u16 hotkey_mask:1; 242 u16 hotkey_mask:1;
243 u16 hotkey_wlsw:1;
231 u16 light:1; 244 u16 light:1;
232 u16 light_status:1; 245 u16 light_status:1;
233 u16 wan:1; 246 u16 wan:1;
234 u16 fan_ctrl_status_undef:1; 247 u16 fan_ctrl_status_undef:1;
248 u16 input_device_registered:1;
235} tp_features; 249} tp_features;
236 250
251struct thinkpad_id_data {
252 unsigned int vendor; /* ThinkPad vendor:
253 * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */
254
255 char *bios_version_str; /* Something like 1ZET51WW (1.03z) */
256 char *ec_version_str; /* Something like 1ZHT51WW-1.04a */
257
258 u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */
259 u16 ec_model;
260
261 char *model_str;
262};
263
264static struct thinkpad_id_data thinkpad_id;
265
237static struct list_head tpacpi_all_drivers; 266static struct list_head tpacpi_all_drivers;
238 267
239static struct ibm_init_struct ibms_init[]; 268static struct ibm_init_struct ibms_init[];
@@ -300,6 +329,7 @@ static int bluetooth_write(char *buf);
300 329
301static struct backlight_device *ibm_backlight_device; 330static struct backlight_device *ibm_backlight_device;
302static int brightness_offset = 0x31; 331static int brightness_offset = 0x31;
332static int brightness_mode;
303 333
304static int brightness_init(struct ibm_init_struct *iibm); 334static int brightness_init(struct ibm_init_struct *iibm);
305static void brightness_exit(void); 335static void brightness_exit(void);
@@ -415,14 +445,14 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc);
415 */ 445 */
416 446
417static int hotkey_orig_status; 447static int hotkey_orig_status;
418static int hotkey_orig_mask; 448static u32 hotkey_orig_mask;
419 449
420static struct mutex hotkey_mutex; 450static struct mutex hotkey_mutex;
421 451
422static int hotkey_init(struct ibm_init_struct *iibm); 452static int hotkey_init(struct ibm_init_struct *iibm);
423static void hotkey_exit(void); 453static void hotkey_exit(void);
424static int hotkey_get(int *status, int *mask); 454static int hotkey_get(int *status, u32 *mask);
425static int hotkey_set(int status, int mask); 455static int hotkey_set(int status, u32 mask);
426static void hotkey_notify(struct ibm_struct *ibm, u32 event); 456static void hotkey_notify(struct ibm_struct *ibm, u32 event);
427static int hotkey_read(char *p); 457static int hotkey_read(char *p);
428static int hotkey_write(char *buf); 458static int hotkey_write(char *buf);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2a237f09ee5d..564cc9b51822 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -12,6 +12,13 @@ config VGASTATE
12 tristate 12 tristate
13 default n 13 default n
14 14
15config VIDEO_OUTPUT_CONTROL
16 tristate "Lowlevel video output switch controls"
17 default m
18 help
19 This framework adds support for low-level control of the video
20 output switch.
21
15config FB 22config FB
16 tristate "Support for frame buffer devices" 23 tristate "Support for frame buffer devices"
17 ---help--- 24 ---help---
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index a562f9d69d2c..518933d4905f 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -123,3 +123,6 @@ obj-$(CONFIG_FB_OF) += offb.o
123 123
124# the test framebuffer is last 124# the test framebuffer is last
125obj-$(CONFIG_FB_VIRTUAL) += vfb.o 125obj-$(CONFIG_FB_VIRTUAL) += vfb.o
126
127#video output switch sysfs driver
128obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 8948a6461834..45662f6dbdb6 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -486,6 +486,8 @@
486#define ACPI_FUNCTION_NAME(name) 486#define ACPI_FUNCTION_NAME(name)
487#endif 487#endif
488 488
489#ifdef DEBUG_FUNC_TRACE
490
489#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ 491#define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \
490 acpi_ut_trace(ACPI_DEBUG_PARAMETERS) 492 acpi_ut_trace(ACPI_DEBUG_PARAMETERS)
491#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ 493#define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \
@@ -563,6 +565,27 @@
563 565
564#endif /* ACPI_SIMPLE_RETURN_MACROS */ 566#endif /* ACPI_SIMPLE_RETURN_MACROS */
565 567
568#else /* !DEBUG_FUNC_TRACE */
569
570#define ACPI_FUNCTION_TRACE(a)
571#define ACPI_FUNCTION_TRACE_PTR(a,b)
572#define ACPI_FUNCTION_TRACE_U32(a,b)
573#define ACPI_FUNCTION_TRACE_STR(a,b)
574#define ACPI_FUNCTION_EXIT
575#define ACPI_FUNCTION_STATUS_EXIT(s)
576#define ACPI_FUNCTION_VALUE_EXIT(s)
577#define ACPI_FUNCTION_TRACE(a)
578#define ACPI_FUNCTION_ENTRY()
579
580#define return_VOID return
581#define return_ACPI_STATUS(s) return(s)
582#define return_VALUE(s) return(s)
583#define return_UINT8(s) return(s)
584#define return_UINT32(s) return(s)
585#define return_PTR(s) return(s)
586
587#endif /* DEBUG_FUNC_TRACE */
588
566/* Conditional execution */ 589/* Conditional execution */
567 590
568#define ACPI_DEBUG_EXEC(a) a 591#define ACPI_DEBUG_EXEC(a) a
@@ -599,26 +622,26 @@
599#define ACPI_DEBUG_EXEC(a) 622#define ACPI_DEBUG_EXEC(a)
600#define ACPI_NORMAL_EXEC(a) a; 623#define ACPI_NORMAL_EXEC(a) a;
601 624
602#define ACPI_DEBUG_DEFINE(a) 625#define ACPI_DEBUG_DEFINE(a) do { } while(0)
603#define ACPI_DEBUG_ONLY_MEMBERS(a) 626#define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0)
604#define ACPI_FUNCTION_NAME(a) 627#define ACPI_FUNCTION_NAME(a) do { } while(0)
605#define ACPI_FUNCTION_TRACE(a) 628#define ACPI_FUNCTION_TRACE(a) do { } while(0)
606#define ACPI_FUNCTION_TRACE_PTR(a,b) 629#define ACPI_FUNCTION_TRACE_PTR(a,b) do { } while(0)
607#define ACPI_FUNCTION_TRACE_U32(a,b) 630#define ACPI_FUNCTION_TRACE_U32(a,b) do { } while(0)
608#define ACPI_FUNCTION_TRACE_STR(a,b) 631#define ACPI_FUNCTION_TRACE_STR(a,b) do { } while(0)
609#define ACPI_FUNCTION_EXIT 632#define ACPI_FUNCTION_EXIT do { } while(0)
610#define ACPI_FUNCTION_STATUS_EXIT(s) 633#define ACPI_FUNCTION_STATUS_EXIT(s) do { } while(0)
611#define ACPI_FUNCTION_VALUE_EXIT(s) 634#define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0)
612#define ACPI_FUNCTION_ENTRY() 635#define ACPI_FUNCTION_ENTRY() do { } while(0)
613#define ACPI_DUMP_STACK_ENTRY(a) 636#define ACPI_DUMP_STACK_ENTRY(a) do { } while(0)
614#define ACPI_DUMP_OPERANDS(a,b,c,d,e) 637#define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0)
615#define ACPI_DUMP_ENTRY(a,b) 638#define ACPI_DUMP_ENTRY(a,b) do { } while(0)
616#define ACPI_DUMP_TABLES(a,b) 639#define ACPI_DUMP_TABLES(a,b) do { } while(0)
617#define ACPI_DUMP_PATHNAME(a,b,c,d) 640#define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0)
618#define ACPI_DUMP_RESOURCE_LIST(a) 641#define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0)
619#define ACPI_DUMP_BUFFER(a,b) 642#define ACPI_DUMP_BUFFER(a,b) do { } while(0)
620#define ACPI_DEBUG_PRINT(pl) 643#define ACPI_DEBUG_PRINT(pl) do { } while(0)
621#define ACPI_DEBUG_PRINT_RAW(pl) 644#define ACPI_DEBUG_PRINT_RAW(pl) do { } while(0)
622 645
623#define return_VOID return 646#define return_VOID return
624#define return_ACPI_STATUS(s) return(s) 647#define return_ACPI_STATUS(s) return(s)
diff --git a/include/acpi/acoutput.h b/include/acpi/acoutput.h
index 7812267b577f..c090a8b0bc99 100644
--- a/include/acpi/acoutput.h
+++ b/include/acpi/acoutput.h
@@ -178,8 +178,8 @@
178 178
179/* Defaults for debug_level, debug and normal */ 179/* Defaults for debug_level, debug and normal */
180 180
181#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) 181#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR)
182#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) 182#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR)
183#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) 183#define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL)
184 184
185#endif /* __ACOUTPUT_H__ */ 185#endif /* __ACOUTPUT_H__ */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c6fa5e023bc7..5e3dcf3299bf 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -321,7 +321,8 @@ struct acpi_bus_event {
321}; 321};
322 322
323extern struct kset acpi_subsys; 323extern struct kset acpi_subsys;
324 324extern int acpi_bus_generate_genetlink_event(struct acpi_device *device,
325 u8 type, int data);
325/* 326/*
326 * External Functions 327 * External Functions
327 */ 328 */
diff --git a/include/acpi/platform/acenv.h b/include/acpi/platform/acenv.h
index dab2ec59a3b0..c785485e62a6 100644
--- a/include/acpi/platform/acenv.h
+++ b/include/acpi/platform/acenv.h
@@ -136,7 +136,7 @@
136 136
137/*! [Begin] no source code translation */ 137/*! [Begin] no source code translation */
138 138
139#if defined(__linux__) 139#if defined(_LINUX) || defined(__linux__)
140#include "aclinux.h" 140#include "aclinux.h"
141 141
142#elif defined(_AED_EFI) 142#elif defined(_AED_EFI)
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index a568717f98c6..6ed15a0978eb 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -91,7 +91,10 @@
91#define ACPI_USE_NATIVE_DIVIDE 91#define ACPI_USE_NATIVE_DIVIDE
92#endif 92#endif
93 93
94#ifndef __cdecl
94#define __cdecl 95#define __cdecl
96#endif
97
95#define ACPI_FLUSH_CPU_CACHE() 98#define ACPI_FLUSH_CPU_CACHE()
96#endif /* __KERNEL__ */ 99#endif /* __KERNEL__ */
97 100
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index b4b0ffdab098..f9f987f8e661 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -21,6 +21,8 @@
21#define ACPI_PSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */ 21#define ACPI_PSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */
22#define ACPI_PSD_REV0_ENTRIES 5 22#define ACPI_PSD_REV0_ENTRIES 5
23 23
24#define ACPI_TSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */
25#define ACPI_TSD_REV0_ENTRIES 5
24/* 26/*
25 * Types of coordination defined in ACPI 3.0. Same macros can be used across 27 * Types of coordination defined in ACPI 3.0. Same macros can be used across
26 * P, C and T states 28 * P, C and T states
@@ -125,17 +127,53 @@ struct acpi_processor_performance {
125 127
126/* Throttling Control */ 128/* Throttling Control */
127 129
130struct acpi_tsd_package {
131 acpi_integer num_entries;
132 acpi_integer revision;
133 acpi_integer domain;
134 acpi_integer coord_type;
135 acpi_integer num_processors;
136} __attribute__ ((packed));
137
138struct acpi_ptc_register {
139 u8 descriptor;
140 u16 length;
141 u8 space_id;
142 u8 bit_width;
143 u8 bit_offset;
144 u8 reserved;
145 u64 address;
146} __attribute__ ((packed));
147
148struct acpi_processor_tx_tss {
149 acpi_integer freqpercentage; /* */
150 acpi_integer power; /* milliWatts */
151 acpi_integer transition_latency; /* microseconds */
152 acpi_integer control; /* control value */
153 acpi_integer status; /* success indicator */
154};
128struct acpi_processor_tx { 155struct acpi_processor_tx {
129 u16 power; 156 u16 power;
130 u16 performance; 157 u16 performance;
131}; 158};
132 159
160struct acpi_processor;
133struct acpi_processor_throttling { 161struct acpi_processor_throttling {
134 int state; 162 unsigned int state;
163 unsigned int platform_limit;
164 struct acpi_pct_register control_register;
165 struct acpi_pct_register status_register;
166 unsigned int state_count;
167 struct acpi_processor_tx_tss *states_tss;
168 struct acpi_tsd_package domain_info;
169 cpumask_t shared_cpu_map;
170 int (*acpi_processor_get_throttling) (struct acpi_processor * pr);
171 int (*acpi_processor_set_throttling) (struct acpi_processor * pr,
172 int state);
173
135 u32 address; 174 u32 address;
136 u8 duty_offset; 175 u8 duty_offset;
137 u8 duty_width; 176 u8 duty_width;
138 int state_count;
139 struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; 177 struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING];
140}; 178};
141 179
@@ -169,6 +207,9 @@ struct acpi_processor {
169 u32 id; 207 u32 id;
170 u32 pblk; 208 u32 pblk;
171 int performance_platform_limit; 209 int performance_platform_limit;
210 int throttling_platform_limit;
211 /* 0 - states 0..n-th state available */
212
172 struct acpi_processor_flags flags; 213 struct acpi_processor_flags flags;
173 struct acpi_processor_power power; 214 struct acpi_processor_power power;
174 struct acpi_processor_performance *performance; 215 struct acpi_processor_performance *performance;
@@ -270,7 +311,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr)
270 311
271/* in processor_throttling.c */ 312/* in processor_throttling.c */
272int acpi_processor_get_throttling_info(struct acpi_processor *pr); 313int acpi_processor_get_throttling_info(struct acpi_processor *pr);
273int acpi_processor_set_throttling(struct acpi_processor *pr, int state); 314extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
274extern struct file_operations acpi_processor_throttling_fops; 315extern struct file_operations acpi_processor_throttling_fops;
275 316
276/* in processor_idle.c */ 317/* in processor_idle.c */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index b15c6498fe67..ced4d3f76104 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2040,6 +2040,8 @@
2040#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea 2040#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea
2041#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb 2041#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb
2042 2042
2043#define PCI_VENDOR_ID_LENOVO 0x17aa
2044
2043#define PCI_VENDOR_ID_ARECA 0x17d3 2045#define PCI_VENDOR_ID_ARECA 0x17d3
2044#define PCI_DEVICE_ID_ARECA_1110 0x1110 2046#define PCI_DEVICE_ID_ARECA_1110 0x1110
2045#define PCI_DEVICE_ID_ARECA_1120 0x1120 2047#define PCI_DEVICE_ID_ARECA_1120 0x1120