aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ibm-acpi.txt151
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/i386/kernel/acpi/boot.c22
-rw-r--r--drivers/acpi/Kconfig17
-rw-r--r--drivers/acpi/ac.c6
-rw-r--r--drivers/acpi/acpi_memhotplug.c2
-rw-r--r--drivers/acpi/asus_acpi.c69
-rw-r--r--drivers/acpi/battery.c22
-rw-r--r--drivers/acpi/button.c223
-rw-r--r--drivers/acpi/container.c2
-rw-r--r--drivers/acpi/dock.c153
-rw-r--r--drivers/acpi/ec.c347
-rw-r--r--drivers/acpi/events/evmisc.c1
-rw-r--r--drivers/acpi/executer/exmutex.c6
-rw-r--r--drivers/acpi/fan.c6
-rw-r--r--drivers/acpi/glue.c10
-rw-r--r--drivers/acpi/hotkey.c5
-rw-r--r--drivers/acpi/i2c_ec.c2
-rw-r--r--drivers/acpi/ibm_acpi.c1046
-rw-r--r--drivers/acpi/numa.c2
-rw-r--r--drivers/acpi/osl.c5
-rw-r--r--drivers/acpi/pci_bind.c4
-rw-r--r--drivers/acpi/pci_irq.c2
-rw-r--r--drivers/acpi/pci_link.c8
-rw-r--r--drivers/acpi/pci_root.c13
-rw-r--r--drivers/acpi/power.c6
-rw-r--r--drivers/acpi/processor_core.c14
-rw-r--r--drivers/acpi/processor_idle.c14
-rw-r--r--drivers/acpi/processor_perflib.c10
-rw-r--r--drivers/acpi/processor_thermal.c6
-rw-r--r--drivers/acpi/processor_throttling.c6
-rw-r--r--drivers/acpi/sbs.c24
-rw-r--r--drivers/acpi/sleep/wakeup.c6
-rw-r--r--drivers/acpi/tables.c2
-rw-r--r--drivers/acpi/thermal.c30
-rw-r--r--drivers/acpi/toshiba_acpi.c89
-rw-r--r--drivers/acpi/utilities/utdebug.c5
-rw-r--r--drivers/acpi/utilities/utmutex.c16
-rw-r--r--drivers/acpi/utils.c4
-rw-r--r--drivers/acpi/video.c100
-rw-r--r--drivers/misc/msi-laptop.c3
-rw-r--r--drivers/usb/misc/appledisplay.c2
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb_base.c2
-rw-r--r--drivers/video/aty/radeon_backlight.c2
-rw-r--r--drivers/video/backlight/backlight.c7
-rw-r--r--drivers/video/nvidia/nv_backlight.c2
-rw-r--r--drivers/video/riva/fbdev.c2
-rw-r--r--include/asm-i386/acpi.h26
-rw-r--r--include/asm-x86_64/acpi.h26
-rw-r--r--include/linux/backlight.h2
-rw-r--r--kernel/power/disk.c8
-rw-r--r--kernel/power/main.c2
53 files changed, 1794 insertions, 757 deletions
diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index e50595bfd8ea..0132d363feb5 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -398,25 +398,67 @@ Temperature sensors -- /proc/acpi/ibm/thermal
398 398
399Most ThinkPads include six or more separate temperature sensors but 399Most ThinkPads include six or more separate temperature sensors but
400only expose the CPU temperature through the standard ACPI methods. 400only expose the CPU temperature through the standard ACPI methods.
401This feature shows readings from up to eight different sensors. Some 401This feature shows readings from up to eight different sensors on older
402readings may not be valid, e.g. may show large negative values. For 402ThinkPads, and it has experimental support for up to sixteen different
403example, on the X40, a typical output may be: 403sensors on newer ThinkPads. Readings from sensors that are not available
404return -128.
404 405
406No commands can be written to this file.
407
408EXPERIMENTAL: The 16-sensors feature is marked EXPERIMENTAL because the
409implementation directly accesses hardware registers and may not work as
410expected. USE WITH CAUTION! To use this feature, you need to supply the
411experimental=1 parameter when loading the module. When EXPERIMENTAL
412mode is enabled, reading the first 8 sensors on newer ThinkPads will
413also use an new experimental thermal sensor access mode.
414
415For example, on the X40, a typical output may be:
405temperatures: 42 42 45 41 36 -128 33 -128 416temperatures: 42 42 45 41 36 -128 33 -128
406 417
407Thomas Gruber took his R51 apart and traced all six active sensors in 418EXPERIMENTAL: On the T43/p, a typical output may be:
408his laptop (the location of sensors may vary on other models): 419temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128
420
421The mapping of thermal sensors to physical locations varies depending on
422system-board model (and thus, on ThinkPad model).
423
424http://thinkwiki.org/wiki/Thermal_Sensors is a public wiki page that
425tries to track down these locations for various models.
426
427Most (newer?) models seem to follow this pattern:
409 428
4101: CPU 4291: CPU
4112: Mini PCI Module 4302: (depends on model)
4123: HDD 4313: (depends on model)
4134: GPU 4324: GPU
4145: Battery 4335: Main battery: main sensor
4156: N/A 4346: Bay battery: main sensor
4167: Battery 4357: Main battery: secondary sensor
4178: N/A 4368: Bay battery: secondary sensor
4379-15: (depends on model)
438
439For the R51 (source: Thomas Gruber):
4402: Mini-PCI
4413: Internal HDD
442
443For the T43, T43/p (source: Shmidoax/Thinkwiki.org)
444http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p
4452: System board, left side (near PCMCIA slot), reported as HDAPS temp
4463: PCMCIA slot
4479: MCH (northbridge) to DRAM Bus
44810: ICH (southbridge), under Mini-PCI card, under touchpad
44911: Power regulator, underside of system board, below F2 key
450
451The A31 has a very atypical layout for the thermal sensors
452(source: Milos Popovic, http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_A31)
4531: CPU
4542: Main Battery: main sensor
4553: Power Converter
4564: Bay Battery: main sensor
4575: MCH (northbridge)
4586: PCMCIA/ambient
4597: Main Battery: secondary sensor
4608: Bay Battery: secondary sensor
418 461
419No commands can be written to this file.
420 462
421EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump 463EXPERIMENTAL: Embedded controller register dump -- /proc/acpi/ibm/ecdump
422------------------------------------------------------------------------ 464------------------------------------------------------------------------
@@ -529,27 +571,57 @@ directly accesses hardware registers and may not work as expected. USE
529WITH CAUTION! To use this feature, you need to supply the 571WITH CAUTION! To use this feature, you need to supply the
530experimental=1 parameter when loading the module. 572experimental=1 parameter when loading the module.
531 573
532This feature attempts to show the current fan speed. The speed is read 574This feature attempts to show the current fan speed, control mode and
533directly from the hardware registers of the embedded controller. This 575other fan data that might be available. The speed is read directly
534is known to work on later R, T and X series ThinkPads but may show a 576from the hardware registers of the embedded controller. This is known
535bogus value on other models. 577to work on later R, T and X series ThinkPads but may show a bogus
578value on other models.
579
580Most ThinkPad fans work in "levels". Level 0 stops the fan. The higher
581the level, the higher the fan speed, although adjacent levels often map
582to the same fan speed. 7 is the highest level, where the fan reaches
583the maximum recommended speed. Level "auto" means the EC changes the
584fan level according to some internal algorithm, usually based on
585readings from the thermal sensors. Level "disengaged" means the EC
586disables the speed-locked closed-loop fan control, and drives the fan as
587fast as it can go, which might exceed hardware limits, so use this level
588with caution.
589
590The fan usually ramps up or down slowly from one speed to another,
591and it is normal for the EC to take several seconds to react to fan
592commands.
536 593
537The fan may be enabled or disabled with the following commands: 594The fan may be enabled or disabled with the following commands:
538 595
539 echo enable >/proc/acpi/ibm/fan 596 echo enable >/proc/acpi/ibm/fan
540 echo disable >/proc/acpi/ibm/fan 597 echo disable >/proc/acpi/ibm/fan
541 598
599Placing a fan on level 0 is the same as disabling it. Enabling a fan
600will try to place it in a safe level if it is too slow or disabled.
601
542WARNING WARNING WARNING: do not leave the fan disabled unless you are 602WARNING WARNING WARNING: do not leave the fan disabled unless you are
543monitoring the temperature sensor readings and you are ready to enable 603monitoring all of the temperature sensor readings and you are ready to
544it if necessary to avoid overheating. 604enable it if necessary to avoid overheating.
545 605
546The fan only runs if it's enabled *and* the various temperature 606An enabled fan in level "auto" may stop spinning if the EC decides the
547sensors which control it read high enough. On the X40, this seems to 607ThinkPad is cool enough and doesn't need the extra airflow. This is
548depend on the CPU and HDD temperatures. Specifically, the fan is 608normal, and the EC will spin the fan up if the varios thermal readings
549turned on when either the CPU temperature climbs to 56 degrees or the 609rise too much.
550HDD temperature climbs to 46 degrees. The fan is turned off when the 610
551CPU temperature drops to 49 degrees and the HDD temperature drops to 611On the X40, this seems to depend on the CPU and HDD temperatures.
55241 degrees. These thresholds cannot currently be controlled. 612Specifically, the fan is turned on when either the CPU temperature
613climbs to 56 degrees or the HDD temperature climbs to 46 degrees. The
614fan is turned off when the CPU temperature drops to 49 degrees and the
615HDD temperature drops to 41 degrees. These thresholds cannot
616currently be controlled.
617
618The fan level can be controlled with the command:
619
620 echo 'level <level>' > /proc/acpi/ibm/thermal
621
622Where <level> is an integer from 0 to 7, or one of the words "auto"
623or "disengaged" (without the quotes). Not all ThinkPads support the
624"auto" and "disengaged" levels.
553 625
554On the X31 and X40 (and ONLY on those models), the fan speed can be 626On the X31 and X40 (and ONLY on those models), the fan speed can be
555controlled to a certain degree. Once the fan is running, it can be 627controlled to a certain degree. Once the fan is running, it can be
@@ -562,12 +634,9 @@ about 3700 to about 7350. Values outside this range either do not have
562any effect or the fan speed eventually settles somewhere in that 634any effect or the fan speed eventually settles somewhere in that
563range. The fan cannot be stopped or started with this command. 635range. The fan cannot be stopped or started with this command.
564 636
565On the 570, temperature readings are not available through this 637The ThinkPad's ACPI DSDT code will reprogram the fan on its own when
566feature and the fan control works a little differently. The fan speed 638certain conditions are met. It will override any fan programming done
567is reported in levels from 0 (off) to 7 (max) and can be controlled 639through ibm-acpi.
568with the following command:
569
570 echo 'level <level>' > /proc/acpi/ibm/thermal
571 640
572EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan 641EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
573--------------------------------------- 642---------------------------------------
@@ -601,6 +670,26 @@ example:
601 670
602 modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable 671 modprobe ibm_acpi hotkey=enable,0xffff video=auto_disable
603 672
673The ibm-acpi kernel driver can be programmed to revert the fan level
674to a safe setting if userspace does not issue one of the fan commands:
675"enable", "disable", "level" or "watchdog" within a configurable
676ammount of time. To do this, use the "watchdog" command.
677
678 echo 'watchdog <interval>' > /proc/acpi/ibm/fan
679
680Interval is the ammount of time in seconds to wait for one of the
681above mentioned fan commands before reseting the fan level to a safe
682one. If set to zero, the watchdog is disabled (default). When the
683watchdog timer runs out, it does the exact equivalent of the "enable"
684fan command.
685
686Note that the watchdog timer stops after it enables the fan. It will
687be rearmed again automatically (using the same interval) when one of
688the above mentioned fan commands is received. The fan watchdog is,
689therefore, not suitable to protect against fan mode changes made
690through means other than the "enable", "disable", and "level" fan
691commands.
692
604 693
605Example Configuration 694Example Configuration
606--------------------- 695---------------------
diff --git a/MAINTAINERS b/MAINTAINERS
index 3e926e733878..db38a4d28039 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1403,6 +1403,15 @@ W: http://www.ia64-linux.org/
1403T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git 1403T: git kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git
1404S: Maintained 1404S: Maintained
1405 1405
1406IBM ACPI EXTRAS DRIVER
1407P: Henrique de Moraes Holschuh
1408M: ibm-acpi@hmh.eng.br
1409L: ibm-acpi-devel@lists.sourceforge.net
1410W: http://ibm-acpi.sourceforge.net
1411W: http://thinkwiki.org/wiki/Ibm-acpi
1412T: git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
1413S: Maintained
1414
1406SN-IA64 (Itanium) SUB-PLATFORM 1415SN-IA64 (Itanium) SUB-PLATFORM
1407P: Jes Sorensen 1416P: Jes Sorensen
1408M: jes@sgi.com 1417M: jes@sgi.com
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index c8f96cff07c6..094300b3a81f 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -1327,3 +1327,25 @@ static int __init setup_acpi_sci(char *s)
1327 return 0; 1327 return 0;
1328} 1328}
1329early_param("acpi_sci", setup_acpi_sci); 1329early_param("acpi_sci", setup_acpi_sci);
1330
1331int __acpi_acquire_global_lock(unsigned int *lock)
1332{
1333 unsigned int old, new, val;
1334 do {
1335 old = *lock;
1336 new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
1337 val = cmpxchg(lock, old, new);
1338 } while (unlikely (val != old));
1339 return (new < 3) ? -1 : 0;
1340}
1341
1342int __acpi_release_global_lock(unsigned int *lock)
1343{
1344 unsigned int old, new, val;
1345 do {
1346 old = *lock;
1347 new = old & ~0x3;
1348 val = cmpxchg(lock, old, new);
1349 } while (unlikely (val != old));
1350 return old & 0x1;
1351}
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 0f9d4be7ed75..1639998e4d27 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,7 +11,7 @@ config ACPI
11 bool "ACPI Support" 11 bool "ACPI Support"
12 depends on IA64 || X86 12 depends on IA64 || X86
13 depends on PCI 13 depends on PCI
14 select PM 14 depends on PM
15 default y 15 default y
16 ---help--- 16 ---help---
17 Advanced Configuration and Power Interface (ACPI) support for 17 Advanced Configuration and Power Interface (ACPI) support for
@@ -97,6 +97,7 @@ config ACPI_BATTERY
97 97
98config ACPI_BUTTON 98config ACPI_BUTTON
99 tristate "Button" 99 tristate "Button"
100 depends on INPUT
100 default y 101 default y
101 help 102 help
102 This driver handles events on the power, sleep and lid buttons. 103 This driver handles events on the power, sleep and lid buttons.
@@ -172,6 +173,7 @@ config ACPI_NUMA
172config ACPI_ASUS 173config ACPI_ASUS
173 tristate "ASUS/Medion Laptop Extras" 174 tristate "ASUS/Medion Laptop Extras"
174 depends on X86 175 depends on X86
176 select BACKLIGHT_CLASS_DEVICE
175 ---help--- 177 ---help---
176 This driver provides support for extra features of ACPI-compatible 178 This driver provides support for extra features of ACPI-compatible
177 ASUS laptops. As some of Medion laptops are made by ASUS, it may also 179 ASUS laptops. As some of Medion laptops are made by ASUS, it may also
@@ -200,6 +202,7 @@ config ACPI_ASUS
200config ACPI_IBM 202config ACPI_IBM
201 tristate "IBM ThinkPad Laptop Extras" 203 tristate "IBM ThinkPad Laptop Extras"
202 depends on X86 204 depends on X86
205 select BACKLIGHT_CLASS_DEVICE
203 ---help--- 206 ---help---
204 This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds 207 This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
205 support for Fn-Fx key combinations, Bluetooth control, video 208 support for Fn-Fx key combinations, Bluetooth control, video
@@ -222,9 +225,21 @@ config ACPI_IBM_DOCK
222 225
223 If you are not sure, say N here. 226 If you are not sure, say N here.
224 227
228config ACPI_IBM_BAY
229 bool "Legacy Removable Bay Support"
230 depends on ACPI_IBM
231 depends on ACPI_BAY=n
232 default n
233 ---help---
234 Allows the ibm_acpi driver to handle removable bays.
235 This support is obsoleted by CONFIG_ACPI_BAY.
236
237 If you are not sure, say N here.
238
225config ACPI_TOSHIBA 239config ACPI_TOSHIBA
226 tristate "Toshiba Laptop Extras" 240 tristate "Toshiba Laptop Extras"
227 depends on X86 241 depends on X86
242 select BACKLIGHT_CLASS_DEVICE
228 ---help--- 243 ---help---
229 This driver adds support for access to certain system settings 244 This driver adds support for access to certain system settings
230 on "legacy free" Toshiba laptops. These laptops can be recognized by 245 on "legacy free" Toshiba laptops. These laptops can be recognized by
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 11abc7bf777e..46e58663dcb5 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -109,7 +109,7 @@ static struct proc_dir_entry *acpi_ac_dir;
109 109
110static int acpi_ac_seq_show(struct seq_file *seq, void *offset) 110static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
111{ 111{
112 struct acpi_ac *ac = (struct acpi_ac *)seq->private; 112 struct acpi_ac *ac = seq->private;
113 113
114 114
115 if (!ac) 115 if (!ac)
@@ -187,7 +187,7 @@ static int acpi_ac_remove_fs(struct acpi_device *device)
187 187
188static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) 188static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
189{ 189{
190 struct acpi_ac *ac = (struct acpi_ac *)data; 190 struct acpi_ac *ac = data;
191 struct acpi_device *device = NULL; 191 struct acpi_device *device = NULL;
192 192
193 193
@@ -269,7 +269,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
269 if (!device || !acpi_driver_data(device)) 269 if (!device || !acpi_driver_data(device))
270 return -EINVAL; 270 return -EINVAL;
271 271
272 ac = (struct acpi_ac *)acpi_driver_data(device); 272 ac = acpi_driver_data(device);
273 273
274 status = acpi_remove_notify_handler(device->handle, 274 status = acpi_remove_notify_handler(device->handle,
275 ACPI_ALL_NOTIFY, acpi_ac_notify); 275 ACPI_ALL_NOTIFY, acpi_ac_notify);
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 6bcd9e8e7bcb..150112ae48ed 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -429,7 +429,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type)
429 if (!device || !acpi_driver_data(device)) 429 if (!device || !acpi_driver_data(device))
430 return -EINVAL; 430 return -EINVAL;
431 431
432 mem_device = (struct acpi_memory_device *)acpi_driver_data(device); 432 mem_device = acpi_driver_data(device);
433 kfree(mem_device); 433 kfree(mem_device);
434 434
435 return 0; 435 return 0;
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index c7ac9297a204..7cc54aacd4c0 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -35,6 +35,7 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/backlight.h>
38#include <acpi/acpi_drivers.h> 39#include <acpi/acpi_drivers.h>
39#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
40#include <asm/uaccess.h> 41#include <asm/uaccess.h>
@@ -402,6 +403,8 @@ static struct model_data model_conf[END_MODEL] = {
402/* procdir we use */ 403/* procdir we use */
403static struct proc_dir_entry *asus_proc_dir; 404static struct proc_dir_entry *asus_proc_dir;
404 405
406static struct backlight_device *asus_backlight_device;
407
405/* 408/*
406 * This header is made available to allow proper configuration given model, 409 * This header is made available to allow proper configuration given model,
407 * revision number , ... this info cannot go in struct asus_hotk because it is 410 * revision number , ... this info cannot go in struct asus_hotk because it is
@@ -779,7 +782,7 @@ proc_write_lcd(struct file *file, const char __user * buffer,
779 return rv; 782 return rv;
780} 783}
781 784
782static int read_brightness(void) 785static int read_brightness(struct backlight_device *bd)
783{ 786{
784 int value; 787 int value;
785 788
@@ -801,9 +804,10 @@ static int read_brightness(void)
801/* 804/*
802 * Change the brightness level 805 * Change the brightness level
803 */ 806 */
804static void set_brightness(int value) 807static int set_brightness(int value)
805{ 808{
806 acpi_status status = 0; 809 acpi_status status = 0;
810 int ret = 0;
807 811
808 /* SPLV laptop */ 812 /* SPLV laptop */
809 if (hotk->methods->brightness_set) { 813 if (hotk->methods->brightness_set) {
@@ -811,11 +815,12 @@ static void set_brightness(int value)
811 value, NULL)) 815 value, NULL))
812 printk(KERN_WARNING 816 printk(KERN_WARNING
813 "Asus ACPI: Error changing brightness\n"); 817 "Asus ACPI: Error changing brightness\n");
814 return; 818 ret = -EIO;
819 goto out;
815 } 820 }
816 821
817 /* No SPLV method if we are here, act as appropriate */ 822 /* No SPLV method if we are here, act as appropriate */
818 value -= read_brightness(); 823 value -= read_brightness(NULL);
819 while (value != 0) { 824 while (value != 0) {
820 status = acpi_evaluate_object(NULL, (value > 0) ? 825 status = acpi_evaluate_object(NULL, (value > 0) ?
821 hotk->methods->brightness_up : 826 hotk->methods->brightness_up :
@@ -825,15 +830,22 @@ static void set_brightness(int value)
825 if (ACPI_FAILURE(status)) 830 if (ACPI_FAILURE(status))
826 printk(KERN_WARNING 831 printk(KERN_WARNING
827 "Asus ACPI: Error changing brightness\n"); 832 "Asus ACPI: Error changing brightness\n");
833 ret = -EIO;
828 } 834 }
829 return; 835out:
836 return ret;
837}
838
839static int set_brightness_status(struct backlight_device *bd)
840{
841 return set_brightness(bd->props->brightness);
830} 842}
831 843
832static int 844static int
833proc_read_brn(char *page, char **start, off_t off, int count, int *eof, 845proc_read_brn(char *page, char **start, off_t off, int count, int *eof,
834 void *data) 846 void *data)
835{ 847{
836 return sprintf(page, "%d\n", read_brightness()); 848 return sprintf(page, "%d\n", read_brightness(NULL));
837} 849}
838 850
839static int 851static int
@@ -1134,7 +1146,7 @@ static int asus_hotk_get_info(void)
1134 if (ACPI_FAILURE(status)) 1146 if (ACPI_FAILURE(status))
1135 printk(KERN_WARNING " Couldn't get the DSDT table header\n"); 1147 printk(KERN_WARNING " Couldn't get the DSDT table header\n");
1136 else 1148 else
1137 asus_info = (struct acpi_table_header *)dsdt.pointer; 1149 asus_info = dsdt.pointer;
1138 1150
1139 /* We have to write 0 on init this far for all ASUS models */ 1151 /* We have to write 0 on init this far for all ASUS models */
1140 if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { 1152 if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) {
@@ -1156,7 +1168,7 @@ static int asus_hotk_get_info(void)
1156 * asus_model_match() and try something completely different. 1168 * asus_model_match() and try something completely different.
1157 */ 1169 */
1158 if (buffer.pointer) { 1170 if (buffer.pointer) {
1159 model = (union acpi_object *)buffer.pointer; 1171 model = buffer.pointer;
1160 switch (model->type) { 1172 switch (model->type) {
1161 case ACPI_TYPE_STRING: 1173 case ACPI_TYPE_STRING:
1162 string = model->string.pointer; 1174 string = model->string.pointer;
@@ -1252,8 +1264,7 @@ static int asus_hotk_add(struct acpi_device *device)
1252 printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", 1264 printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
1253 ASUS_ACPI_VERSION); 1265 ASUS_ACPI_VERSION);
1254 1266
1255 hotk = 1267 hotk = kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
1256 (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL);
1257 if (!hotk) 1268 if (!hotk)
1258 return -ENOMEM; 1269 return -ENOMEM;
1259 memset(hotk, 0, sizeof(struct asus_hotk)); 1270 memset(hotk, 0, sizeof(struct asus_hotk));
@@ -1333,6 +1344,26 @@ static int asus_hotk_remove(struct acpi_device *device, int type)
1333 return 0; 1344 return 0;
1334} 1345}
1335 1346
1347static struct backlight_properties asus_backlight_data = {
1348 .owner = THIS_MODULE,
1349 .get_brightness = read_brightness,
1350 .update_status = set_brightness_status,
1351 .max_brightness = 15,
1352};
1353
1354static void __exit asus_acpi_exit(void)
1355{
1356 if (asus_backlight_device)
1357 backlight_device_unregister(asus_backlight_device);
1358
1359 acpi_bus_unregister_driver(&asus_hotk_driver);
1360 remove_proc_entry(PROC_ASUS, acpi_root_dir);
1361
1362 kfree(asus_info);
1363
1364 return;
1365}
1366
1336static int __init asus_acpi_init(void) 1367static int __init asus_acpi_init(void)
1337{ 1368{
1338 int result; 1369 int result;
@@ -1370,17 +1401,15 @@ static int __init asus_acpi_init(void)
1370 return result; 1401 return result;
1371 } 1402 }
1372 1403
1373 return 0; 1404 asus_backlight_device = backlight_device_register("asus",NULL,NULL,
1374} 1405 &asus_backlight_data);
1375 1406 if (IS_ERR(asus_backlight_device)) {
1376static void __exit asus_acpi_exit(void) 1407 printk(KERN_ERR "Could not register asus backlight device\n");
1377{ 1408 asus_backlight_device = NULL;
1378 acpi_bus_unregister_driver(&asus_hotk_driver); 1409 asus_acpi_exit();
1379 remove_proc_entry(PROC_ASUS, acpi_root_dir); 1410 }
1380
1381 kfree(asus_info);
1382 1411
1383 return; 1412 return 0;
1384} 1413}
1385 1414
1386module_init(asus_acpi_init); 1415module_init(asus_acpi_init);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 026e40755cdd..f47c78a10656 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -149,7 +149,7 @@ acpi_battery_get_info(struct acpi_battery *battery,
149 return -ENODEV; 149 return -ENODEV;
150 } 150 }
151 151
152 package = (union acpi_object *)buffer.pointer; 152 package = buffer.pointer;
153 153
154 /* Extract Package Data */ 154 /* Extract Package Data */
155 155
@@ -179,7 +179,7 @@ acpi_battery_get_info(struct acpi_battery *battery,
179 kfree(buffer.pointer); 179 kfree(buffer.pointer);
180 180
181 if (!result) 181 if (!result)
182 (*bif) = (struct acpi_battery_info *)data.pointer; 182 (*bif) = data.pointer;
183 183
184 return result; 184 return result;
185} 185}
@@ -209,7 +209,7 @@ acpi_battery_get_status(struct acpi_battery *battery,
209 return -ENODEV; 209 return -ENODEV;
210 } 210 }
211 211
212 package = (union acpi_object *)buffer.pointer; 212 package = buffer.pointer;
213 213
214 /* Extract Package Data */ 214 /* Extract Package Data */
215 215
@@ -239,7 +239,7 @@ acpi_battery_get_status(struct acpi_battery *battery,
239 kfree(buffer.pointer); 239 kfree(buffer.pointer);
240 240
241 if (!result) 241 if (!result)
242 (*bst) = (struct acpi_battery_status *)data.pointer; 242 (*bst) = data.pointer;
243 243
244 return result; 244 return result;
245} 245}
@@ -334,7 +334,7 @@ static struct proc_dir_entry *acpi_battery_dir;
334static int acpi_battery_read_info(struct seq_file *seq, void *offset) 334static int acpi_battery_read_info(struct seq_file *seq, void *offset)
335{ 335{
336 int result = 0; 336 int result = 0;
337 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 337 struct acpi_battery *battery = seq->private;
338 struct acpi_battery_info *bif = NULL; 338 struct acpi_battery_info *bif = NULL;
339 char *units = "?"; 339 char *units = "?";
340 340
@@ -418,7 +418,7 @@ static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
418static int acpi_battery_read_state(struct seq_file *seq, void *offset) 418static int acpi_battery_read_state(struct seq_file *seq, void *offset)
419{ 419{
420 int result = 0; 420 int result = 0;
421 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 421 struct acpi_battery *battery = seq->private;
422 struct acpi_battery_status *bst = NULL; 422 struct acpi_battery_status *bst = NULL;
423 char *units = "?"; 423 char *units = "?";
424 424
@@ -494,7 +494,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
494 494
495static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 495static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
496{ 496{
497 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 497 struct acpi_battery *battery = seq->private;
498 char *units = "?"; 498 char *units = "?";
499 499
500 500
@@ -531,8 +531,8 @@ acpi_battery_write_alarm(struct file *file,
531{ 531{
532 int result = 0; 532 int result = 0;
533 char alarm_string[12] = { '\0' }; 533 char alarm_string[12] = { '\0' };
534 struct seq_file *m = (struct seq_file *)file->private_data; 534 struct seq_file *m = file->private_data;
535 struct acpi_battery *battery = (struct acpi_battery *)m->private; 535 struct acpi_battery *battery = m->private;
536 536
537 537
538 if (!battery || (count > sizeof(alarm_string) - 1)) 538 if (!battery || (count > sizeof(alarm_string) - 1))
@@ -658,7 +658,7 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
658 658
659static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) 659static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
660{ 660{
661 struct acpi_battery *battery = (struct acpi_battery *)data; 661 struct acpi_battery *battery = data;
662 struct acpi_device *device = NULL; 662 struct acpi_device *device = NULL;
663 663
664 664
@@ -742,7 +742,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
742 if (!device || !acpi_driver_data(device)) 742 if (!device || !acpi_driver_data(device))
743 return -EINVAL; 743 return -EINVAL;
744 744
745 battery = (struct acpi_battery *)acpi_driver_data(device); 745 battery = acpi_driver_data(device);
746 746
747 status = acpi_remove_notify_handler(device->handle, 747 status = acpi_remove_notify_handler(device->handle,
748 ACPI_ALL_NOTIFY, 748 ACPI_ALL_NOTIFY,
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 5ef885e82c78..ac860583c203 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -29,6 +29,7 @@
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/input.h>
32#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
33#include <acpi/acpi_drivers.h> 34#include <acpi/acpi_drivers.h>
34 35
@@ -62,7 +63,7 @@
62#define _COMPONENT ACPI_BUTTON_COMPONENT 63#define _COMPONENT ACPI_BUTTON_COMPONENT
63ACPI_MODULE_NAME("acpi_button") 64ACPI_MODULE_NAME("acpi_button")
64 65
65 MODULE_AUTHOR("Paul Diefenbaugh"); 66MODULE_AUTHOR("Paul Diefenbaugh");
66MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); 67MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME);
67MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
68 69
@@ -78,12 +79,14 @@ static struct acpi_driver acpi_button_driver = {
78 .ops = { 79 .ops = {
79 .add = acpi_button_add, 80 .add = acpi_button_add,
80 .remove = acpi_button_remove, 81 .remove = acpi_button_remove,
81 }, 82 },
82}; 83};
83 84
84struct acpi_button { 85struct acpi_button {
85 struct acpi_device *device; /* Fixed button kludge */ 86 struct acpi_device *device; /* Fixed button kludge */
86 u8 type; 87 unsigned int type;
88 struct input_dev *input;
89 char phys[32]; /* for input device */
87 unsigned long pushed; 90 unsigned long pushed;
88}; 91};
89 92
@@ -109,8 +112,7 @@ static struct proc_dir_entry *acpi_button_dir;
109 112
110static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) 113static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
111{ 114{
112 struct acpi_button *button = (struct acpi_button *)seq->private; 115 struct acpi_button *button = seq->private;
113
114 116
115 if (!button || !button->device) 117 if (!button || !button->device)
116 return 0; 118 return 0;
@@ -128,22 +130,17 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
128 130
129static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) 131static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
130{ 132{
131 struct acpi_button *button = (struct acpi_button *)seq->private; 133 struct acpi_button *button = seq->private;
132 acpi_status status; 134 acpi_status status;
133 unsigned long state; 135 unsigned long state;
134 136
135
136 if (!button || !button->device) 137 if (!button || !button->device)
137 return 0; 138 return 0;
138 139
139 status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state); 140 status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
140 if (ACPI_FAILURE(status)) { 141 seq_printf(seq, "state: %s\n",
141 seq_printf(seq, "state: unsupported\n"); 142 ACPI_FAILURE(status) ? "unsupported" :
142 } else { 143 (state ? "open" : "closed"));
143 seq_printf(seq, "state: %s\n",
144 (state ? "open" : "closed"));
145 }
146
147 return 0; 144 return 0;
148} 145}
149 146
@@ -159,8 +156,7 @@ static struct proc_dir_entry *acpi_lid_dir;
159static int acpi_button_add_fs(struct acpi_device *device) 156static int acpi_button_add_fs(struct acpi_device *device)
160{ 157{
161 struct proc_dir_entry *entry = NULL; 158 struct proc_dir_entry *entry = NULL;
162 struct acpi_button *button = NULL; 159 struct acpi_button *button;
163
164 160
165 if (!device || !acpi_driver_data(device)) 161 if (!device || !acpi_driver_data(device))
166 return -EINVAL; 162 return -EINVAL;
@@ -228,10 +224,8 @@ static int acpi_button_add_fs(struct acpi_device *device)
228 224
229static int acpi_button_remove_fs(struct acpi_device *device) 225static int acpi_button_remove_fs(struct acpi_device *device)
230{ 226{
231 struct acpi_button *button = NULL; 227 struct acpi_button *button = acpi_driver_data(device);
232
233 228
234 button = acpi_driver_data(device);
235 if (acpi_device_dir(device)) { 229 if (acpi_device_dir(device)) {
236 if (button->type == ACPI_BUTTON_TYPE_LID) 230 if (button->type == ACPI_BUTTON_TYPE_LID)
237 remove_proc_entry(ACPI_BUTTON_FILE_STATE, 231 remove_proc_entry(ACPI_BUTTON_FILE_STATE,
@@ -253,14 +247,34 @@ static int acpi_button_remove_fs(struct acpi_device *device)
253 247
254static void acpi_button_notify(acpi_handle handle, u32 event, void *data) 248static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
255{ 249{
256 struct acpi_button *button = (struct acpi_button *)data; 250 struct acpi_button *button = data;
257 251 struct input_dev *input;
258 252
259 if (!button || !button->device) 253 if (!button || !button->device)
260 return; 254 return;
261 255
262 switch (event) { 256 switch (event) {
263 case ACPI_BUTTON_NOTIFY_STATUS: 257 case ACPI_BUTTON_NOTIFY_STATUS:
258 input = button->input;
259
260 if (button->type == ACPI_BUTTON_TYPE_LID) {
261 struct acpi_handle *handle = button->device->handle;
262 unsigned long state;
263
264 if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
265 NULL, &state)))
266 input_report_switch(input, SW_LID, !state);
267
268 } else {
269 int keycode = test_bit(KEY_SLEEP, input->keybit) ?
270 KEY_SLEEP : KEY_POWER;
271
272 input_report_key(input, keycode, 1);
273 input_sync(input);
274 input_report_key(input, keycode, 0);
275 }
276 input_sync(input);
277
264 acpi_bus_generate_event(button->device, event, 278 acpi_bus_generate_event(button->device, event,
265 ++button->pushed); 279 ++button->pushed);
266 break; 280 break;
@@ -275,8 +289,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
275 289
276static acpi_status acpi_button_notify_fixed(void *data) 290static acpi_status acpi_button_notify_fixed(void *data)
277{ 291{
278 struct acpi_button *button = (struct acpi_button *)data; 292 struct acpi_button *button = data;
279
280 293
281 if (!button) 294 if (!button)
282 return AE_BAD_PARAMETER; 295 return AE_BAD_PARAMETER;
@@ -286,24 +299,75 @@ static acpi_status acpi_button_notify_fixed(void *data)
286 return AE_OK; 299 return AE_OK;
287} 300}
288 301
289static int acpi_button_add(struct acpi_device *device) 302static int acpi_button_install_notify_handlers(struct acpi_button *button)
290{ 303{
291 int result = 0; 304 acpi_status status;
292 acpi_status status = AE_OK;
293 struct acpi_button *button = NULL;
294 305
306 switch (button->type) {
307 case ACPI_BUTTON_TYPE_POWERF:
308 status =
309 acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
310 acpi_button_notify_fixed,
311 button);
312 break;
313 case ACPI_BUTTON_TYPE_SLEEPF:
314 status =
315 acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
316 acpi_button_notify_fixed,
317 button);
318 break;
319 default:
320 status = acpi_install_notify_handler(button->device->handle,
321 ACPI_DEVICE_NOTIFY,
322 acpi_button_notify,
323 button);
324 break;
325 }
326
327 return ACPI_FAILURE(status) ? -ENODEV : 0;
328}
329
330static void acpi_button_remove_notify_handlers(struct acpi_button *button)
331{
332 switch (button->type) {
333 case ACPI_BUTTON_TYPE_POWERF:
334 acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
335 acpi_button_notify_fixed);
336 break;
337 case ACPI_BUTTON_TYPE_SLEEPF:
338 acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
339 acpi_button_notify_fixed);
340 break;
341 default:
342 acpi_remove_notify_handler(button->device->handle,
343 ACPI_DEVICE_NOTIFY,
344 acpi_button_notify);
345 break;
346 }
347}
348
349static int acpi_button_add(struct acpi_device *device)
350{
351 int error;
352 struct acpi_button *button;
353 struct input_dev *input;
295 354
296 if (!device) 355 if (!device)
297 return -EINVAL; 356 return -EINVAL;
298 357
299 button = kmalloc(sizeof(struct acpi_button), GFP_KERNEL); 358 button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
300 if (!button) 359 if (!button)
301 return -ENOMEM; 360 return -ENOMEM;
302 memset(button, 0, sizeof(struct acpi_button));
303 361
304 button->device = device; 362 button->device = device;
305 acpi_driver_data(device) = button; 363 acpi_driver_data(device) = button;
306 364
365 button->input = input = input_allocate_device();
366 if (!input) {
367 error = -ENOMEM;
368 goto err_free_button;
369 }
370
307 /* 371 /*
308 * Determine the button type (via hid), as fixed-feature buttons 372 * Determine the button type (via hid), as fixed-feature buttons
309 * need to be handled a bit differently than generic-space. 373 * need to be handled a bit differently than generic-space.
@@ -338,39 +402,48 @@ static int acpi_button_add(struct acpi_device *device)
338 } else { 402 } else {
339 printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", 403 printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
340 acpi_device_hid(device)); 404 acpi_device_hid(device));
341 result = -ENODEV; 405 error = -ENODEV;
342 goto end; 406 goto err_free_input;
343 } 407 }
344 408
345 result = acpi_button_add_fs(device); 409 error = acpi_button_add_fs(device);
346 if (result) 410 if (error)
347 goto end; 411 goto err_free_input;
412
413 error = acpi_button_install_notify_handlers(button);
414 if (error)
415 goto err_remove_fs;
416
417 snprintf(button->phys, sizeof(button->phys),
418 "%s/button/input0", acpi_device_hid(device));
419
420 input->name = acpi_device_name(device);
421 input->phys = button->phys;
422 input->id.bustype = BUS_HOST;
423 input->id.product = button->type;
348 424
349 switch (button->type) { 425 switch (button->type) {
426 case ACPI_BUTTON_TYPE_POWER:
350 case ACPI_BUTTON_TYPE_POWERF: 427 case ACPI_BUTTON_TYPE_POWERF:
351 status = 428 input->evbit[0] = BIT(EV_KEY);
352 acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, 429 set_bit(KEY_POWER, input->keybit);
353 acpi_button_notify_fixed,
354 button);
355 break; 430 break;
431
432 case ACPI_BUTTON_TYPE_SLEEP:
356 case ACPI_BUTTON_TYPE_SLEEPF: 433 case ACPI_BUTTON_TYPE_SLEEPF:
357 status = 434 input->evbit[0] = BIT(EV_KEY);
358 acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, 435 set_bit(KEY_SLEEP, input->keybit);
359 acpi_button_notify_fixed,
360 button);
361 break; 436 break;
362 default: 437
363 status = acpi_install_notify_handler(device->handle, 438 case ACPI_BUTTON_TYPE_LID:
364 ACPI_DEVICE_NOTIFY, 439 input->evbit[0] = BIT(EV_SW);
365 acpi_button_notify, 440 set_bit(SW_LID, input->swbit);
366 button);
367 break; 441 break;
368 } 442 }
369 443
370 if (ACPI_FAILURE(status)) { 444 error = input_register_device(input);
371 result = -ENODEV; 445 if (error)
372 goto end; 446 goto err_remove_handlers;
373 }
374 447
375 if (device->wakeup.flags.valid) { 448 if (device->wakeup.flags.valid) {
376 /* Button's GPE is run-wake GPE */ 449 /* Button's GPE is run-wake GPE */
@@ -385,47 +458,31 @@ static int acpi_button_add(struct acpi_device *device)
385 printk(KERN_INFO PREFIX "%s [%s]\n", 458 printk(KERN_INFO PREFIX "%s [%s]\n",
386 acpi_device_name(device), acpi_device_bid(device)); 459 acpi_device_name(device), acpi_device_bid(device));
387 460
388 end: 461 return 0;
389 if (result) {
390 acpi_button_remove_fs(device);
391 kfree(button);
392 }
393 462
394 return result; 463 err_remove_handlers:
464 acpi_button_remove_notify_handlers(button);
465 err_remove_fs:
466 acpi_button_remove_fs(device);
467 err_free_input:
468 input_free_device(input);
469 err_free_button:
470 kfree(button);
471 return error;
395} 472}
396 473
397static int acpi_button_remove(struct acpi_device *device, int type) 474static int acpi_button_remove(struct acpi_device *device, int type)
398{ 475{
399 acpi_status status = 0; 476 struct acpi_button *button;
400 struct acpi_button *button = NULL;
401
402 477
403 if (!device || !acpi_driver_data(device)) 478 if (!device || !acpi_driver_data(device))
404 return -EINVAL; 479 return -EINVAL;
405 480
406 button = acpi_driver_data(device); 481 button = acpi_driver_data(device);
407 482
408 /* Unregister for device notifications. */ 483 acpi_button_remove_notify_handlers(button);
409 switch (button->type) {
410 case ACPI_BUTTON_TYPE_POWERF:
411 status =
412 acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
413 acpi_button_notify_fixed);
414 break;
415 case ACPI_BUTTON_TYPE_SLEEPF:
416 status =
417 acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
418 acpi_button_notify_fixed);
419 break;
420 default:
421 status = acpi_remove_notify_handler(device->handle,
422 ACPI_DEVICE_NOTIFY,
423 acpi_button_notify);
424 break;
425 }
426
427 acpi_button_remove_fs(device); 484 acpi_button_remove_fs(device);
428 485 input_unregister_device(button->input);
429 kfree(button); 486 kfree(button);
430 487
431 return 0; 488 return 0;
@@ -433,8 +490,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
433 490
434static int __init acpi_button_init(void) 491static int __init acpi_button_init(void)
435{ 492{
436 int result = 0; 493 int result;
437
438 494
439 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); 495 acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
440 if (!acpi_button_dir) 496 if (!acpi_button_dir)
@@ -451,7 +507,6 @@ static int __init acpi_button_init(void)
451 507
452static void __exit acpi_button_exit(void) 508static void __exit acpi_button_exit(void)
453{ 509{
454
455 acpi_bus_unregister_driver(&acpi_button_driver); 510 acpi_bus_unregister_driver(&acpi_button_driver);
456 511
457 if (acpi_power_dir) 512 if (acpi_power_dir)
@@ -461,8 +516,6 @@ static void __exit acpi_button_exit(void)
461 if (acpi_lid_dir) 516 if (acpi_lid_dir)
462 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); 517 remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
463 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); 518 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
464
465 return;
466} 519}
467 520
468module_init(acpi_button_init); 521module_init(acpi_button_init);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 871aa520ece7..a15381789462 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -117,7 +117,7 @@ static int acpi_container_remove(struct acpi_device *device, int type)
117 acpi_status status = AE_OK; 117 acpi_status status = AE_OK;
118 struct acpi_container *pc = NULL; 118 struct acpi_container *pc = NULL;
119 119
120 pc = (struct acpi_container *)acpi_driver_data(device); 120 pc = acpi_driver_data(device);
121 kfree(pc); 121 kfree(pc);
122 return status; 122 return status;
123} 123}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index bf5b79ed3613..90990a4b6526 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/notifier.h> 29#include <linux/notifier.h>
30#include <linux/platform_device.h>
30#include <linux/jiffies.h> 31#include <linux/jiffies.h>
31#include <acpi/acpi_bus.h> 32#include <acpi/acpi_bus.h>
32#include <acpi/acpi_drivers.h> 33#include <acpi/acpi_drivers.h>
@@ -39,13 +40,15 @@ MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME);
39MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
40 41
41static struct atomic_notifier_head dock_notifier_list; 42static struct atomic_notifier_head dock_notifier_list;
43static struct platform_device dock_device;
44static char dock_device_name[] = "dock";
42 45
43struct dock_station { 46struct dock_station {
44 acpi_handle handle; 47 acpi_handle handle;
45 unsigned long last_dock_time; 48 unsigned long last_dock_time;
46 u32 flags; 49 u32 flags;
47 spinlock_t dd_lock; 50 spinlock_t dd_lock;
48 spinlock_t hp_lock; 51 struct mutex hp_lock;
49 struct list_head dependent_devices; 52 struct list_head dependent_devices;
50 struct list_head hotplug_devices; 53 struct list_head hotplug_devices;
51}; 54};
@@ -115,9 +118,9 @@ static void
115dock_add_hotplug_device(struct dock_station *ds, 118dock_add_hotplug_device(struct dock_station *ds,
116 struct dock_dependent_device *dd) 119 struct dock_dependent_device *dd)
117{ 120{
118 spin_lock(&ds->hp_lock); 121 mutex_lock(&ds->hp_lock);
119 list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); 122 list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
120 spin_unlock(&ds->hp_lock); 123 mutex_unlock(&ds->hp_lock);
121} 124}
122 125
123/** 126/**
@@ -131,9 +134,9 @@ static void
131dock_del_hotplug_device(struct dock_station *ds, 134dock_del_hotplug_device(struct dock_station *ds,
132 struct dock_dependent_device *dd) 135 struct dock_dependent_device *dd)
133{ 136{
134 spin_lock(&ds->hp_lock); 137 mutex_lock(&ds->hp_lock);
135 list_del(&dd->hotplug_list); 138 list_del(&dd->hotplug_list);
136 spin_unlock(&ds->hp_lock); 139 mutex_unlock(&ds->hp_lock);
137} 140}
138 141
139/** 142/**
@@ -296,7 +299,7 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
296{ 299{
297 struct dock_dependent_device *dd; 300 struct dock_dependent_device *dd;
298 301
299 spin_lock(&ds->hp_lock); 302 mutex_lock(&ds->hp_lock);
300 303
301 /* 304 /*
302 * First call driver specific hotplug functions 305 * First call driver specific hotplug functions
@@ -318,15 +321,17 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
318 else 321 else
319 dock_create_acpi_device(dd->handle); 322 dock_create_acpi_device(dd->handle);
320 } 323 }
321 spin_unlock(&ds->hp_lock); 324 mutex_unlock(&ds->hp_lock);
322} 325}
323 326
324static void dock_event(struct dock_station *ds, u32 event, int num) 327static void dock_event(struct dock_station *ds, u32 event, int num)
325{ 328{
329 struct device *dev = &dock_device.dev;
326 /* 330 /*
327 * we don't do events until someone tells me that 331 * Indicate that the status of the dock station has
328 * they would like to have them. 332 * changed.
329 */ 333 */
334 kobject_uevent(&dev->kobj, KOBJ_CHANGE);
330} 335}
331 336
332/** 337/**
@@ -441,6 +446,9 @@ static int dock_in_progress(struct dock_station *ds)
441 */ 446 */
442int register_dock_notifier(struct notifier_block *nb) 447int register_dock_notifier(struct notifier_block *nb)
443{ 448{
449 if (!dock_station)
450 return -ENODEV;
451
444 return atomic_notifier_chain_register(&dock_notifier_list, nb); 452 return atomic_notifier_chain_register(&dock_notifier_list, nb);
445} 453}
446 454
@@ -452,6 +460,9 @@ EXPORT_SYMBOL_GPL(register_dock_notifier);
452 */ 460 */
453void unregister_dock_notifier(struct notifier_block *nb) 461void unregister_dock_notifier(struct notifier_block *nb)
454{ 462{
463 if (!dock_station)
464 return;
465
455 atomic_notifier_chain_unregister(&dock_notifier_list, nb); 466 atomic_notifier_chain_unregister(&dock_notifier_list, nb);
456} 467}
457 468
@@ -512,6 +523,37 @@ void unregister_hotplug_dock_device(acpi_handle handle)
512EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); 523EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
513 524
514/** 525/**
526 * handle_eject_request - handle an undock request checking for error conditions
527 *
528 * Check to make sure the dock device is still present, then undock and
529 * hotremove all the devices that may need removing.
530 */
531static int handle_eject_request(struct dock_station *ds, u32 event)
532{
533 if (!dock_present(ds))
534 return -ENODEV;
535
536 if (dock_in_progress(ds))
537 return -EBUSY;
538
539 /*
540 * here we need to generate the undock
541 * event prior to actually doing the undock
542 * so that the device struct still exists.
543 */
544 dock_event(ds, event, UNDOCK_EVENT);
545 hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
546 undock(ds);
547 eject_dock(ds);
548 if (dock_present(ds)) {
549 printk(KERN_ERR PREFIX "Unable to undock!\n");
550 return -EBUSY;
551 }
552
553 return 0;
554}
555
556/**
515 * dock_notify - act upon an acpi dock notification 557 * dock_notify - act upon an acpi dock notification
516 * @handle: the dock station handle 558 * @handle: the dock station handle
517 * @event: the acpi event 559 * @event: the acpi event
@@ -519,13 +561,11 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
519 * 561 *
520 * If we are notified to dock, then check to see if the dock is 562 * If we are notified to dock, then check to see if the dock is
521 * present and then dock. Notify all drivers of the dock event, 563 * present and then dock. Notify all drivers of the dock event,
522 * and then hotplug and devices that may need hotplugging. For undock 564 * and then hotplug and devices that may need hotplugging.
523 * check to make sure the dock device is still present, then undock
524 * and hotremove all the devices that may need removing.
525 */ 565 */
526static void dock_notify(acpi_handle handle, u32 event, void *data) 566static void dock_notify(acpi_handle handle, u32 event, void *data)
527{ 567{
528 struct dock_station *ds = (struct dock_station *)data; 568 struct dock_station *ds = data;
529 569
530 switch (event) { 570 switch (event) {
531 case ACPI_NOTIFY_BUS_CHECK: 571 case ACPI_NOTIFY_BUS_CHECK:
@@ -553,19 +593,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data)
553 * to the driver who wish to hotplug. 593 * to the driver who wish to hotplug.
554 */ 594 */
555 case ACPI_NOTIFY_EJECT_REQUEST: 595 case ACPI_NOTIFY_EJECT_REQUEST:
556 if (!dock_in_progress(ds) && dock_present(ds)) { 596 handle_eject_request(ds, event);
557 /*
558 * here we need to generate the undock
559 * event prior to actually doing the undock
560 * so that the device struct still exists.
561 */
562 dock_event(ds, event, UNDOCK_EVENT);
563 hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST);
564 undock(ds);
565 eject_dock(ds);
566 if (dock_present(ds))
567 printk(KERN_ERR PREFIX "Unable to undock!\n");
568 }
569 break; 597 break;
570 default: 598 default:
571 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); 599 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event);
@@ -588,7 +616,7 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
588{ 616{
589 acpi_status status; 617 acpi_status status;
590 acpi_handle tmp; 618 acpi_handle tmp;
591 struct dock_station *ds = (struct dock_station *)context; 619 struct dock_station *ds = context;
592 struct dock_dependent_device *dd; 620 struct dock_dependent_device *dd;
593 621
594 status = acpi_bus_get_ejd(handle, &tmp); 622 status = acpi_bus_get_ejd(handle, &tmp);
@@ -604,6 +632,33 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
604 return AE_OK; 632 return AE_OK;
605} 633}
606 634
635/*
636 * show_docked - read method for "docked" file in sysfs
637 */
638static ssize_t show_docked(struct device *dev,
639 struct device_attribute *attr, char *buf)
640{
641 return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station));
642
643}
644DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
645
646/*
647 * write_undock - write method for "undock" file in sysfs
648 */
649static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
650 const char *buf, size_t count)
651{
652 int ret;
653
654 if (!count)
655 return -EINVAL;
656
657 ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST);
658 return ret ? ret: count;
659}
660DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock);
661
607/** 662/**
608 * dock_add - add a new dock station 663 * dock_add - add a new dock station
609 * @handle: the dock station handle 664 * @handle: the dock station handle
@@ -626,9 +681,33 @@ static int dock_add(acpi_handle handle)
626 INIT_LIST_HEAD(&dock_station->dependent_devices); 681 INIT_LIST_HEAD(&dock_station->dependent_devices);
627 INIT_LIST_HEAD(&dock_station->hotplug_devices); 682 INIT_LIST_HEAD(&dock_station->hotplug_devices);
628 spin_lock_init(&dock_station->dd_lock); 683 spin_lock_init(&dock_station->dd_lock);
629 spin_lock_init(&dock_station->hp_lock); 684 mutex_init(&dock_station->hp_lock);
630 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 685 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
631 686
687 /* initialize platform device stuff */
688 dock_device.name = dock_device_name;
689 ret = platform_device_register(&dock_device);
690 if (ret) {
691 printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
692 kfree(dock_station);
693 return ret;
694 }
695 ret = device_create_file(&dock_device.dev, &dev_attr_docked);
696 if (ret) {
697 printk("Error %d adding sysfs file\n", ret);
698 platform_device_unregister(&dock_device);
699 kfree(dock_station);
700 return ret;
701 }
702 ret = device_create_file(&dock_device.dev, &dev_attr_undock);
703 if (ret) {
704 printk("Error %d adding sysfs file\n", ret);
705 device_remove_file(&dock_device.dev, &dev_attr_docked);
706 platform_device_unregister(&dock_device);
707 kfree(dock_station);
708 return ret;
709 }
710
632 /* Find dependent devices */ 711 /* Find dependent devices */
633 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 712 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
634 ACPI_UINT32_MAX, find_dock_devices, dock_station, 713 ACPI_UINT32_MAX, find_dock_devices, dock_station,
@@ -638,7 +717,8 @@ static int dock_add(acpi_handle handle)
638 dd = alloc_dock_dependent_device(handle); 717 dd = alloc_dock_dependent_device(handle);
639 if (!dd) { 718 if (!dd) {
640 kfree(dock_station); 719 kfree(dock_station);
641 return -ENOMEM; 720 ret = -ENOMEM;
721 goto dock_add_err_unregister;
642 } 722 }
643 add_dock_dependent_device(dock_station, dd); 723 add_dock_dependent_device(dock_station, dd);
644 724
@@ -658,8 +738,12 @@ static int dock_add(acpi_handle handle)
658 return 0; 738 return 0;
659 739
660dock_add_err: 740dock_add_err:
661 kfree(dock_station);
662 kfree(dd); 741 kfree(dd);
742dock_add_err_unregister:
743 device_remove_file(&dock_device.dev, &dev_attr_docked);
744 device_remove_file(&dock_device.dev, &dev_attr_undock);
745 platform_device_unregister(&dock_device);
746 kfree(dock_station);
663 return ret; 747 return ret;
664} 748}
665 749
@@ -686,6 +770,11 @@ static int dock_remove(void)
686 if (ACPI_FAILURE(status)) 770 if (ACPI_FAILURE(status))
687 printk(KERN_ERR "Error removing notify handler\n"); 771 printk(KERN_ERR "Error removing notify handler\n");
688 772
773 /* cleanup sysfs */
774 device_remove_file(&dock_device.dev, &dev_attr_docked);
775 device_remove_file(&dock_device.dev, &dev_attr_undock);
776 platform_device_unregister(&dock_device);
777
689 /* free dock station memory */ 778 /* free dock station memory */
690 kfree(dock_station); 779 kfree(dock_station);
691 return 0; 780 return 0;
@@ -703,7 +792,7 @@ static int dock_remove(void)
703static acpi_status 792static acpi_status
704find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) 793find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
705{ 794{
706 int *count = (int *)context; 795 int *count = context;
707 acpi_status status = AE_OK; 796 acpi_status status = AE_OK;
708 797
709 if (is_dock(handle)) { 798 if (is_dock(handle)) {
@@ -726,7 +815,7 @@ static int __init dock_init(void)
726 ACPI_UINT32_MAX, find_dock, &num, NULL); 815 ACPI_UINT32_MAX, find_dock, &num, NULL);
727 816
728 if (!num) 817 if (!num)
729 return -ENODEV; 818 printk(KERN_INFO "No dock devices found.\n");
730 819
731 return 0; 820 return 0;
732} 821}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e6d4b084dca2..08c12588af69 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -45,35 +45,34 @@ ACPI_MODULE_NAME("acpi_ec")
45#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" 45#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
46#define ACPI_EC_DEVICE_NAME "Embedded Controller" 46#define ACPI_EC_DEVICE_NAME "Embedded Controller"
47#define ACPI_EC_FILE_INFO "info" 47#define ACPI_EC_FILE_INFO "info"
48 48#undef PREFIX
49#define PREFIX "ACPI: EC: "
49/* EC status register */ 50/* EC status register */
50#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 51#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
51#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 52#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
52#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ 53#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
53#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 54#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
54
55/* EC commands */ 55/* EC commands */
56#define ACPI_EC_COMMAND_READ 0x80 56enum ec_command {
57#define ACPI_EC_COMMAND_WRITE 0x81 57 ACPI_EC_COMMAND_READ = 0x80,
58#define ACPI_EC_BURST_ENABLE 0x82 58 ACPI_EC_COMMAND_WRITE = 0x81,
59#define ACPI_EC_BURST_DISABLE 0x83 59 ACPI_EC_BURST_ENABLE = 0x82,
60#define ACPI_EC_COMMAND_QUERY 0x84 60 ACPI_EC_BURST_DISABLE = 0x83,
61 61 ACPI_EC_COMMAND_QUERY = 0x84,
62};
62/* EC events */ 63/* EC events */
63enum { 64enum ec_event {
64 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ 65 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
65 ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ 66 ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
66}; 67};
67 68
68#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ 69#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
69#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ 70#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
70#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
71#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
72 71
73enum { 72static enum ec_mode {
74 EC_INTR = 1, /* Output buffer full */ 73 EC_INTR = 1, /* Output buffer full */
75 EC_POLL, /* Input buffer empty */ 74 EC_POLL, /* Input buffer empty */
76}; 75} acpi_ec_mode = EC_INTR;
77 76
78static int acpi_ec_remove(struct acpi_device *device, int type); 77static int acpi_ec_remove(struct acpi_device *device, int type);
79static int acpi_ec_start(struct acpi_device *device); 78static int acpi_ec_start(struct acpi_device *device);
@@ -93,22 +92,21 @@ static struct acpi_driver acpi_ec_driver = {
93}; 92};
94 93
95/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 94/* If we find an EC via the ECDT, we need to keep a ptr to its context */
96struct acpi_ec { 95static struct acpi_ec {
97 acpi_handle handle; 96 acpi_handle handle;
98 unsigned long uid; 97 unsigned long uid;
99 unsigned long gpe_bit; 98 unsigned long gpe;
100 unsigned long command_addr; 99 unsigned long command_addr;
101 unsigned long data_addr; 100 unsigned long data_addr;
102 unsigned long global_lock; 101 unsigned long global_lock;
103 struct semaphore sem; 102 struct mutex lock;
104 unsigned int expect_event; 103 atomic_t query_pending;
105 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ 104 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
106 wait_queue_head_t wait; 105 wait_queue_head_t wait;
107} *ec_ecdt; 106} *ec_ecdt;
108 107
109/* External interfaces use first EC only, so remember */ 108/* External interfaces use first EC only, so remember */
110static struct acpi_device *first_ec; 109static struct acpi_device *first_ec;
111static int acpi_ec_mode = EC_INTR;
112 110
113/* -------------------------------------------------------------------------- 111/* --------------------------------------------------------------------------
114 Transaction Management 112 Transaction Management
@@ -134,54 +132,41 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
134 outb(data, ec->data_addr); 132 outb(data, ec->data_addr);
135} 133}
136 134
137static int acpi_ec_check_status(u8 status, u8 event) 135static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
138{ 136{
139 switch (event) { 137 u8 status = acpi_ec_read_status(ec);
140 case ACPI_EC_EVENT_OBF_1: 138
139 if (event == ACPI_EC_EVENT_OBF_1) {
141 if (status & ACPI_EC_FLAG_OBF) 140 if (status & ACPI_EC_FLAG_OBF)
142 return 1; 141 return 1;
143 break; 142 } else if (event == ACPI_EC_EVENT_IBF_0) {
144 case ACPI_EC_EVENT_IBF_0:
145 if (!(status & ACPI_EC_FLAG_IBF)) 143 if (!(status & ACPI_EC_FLAG_IBF))
146 return 1; 144 return 1;
147 break;
148 default:
149 break;
150 } 145 }
151 146
152 return 0; 147 return 0;
153} 148}
154 149
155static int acpi_ec_wait(struct acpi_ec *ec, u8 event) 150static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event)
156{ 151{
157 int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; 152 if (acpi_ec_mode == EC_POLL) {
158 long time_left; 153 unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
159 154 while (time_before(jiffies, delay)) {
160 ec->expect_event = event; 155 if (acpi_ec_check_status(ec, event))
161 if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
162 ec->expect_event = 0;
163 return 0;
164 }
165
166 do {
167 if (acpi_ec_mode == EC_POLL) {
168 udelay(ACPI_EC_UDELAY);
169 } else {
170 time_left = wait_event_timeout(ec->wait,
171 !ec->expect_event,
172 msecs_to_jiffies(ACPI_EC_DELAY));
173 if (time_left > 0) {
174 ec->expect_event = 0;
175 return 0; 156 return 0;
176 }
177 } 157 }
178 if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { 158 } else {
179 ec->expect_event = 0; 159 if (wait_event_timeout(ec->wait,
160 acpi_ec_check_status(ec, event),
161 msecs_to_jiffies(ACPI_EC_DELAY)) ||
162 acpi_ec_check_status(ec, event)) {
180 return 0; 163 return 0;
164 } else {
165 printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
166 " status = %d, expect_event = %d\n",
167 acpi_ec_read_status(ec), event);
181 } 168 }
182 } while (--i > 0); 169 }
183
184 ec->expect_event = 0;
185 170
186 return -ETIME; 171 return -ETIME;
187} 172}
@@ -196,7 +181,6 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
196 u8 tmp = 0; 181 u8 tmp = 0;
197 u8 status = 0; 182 u8 status = 0;
198 183
199
200 status = acpi_ec_read_status(ec); 184 status = acpi_ec_read_status(ec);
201 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { 185 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
202 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); 186 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
@@ -212,7 +196,7 @@ int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
212 196
213 atomic_set(&ec->leaving_burst, 0); 197 atomic_set(&ec->leaving_burst, 0);
214 return 0; 198 return 0;
215 end: 199 end:
216 ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); 200 ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
217 return -1; 201 return -1;
218} 202}
@@ -221,58 +205,68 @@ int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
221{ 205{
222 u8 status = 0; 206 u8 status = 0;
223 207
224
225 status = acpi_ec_read_status(ec); 208 status = acpi_ec_read_status(ec);
226 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ 209 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)) {
227 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); 210 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
228 if(status) 211 if (status)
229 goto end; 212 goto end;
230 acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); 213 acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
231 acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); 214 acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
232 } 215 }
233 atomic_set(&ec->leaving_burst, 1); 216 atomic_set(&ec->leaving_burst, 1);
234 return 0; 217 return 0;
235 end: 218 end:
236 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); 219 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
237 return -1; 220 return -1;
238} 221}
239#endif /* ACPI_FUTURE_USAGE */ 222#endif /* ACPI_FUTURE_USAGE */
240 223
241static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, 224static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
242 const u8 *wdata, unsigned wdata_len, 225 const u8 * wdata, unsigned wdata_len,
243 u8 *rdata, unsigned rdata_len) 226 u8 * rdata, unsigned rdata_len)
244{ 227{
245 int result; 228 int result = 0;
246 229
247 acpi_ec_write_cmd(ec, command); 230 acpi_ec_write_cmd(ec, command);
248 231
249 for (; wdata_len > 0; wdata_len --) { 232 for (; wdata_len > 0; --wdata_len) {
250 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); 233 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
251 if (result) 234 if (result) {
252 return result; 235 printk(KERN_ERR PREFIX
236 "write_cmd timeout, command = %d\n", command);
237 goto end;
238 }
253 acpi_ec_write_data(ec, *(wdata++)); 239 acpi_ec_write_data(ec, *(wdata++));
254 } 240 }
255 241
256 if (command == ACPI_EC_COMMAND_WRITE) { 242 if (!rdata_len) {
257 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); 243 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
258 if (result) 244 if (result) {
259 return result; 245 printk(KERN_ERR PREFIX
246 "finish-write timeout, command = %d\n", command);
247 goto end;
248 }
249 } else if (command == ACPI_EC_COMMAND_QUERY) {
250 atomic_set(&ec->query_pending, 0);
260 } 251 }
261 252
262 for (; rdata_len > 0; rdata_len --) { 253 for (; rdata_len > 0; --rdata_len) {
263 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); 254 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
264 if (result) 255 if (result) {
265 return result; 256 printk(KERN_ERR PREFIX "read timeout, command = %d\n",
257 command);
258 goto end;
259 }
266 260
267 *(rdata++) = acpi_ec_read_data(ec); 261 *(rdata++) = acpi_ec_read_data(ec);
268 } 262 }
269 263 end:
270 return 0; 264 return result;
271} 265}
272 266
273static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, 267static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
274 const u8 *wdata, unsigned wdata_len, 268 const u8 * wdata, unsigned wdata_len,
275 u8 *rdata, unsigned rdata_len) 269 u8 * rdata, unsigned rdata_len)
276{ 270{
277 int status; 271 int status;
278 u32 glk; 272 u32 glk;
@@ -280,36 +274,40 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
280 if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) 274 if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
281 return -EINVAL; 275 return -EINVAL;
282 276
283 if (rdata) 277 if (rdata)
284 memset(rdata, 0, rdata_len); 278 memset(rdata, 0, rdata_len);
285 279
280 mutex_lock(&ec->lock);
286 if (ec->global_lock) { 281 if (ec->global_lock) {
287 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 282 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
288 if (ACPI_FAILURE(status)) 283 if (ACPI_FAILURE(status))
289 return -ENODEV; 284 return -ENODEV;
290 } 285 }
291 down(&ec->sem); 286
287 /* Make sure GPE is enabled before doing transaction */
288 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
292 289
293 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); 290 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
294 if (status) { 291 if (status) {
295 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); 292 printk(KERN_DEBUG PREFIX
293 "input buffer is not empty, aborting transaction\n");
296 goto end; 294 goto end;
297 } 295 }
298 296
299 status = acpi_ec_transaction_unlocked(ec, command, 297 status = acpi_ec_transaction_unlocked(ec, command,
300 wdata, wdata_len, 298 wdata, wdata_len,
301 rdata, rdata_len); 299 rdata, rdata_len);
302 300
303end: 301 end:
304 up(&ec->sem);
305 302
306 if (ec->global_lock) 303 if (ec->global_lock)
307 acpi_release_global_lock(glk); 304 acpi_release_global_lock(glk);
305 mutex_unlock(&ec->lock);
308 306
309 return status; 307 return status;
310} 308}
311 309
312static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) 310static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data)
313{ 311{
314 int result; 312 int result;
315 u8 d; 313 u8 d;
@@ -322,15 +320,15 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
322 320
323static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) 321static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
324{ 322{
325 u8 wdata[2] = { address, data }; 323 u8 wdata[2] = { address, data };
326 return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, 324 return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
327 wdata, 2, NULL, 0); 325 wdata, 2, NULL, 0);
328} 326}
329 327
330/* 328/*
331 * Externally callable EC access functions. For now, assume 1 EC only 329 * Externally callable EC access functions. For now, assume 1 EC only
332 */ 330 */
333int ec_read(u8 addr, u8 *val) 331int ec_read(u8 addr, u8 * val)
334{ 332{
335 struct acpi_ec *ec; 333 struct acpi_ec *ec;
336 int err; 334 int err;
@@ -369,9 +367,9 @@ int ec_write(u8 addr, u8 val)
369 367
370EXPORT_SYMBOL(ec_write); 368EXPORT_SYMBOL(ec_write);
371 369
372extern int ec_transaction(u8 command, 370int ec_transaction(u8 command,
373 const u8 *wdata, unsigned wdata_len, 371 const u8 * wdata, unsigned wdata_len,
374 u8 *rdata, unsigned rdata_len) 372 u8 * rdata, unsigned rdata_len)
375{ 373{
376 struct acpi_ec *ec; 374 struct acpi_ec *ec;
377 375
@@ -386,65 +384,49 @@ extern int ec_transaction(u8 command,
386 384
387EXPORT_SYMBOL(ec_transaction); 385EXPORT_SYMBOL(ec_transaction);
388 386
389static int acpi_ec_query(struct acpi_ec *ec, u8 *data) 387static int acpi_ec_query(struct acpi_ec *ec, u8 * data)
390{ 388{
391 int result; 389 int result;
392 u8 d; 390 u8 d;
393 391
394 if (!ec || !data) 392 if (!ec || !data)
395 return -EINVAL; 393 return -EINVAL;
396 394
397 /* 395 /*
398 * Query the EC to find out which _Qxx method we need to evaluate. 396 * Query the EC to find out which _Qxx method we need to evaluate.
399 * Note that successful completion of the query causes the ACPI_EC_SCI 397 * Note that successful completion of the query causes the ACPI_EC_SCI
400 * bit to be cleared (and thus clearing the interrupt source). 398 * bit to be cleared (and thus clearing the interrupt source).
401 */ 399 */
402 400
403 result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); 401 result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
404 if (result) 402 if (result)
405 return result; 403 return result;
406 404
407 if (!d) 405 if (!d)
408 return -ENODATA; 406 return -ENODATA;
409 407
410 *data = d; 408 *data = d;
411 return 0; 409 return 0;
412} 410}
413 411
414/* -------------------------------------------------------------------------- 412/* --------------------------------------------------------------------------
415 Event Management 413 Event Management
416 -------------------------------------------------------------------------- */ 414 -------------------------------------------------------------------------- */
417 415
418struct acpi_ec_query_data {
419 acpi_handle handle;
420 u8 data;
421};
422
423static void acpi_ec_gpe_query(void *ec_cxt) 416static void acpi_ec_gpe_query(void *ec_cxt)
424{ 417{
425 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; 418 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
426 u8 value = 0; 419 u8 value = 0;
427 static char object_name[8]; 420 char object_name[8];
428 421
429 if (!ec) 422 if (!ec || acpi_ec_query(ec, &value))
430 goto end; 423 return;
431
432 value = acpi_ec_read_status(ec);
433
434 if (!(value & ACPI_EC_FLAG_SCI))
435 goto end;
436
437 if (acpi_ec_query(ec, &value))
438 goto end;
439 424
440 snprintf(object_name, 8, "_Q%2.2X", value); 425 snprintf(object_name, 8, "_Q%2.2X", value);
441 426
442 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); 427 printk(KERN_INFO PREFIX "evaluating %s\n", object_name);
443 428
444 acpi_evaluate_object(ec->handle, object_name, NULL, NULL); 429 acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
445
446 end:
447 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
448} 430}
449 431
450static u32 acpi_ec_gpe_handler(void *data) 432static u32 acpi_ec_gpe_handler(void *data)
@@ -453,22 +435,18 @@ static u32 acpi_ec_gpe_handler(void *data)
453 u8 value; 435 u8 value;
454 struct acpi_ec *ec = (struct acpi_ec *)data; 436 struct acpi_ec *ec = (struct acpi_ec *)data;
455 437
456 acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
457 value = acpi_ec_read_status(ec);
458
459 if (acpi_ec_mode == EC_INTR) { 438 if (acpi_ec_mode == EC_INTR) {
460 if (acpi_ec_check_status(value, ec->expect_event)) { 439 wake_up(&ec->wait);
461 ec->expect_event = 0;
462 wake_up(&ec->wait);
463 }
464 } 440 }
465 441
466 if (value & ACPI_EC_FLAG_SCI) { 442 value = acpi_ec_read_status(ec);
467 status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); 443 if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
468 return status == AE_OK ? 444 atomic_set(&ec->query_pending, 1);
469 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 445 status =
446 acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query,
447 ec);
470 } 448 }
471 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); 449
472 return status == AE_OK ? 450 return status == AE_OK ?
473 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 451 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
474} 452}
@@ -504,7 +482,6 @@ acpi_ec_space_handler(u32 function,
504 acpi_integer f_v = 0; 482 acpi_integer f_v = 0;
505 int i = 0; 483 int i = 0;
506 484
507
508 if ((address > 0xFF) || !value || !handler_context) 485 if ((address > 0xFF) || !value || !handler_context)
509 return AE_BAD_PARAMETER; 486 return AE_BAD_PARAMETER;
510 487
@@ -518,7 +495,7 @@ acpi_ec_space_handler(u32 function,
518 switch (function) { 495 switch (function) {
519 case ACPI_READ: 496 case ACPI_READ:
520 temp = 0; 497 temp = 0;
521 result = acpi_ec_read(ec, (u8) address, (u8 *) &temp); 498 result = acpi_ec_read(ec, (u8) address, (u8 *) & temp);
522 break; 499 break;
523 case ACPI_WRITE: 500 case ACPI_WRITE:
524 result = acpi_ec_write(ec, (u8) address, (u8) temp); 501 result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -571,18 +548,15 @@ static int acpi_ec_read_info(struct seq_file *seq, void *offset)
571{ 548{
572 struct acpi_ec *ec = (struct acpi_ec *)seq->private; 549 struct acpi_ec *ec = (struct acpi_ec *)seq->private;
573 550
574
575 if (!ec) 551 if (!ec)
576 goto end; 552 goto end;
577 553
578 seq_printf(seq, "gpe bit: 0x%02x\n", 554 seq_printf(seq, "gpe: 0x%02x\n", (u32) ec->gpe);
579 (u32) ec->gpe_bit);
580 seq_printf(seq, "ports: 0x%02x, 0x%02x\n", 555 seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
581 (u32) ec->command_addr, 556 (u32) ec->command_addr, (u32) ec->data_addr);
582 (u32) ec->data_addr);
583 seq_printf(seq, "use global lock: %s\n", 557 seq_printf(seq, "use global lock: %s\n",
584 ec->global_lock ? "yes" : "no"); 558 ec->global_lock ? "yes" : "no");
585 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); 559 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
586 560
587 end: 561 end:
588 return 0; 562 return 0;
@@ -605,7 +579,6 @@ static int acpi_ec_add_fs(struct acpi_device *device)
605{ 579{
606 struct proc_dir_entry *entry = NULL; 580 struct proc_dir_entry *entry = NULL;
607 581
608
609 if (!acpi_device_dir(device)) { 582 if (!acpi_device_dir(device)) {
610 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 583 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
611 acpi_ec_dir); 584 acpi_ec_dir);
@@ -648,7 +621,6 @@ static int acpi_ec_add(struct acpi_device *device)
648 acpi_status status = AE_OK; 621 acpi_status status = AE_OK;
649 struct acpi_ec *ec = NULL; 622 struct acpi_ec *ec = NULL;
650 623
651
652 if (!device) 624 if (!device)
653 return -EINVAL; 625 return -EINVAL;
654 626
@@ -659,7 +631,8 @@ static int acpi_ec_add(struct acpi_device *device)
659 631
660 ec->handle = device->handle; 632 ec->handle = device->handle;
661 ec->uid = -1; 633 ec->uid = -1;
662 init_MUTEX(&ec->sem); 634 mutex_init(&ec->lock);
635 atomic_set(&ec->query_pending, 0);
663 if (acpi_ec_mode == EC_INTR) { 636 if (acpi_ec_mode == EC_INTR) {
664 atomic_set(&ec->leaving_burst, 1); 637 atomic_set(&ec->leaving_burst, 1);
665 init_waitqueue_head(&ec->wait); 638 init_waitqueue_head(&ec->wait);
@@ -669,8 +642,7 @@ static int acpi_ec_add(struct acpi_device *device)
669 acpi_driver_data(device) = ec; 642 acpi_driver_data(device) = ec;
670 643
671 /* Use the global lock for all EC transactions? */ 644 /* Use the global lock for all EC transactions? */
672 acpi_evaluate_integer(ec->handle, "_GLK", NULL, 645 acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock);
673 &ec->global_lock);
674 646
675 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: 647 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
676 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ 648 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -679,7 +651,7 @@ static int acpi_ec_add(struct acpi_device *device)
679 ACPI_ADR_SPACE_EC, 651 ACPI_ADR_SPACE_EC,
680 &acpi_ec_space_handler); 652 &acpi_ec_space_handler);
681 653
682 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, 654 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
683 &acpi_ec_gpe_handler); 655 &acpi_ec_gpe_handler);
684 656
685 kfree(ec_ecdt); 657 kfree(ec_ecdt);
@@ -687,11 +659,10 @@ static int acpi_ec_add(struct acpi_device *device)
687 659
688 /* Get GPE bit assignment (EC events). */ 660 /* Get GPE bit assignment (EC events). */
689 /* TODO: Add support for _GPE returning a package */ 661 /* TODO: Add support for _GPE returning a package */
690 status = 662 status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe);
691 acpi_evaluate_integer(ec->handle, "_GPE", NULL,
692 &ec->gpe_bit);
693 if (ACPI_FAILURE(status)) { 663 if (ACPI_FAILURE(status)) {
694 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); 664 ACPI_EXCEPTION((AE_INFO, status,
665 "Obtaining GPE bit assignment"));
695 result = -ENODEV; 666 result = -ENODEV;
696 goto end; 667 goto end;
697 } 668 }
@@ -701,13 +672,13 @@ static int acpi_ec_add(struct acpi_device *device)
701 goto end; 672 goto end;
702 673
703 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", 674 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
704 acpi_device_name(device), acpi_device_bid(device), 675 acpi_device_name(device), acpi_device_bid(device),
705 (u32) ec->gpe_bit)); 676 (u32) ec->gpe));
706 677
707 if (!first_ec) 678 if (!first_ec)
708 first_ec = device; 679 first_ec = device;
709 680
710 end: 681 end:
711 if (result) 682 if (result)
712 kfree(ec); 683 kfree(ec);
713 684
@@ -718,7 +689,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
718{ 689{
719 struct acpi_ec *ec = NULL; 690 struct acpi_ec *ec = NULL;
720 691
721
722 if (!device) 692 if (!device)
723 return -EINVAL; 693 return -EINVAL;
724 694
@@ -761,7 +731,6 @@ static int acpi_ec_start(struct acpi_device *device)
761 acpi_status status = AE_OK; 731 acpi_status status = AE_OK;
762 struct acpi_ec *ec = NULL; 732 struct acpi_ec *ec = NULL;
763 733
764
765 if (!device) 734 if (!device)
766 return -EINVAL; 735 return -EINVAL;
767 736
@@ -782,27 +751,26 @@ static int acpi_ec_start(struct acpi_device *device)
782 } 751 }
783 752
784 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", 753 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
785 ec->gpe_bit, ec->command_addr, ec->data_addr)); 754 ec->gpe, ec->command_addr, ec->data_addr));
786 755
787 /* 756 /*
788 * Install GPE handler 757 * Install GPE handler
789 */ 758 */
790 status = acpi_install_gpe_handler(NULL, ec->gpe_bit, 759 status = acpi_install_gpe_handler(NULL, ec->gpe,
791 ACPI_GPE_EDGE_TRIGGERED, 760 ACPI_GPE_EDGE_TRIGGERED,
792 &acpi_ec_gpe_handler, ec); 761 &acpi_ec_gpe_handler, ec);
793 if (ACPI_FAILURE(status)) { 762 if (ACPI_FAILURE(status)) {
794 return -ENODEV; 763 return -ENODEV;
795 } 764 }
796 acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); 765 acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
797 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); 766 acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
798 767
799 status = acpi_install_address_space_handler(ec->handle, 768 status = acpi_install_address_space_handler(ec->handle,
800 ACPI_ADR_SPACE_EC, 769 ACPI_ADR_SPACE_EC,
801 &acpi_ec_space_handler, 770 &acpi_ec_space_handler,
802 &acpi_ec_space_setup, ec); 771 &acpi_ec_space_setup, ec);
803 if (ACPI_FAILURE(status)) { 772 if (ACPI_FAILURE(status)) {
804 acpi_remove_gpe_handler(NULL, ec->gpe_bit, 773 acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
805 &acpi_ec_gpe_handler);
806 return -ENODEV; 774 return -ENODEV;
807 } 775 }
808 776
@@ -814,7 +782,6 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
814 acpi_status status = AE_OK; 782 acpi_status status = AE_OK;
815 struct acpi_ec *ec = NULL; 783 struct acpi_ec *ec = NULL;
816 784
817
818 if (!device) 785 if (!device)
819 return -EINVAL; 786 return -EINVAL;
820 787
@@ -826,9 +793,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
826 if (ACPI_FAILURE(status)) 793 if (ACPI_FAILURE(status))
827 return -ENODEV; 794 return -ENODEV;
828 795
829 status = 796 status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
830 acpi_remove_gpe_handler(NULL, ec->gpe_bit,
831 &acpi_ec_gpe_handler);
832 if (ACPI_FAILURE(status)) 797 if (ACPI_FAILURE(status))
833 return -ENODEV; 798 return -ENODEV;
834 799
@@ -841,7 +806,7 @@ acpi_fake_ecdt_callback(acpi_handle handle,
841{ 806{
842 acpi_status status; 807 acpi_status status;
843 808
844 init_MUTEX(&ec_ecdt->sem); 809 mutex_init(&ec_ecdt->lock);
845 if (acpi_ec_mode == EC_INTR) { 810 if (acpi_ec_mode == EC_INTR) {
846 init_waitqueue_head(&ec_ecdt->wait); 811 init_waitqueue_head(&ec_ecdt->wait);
847 } 812 }
@@ -853,16 +818,15 @@ acpi_fake_ecdt_callback(acpi_handle handle,
853 ec_ecdt->uid = -1; 818 ec_ecdt->uid = -1;
854 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); 819 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
855 820
856 status = 821 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe);
857 acpi_evaluate_integer(handle, "_GPE", NULL,
858 &ec_ecdt->gpe_bit);
859 if (ACPI_FAILURE(status)) 822 if (ACPI_FAILURE(status))
860 return status; 823 return status;
861 ec_ecdt->global_lock = TRUE; 824 ec_ecdt->global_lock = TRUE;
862 ec_ecdt->handle = handle; 825 ec_ecdt->handle = handle;
863 826
864 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", 827 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
865 ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr)); 828 ec_ecdt->gpe, ec_ecdt->command_addr,
829 ec_ecdt->data_addr));
866 830
867 return AE_CTRL_TERMINATE; 831 return AE_CTRL_TERMINATE;
868} 832}
@@ -901,7 +865,7 @@ static int __init acpi_ec_fake_ecdt(void)
901 goto error; 865 goto error;
902 } 866 }
903 return 0; 867 return 0;
904 error: 868 error:
905 return ret; 869 return ret;
906} 870}
907 871
@@ -926,25 +890,24 @@ static int __init acpi_ec_get_real_ecdt(void)
926 return -ENOMEM; 890 return -ENOMEM;
927 memset(ec_ecdt, 0, sizeof(struct acpi_ec)); 891 memset(ec_ecdt, 0, sizeof(struct acpi_ec));
928 892
929 init_MUTEX(&ec_ecdt->sem); 893 mutex_init(&ec_ecdt->lock);
930 if (acpi_ec_mode == EC_INTR) { 894 if (acpi_ec_mode == EC_INTR) {
931 init_waitqueue_head(&ec_ecdt->wait); 895 init_waitqueue_head(&ec_ecdt->wait);
932 } 896 }
933 ec_ecdt->command_addr = ecdt_ptr->ec_control.address; 897 ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
934 ec_ecdt->data_addr = ecdt_ptr->ec_data.address; 898 ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
935 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; 899 ec_ecdt->gpe = ecdt_ptr->gpe_bit;
936 /* use the GL just to be safe */ 900 /* use the GL just to be safe */
937 ec_ecdt->global_lock = TRUE; 901 ec_ecdt->global_lock = TRUE;
938 ec_ecdt->uid = ecdt_ptr->uid; 902 ec_ecdt->uid = ecdt_ptr->uid;
939 903
940 status = 904 status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
941 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
942 if (ACPI_FAILURE(status)) { 905 if (ACPI_FAILURE(status)) {
943 goto error; 906 goto error;
944 } 907 }
945 908
946 return 0; 909 return 0;
947 error: 910 error:
948 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); 911 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
949 kfree(ec_ecdt); 912 kfree(ec_ecdt);
950 ec_ecdt = NULL; 913 ec_ecdt = NULL;
@@ -970,14 +933,14 @@ int __init acpi_ec_ecdt_probe(void)
970 /* 933 /*
971 * Install GPE handler 934 * Install GPE handler
972 */ 935 */
973 status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, 936 status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe,
974 ACPI_GPE_EDGE_TRIGGERED, 937 ACPI_GPE_EDGE_TRIGGERED,
975 &acpi_ec_gpe_handler, ec_ecdt); 938 &acpi_ec_gpe_handler, ec_ecdt);
976 if (ACPI_FAILURE(status)) { 939 if (ACPI_FAILURE(status)) {
977 goto error; 940 goto error;
978 } 941 }
979 acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); 942 acpi_set_gpe_type(NULL, ec_ecdt->gpe, ACPI_GPE_TYPE_RUNTIME);
980 acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); 943 acpi_enable_gpe(NULL, ec_ecdt->gpe, ACPI_NOT_ISR);
981 944
982 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, 945 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
983 ACPI_ADR_SPACE_EC, 946 ACPI_ADR_SPACE_EC,
@@ -985,7 +948,7 @@ int __init acpi_ec_ecdt_probe(void)
985 &acpi_ec_space_setup, 948 &acpi_ec_space_setup,
986 ec_ecdt); 949 ec_ecdt);
987 if (ACPI_FAILURE(status)) { 950 if (ACPI_FAILURE(status)) {
988 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, 951 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe,
989 &acpi_ec_gpe_handler); 952 &acpi_ec_gpe_handler);
990 goto error; 953 goto error;
991 } 954 }
@@ -1004,7 +967,6 @@ static int __init acpi_ec_init(void)
1004{ 967{
1005 int result = 0; 968 int result = 0;
1006 969
1007
1008 if (acpi_disabled) 970 if (acpi_disabled)
1009 return 0; 971 return 0;
1010 972
@@ -1057,7 +1019,8 @@ static int __init acpi_ec_set_intr_mode(char *str)
1057 acpi_ec_mode = EC_POLL; 1019 acpi_ec_mode = EC_POLL;
1058 } 1020 }
1059 acpi_ec_driver.ops.add = acpi_ec_add; 1021 acpi_ec_driver.ops.add = acpi_ec_add;
1060 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling")); 1022 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n",
1023 intr ? "interrupt" : "polling"));
1061 1024
1062 return 1; 1025 return 1;
1063} 1026}
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index ee2a10bf9077..bf63edc6608d 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -331,7 +331,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context)
331static u32 acpi_ev_global_lock_handler(void *context) 331static u32 acpi_ev_global_lock_handler(void *context)
332{ 332{
333 u8 acquired = FALSE; 333 u8 acquired = FALSE;
334 acpi_status status;
335 334
336 /* 335 /*
337 * Attempt to get the lock 336 * Attempt to get the lock
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 3a39c2e8e104..bf90f04f2c60 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -266,10 +266,10 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
266 walk_state->thread->thread_id) 266 walk_state->thread->thread_id)
267 && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { 267 && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) {
268 ACPI_ERROR((AE_INFO, 268 ACPI_ERROR((AE_INFO,
269 "Thread %X cannot release Mutex [%4.4s] acquired by thread %X", 269 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
270 (u32) walk_state->thread->thread_id, 270 (unsigned long)walk_state->thread->thread_id,
271 acpi_ut_get_node_name(obj_desc->mutex.node), 271 acpi_ut_get_node_name(obj_desc->mutex.node),
272 (u32) obj_desc->mutex.owner_thread->thread_id)); 272 (unsigned long)obj_desc->mutex.owner_thread->thread_id));
273 return_ACPI_STATUS(AE_AML_NOT_OWNER); 273 return_ACPI_STATUS(AE_AML_NOT_OWNER);
274 } 274 }
275 275
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 045c89477e59..c413e69fea8e 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -99,8 +99,8 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
99 size_t count, loff_t * ppos) 99 size_t count, loff_t * ppos)
100{ 100{
101 int result = 0; 101 int result = 0;
102 struct seq_file *m = (struct seq_file *)file->private_data; 102 struct seq_file *m = file->private_data;
103 struct acpi_fan *fan = (struct acpi_fan *)m->private; 103 struct acpi_fan *fan = m->private;
104 char state_string[12] = { '\0' }; 104 char state_string[12] = { '\0' };
105 105
106 106
@@ -229,7 +229,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
229 if (!device || !acpi_driver_data(device)) 229 if (!device || !acpi_driver_data(device))
230 return -EINVAL; 230 return -EINVAL;
231 231
232 fan = (struct acpi_fan *)acpi_driver_data(device); 232 fan = acpi_driver_data(device);
233 233
234 acpi_fan_remove_fs(device); 234 acpi_fan_remove_fs(device);
235 235
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index a2f46d587d55..8a0324b43e53 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -96,7 +96,7 @@ struct acpi_find_pci_root {
96static acpi_status 96static acpi_status
97do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 97do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
98{ 98{
99 unsigned long *busnr = (unsigned long *)data; 99 unsigned long *busnr = data;
100 struct acpi_resource_address64 address; 100 struct acpi_resource_address64 address;
101 101
102 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && 102 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -189,8 +189,12 @@ find_pci_rootbridge(acpi_handle handle, u32 lvl, void *context, void **rv)
189 bus = tmp; 189 bus = tmp;
190 190
191 if (seg == find->seg && bus == find->bus) 191 if (seg == find->seg && bus == find->bus)
192 {
192 find->handle = handle; 193 find->handle = handle;
193 status = AE_OK; 194 status = AE_CTRL_TERMINATE;
195 }
196 else
197 status = AE_OK;
194 exit: 198 exit:
195 kfree(buffer.pointer); 199 kfree(buffer.pointer);
196 return status; 200 return status;
@@ -217,7 +221,7 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
217 acpi_status status; 221 acpi_status status;
218 struct acpi_device_info *info; 222 struct acpi_device_info *info;
219 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 223 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
220 struct acpi_find_child *find = (struct acpi_find_child *)context; 224 struct acpi_find_child *find = context;
221 225
222 status = acpi_get_object_info(handle, &buffer); 226 status = acpi_get_object_info(handle, &buffer);
223 if (ACPI_SUCCESS(status)) { 227 if (ACPI_SUCCESS(status)) {
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
index 1ba2db671865..8edfb92f7ede 100644
--- a/drivers/acpi/hotkey.c
+++ b/drivers/acpi/hotkey.c
@@ -265,8 +265,7 @@ static char *format_result(union acpi_object *object)
265 265
266static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) 266static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
267{ 267{
268 struct acpi_polling_hotkey *poll_hotkey = 268 struct acpi_polling_hotkey *poll_hotkey = seq->private;
269 (struct acpi_polling_hotkey *)seq->private;
270 char *buf; 269 char *buf;
271 270
272 271
@@ -577,7 +576,7 @@ init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
577 if (ACPI_FAILURE(status)) 576 if (ACPI_FAILURE(status))
578 goto do_fail_zero; 577 goto do_fail_zero;
579 key->poll_hotkey.poll_result = 578 key->poll_hotkey.poll_result =
580 (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); 579 kmalloc(sizeof(union acpi_object), GFP_KERNEL);
581 if (!key->poll_hotkey.poll_result) 580 if (!key->poll_hotkey.poll_result)
582 goto do_fail_zero; 581 goto do_fail_zero;
583 return AE_OK; 582 return AE_OK;
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
index 6342e612c203..82e3e64483fb 100644
--- a/drivers/acpi/i2c_ec.c
+++ b/drivers/acpi/i2c_ec.c
@@ -393,7 +393,7 @@ static void __exit acpi_ec_hc_exit(void)
393 393
394struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device) 394struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device)
395{ 395{
396 return ((struct acpi_ec_hc *)acpi_driver_data(device->parent)); 396 return acpi_driver_data(device->parent);
397} 397}
398 398
399EXPORT_SYMBOL(acpi_get_ec_hc); 399EXPORT_SYMBOL(acpi_get_ec_hc);
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 003a9876c968..130cc8c37e22 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * 4 *
5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net> 5 * Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
6 * Copyright (C) 2006 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -19,10 +20,14 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 21 */
21 22
22#define IBM_VERSION "0.12a" 23#define IBM_VERSION "0.13"
23 24
24/* 25/*
25 * Changelog: 26 * Changelog:
27 *
28 * 2006-11-22 0.13 new maintainer
29 * changelog now lives in git commit history, and will
30 * not be updated further in-file.
26 * 31 *
27 * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels 32 * 2005-08-17 0.12 fix compilation on 2.6.13-rc kernels
28 * 2005-03-17 0.11 support for 600e, 770x 33 * 2005-03-17 0.11 support for 600e, 770x
@@ -77,9 +82,16 @@
77#include <linux/module.h> 82#include <linux/module.h>
78#include <linux/init.h> 83#include <linux/init.h>
79#include <linux/types.h> 84#include <linux/types.h>
85#include <linux/string.h>
86
80#include <linux/proc_fs.h> 87#include <linux/proc_fs.h>
88#include <linux/backlight.h>
81#include <asm/uaccess.h> 89#include <asm/uaccess.h>
82 90
91#include <linux/dmi.h>
92#include <linux/jiffies.h>
93#include <linux/workqueue.h>
94
83#include <acpi/acpi_drivers.h> 95#include <acpi/acpi_drivers.h>
84#include <acpi/acnamesp.h> 96#include <acpi/acnamesp.h>
85 97
@@ -88,7 +100,7 @@
88#define IBM_FILE "ibm_acpi" 100#define IBM_FILE "ibm_acpi"
89#define IBM_URL "http://ibm-acpi.sf.net/" 101#define IBM_URL "http://ibm-acpi.sf.net/"
90 102
91MODULE_AUTHOR("Borislav Deianov"); 103MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh");
92MODULE_DESCRIPTION(IBM_DESC); 104MODULE_DESCRIPTION(IBM_DESC);
93MODULE_VERSION(IBM_VERSION); 105MODULE_VERSION(IBM_VERSION);
94MODULE_LICENSE("GPL"); 106MODULE_LICENSE("GPL");
@@ -116,28 +128,6 @@ static acpi_handle root_handle = NULL;
116 static char *object##_path; \ 128 static char *object##_path; \
117 static char *object##_paths[] = { paths } 129 static char *object##_paths[] = { paths }
118 130
119/*
120 * The following models are supported to various degrees:
121 *
122 * 570, 600e, 600x, 770e, 770x
123 * A20m, A21e, A21m, A21p, A22p, A30, A30p, A31, A31p
124 * G40, G41
125 * R30, R31, R32, R40, R40e, R50, R50e, R50p, R51
126 * T20, T21, T22, T23, T30, T40, T40p, T41, T41p, T42, T42p, T43
127 * X20, X21, X22, X23, X24, X30, X31, X40
128 *
129 * The following models have no supported features:
130 *
131 * 240, 240x, i1400
132 *
133 * Still missing DSDTs for the following models:
134 *
135 * A20p, A22e, A22m
136 * R52
137 * S31
138 * T43p
139 */
140
141IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */ 131IBM_HANDLE(ec, root, "\\_SB.PCI0.ISA.EC0", /* 240, 240x */
142 "\\_SB.PCI.ISA.EC", /* 570 */ 132 "\\_SB.PCI.ISA.EC", /* 570 */
143 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */ 133 "\\_SB.PCI0.ISA0.EC0", /* 600e/x, 770e, 770x */
@@ -167,8 +157,10 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
167 "\\_SB.PCI.ISA.SLCE", /* 570 */ 157 "\\_SB.PCI.ISA.SLCE", /* 570 */
168 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */ 158 ); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
169#endif 159#endif
160#ifdef CONFIG_ACPI_IBM_BAY
170IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */ 161IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
171 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */ 162 "\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
163 "\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
172 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */ 164 "\\_SB.PCI0.IDE0.SCND.MSTR", /* all others */
173 ); /* A21e, R30, R31 */ 165 ); /* A21e, R30, R31 */
174 166
@@ -183,6 +175,7 @@ IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
183IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */ 175IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
184 "_EJ0", /* 770x */ 176 "_EJ0", /* 770x */
185 ); /* all others */ 177 ); /* all others */
178#endif
186 179
187/* don't list other alternatives as we install a notify handler on the 570 */ 180/* don't list other alternatives as we install a notify handler on the 570 */
188IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */ 181IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
@@ -203,7 +196,7 @@ IBM_HANDLE(led, ec, "SLED", /* 570 */
203IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */ 196IBM_HANDLE(beep, ec, "BEEP"); /* all except R30, R31 */
204IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */ 197IBM_HANDLE(ecrd, ec, "ECRD"); /* 570 */
205IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */ 198IBM_HANDLE(ecwr, ec, "ECWR"); /* 570 */
206IBM_HANDLE(fans, ec, "FANS"); /* X31, X40 */ 199IBM_HANDLE(fans, ec, "FANS"); /* X31, X40, X41 */
207 200
208IBM_HANDLE(gfan, ec, "GFAN", /* 570 */ 201IBM_HANDLE(gfan, ec, "GFAN", /* 570 */
209 "\\FSPD", /* 600e/x, 770e, 770x */ 202 "\\FSPD", /* 600e/x, 770e, 770x */
@@ -216,6 +209,152 @@ IBM_HANDLE(sfan, ec, "SFAN", /* 570 */
216#define IBM_HKEY_HID "IBM0068" 209#define IBM_HKEY_HID "IBM0068"
217#define IBM_PCI_HID "PNP0A03" 210#define IBM_PCI_HID "PNP0A03"
218 211
212enum thermal_access_mode {
213 IBMACPI_THERMAL_NONE = 0, /* No thermal support */
214 IBMACPI_THERMAL_ACPI_TMP07, /* Use ACPI TMP0-7 */
215 IBMACPI_THERMAL_ACPI_UPDT, /* Use ACPI TMP0-7 with UPDT */
216 IBMACPI_THERMAL_TPEC_8, /* Use ACPI EC regs, 8 sensors */
217 IBMACPI_THERMAL_TPEC_16, /* Use ACPI EC regs, 16 sensors */
218};
219
220#define IBMACPI_MAX_THERMAL_SENSORS 16 /* Max thermal sensors supported */
221struct ibm_thermal_sensors_struct {
222 s32 temp[IBMACPI_MAX_THERMAL_SENSORS];
223};
224
225/*
226 * FAN ACCESS MODES
227 *
228 * IBMACPI_FAN_RD_ACPI_GFAN:
229 * ACPI GFAN method: returns fan level
230 *
231 * see IBMACPI_FAN_WR_ACPI_SFAN
232 * EC 0x2f not available if GFAN exists
233 *
234 * IBMACPI_FAN_WR_ACPI_SFAN:
235 * ACPI SFAN method: sets fan level, 0 (stop) to 7 (max)
236 *
237 * EC 0x2f might be available *for reading*, but never for writing.
238 *
239 * IBMACPI_FAN_WR_TPEC:
240 * ThinkPad EC register 0x2f (HFSP): fan control loop mode Supported
241 * on almost all ThinkPads
242 *
243 * Fan speed changes of any sort (including those caused by the
244 * disengaged mode) are usually done slowly by the firmware as the
245 * maximum ammount of fan duty cycle change per second seems to be
246 * limited.
247 *
248 * Reading is not available if GFAN exists.
249 * Writing is not available if SFAN exists.
250 *
251 * Bits
252 * 7 automatic mode engaged;
253 * (default operation mode of the ThinkPad)
254 * fan level is ignored in this mode.
255 * 6 disengage mode (takes precedence over bit 7);
256 * not available on all thinkpads. May disable
257 * the tachometer, and speeds up fan to 100% duty-cycle,
258 * which speeds it up far above the standard RPM
259 * levels. It is not impossible that it could cause
260 * hardware damage.
261 * 5-3 unused in some models. Extra bits for fan level
262 * in others, but still useless as all values above
263 * 7 map to the same speed as level 7 in these models.
264 * 2-0 fan level (0..7 usually)
265 * 0x00 = stop
266 * 0x07 = max (set when temperatures critical)
267 * Some ThinkPads may have other levels, see
268 * IBMACPI_FAN_WR_ACPI_FANS (X31/X40/X41)
269 *
270 * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at
271 * boot. Apparently the EC does not intialize it, so unless ACPI DSDT
272 * does so, its initial value is meaningless (0x07).
273 *
274 * For firmware bugs, refer to:
275 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
276 *
277 * ----
278 *
279 * ThinkPad EC register 0x84 (LSB), 0x85 (MSB):
280 * Main fan tachometer reading (in RPM)
281 *
282 * This register is present on all ThinkPads with a new-style EC, and
283 * it is known not to be present on the A21m/e, and T22, as there is
284 * something else in offset 0x84 according to the ACPI DSDT. Other
285 * ThinkPads from this same time period (and earlier) probably lack the
286 * tachometer as well.
287 *
288 * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
289 * was never fixed by IBM to report the EC firmware version string
290 * probably support the tachometer (like the early X models), so
291 * detecting it is quite hard. We need more data to know for sure.
292 *
293 * FIRMWARE BUG: always read 0x84 first, otherwise incorrect readings
294 * might result.
295 *
296 * FIRMWARE BUG: when EC 0x2f bit 6 is set (disengaged mode), this
297 * register is not invalidated in ThinkPads that disable tachometer
298 * readings. Thus, the tachometer readings go stale.
299 *
300 * For firmware bugs, refer to:
301 * http://thinkwiki.org/wiki/Embedded_Controller_Firmware#Firmware_Issues
302 *
303 * IBMACPI_FAN_WR_ACPI_FANS:
304 * ThinkPad X31, X40, X41. Not available in the X60.
305 *
306 * FANS ACPI handle: takes three arguments: low speed, medium speed,
307 * high speed. ACPI DSDT seems to map these three speeds to levels
308 * as follows: STOP LOW LOW MED MED HIGH HIGH HIGH HIGH
309 * (this map is stored on FAN0..FAN8 as "0,1,1,2,2,3,3,3,3")
310 *
311 * The speeds are stored on handles
312 * (FANA:FAN9), (FANC:FANB), (FANE:FAND).
313 *
314 * There are three default speed sets, acessible as handles:
315 * FS1L,FS1M,FS1H; FS2L,FS2M,FS2H; FS3L,FS3M,FS3H
316 *
317 * ACPI DSDT switches which set is in use depending on various
318 * factors.
319 *
320 * IBMACPI_FAN_WR_TPEC is also available and should be used to
321 * command the fan. The X31/X40/X41 seems to have 8 fan levels,
322 * but the ACPI tables just mention level 7.
323 */
324
325enum fan_status_access_mode {
326 IBMACPI_FAN_NONE = 0, /* No fan status or control */
327 IBMACPI_FAN_RD_ACPI_GFAN, /* Use ACPI GFAN */
328 IBMACPI_FAN_RD_TPEC, /* Use ACPI EC regs 0x2f, 0x84-0x85 */
329};
330
331enum fan_control_access_mode {
332 IBMACPI_FAN_WR_NONE = 0, /* No fan control */
333 IBMACPI_FAN_WR_ACPI_SFAN, /* Use ACPI SFAN */
334 IBMACPI_FAN_WR_TPEC, /* Use ACPI EC reg 0x2f */
335 IBMACPI_FAN_WR_ACPI_FANS, /* Use ACPI FANS and EC reg 0x2f */
336};
337
338enum fan_control_commands {
339 IBMACPI_FAN_CMD_SPEED = 0x0001, /* speed command */
340 IBMACPI_FAN_CMD_LEVEL = 0x0002, /* level command */
341 IBMACPI_FAN_CMD_ENABLE = 0x0004, /* enable/disable cmd,
342 * and also watchdog cmd */
343};
344
345enum { /* Fan control constants */
346 fan_status_offset = 0x2f, /* EC register 0x2f */
347 fan_rpm_offset = 0x84, /* EC register 0x84: LSB, 0x85 MSB (RPM)
348 * 0x84 must be read before 0x85 */
349
350 IBMACPI_FAN_EC_DISENGAGED = 0x40, /* EC mode: tachometer
351 * disengaged */
352 IBMACPI_FAN_EC_AUTO = 0x80, /* EC mode: auto fan
353 * control */
354};
355
356static char *ibm_thinkpad_ec_found = NULL;
357
219struct ibm_struct { 358struct ibm_struct {
220 char *name; 359 char *name;
221 char param[32]; 360 char param[32];
@@ -243,6 +382,8 @@ struct ibm_struct {
243 382
244static struct proc_dir_entry *proc_dir = NULL; 383static struct proc_dir_entry *proc_dir = NULL;
245 384
385static struct backlight_device *ibm_backlight_device = NULL;
386
246#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") 387#define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
247#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") 388#define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
248#define strlencmp(a,b) (strncmp((a), (b), strlen(b))) 389#define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
@@ -581,8 +722,7 @@ static int wan_status(void)
581{ 722{
582 int status; 723 int status;
583 724
584 if (!wan_supported || 725 if (!wan_supported || !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
585 !acpi_evalf(hkey_handle, &status, "GWAN", "d"))
586 status = 0; 726 status = 0;
587 727
588 return status; 728 return status;
@@ -630,12 +770,15 @@ static int wan_write(char *buf)
630 return 0; 770 return 0;
631} 771}
632 772
633static int video_supported; 773enum video_access_mode {
634static int video_orig_autosw; 774 IBMACPI_VIDEO_NONE = 0,
775 IBMACPI_VIDEO_570, /* 570 */
776 IBMACPI_VIDEO_770, /* 600e/x, 770e, 770x */
777 IBMACPI_VIDEO_NEW, /* all others */
778};
635 779
636#define VIDEO_570 1 780static enum video_access_mode video_supported;
637#define VIDEO_770 2 781static int video_orig_autosw;
638#define VIDEO_NEW 3
639 782
640static int video_init(void) 783static int video_init(void)
641{ 784{
@@ -647,16 +790,16 @@ static int video_init(void)
647 790
648 if (!vid_handle) 791 if (!vid_handle)
649 /* video switching not supported on R30, R31 */ 792 /* video switching not supported on R30, R31 */
650 video_supported = 0; 793 video_supported = IBMACPI_VIDEO_NONE;
651 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd")) 794 else if (acpi_evalf(vid_handle, &video_orig_autosw, "SWIT", "qd"))
652 /* 570 */ 795 /* 570 */
653 video_supported = VIDEO_570; 796 video_supported = IBMACPI_VIDEO_570;
654 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd")) 797 else if (acpi_evalf(vid_handle, &video_orig_autosw, "^VADL", "qd"))
655 /* 600e/x, 770e, 770x */ 798 /* 600e/x, 770e, 770x */
656 video_supported = VIDEO_770; 799 video_supported = IBMACPI_VIDEO_770;
657 else 800 else
658 /* all others */ 801 /* all others */
659 video_supported = VIDEO_NEW; 802 video_supported = IBMACPI_VIDEO_NEW;
660 803
661 return 0; 804 return 0;
662} 805}
@@ -666,15 +809,15 @@ static int video_status(void)
666 int status = 0; 809 int status = 0;
667 int i; 810 int i;
668 811
669 if (video_supported == VIDEO_570) { 812 if (video_supported == IBMACPI_VIDEO_570) {
670 if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87)) 813 if (acpi_evalf(NULL, &i, "\\_SB.PHS", "dd", 0x87))
671 status = i & 3; 814 status = i & 3;
672 } else if (video_supported == VIDEO_770) { 815 } else if (video_supported == IBMACPI_VIDEO_770) {
673 if (acpi_evalf(NULL, &i, "\\VCDL", "d")) 816 if (acpi_evalf(NULL, &i, "\\VCDL", "d"))
674 status |= 0x01 * i; 817 status |= 0x01 * i;
675 if (acpi_evalf(NULL, &i, "\\VCDC", "d")) 818 if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
676 status |= 0x02 * i; 819 status |= 0x02 * i;
677 } else if (video_supported == VIDEO_NEW) { 820 } else if (video_supported == IBMACPI_VIDEO_NEW) {
678 acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1); 821 acpi_evalf(NULL, NULL, "\\VUPS", "vd", 1);
679 if (acpi_evalf(NULL, &i, "\\VCDC", "d")) 822 if (acpi_evalf(NULL, &i, "\\VCDC", "d"))
680 status |= 0x02 * i; 823 status |= 0x02 * i;
@@ -693,9 +836,10 @@ static int video_autosw(void)
693{ 836{
694 int autosw = 0; 837 int autosw = 0;
695 838
696 if (video_supported == VIDEO_570) 839 if (video_supported == IBMACPI_VIDEO_570)
697 acpi_evalf(vid_handle, &autosw, "SWIT", "d"); 840 acpi_evalf(vid_handle, &autosw, "SWIT", "d");
698 else if (video_supported == VIDEO_770 || video_supported == VIDEO_NEW) 841 else if (video_supported == IBMACPI_VIDEO_770 ||
842 video_supported == IBMACPI_VIDEO_NEW)
699 acpi_evalf(vid_handle, &autosw, "^VDEE", "d"); 843 acpi_evalf(vid_handle, &autosw, "^VDEE", "d");
700 844
701 return autosw & 1; 845 return autosw & 1;
@@ -715,12 +859,12 @@ static int video_read(char *p)
715 len += sprintf(p + len, "status:\t\tsupported\n"); 859 len += sprintf(p + len, "status:\t\tsupported\n");
716 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0)); 860 len += sprintf(p + len, "lcd:\t\t%s\n", enabled(status, 0));
717 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1)); 861 len += sprintf(p + len, "crt:\t\t%s\n", enabled(status, 1));
718 if (video_supported == VIDEO_NEW) 862 if (video_supported == IBMACPI_VIDEO_NEW)
719 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3)); 863 len += sprintf(p + len, "dvi:\t\t%s\n", enabled(status, 3));
720 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0)); 864 len += sprintf(p + len, "auto:\t\t%s\n", enabled(autosw, 0));
721 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n"); 865 len += sprintf(p + len, "commands:\tlcd_enable, lcd_disable\n");
722 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n"); 866 len += sprintf(p + len, "commands:\tcrt_enable, crt_disable\n");
723 if (video_supported == VIDEO_NEW) 867 if (video_supported == IBMACPI_VIDEO_NEW)
724 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n"); 868 len += sprintf(p + len, "commands:\tdvi_enable, dvi_disable\n");
725 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n"); 869 len += sprintf(p + len, "commands:\tauto_enable, auto_disable\n");
726 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n"); 870 len += sprintf(p + len, "commands:\tvideo_switch, expand_toggle\n");
@@ -735,7 +879,7 @@ static int video_switch(void)
735 879
736 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) 880 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
737 return -EIO; 881 return -EIO;
738 ret = video_supported == VIDEO_570 ? 882 ret = video_supported == IBMACPI_VIDEO_570 ?
739 acpi_evalf(ec_handle, NULL, "_Q16", "v") : 883 acpi_evalf(ec_handle, NULL, "_Q16", "v") :
740 acpi_evalf(vid_handle, NULL, "VSWT", "v"); 884 acpi_evalf(vid_handle, NULL, "VSWT", "v");
741 acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw); 885 acpi_evalf(vid_handle, NULL, "_DOS", "vd", autosw);
@@ -745,9 +889,9 @@ static int video_switch(void)
745 889
746static int video_expand(void) 890static int video_expand(void)
747{ 891{
748 if (video_supported == VIDEO_570) 892 if (video_supported == IBMACPI_VIDEO_570)
749 return acpi_evalf(ec_handle, NULL, "_Q17", "v"); 893 return acpi_evalf(ec_handle, NULL, "_Q17", "v");
750 else if (video_supported == VIDEO_770) 894 else if (video_supported == IBMACPI_VIDEO_770)
751 return acpi_evalf(vid_handle, NULL, "VEXP", "v"); 895 return acpi_evalf(vid_handle, NULL, "VEXP", "v");
752 else 896 else
753 return acpi_evalf(NULL, NULL, "\\VEXP", "v"); 897 return acpi_evalf(NULL, NULL, "\\VEXP", "v");
@@ -757,10 +901,10 @@ static int video_switch2(int status)
757{ 901{
758 int ret; 902 int ret;
759 903
760 if (video_supported == VIDEO_570) { 904 if (video_supported == IBMACPI_VIDEO_570) {
761 ret = acpi_evalf(NULL, NULL, 905 ret = acpi_evalf(NULL, NULL,
762 "\\_SB.PHS2", "vdd", 0x8b, status | 0x80); 906 "\\_SB.PHS2", "vdd", 0x8b, status | 0x80);
763 } else if (video_supported == VIDEO_770) { 907 } else if (video_supported == IBMACPI_VIDEO_770) {
764 int autosw = video_autosw(); 908 int autosw = video_autosw();
765 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1)) 909 if (!acpi_evalf(vid_handle, NULL, "_DOS", "vd", 1))
766 return -EIO; 910 return -EIO;
@@ -796,10 +940,10 @@ static int video_write(char *buf)
796 enable |= 0x02; 940 enable |= 0x02;
797 } else if (strlencmp(cmd, "crt_disable") == 0) { 941 } else if (strlencmp(cmd, "crt_disable") == 0) {
798 disable |= 0x02; 942 disable |= 0x02;
799 } else if (video_supported == VIDEO_NEW && 943 } else if (video_supported == IBMACPI_VIDEO_NEW &&
800 strlencmp(cmd, "dvi_enable") == 0) { 944 strlencmp(cmd, "dvi_enable") == 0) {
801 enable |= 0x08; 945 enable |= 0x08;
802 } else if (video_supported == VIDEO_NEW && 946 } else if (video_supported == IBMACPI_VIDEO_NEW &&
803 strlencmp(cmd, "dvi_disable") == 0) { 947 strlencmp(cmd, "dvi_disable") == 0) {
804 disable |= 0x08; 948 disable |= 0x08;
805 } else if (strlencmp(cmd, "auto_enable") == 0) { 949 } else if (strlencmp(cmd, "auto_enable") == 0) {
@@ -898,6 +1042,7 @@ static int light_write(char *buf)
898 return 0; 1042 return 0;
899} 1043}
900 1044
1045#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
901static int _sta(acpi_handle handle) 1046static int _sta(acpi_handle handle)
902{ 1047{
903 int status; 1048 int status;
@@ -907,6 +1052,7 @@ static int _sta(acpi_handle handle)
907 1052
908 return status; 1053 return status;
909} 1054}
1055#endif
910#ifdef CONFIG_ACPI_IBM_DOCK 1056#ifdef CONFIG_ACPI_IBM_DOCK
911#define dock_docked() (_sta(dock_handle) & 1) 1057#define dock_docked() (_sta(dock_handle) & 1)
912 1058
@@ -972,6 +1118,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
972} 1118}
973#endif 1119#endif
974 1120
1121#ifdef CONFIG_ACPI_IBM_BAY
975static int bay_status_supported; 1122static int bay_status_supported;
976static int bay_status2_supported; 1123static int bay_status2_supported;
977static int bay_eject_supported; 1124static int bay_eject_supported;
@@ -1047,6 +1194,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event)
1047{ 1194{
1048 acpi_bus_generate_event(ibm->device, event, 0); 1195 acpi_bus_generate_event(ibm->device, event, 0);
1049} 1196}
1197#endif
1050 1198
1051static int cmos_read(char *p) 1199static int cmos_read(char *p)
1052{ 1200{
@@ -1094,26 +1242,28 @@ static int cmos_write(char *buf)
1094 return 0; 1242 return 0;
1095} 1243}
1096 1244
1097static int led_supported; 1245enum led_access_mode {
1098 1246 IBMACPI_LED_NONE = 0,
1099#define LED_570 1 1247 IBMACPI_LED_570, /* 570 */
1100#define LED_OLD 2 1248 IBMACPI_LED_OLD, /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
1101#define LED_NEW 3 1249 IBMACPI_LED_NEW, /* all others */
1250};
1251static enum led_access_mode led_supported;
1102 1252
1103static int led_init(void) 1253static int led_init(void)
1104{ 1254{
1105 if (!led_handle) 1255 if (!led_handle)
1106 /* led not supported on R30, R31 */ 1256 /* led not supported on R30, R31 */
1107 led_supported = 0; 1257 led_supported = IBMACPI_LED_NONE;
1108 else if (strlencmp(led_path, "SLED") == 0) 1258 else if (strlencmp(led_path, "SLED") == 0)
1109 /* 570 */ 1259 /* 570 */
1110 led_supported = LED_570; 1260 led_supported = IBMACPI_LED_570;
1111 else if (strlencmp(led_path, "SYSL") == 0) 1261 else if (strlencmp(led_path, "SYSL") == 0)
1112 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */ 1262 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20-21 */
1113 led_supported = LED_OLD; 1263 led_supported = IBMACPI_LED_OLD;
1114 else 1264 else
1115 /* all others */ 1265 /* all others */
1116 led_supported = LED_NEW; 1266 led_supported = IBMACPI_LED_NEW;
1117 1267
1118 return 0; 1268 return 0;
1119} 1269}
@@ -1130,7 +1280,7 @@ static int led_read(char *p)
1130 } 1280 }
1131 len += sprintf(p + len, "status:\t\tsupported\n"); 1281 len += sprintf(p + len, "status:\t\tsupported\n");
1132 1282
1133 if (led_supported == LED_570) { 1283 if (led_supported == IBMACPI_LED_570) {
1134 /* 570 */ 1284 /* 570 */
1135 int i, status; 1285 int i, status;
1136 for (i = 0; i < 8; i++) { 1286 for (i = 0; i < 8; i++) {
@@ -1179,13 +1329,13 @@ static int led_write(char *buf)
1179 } else 1329 } else
1180 return -EINVAL; 1330 return -EINVAL;
1181 1331
1182 if (led_supported == LED_570) { 1332 if (led_supported == IBMACPI_LED_570) {
1183 /* 570 */ 1333 /* 570 */
1184 led = 1 << led; 1334 led = 1 << led;
1185 if (!acpi_evalf(led_handle, NULL, NULL, "vdd", 1335 if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
1186 led, led_sled_arg1[ind])) 1336 led, led_sled_arg1[ind]))
1187 return -EIO; 1337 return -EIO;
1188 } else if (led_supported == LED_OLD) { 1338 } else if (led_supported == IBMACPI_LED_OLD) {
1189 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ 1339 /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
1190 led = 1 << led; 1340 led = 1 << led;
1191 ret = ec_write(EC_HLMS, led); 1341 ret = ec_write(EC_HLMS, led);
@@ -1272,50 +1422,142 @@ static int acpi_ec_write(int i, u8 v)
1272 return 1; 1422 return 1;
1273} 1423}
1274 1424
1275static int thermal_tmp_supported; 1425static enum thermal_access_mode thermal_read_mode;
1276static int thermal_updt_supported;
1277 1426
1278static int thermal_init(void) 1427static int thermal_init(void)
1279{ 1428{
1280 /* temperatures not supported on 570, G4x, R30, R31, R32 */ 1429 u8 t, ta1, ta2;
1281 thermal_tmp_supported = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); 1430 int i;
1431 int acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv");
1432
1433 if (ibm_thinkpad_ec_found && experimental) {
1434 /*
1435 * Direct EC access mode: sensors at registers
1436 * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for
1437 * non-implemented, thermal sensors return 0x80 when
1438 * not available
1439 */
1282 1440
1283 /* 600e/x, 770e, 770x */ 1441 ta1 = ta2 = 0;
1284 thermal_updt_supported = acpi_evalf(ec_handle, NULL, "UPDT", "qv"); 1442 for (i = 0; i < 8; i++) {
1443 if (likely(acpi_ec_read(0x78 + i, &t))) {
1444 ta1 |= t;
1445 } else {
1446 ta1 = 0;
1447 break;
1448 }
1449 if (likely(acpi_ec_read(0xC0 + i, &t))) {
1450 ta2 |= t;
1451 } else {
1452 ta1 = 0;
1453 break;
1454 }
1455 }
1456 if (ta1 == 0) {
1457 /* This is sheer paranoia, but we handle it anyway */
1458 if (acpi_tmp7) {
1459 printk(IBM_ERR
1460 "ThinkPad ACPI EC access misbehaving, "
1461 "falling back to ACPI TMPx access mode\n");
1462 thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
1463 } else {
1464 printk(IBM_ERR
1465 "ThinkPad ACPI EC access misbehaving, "
1466 "disabling thermal sensors access\n");
1467 thermal_read_mode = IBMACPI_THERMAL_NONE;
1468 }
1469 } else {
1470 thermal_read_mode =
1471 (ta2 != 0) ?
1472 IBMACPI_THERMAL_TPEC_16 : IBMACPI_THERMAL_TPEC_8;
1473 }
1474 } else if (acpi_tmp7) {
1475 if (acpi_evalf(ec_handle, NULL, "UPDT", "qv")) {
1476 /* 600e/x, 770e, 770x */
1477 thermal_read_mode = IBMACPI_THERMAL_ACPI_UPDT;
1478 } else {
1479 /* Standard ACPI TMPx access, max 8 sensors */
1480 thermal_read_mode = IBMACPI_THERMAL_ACPI_TMP07;
1481 }
1482 } else {
1483 /* temperatures not supported on 570, G4x, R30, R31, R32 */
1484 thermal_read_mode = IBMACPI_THERMAL_NONE;
1485 }
1285 1486
1286 return 0; 1487 return 0;
1287} 1488}
1288 1489
1289static int thermal_read(char *p) 1490static int thermal_get_sensors(struct ibm_thermal_sensors_struct *s)
1290{ 1491{
1291 int len = 0; 1492 int i, t;
1493 s8 tmp;
1494 char tmpi[] = "TMPi";
1292 1495
1293 if (!thermal_tmp_supported) 1496 if (!s)
1294 len += sprintf(p + len, "temperatures:\tnot supported\n"); 1497 return -EINVAL;
1295 else {
1296 int i, t;
1297 char tmpi[] = "TMPi";
1298 s8 tmp[8];
1299 1498
1300 if (thermal_updt_supported) 1499 switch (thermal_read_mode) {
1301 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v")) 1500#if IBMACPI_MAX_THERMAL_SENSORS >= 16
1501 case IBMACPI_THERMAL_TPEC_16:
1502 for (i = 0; i < 8; i++) {
1503 if (!acpi_ec_read(0xC0 + i, &tmp))
1504 return -EIO;
1505 s->temp[i + 8] = tmp * 1000;
1506 }
1507 /* fallthrough */
1508#endif
1509 case IBMACPI_THERMAL_TPEC_8:
1510 for (i = 0; i < 8; i++) {
1511 if (!acpi_ec_read(0x78 + i, &tmp))
1302 return -EIO; 1512 return -EIO;
1513 s->temp[i] = tmp * 1000;
1514 }
1515 return (thermal_read_mode == IBMACPI_THERMAL_TPEC_16) ? 16 : 8;
1303 1516
1517 case IBMACPI_THERMAL_ACPI_UPDT:
1518 if (!acpi_evalf(ec_handle, NULL, "UPDT", "v"))
1519 return -EIO;
1304 for (i = 0; i < 8; i++) { 1520 for (i = 0; i < 8; i++) {
1305 tmpi[3] = '0' + i; 1521 tmpi[3] = '0' + i;
1306 if (!acpi_evalf(ec_handle, &t, tmpi, "d")) 1522 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
1307 return -EIO; 1523 return -EIO;
1308 if (thermal_updt_supported) 1524 s->temp[i] = (t - 2732) * 100;
1309 tmp[i] = (t - 2732 + 5) / 10;
1310 else
1311 tmp[i] = t;
1312 } 1525 }
1526 return 8;
1313 1527
1314 len += sprintf(p + len, 1528 case IBMACPI_THERMAL_ACPI_TMP07:
1315 "temperatures:\t%d %d %d %d %d %d %d %d\n", 1529 for (i = 0; i < 8; i++) {
1316 tmp[0], tmp[1], tmp[2], tmp[3], 1530 tmpi[3] = '0' + i;
1317 tmp[4], tmp[5], tmp[6], tmp[7]); 1531 if (!acpi_evalf(ec_handle, &t, tmpi, "d"))
1532 return -EIO;
1533 s->temp[i] = t * 1000;
1534 }
1535 return 8;
1536
1537 case IBMACPI_THERMAL_NONE:
1538 default:
1539 return 0;
1318 } 1540 }
1541}
1542
1543static int thermal_read(char *p)
1544{
1545 int len = 0;
1546 int n, i;
1547 struct ibm_thermal_sensors_struct t;
1548
1549 n = thermal_get_sensors(&t);
1550 if (unlikely(n < 0))
1551 return n;
1552
1553 len += sprintf(p + len, "temperatures:\t");
1554
1555 if (n > 0) {
1556 for (i = 0; i < (n - 1); i++)
1557 len += sprintf(p + len, "%d ", t.temp[i] / 1000);
1558 len += sprintf(p + len, "%d\n", t.temp[i] / 1000);
1559 } else
1560 len += sprintf(p + len, "not supported\n");
1319 1561
1320 return len; 1562 return len;
1321} 1563}
@@ -1381,12 +1623,23 @@ static int ecdump_write(char *buf)
1381 1623
1382static int brightness_offset = 0x31; 1624static int brightness_offset = 0x31;
1383 1625
1626static int brightness_get(struct backlight_device *bd)
1627{
1628 u8 level;
1629 if (!acpi_ec_read(brightness_offset, &level))
1630 return -EIO;
1631
1632 level &= 0x7;
1633
1634 return level;
1635}
1636
1384static int brightness_read(char *p) 1637static int brightness_read(char *p)
1385{ 1638{
1386 int len = 0; 1639 int len = 0;
1387 u8 level; 1640 int level;
1388 1641
1389 if (!acpi_ec_read(brightness_offset, &level)) { 1642 if ((level = brightness_get(NULL)) < 0) {
1390 len += sprintf(p + len, "level:\t\tunreadable\n"); 1643 len += sprintf(p + len, "level:\t\tunreadable\n");
1391 } else { 1644 } else {
1392 len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); 1645 len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
@@ -1401,16 +1654,34 @@ static int brightness_read(char *p)
1401#define BRIGHTNESS_UP 4 1654#define BRIGHTNESS_UP 4
1402#define BRIGHTNESS_DOWN 5 1655#define BRIGHTNESS_DOWN 5
1403 1656
1404static int brightness_write(char *buf) 1657static int brightness_set(int value)
1405{ 1658{
1406 int cmos_cmd, inc, i; 1659 int cmos_cmd, inc, i;
1407 u8 level; 1660 int current_value = brightness_get(NULL);
1661
1662 value &= 7;
1663
1664 cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
1665 inc = value > current_value ? 1 : -1;
1666 for (i = current_value; i != value; i += inc) {
1667 if (!cmos_eval(cmos_cmd))
1668 return -EIO;
1669 if (!acpi_ec_write(brightness_offset, i + inc))
1670 return -EIO;
1671 }
1672
1673 return 0;
1674}
1675
1676static int brightness_write(char *buf)
1677{
1678 int level;
1408 int new_level; 1679 int new_level;
1409 char *cmd; 1680 char *cmd;
1410 1681
1411 while ((cmd = next_cmd(&buf))) { 1682 while ((cmd = next_cmd(&buf))) {
1412 if (!acpi_ec_read(brightness_offset, &level)) 1683 if ((level = brightness_get(NULL)) < 0)
1413 return -EIO; 1684 return level;
1414 level &= 7; 1685 level &= 7;
1415 1686
1416 if (strlencmp(cmd, "up") == 0) { 1687 if (strlencmp(cmd, "up") == 0) {
@@ -1423,19 +1694,44 @@ static int brightness_write(char *buf)
1423 } else 1694 } else
1424 return -EINVAL; 1695 return -EINVAL;
1425 1696
1426 cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; 1697 brightness_set(new_level);
1427 inc = new_level > level ? 1 : -1;
1428 for (i = level; i != new_level; i += inc) {
1429 if (!cmos_eval(cmos_cmd))
1430 return -EIO;
1431 if (!acpi_ec_write(brightness_offset, i + inc))
1432 return -EIO;
1433 }
1434 } 1698 }
1435 1699
1436 return 0; 1700 return 0;
1437} 1701}
1438 1702
1703static int brightness_update_status(struct backlight_device *bd)
1704{
1705 return brightness_set(bd->props->brightness);
1706}
1707
1708static struct backlight_properties ibm_backlight_data = {
1709 .owner = THIS_MODULE,
1710 .get_brightness = brightness_get,
1711 .update_status = brightness_update_status,
1712 .max_brightness = 7,
1713};
1714
1715static int brightness_init(void)
1716{
1717 ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
1718 &ibm_backlight_data);
1719 if (IS_ERR(ibm_backlight_device)) {
1720 printk(IBM_ERR "Could not register backlight device\n");
1721 return PTR_ERR(ibm_backlight_device);
1722 }
1723
1724 return 0;
1725}
1726
1727static void brightness_exit(void)
1728{
1729 if (ibm_backlight_device) {
1730 backlight_device_unregister(ibm_backlight_device);
1731 ibm_backlight_device = NULL;
1732 }
1733}
1734
1439static int volume_offset = 0x30; 1735static int volume_offset = 0x30;
1440 1736
1441static int volume_read(char *p) 1737static int volume_read(char *p)
@@ -1522,86 +1818,482 @@ static int volume_write(char *buf)
1522 return 0; 1818 return 0;
1523} 1819}
1524 1820
1525static int fan_status_offset = 0x2f; 1821static enum fan_status_access_mode fan_status_access_mode;
1526static int fan_rpm_offset = 0x84; 1822static enum fan_control_access_mode fan_control_access_mode;
1823static enum fan_control_commands fan_control_commands;
1527 1824
1528static int fan_read(char *p) 1825static int fan_control_status_known;
1826static u8 fan_control_initial_status;
1827
1828static void fan_watchdog_fire(struct work_struct *ignored);
1829static int fan_watchdog_maxinterval;
1830static DECLARE_DELAYED_WORK(fan_watchdog_task, fan_watchdog_fire);
1831
1832static int fan_init(void)
1529{ 1833{
1530 int len = 0; 1834 fan_status_access_mode = IBMACPI_FAN_NONE;
1531 int s; 1835 fan_control_access_mode = IBMACPI_FAN_WR_NONE;
1532 u8 lo, hi, status; 1836 fan_control_commands = 0;
1837 fan_control_status_known = 1;
1838 fan_watchdog_maxinterval = 0;
1533 1839
1534 if (gfan_handle) { 1840 if (gfan_handle) {
1535 /* 570, 600e/x, 770e, 770x */ 1841 /* 570, 600e/x, 770e, 770x */
1536 if (!acpi_evalf(gfan_handle, &s, NULL, "d")) 1842 fan_status_access_mode = IBMACPI_FAN_RD_ACPI_GFAN;
1537 return -EIO; 1843 } else {
1844 /* all other ThinkPads: note that even old-style
1845 * ThinkPad ECs supports the fan control register */
1846 if (likely(acpi_ec_read(fan_status_offset,
1847 &fan_control_initial_status))) {
1848 fan_status_access_mode = IBMACPI_FAN_RD_TPEC;
1849
1850 /* In some ThinkPads, neither the EC nor the ACPI
1851 * DSDT initialize the fan status, and it ends up
1852 * being set to 0x07 when it *could* be either
1853 * 0x07 or 0x80.
1854 *
1855 * Enable for TP-1Y (T43), TP-78 (R51e),
1856 * TP-76 (R52), TP-70 (T43, R52), which are known
1857 * to be buggy. */
1858 if (fan_control_initial_status == 0x07 &&
1859 ibm_thinkpad_ec_found &&
1860 ((ibm_thinkpad_ec_found[0] == '1' &&
1861 ibm_thinkpad_ec_found[1] == 'Y') ||
1862 (ibm_thinkpad_ec_found[0] == '7' &&
1863 (ibm_thinkpad_ec_found[1] == '6' ||
1864 ibm_thinkpad_ec_found[1] == '8' ||
1865 ibm_thinkpad_ec_found[1] == '0'))
1866 )) {
1867 printk(IBM_NOTICE
1868 "fan_init: initial fan status is "
1869 "unknown, assuming it is in auto "
1870 "mode\n");
1871 fan_control_status_known = 0;
1872 }
1873 } else {
1874 printk(IBM_ERR
1875 "ThinkPad ACPI EC access misbehaving, "
1876 "fan status and control unavailable\n");
1877 return 0;
1878 }
1879 }
1538 1880
1539 len += sprintf(p + len, "level:\t\t%d\n", s); 1881 if (sfan_handle) {
1882 /* 570, 770x-JL */
1883 fan_control_access_mode = IBMACPI_FAN_WR_ACPI_SFAN;
1884 fan_control_commands |=
1885 IBMACPI_FAN_CMD_LEVEL | IBMACPI_FAN_CMD_ENABLE;
1540 } else { 1886 } else {
1887 if (!gfan_handle) {
1888 /* gfan without sfan means no fan control */
1889 /* all other models implement TP EC 0x2f control */
1890
1891 if (fans_handle) {
1892 /* X31, X40, X41 */
1893 fan_control_access_mode =
1894 IBMACPI_FAN_WR_ACPI_FANS;
1895 fan_control_commands |=
1896 IBMACPI_FAN_CMD_SPEED |
1897 IBMACPI_FAN_CMD_LEVEL |
1898 IBMACPI_FAN_CMD_ENABLE;
1899 } else {
1900 fan_control_access_mode = IBMACPI_FAN_WR_TPEC;
1901 fan_control_commands |=
1902 IBMACPI_FAN_CMD_LEVEL |
1903 IBMACPI_FAN_CMD_ENABLE;
1904 }
1905 }
1906 }
1907
1908 return 0;
1909}
1910
1911static int fan_get_status(u8 *status)
1912{
1913 u8 s;
1914
1915 /* TODO:
1916 * Add IBMACPI_FAN_RD_ACPI_FANS ? */
1917
1918 switch (fan_status_access_mode) {
1919 case IBMACPI_FAN_RD_ACPI_GFAN:
1920 /* 570, 600e/x, 770e, 770x */
1921
1922 if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d")))
1923 return -EIO;
1924
1925 if (likely(status))
1926 *status = s & 0x07;
1927
1928 break;
1929
1930 case IBMACPI_FAN_RD_TPEC:
1541 /* all except 570, 600e/x, 770e, 770x */ 1931 /* all except 570, 600e/x, 770e, 770x */
1542 if (!acpi_ec_read(fan_status_offset, &status)) 1932 if (unlikely(!acpi_ec_read(fan_status_offset, &s)))
1543 len += sprintf(p + len, "status:\t\tunreadable\n"); 1933 return -EIO;
1544 else
1545 len += sprintf(p + len, "status:\t\t%s\n",
1546 enabled(status, 7));
1547 1934
1548 if (!acpi_ec_read(fan_rpm_offset, &lo) || 1935 if (likely(status))
1549 !acpi_ec_read(fan_rpm_offset + 1, &hi)) 1936 *status = s;
1550 len += sprintf(p + len, "speed:\t\tunreadable\n"); 1937
1551 else 1938 break;
1552 len += sprintf(p + len, "speed:\t\t%d\n", 1939
1553 (hi << 8) + lo); 1940 default:
1941 return -ENXIO;
1554 } 1942 }
1555 1943
1556 if (sfan_handle) 1944 return 0;
1557 /* 570, 770x-JL */ 1945}
1558 len += sprintf(p + len, "commands:\tlevel <level>" 1946
1559 " (<level> is 0-7)\n"); 1947static int fan_get_speed(unsigned int *speed)
1560 if (!gfan_handle) 1948{
1949 u8 hi, lo;
1950
1951 switch (fan_status_access_mode) {
1952 case IBMACPI_FAN_RD_TPEC:
1561 /* all except 570, 600e/x, 770e, 770x */ 1953 /* all except 570, 600e/x, 770e, 770x */
1562 len += sprintf(p + len, "commands:\tenable, disable\n"); 1954 if (unlikely(!acpi_ec_read(fan_rpm_offset, &lo) ||
1563 if (fans_handle) 1955 !acpi_ec_read(fan_rpm_offset + 1, &hi)))
1564 /* X31, X40 */ 1956 return -EIO;
1957
1958 if (likely(speed))
1959 *speed = (hi << 8) | lo;
1960
1961 break;
1962
1963 default:
1964 return -ENXIO;
1965 }
1966
1967 return 0;
1968}
1969
1970static void fan_exit(void)
1971{
1972 cancel_delayed_work(&fan_watchdog_task);
1973 flush_scheduled_work();
1974}
1975
1976static void fan_watchdog_reset(void)
1977{
1978 static int fan_watchdog_active = 0;
1979
1980 if (fan_watchdog_active)
1981 cancel_delayed_work(&fan_watchdog_task);
1982
1983 if (fan_watchdog_maxinterval > 0) {
1984 fan_watchdog_active = 1;
1985 if (!schedule_delayed_work(&fan_watchdog_task,
1986 msecs_to_jiffies(fan_watchdog_maxinterval
1987 * 1000))) {
1988 printk(IBM_ERR "failed to schedule the fan watchdog, "
1989 "watchdog will not trigger\n");
1990 }
1991 } else
1992 fan_watchdog_active = 0;
1993}
1994
1995static int fan_read(char *p)
1996{
1997 int len = 0;
1998 int rc;
1999 u8 status;
2000 unsigned int speed = 0;
2001
2002 switch (fan_status_access_mode) {
2003 case IBMACPI_FAN_RD_ACPI_GFAN:
2004 /* 570, 600e/x, 770e, 770x */
2005 if ((rc = fan_get_status(&status)) < 0)
2006 return rc;
2007
2008 len += sprintf(p + len, "status:\t\t%s\n"
2009 "level:\t\t%d\n",
2010 (status != 0) ? "enabled" : "disabled", status);
2011 break;
2012
2013 case IBMACPI_FAN_RD_TPEC:
2014 /* all except 570, 600e/x, 770e, 770x */
2015 if ((rc = fan_get_status(&status)) < 0)
2016 return rc;
2017
2018 if (unlikely(!fan_control_status_known)) {
2019 if (status != fan_control_initial_status)
2020 fan_control_status_known = 1;
2021 else
2022 /* Return most likely status. In fact, it
2023 * might be the only possible status */
2024 status = IBMACPI_FAN_EC_AUTO;
2025 }
2026
2027 len += sprintf(p + len, "status:\t\t%s\n",
2028 (status != 0) ? "enabled" : "disabled");
2029
2030 /* No ThinkPad boots on disengaged mode, we can safely
2031 * assume the tachometer is online if fan control status
2032 * was unknown */
2033 if ((rc = fan_get_speed(&speed)) < 0)
2034 return rc;
2035
2036 len += sprintf(p + len, "speed:\t\t%d\n", speed);
2037
2038 if (status & IBMACPI_FAN_EC_DISENGAGED)
2039 /* Disengaged mode takes precedence */
2040 len += sprintf(p + len, "level:\t\tdisengaged\n");
2041 else if (status & IBMACPI_FAN_EC_AUTO)
2042 len += sprintf(p + len, "level:\t\tauto\n");
2043 else
2044 len += sprintf(p + len, "level:\t\t%d\n", status);
2045 break;
2046
2047 case IBMACPI_FAN_NONE:
2048 default:
2049 len += sprintf(p + len, "status:\t\tnot supported\n");
2050 }
2051
2052 if (fan_control_commands & IBMACPI_FAN_CMD_LEVEL) {
2053 len += sprintf(p + len, "commands:\tlevel <level>");
2054
2055 switch (fan_control_access_mode) {
2056 case IBMACPI_FAN_WR_ACPI_SFAN:
2057 len += sprintf(p + len, " (<level> is 0-7)\n");
2058 break;
2059
2060 default:
2061 len += sprintf(p + len, " (<level> is 0-7, "
2062 "auto, disengaged)\n");
2063 break;
2064 }
2065 }
2066
2067 if (fan_control_commands & IBMACPI_FAN_CMD_ENABLE)
2068 len += sprintf(p + len, "commands:\tenable, disable\n"
2069 "commands:\twatchdog <timeout> (<timeout> is 0 (off), "
2070 "1-120 (seconds))\n");
2071
2072 if (fan_control_commands & IBMACPI_FAN_CMD_SPEED)
1565 len += sprintf(p + len, "commands:\tspeed <speed>" 2073 len += sprintf(p + len, "commands:\tspeed <speed>"
1566 " (<speed> is 0-65535)\n"); 2074 " (<speed> is 0-65535)\n");
1567 2075
1568 return len; 2076 return len;
1569} 2077}
1570 2078
1571static int fan_write(char *buf) 2079static int fan_set_level(int level)
1572{ 2080{
1573 char *cmd; 2081 switch (fan_control_access_mode) {
1574 int level, speed; 2082 case IBMACPI_FAN_WR_ACPI_SFAN:
1575 2083 if (level >= 0 && level <= 7) {
1576 while ((cmd = next_cmd(&buf))) {
1577 if (sfan_handle &&
1578 sscanf(cmd, "level %d", &level) == 1 &&
1579 level >= 0 && level <= 7) {
1580 /* 570, 770x-JL */
1581 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level)) 2084 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", level))
1582 return -EIO; 2085 return -EIO;
1583 } else if (!gfan_handle && strlencmp(cmd, "enable") == 0) { 2086 } else
1584 /* all except 570, 600e/x, 770e, 770x */ 2087 return -EINVAL;
1585 if (!acpi_ec_write(fan_status_offset, 0x80)) 2088 break;
1586 return -EIO; 2089
1587 } else if (!gfan_handle && strlencmp(cmd, "disable") == 0) { 2090 case IBMACPI_FAN_WR_ACPI_FANS:
1588 /* all except 570, 600e/x, 770e, 770x */ 2091 case IBMACPI_FAN_WR_TPEC:
1589 if (!acpi_ec_write(fan_status_offset, 0x00)) 2092 if ((level != IBMACPI_FAN_EC_AUTO) &&
1590 return -EIO; 2093 (level != IBMACPI_FAN_EC_DISENGAGED) &&
1591 } else if (fans_handle && 2094 ((level < 0) || (level > 7)))
1592 sscanf(cmd, "speed %d", &speed) == 1 && 2095 return -EINVAL;
1593 speed >= 0 && speed <= 65535) { 2096
1594 /* X31, X40 */ 2097 if (!acpi_ec_write(fan_status_offset, level))
2098 return -EIO;
2099 else
2100 fan_control_status_known = 1;
2101 break;
2102
2103 default:
2104 return -ENXIO;
2105 }
2106 return 0;
2107}
2108
2109static int fan_set_enable(void)
2110{
2111 u8 s;
2112 int rc;
2113
2114 switch (fan_control_access_mode) {
2115 case IBMACPI_FAN_WR_ACPI_FANS:
2116 case IBMACPI_FAN_WR_TPEC:
2117 if ((rc = fan_get_status(&s)) < 0)
2118 return rc;
2119
2120 /* Don't go out of emergency fan mode */
2121 if (s != 7)
2122 s = IBMACPI_FAN_EC_AUTO;
2123
2124 if (!acpi_ec_write(fan_status_offset, s))
2125 return -EIO;
2126 else
2127 fan_control_status_known = 1;
2128 break;
2129
2130 case IBMACPI_FAN_WR_ACPI_SFAN:
2131 if ((rc = fan_get_status(&s)) < 0)
2132 return rc;
2133
2134 s &= 0x07;
2135
2136 /* Set fan to at least level 4 */
2137 if (s < 4)
2138 s = 4;
2139
2140 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", s))
2141 return -EIO;
2142 break;
2143
2144 default:
2145 return -ENXIO;
2146 }
2147 return 0;
2148}
2149
2150static int fan_set_disable(void)
2151{
2152 switch (fan_control_access_mode) {
2153 case IBMACPI_FAN_WR_ACPI_FANS:
2154 case IBMACPI_FAN_WR_TPEC:
2155 if (!acpi_ec_write(fan_status_offset, 0x00))
2156 return -EIO;
2157 else
2158 fan_control_status_known = 1;
2159 break;
2160
2161 case IBMACPI_FAN_WR_ACPI_SFAN:
2162 if (!acpi_evalf(sfan_handle, NULL, NULL, "vd", 0x00))
2163 return -EIO;
2164 break;
2165
2166 default:
2167 return -ENXIO;
2168 }
2169 return 0;
2170}
2171
2172static int fan_set_speed(int speed)
2173{
2174 switch (fan_control_access_mode) {
2175 case IBMACPI_FAN_WR_ACPI_FANS:
2176 if (speed >= 0 && speed <= 65535) {
1595 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd", 2177 if (!acpi_evalf(fans_handle, NULL, NULL, "vddd",
1596 speed, speed, speed)) 2178 speed, speed, speed))
1597 return -EIO; 2179 return -EIO;
1598 } else 2180 } else
1599 return -EINVAL; 2181 return -EINVAL;
1600 } 2182 break;
1601 2183
2184 default:
2185 return -ENXIO;
2186 }
1602 return 0; 2187 return 0;
1603} 2188}
1604 2189
2190static int fan_write_cmd_level(const char *cmd, int *rc)
2191{
2192 int level;
2193
2194 if (strlencmp(cmd, "level auto") == 0)
2195 level = IBMACPI_FAN_EC_AUTO;
2196 else if (strlencmp(cmd, "level disengaged") == 0)
2197 level = IBMACPI_FAN_EC_DISENGAGED;
2198 else if (sscanf(cmd, "level %d", &level) != 1)
2199 return 0;
2200
2201 if ((*rc = fan_set_level(level)) == -ENXIO)
2202 printk(IBM_ERR "level command accepted for unsupported "
2203 "access mode %d", fan_control_access_mode);
2204
2205 return 1;
2206}
2207
2208static int fan_write_cmd_enable(const char *cmd, int *rc)
2209{
2210 if (strlencmp(cmd, "enable") != 0)
2211 return 0;
2212
2213 if ((*rc = fan_set_enable()) == -ENXIO)
2214 printk(IBM_ERR "enable command accepted for unsupported "
2215 "access mode %d", fan_control_access_mode);
2216
2217 return 1;
2218}
2219
2220static int fan_write_cmd_disable(const char *cmd, int *rc)
2221{
2222 if (strlencmp(cmd, "disable") != 0)
2223 return 0;
2224
2225 if ((*rc = fan_set_disable()) == -ENXIO)
2226 printk(IBM_ERR "disable command accepted for unsupported "
2227 "access mode %d", fan_control_access_mode);
2228
2229 return 1;
2230}
2231
2232static int fan_write_cmd_speed(const char *cmd, int *rc)
2233{
2234 int speed;
2235
2236 /* TODO:
2237 * Support speed <low> <medium> <high> ? */
2238
2239 if (sscanf(cmd, "speed %d", &speed) != 1)
2240 return 0;
2241
2242 if ((*rc = fan_set_speed(speed)) == -ENXIO)
2243 printk(IBM_ERR "speed command accepted for unsupported "
2244 "access mode %d", fan_control_access_mode);
2245
2246 return 1;
2247}
2248
2249static int fan_write_cmd_watchdog(const char *cmd, int *rc)
2250{
2251 int interval;
2252
2253 if (sscanf(cmd, "watchdog %d", &interval) != 1)
2254 return 0;
2255
2256 if (interval < 0 || interval > 120)
2257 *rc = -EINVAL;
2258 else
2259 fan_watchdog_maxinterval = interval;
2260
2261 return 1;
2262}
2263
2264static int fan_write(char *buf)
2265{
2266 char *cmd;
2267 int rc = 0;
2268
2269 while (!rc && (cmd = next_cmd(&buf))) {
2270 if (!((fan_control_commands & IBMACPI_FAN_CMD_LEVEL) &&
2271 fan_write_cmd_level(cmd, &rc)) &&
2272 !((fan_control_commands & IBMACPI_FAN_CMD_ENABLE) &&
2273 (fan_write_cmd_enable(cmd, &rc) ||
2274 fan_write_cmd_disable(cmd, &rc) ||
2275 fan_write_cmd_watchdog(cmd, &rc))) &&
2276 !((fan_control_commands & IBMACPI_FAN_CMD_SPEED) &&
2277 fan_write_cmd_speed(cmd, &rc))
2278 )
2279 rc = -EINVAL;
2280 else if (!rc)
2281 fan_watchdog_reset();
2282 }
2283
2284 return rc;
2285}
2286
2287static void fan_watchdog_fire(struct work_struct *ignored)
2288{
2289 printk(IBM_NOTICE "fan watchdog: enabling fan\n");
2290 if (fan_set_enable()) {
2291 printk(IBM_ERR "fan watchdog: error while enabling fan\n");
2292 /* reschedule for later */
2293 fan_watchdog_reset();
2294 }
2295}
2296
1605static struct ibm_struct ibms[] = { 2297static struct ibm_struct ibms[] = {
1606 { 2298 {
1607 .name = "driver", 2299 .name = "driver",
@@ -1662,6 +2354,7 @@ static struct ibm_struct ibms[] = {
1662 .type = ACPI_SYSTEM_NOTIFY, 2354 .type = ACPI_SYSTEM_NOTIFY,
1663 }, 2355 },
1664#endif 2356#endif
2357#ifdef CONFIG_ACPI_IBM_BAY
1665 { 2358 {
1666 .name = "bay", 2359 .name = "bay",
1667 .init = bay_init, 2360 .init = bay_init,
@@ -1671,6 +2364,7 @@ static struct ibm_struct ibms[] = {
1671 .handle = &bay_handle, 2364 .handle = &bay_handle,
1672 .type = ACPI_SYSTEM_NOTIFY, 2365 .type = ACPI_SYSTEM_NOTIFY,
1673 }, 2366 },
2367#endif
1674 { 2368 {
1675 .name = "cmos", 2369 .name = "cmos",
1676 .read = cmos_read, 2370 .read = cmos_read,
@@ -1702,6 +2396,8 @@ static struct ibm_struct ibms[] = {
1702 .name = "brightness", 2396 .name = "brightness",
1703 .read = brightness_read, 2397 .read = brightness_read,
1704 .write = brightness_write, 2398 .write = brightness_write,
2399 .init = brightness_init,
2400 .exit = brightness_exit,
1705 }, 2401 },
1706 { 2402 {
1707 .name = "volume", 2403 .name = "volume",
@@ -1712,6 +2408,8 @@ static struct ibm_struct ibms[] = {
1712 .name = "fan", 2408 .name = "fan",
1713 .read = fan_read, 2409 .read = fan_read,
1714 .write = fan_write, 2410 .write = fan_write,
2411 .init = fan_init,
2412 .exit = fan_exit,
1715 .experimental = 1, 2413 .experimental = 1,
1716 }, 2414 },
1717}; 2415};
@@ -1719,7 +2417,7 @@ static struct ibm_struct ibms[] = {
1719static int dispatch_read(char *page, char **start, off_t off, int count, 2417static int dispatch_read(char *page, char **start, off_t off, int count,
1720 int *eof, void *data) 2418 int *eof, void *data)
1721{ 2419{
1722 struct ibm_struct *ibm = (struct ibm_struct *)data; 2420 struct ibm_struct *ibm = data;
1723 int len; 2421 int len;
1724 2422
1725 if (!ibm || !ibm->read) 2423 if (!ibm || !ibm->read)
@@ -1744,7 +2442,7 @@ static int dispatch_read(char *page, char **start, off_t off, int count,
1744static int dispatch_write(struct file *file, const char __user * userbuf, 2442static int dispatch_write(struct file *file, const char __user * userbuf,
1745 unsigned long count, void *data) 2443 unsigned long count, void *data)
1746{ 2444{
1747 struct ibm_struct *ibm = (struct ibm_struct *)data; 2445 struct ibm_struct *ibm = data;
1748 char *kernbuf; 2446 char *kernbuf;
1749 int ret; 2447 int ret;
1750 2448
@@ -1773,7 +2471,7 @@ static int dispatch_write(struct file *file, const char __user * userbuf,
1773 2471
1774static void dispatch_notify(acpi_handle handle, u32 event, void *data) 2472static void dispatch_notify(acpi_handle handle, u32 event, void *data)
1775{ 2473{
1776 struct ibm_struct *ibm = (struct ibm_struct *)data; 2474 struct ibm_struct *ibm = data;
1777 2475
1778 if (!ibm || !ibm->notify) 2476 if (!ibm || !ibm->notify)
1779 return; 2477 return;
@@ -1805,7 +2503,7 @@ static int __init setup_notify(struct ibm_struct *ibm)
1805 ibm->name, status); 2503 ibm->name, status);
1806 return -ENODEV; 2504 return -ENODEV;
1807 } 2505 }
1808 2506 ibm->notify_installed = 1;
1809 return 0; 2507 return 0;
1810} 2508}
1811 2509
@@ -1825,7 +2523,7 @@ static int __init register_driver(struct ibm_struct *ibm)
1825 } 2523 }
1826 2524
1827 memset(ibm->driver, 0, sizeof(struct acpi_driver)); 2525 memset(ibm->driver, 0, sizeof(struct acpi_driver));
1828 sprintf(ibm->driver->name, "%s/%s", IBM_NAME, ibm->name); 2526 sprintf(ibm->driver->name, "%s_%s", IBM_NAME, ibm->name);
1829 ibm->driver->ids = ibm->hid; 2527 ibm->driver->ids = ibm->hid;
1830 ibm->driver->ops.add = &ibm_device_add; 2528 ibm->driver->ops.add = &ibm_device_add;
1831 2529
@@ -1882,7 +2580,6 @@ static int __init ibm_init(struct ibm_struct *ibm)
1882 ret = setup_notify(ibm); 2580 ret = setup_notify(ibm);
1883 if (ret < 0) 2581 if (ret < 0)
1884 return ret; 2582 return ret;
1885 ibm->notify_installed = 1;
1886 } 2583 }
1887 2584
1888 return 0; 2585 return 0;
@@ -1954,7 +2651,9 @@ IBM_PARAM(light);
1954#ifdef CONFIG_ACPI_IBM_DOCK 2651#ifdef CONFIG_ACPI_IBM_DOCK
1955IBM_PARAM(dock); 2652IBM_PARAM(dock);
1956#endif 2653#endif
2654#ifdef CONFIG_ACPI_IBM_BAY
1957IBM_PARAM(bay); 2655IBM_PARAM(bay);
2656#endif
1958IBM_PARAM(cmos); 2657IBM_PARAM(cmos);
1959IBM_PARAM(led); 2658IBM_PARAM(led);
1960IBM_PARAM(beep); 2659IBM_PARAM(beep);
@@ -1971,6 +2670,33 @@ static void acpi_ibm_exit(void)
1971 ibm_exit(&ibms[i]); 2670 ibm_exit(&ibms[i]);
1972 2671
1973 remove_proc_entry(IBM_DIR, acpi_root_dir); 2672 remove_proc_entry(IBM_DIR, acpi_root_dir);
2673
2674 if (ibm_thinkpad_ec_found)
2675 kfree(ibm_thinkpad_ec_found);
2676}
2677
2678static char* __init check_dmi_for_ec(void)
2679{
2680 struct dmi_device *dev = NULL;
2681 char ec_fw_string[18];
2682
2683 /*
2684 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
2685 * X32 or newer, all Z series; Some models must have an
2686 * up-to-date BIOS or they will not be detected.
2687 *
2688 * See http://thinkwiki.org/wiki/List_of_DMI_IDs
2689 */
2690 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
2691 if (sscanf(dev->name,
2692 "IBM ThinkPad Embedded Controller -[%17c",
2693 ec_fw_string) == 1) {
2694 ec_fw_string[sizeof(ec_fw_string) - 1] = 0;
2695 ec_fw_string[strcspn(ec_fw_string, " ]")] = 0;
2696 return kstrdup(ec_fw_string, GFP_KERNEL);
2697 }
2698 }
2699 return NULL;
1974} 2700}
1975 2701
1976static int __init acpi_ibm_init(void) 2702static int __init acpi_ibm_init(void)
@@ -1992,6 +2718,12 @@ static int __init acpi_ibm_init(void)
1992 return -ENODEV; 2718 return -ENODEV;
1993 } 2719 }
1994 2720
2721 /* Models with newer firmware report the EC in DMI */
2722 ibm_thinkpad_ec_found = check_dmi_for_ec();
2723 if (ibm_thinkpad_ec_found)
2724 printk(IBM_INFO "ThinkPad EC firmware %s\n",
2725 ibm_thinkpad_ec_found);
2726
1995 /* these handles are not required */ 2727 /* these handles are not required */
1996 IBM_HANDLE_INIT(vid); 2728 IBM_HANDLE_INIT(vid);
1997 IBM_HANDLE_INIT(vid2); 2729 IBM_HANDLE_INIT(vid2);
@@ -2004,12 +2736,14 @@ static int __init acpi_ibm_init(void)
2004 IBM_HANDLE_INIT(dock); 2736 IBM_HANDLE_INIT(dock);
2005#endif 2737#endif
2006 IBM_HANDLE_INIT(pci); 2738 IBM_HANDLE_INIT(pci);
2739#ifdef CONFIG_ACPI_IBM_BAY
2007 IBM_HANDLE_INIT(bay); 2740 IBM_HANDLE_INIT(bay);
2008 if (bay_handle) 2741 if (bay_handle)
2009 IBM_HANDLE_INIT(bay_ej); 2742 IBM_HANDLE_INIT(bay_ej);
2010 IBM_HANDLE_INIT(bay2); 2743 IBM_HANDLE_INIT(bay2);
2011 if (bay2_handle) 2744 if (bay2_handle)
2012 IBM_HANDLE_INIT(bay2_ej); 2745 IBM_HANDLE_INIT(bay2_ej);
2746#endif
2013 IBM_HANDLE_INIT(beep); 2747 IBM_HANDLE_INIT(beep);
2014 IBM_HANDLE_INIT(ecrd); 2748 IBM_HANDLE_INIT(ecrd);
2015 IBM_HANDLE_INIT(ecwr); 2749 IBM_HANDLE_INIT(ecwr);
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index e5e448edca41..bd96a7045925 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -248,7 +248,7 @@ int acpi_get_pxm(acpi_handle h)
248 handle = phandle; 248 handle = phandle;
249 status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm); 249 status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
250 if (ACPI_SUCCESS(status)) 250 if (ACPI_SUCCESS(status))
251 return (int)pxm; 251 return pxm;
252 status = acpi_get_parent(handle, &phandle); 252 status = acpi_get_parent(handle, &phandle);
253 } while (ACPI_SUCCESS(status)); 253 } while (ACPI_SUCCESS(status));
254 return -1; 254 return -1;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 02b30ae6a68e..57ae1e5cde0a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -568,6 +568,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
568static void acpi_os_execute_deferred(struct work_struct *work) 568static void acpi_os_execute_deferred(struct work_struct *work)
569{ 569{
570 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); 570 struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
571
571 if (!dpc) { 572 if (!dpc) {
572 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 573 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
573 return; 574 return;
@@ -1031,7 +1032,7 @@ acpi_status
1031acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) 1032acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1032{ 1033{
1033 *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); 1034 *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL);
1034 if (cache == NULL) 1035 if (*cache == NULL)
1035 return AE_ERROR; 1036 return AE_ERROR;
1036 else 1037 else
1037 return AE_OK; 1038 return AE_OK;
@@ -1051,7 +1052,7 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1051 1052
1052acpi_status acpi_os_purge_cache(acpi_cache_t * cache) 1053acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
1053{ 1054{
1054 (void)kmem_cache_shrink(cache); 1055 kmem_cache_shrink(cache);
1055 return (AE_OK); 1056 return (AE_OK);
1056} 1057}
1057 1058
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 1e2ae6e7a7e4..70b440f3f262 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -281,7 +281,7 @@ int acpi_pci_unbind(struct acpi_device *device)
281 if (!device || !device->parent) 281 if (!device || !device->parent)
282 return -EINVAL; 282 return -EINVAL;
283 283
284 pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); 284 pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
285 if (!pathname) 285 if (!pathname)
286 return -ENOMEM; 286 return -ENOMEM;
287 memset(pathname, 0, ACPI_PATHNAME_MAX); 287 memset(pathname, 0, ACPI_PATHNAME_MAX);
@@ -332,7 +332,7 @@ acpi_pci_bind_root(struct acpi_device *device,
332 struct acpi_buffer buffer = { 0, NULL }; 332 struct acpi_buffer buffer = { 0, NULL };
333 333
334 334
335 pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); 335 pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
336 if (!pathname) 336 if (!pathname)
337 return -ENOMEM; 337 return -ENOMEM;
338 memset(pathname, 0, ACPI_PATHNAME_MAX); 338 memset(pathname, 0, ACPI_PATHNAME_MAX);
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index feda0341f5a7..226892eaf987 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -161,7 +161,7 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus)
161 static int first_time = 1; 161 static int first_time = 1;
162 162
163 163
164 pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); 164 pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL);
165 if (!pathname) 165 if (!pathname)
166 return -ENOMEM; 166 return -ENOMEM;
167 memset(pathname, 0, ACPI_PATHNAME_MAX); 167 memset(pathname, 0, ACPI_PATHNAME_MAX);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index d53bd9878ca2..812d733fe816 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -103,7 +103,7 @@ DEFINE_MUTEX(acpi_link_lock);
103static acpi_status 103static acpi_status
104acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) 104acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
105{ 105{
106 struct acpi_pci_link *link = (struct acpi_pci_link *)context; 106 struct acpi_pci_link *link = context;
107 u32 i = 0; 107 u32 i = 0;
108 108
109 109
@@ -613,7 +613,7 @@ acpi_pci_link_allocate_irq(acpi_handle handle,
613 return -1; 613 return -1;
614 } 614 }
615 615
616 link = (struct acpi_pci_link *)acpi_driver_data(device); 616 link = acpi_driver_data(device);
617 if (!link) { 617 if (!link) {
618 printk(KERN_ERR PREFIX "Invalid link context\n"); 618 printk(KERN_ERR PREFIX "Invalid link context\n");
619 return -1; 619 return -1;
@@ -668,7 +668,7 @@ int acpi_pci_link_free_irq(acpi_handle handle)
668 return -1; 668 return -1;
669 } 669 }
670 670
671 link = (struct acpi_pci_link *)acpi_driver_data(device); 671 link = acpi_driver_data(device);
672 if (!link) { 672 if (!link) {
673 printk(KERN_ERR PREFIX "Invalid link context\n"); 673 printk(KERN_ERR PREFIX "Invalid link context\n");
674 return -1; 674 return -1;
@@ -808,7 +808,7 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type)
808 if (!device || !acpi_driver_data(device)) 808 if (!device || !acpi_driver_data(device))
809 return -EINVAL; 809 return -EINVAL;
810 810
811 link = (struct acpi_pci_link *)acpi_driver_data(device); 811 link = acpi_driver_data(device);
812 812
813 mutex_lock(&acpi_link_lock); 813 mutex_lock(&acpi_link_lock);
814 list_del(&link->node); 814 list_del(&link->node);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0984a1ee24ed..b9c52cdbf658 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -98,11 +98,12 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
98 98
99 struct acpi_pci_driver **pptr = &sub_driver; 99 struct acpi_pci_driver **pptr = &sub_driver;
100 while (*pptr) { 100 while (*pptr) {
101 if (*pptr != driver) 101 if (*pptr == driver)
102 continue; 102 break;
103 *pptr = (*pptr)->next; 103 pptr = &(*pptr)->next;
104 break;
105 } 104 }
105 BUG_ON(!*pptr);
106 *pptr = (*pptr)->next;
106 107
107 if (!driver->remove) 108 if (!driver->remove)
108 return; 109 return;
@@ -119,7 +120,7 @@ EXPORT_SYMBOL(acpi_pci_unregister_driver);
119static acpi_status 120static acpi_status
120get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) 121get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
121{ 122{
122 int *busnr = (int *)data; 123 int *busnr = data;
123 struct acpi_resource_address64 address; 124 struct acpi_resource_address64 address;
124 125
125 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && 126 if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
@@ -331,7 +332,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
331 if (!device || !acpi_driver_data(device)) 332 if (!device || !acpi_driver_data(device))
332 return -EINVAL; 333 return -EINVAL;
333 334
334 root = (struct acpi_pci_root *)acpi_driver_data(device); 335 root = acpi_driver_data(device);
335 336
336 kfree(root); 337 kfree(root);
337 338
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index fe67a8af520e..23a8a9295578 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -108,7 +108,7 @@ acpi_power_get_context(acpi_handle handle,
108 return result; 108 return result;
109 } 109 }
110 110
111 *resource = (struct acpi_power_resource *)acpi_driver_data(device); 111 *resource = acpi_driver_data(device);
112 if (!resource) 112 if (!resource)
113 return -ENODEV; 113 return -ENODEV;
114 114
@@ -442,7 +442,7 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
442 struct acpi_power_resource *resource = NULL; 442 struct acpi_power_resource *resource = NULL;
443 443
444 444
445 resource = (struct acpi_power_resource *)seq->private; 445 resource = seq->private;
446 446
447 if (!resource) 447 if (!resource)
448 goto end; 448 goto end;
@@ -590,7 +590,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
590 if (!device || !acpi_driver_data(device)) 590 if (!device || !acpi_driver_data(device))
591 return -EINVAL; 591 return -EINVAL;
592 592
593 resource = (struct acpi_power_resource *)acpi_driver_data(device); 593 resource = acpi_driver_data(device);
594 594
595 acpi_power_remove_fs(device); 595 acpi_power_remove_fs(device);
596 596
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 1908e0d20222..89b3610feb47 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -277,7 +277,7 @@ static struct proc_dir_entry *acpi_processor_dir = NULL;
277 277
278static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) 278static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset)
279{ 279{
280 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 280 struct acpi_processor *pr = seq->private;
281 281
282 282
283 if (!pr) 283 if (!pr)
@@ -542,12 +542,12 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
542 * Don't trust it blindly 542 * Don't trust it blindly
543 */ 543 */
544 if (processor_device_array[pr->id] != NULL && 544 if (processor_device_array[pr->id] != NULL &&
545 processor_device_array[pr->id] != (void *)device) { 545 processor_device_array[pr->id] != device) {
546 printk(KERN_WARNING "BIOS reported wrong ACPI id" 546 printk(KERN_WARNING "BIOS reported wrong ACPI id"
547 "for the processor\n"); 547 "for the processor\n");
548 return -ENODEV; 548 return -ENODEV;
549 } 549 }
550 processor_device_array[pr->id] = (void *)device; 550 processor_device_array[pr->id] = device;
551 551
552 processors[pr->id] = pr; 552 processors[pr->id] = pr;
553 553
@@ -578,7 +578,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
578 578
579static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) 579static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
580{ 580{
581 struct acpi_processor *pr = (struct acpi_processor *)data; 581 struct acpi_processor *pr = data;
582 struct acpi_device *device = NULL; 582 struct acpi_device *device = NULL;
583 583
584 584
@@ -637,7 +637,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
637 if (!device || !acpi_driver_data(device)) 637 if (!device || !acpi_driver_data(device))
638 return -EINVAL; 638 return -EINVAL;
639 639
640 pr = (struct acpi_processor *)acpi_driver_data(device); 640 pr = acpi_driver_data(device);
641 641
642 if (pr->id >= NR_CPUS) { 642 if (pr->id >= NR_CPUS) {
643 kfree(pr); 643 kfree(pr);
@@ -901,13 +901,13 @@ static int __init acpi_processor_init(void)
901 901
902 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); 902 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
903 if (!acpi_processor_dir) 903 if (!acpi_processor_dir)
904 return 0; 904 return -ENOMEM;
905 acpi_processor_dir->owner = THIS_MODULE; 905 acpi_processor_dir->owner = THIS_MODULE;
906 906
907 result = acpi_bus_register_driver(&acpi_processor_driver); 907 result = acpi_bus_register_driver(&acpi_processor_driver);
908 if (result < 0) { 908 if (result < 0) {
909 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); 909 remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
910 return 0; 910 return result;
911 } 911 }
912 912
913 acpi_processor_install_hotplug_notify(); 913 acpi_processor_install_hotplug_notify();
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 65b3f056ad89..4f2982cc5478 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -673,7 +673,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
673 return -ENODEV; 673 return -ENODEV;
674 } 674 }
675 675
676 cst = (union acpi_object *)buffer.pointer; 676 cst = buffer.pointer;
677 677
678 /* There must be at least 2 elements */ 678 /* There must be at least 2 elements */
679 if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { 679 if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {
@@ -702,14 +702,14 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
702 702
703 memset(&cx, 0, sizeof(cx)); 703 memset(&cx, 0, sizeof(cx));
704 704
705 element = (union acpi_object *)&(cst->package.elements[i]); 705 element = &(cst->package.elements[i]);
706 if (element->type != ACPI_TYPE_PACKAGE) 706 if (element->type != ACPI_TYPE_PACKAGE)
707 continue; 707 continue;
708 708
709 if (element->package.count != 4) 709 if (element->package.count != 4)
710 continue; 710 continue;
711 711
712 obj = (union acpi_object *)&(element->package.elements[0]); 712 obj = &(element->package.elements[0]);
713 713
714 if (obj->type != ACPI_TYPE_BUFFER) 714 if (obj->type != ACPI_TYPE_BUFFER)
715 continue; 715 continue;
@@ -721,7 +721,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
721 continue; 721 continue;
722 722
723 /* There should be an easy way to extract an integer... */ 723 /* There should be an easy way to extract an integer... */
724 obj = (union acpi_object *)&(element->package.elements[1]); 724 obj = &(element->package.elements[1]);
725 if (obj->type != ACPI_TYPE_INTEGER) 725 if (obj->type != ACPI_TYPE_INTEGER)
726 continue; 726 continue;
727 727
@@ -754,13 +754,13 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
754 } 754 }
755 } 755 }
756 756
757 obj = (union acpi_object *)&(element->package.elements[2]); 757 obj = &(element->package.elements[2]);
758 if (obj->type != ACPI_TYPE_INTEGER) 758 if (obj->type != ACPI_TYPE_INTEGER)
759 continue; 759 continue;
760 760
761 cx.latency = obj->integer.value; 761 cx.latency = obj->integer.value;
762 762
763 obj = (union acpi_object *)&(element->package.elements[3]); 763 obj = &(element->package.elements[3]);
764 if (obj->type != ACPI_TYPE_INTEGER) 764 if (obj->type != ACPI_TYPE_INTEGER)
765 continue; 765 continue;
766 766
@@ -1029,7 +1029,7 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr)
1029 1029
1030static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) 1030static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
1031{ 1031{
1032 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 1032 struct acpi_processor *pr = seq->private;
1033 unsigned int i; 1033 unsigned int i;
1034 1034
1035 1035
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 6fd174a37149..0e60382714bb 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -236,7 +236,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
236 return -ENODEV; 236 return -ENODEV;
237 } 237 }
238 238
239 pss = (union acpi_object *)buffer.pointer; 239 pss = buffer.pointer;
240 if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { 240 if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
241 printk(KERN_ERR PREFIX "Invalid _PSS data\n"); 241 printk(KERN_ERR PREFIX "Invalid _PSS data\n");
242 result = -EFAULT; 242 result = -EFAULT;
@@ -410,7 +410,7 @@ static struct file_operations acpi_processor_perf_fops = {
410 410
411static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) 411static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset)
412{ 412{
413 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 413 struct acpi_processor *pr = seq->private;
414 int i; 414 int i;
415 415
416 416
@@ -451,8 +451,8 @@ acpi_processor_write_performance(struct file *file,
451 size_t count, loff_t * data) 451 size_t count, loff_t * data)
452{ 452{
453 int result = 0; 453 int result = 0;
454 struct seq_file *m = (struct seq_file *)file->private_data; 454 struct seq_file *m = file->private_data;
455 struct acpi_processor *pr = (struct acpi_processor *)m->private; 455 struct acpi_processor *pr = m->private;
456 struct acpi_processor_performance *perf; 456 struct acpi_processor_performance *perf;
457 char state_string[12] = { '\0' }; 457 char state_string[12] = { '\0' };
458 unsigned int new_state = 0; 458 unsigned int new_state = 0;
@@ -551,7 +551,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
551 return -ENODEV; 551 return -ENODEV;
552 } 552 }
553 553
554 psd = (union acpi_object *) buffer.pointer; 554 psd = buffer.pointer;
555 if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { 555 if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
556 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); 556 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
557 result = -EFAULT; 557 result = -EFAULT;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index ef5e0f6efdba..40fecd67ad83 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -208,7 +208,7 @@ int acpi_processor_set_thermal_limit(acpi_handle handle, int type)
208 if (result) 208 if (result)
209 return result; 209 return result;
210 210
211 pr = (struct acpi_processor *)acpi_driver_data(device); 211 pr = acpi_driver_data(device);
212 if (!pr) 212 if (!pr)
213 return -ENODEV; 213 return -ENODEV;
214 214
@@ -348,8 +348,8 @@ static ssize_t acpi_processor_write_limit(struct file * file,
348 size_t count, loff_t * data) 348 size_t count, loff_t * data)
349{ 349{
350 int result = 0; 350 int result = 0;
351 struct seq_file *m = (struct seq_file *)file->private_data; 351 struct seq_file *m = file->private_data;
352 struct acpi_processor *pr = (struct acpi_processor *)m->private; 352 struct acpi_processor *pr = m->private;
353 char limit_string[25] = { '\0' }; 353 char limit_string[25] = { '\0' };
354 int px = 0; 354 int px = 0;
355 int tx = 0; 355 int tx = 0;
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d044ec519db0..0ec7dcde0063 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -259,7 +259,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
259static int acpi_processor_throttling_seq_show(struct seq_file *seq, 259static int acpi_processor_throttling_seq_show(struct seq_file *seq,
260 void *offset) 260 void *offset)
261{ 261{
262 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 262 struct acpi_processor *pr = seq->private;
263 int i = 0; 263 int i = 0;
264 int result = 0; 264 int result = 0;
265 265
@@ -307,8 +307,8 @@ static ssize_t acpi_processor_write_throttling(struct file * file,
307 size_t count, loff_t * data) 307 size_t count, loff_t * data)
308{ 308{
309 int result = 0; 309 int result = 0;
310 struct seq_file *m = (struct seq_file *)file->private_data; 310 struct seq_file *m = file->private_data;
311 struct acpi_processor *pr = (struct acpi_processor *)m->private; 311 struct acpi_processor *pr = m->private;
312 char state_string[12] = { '\0' }; 312 char state_string[12] = { '\0' };
313 313
314 314
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 8908a975e575..2fb7533314cd 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -923,7 +923,7 @@ static struct proc_dir_entry *acpi_battery_dir = NULL;
923 923
924static int acpi_battery_read_info(struct seq_file *seq, void *offset) 924static int acpi_battery_read_info(struct seq_file *seq, void *offset)
925{ 925{
926 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 926 struct acpi_battery *battery = seq->private;
927 int cscale; 927 int cscale;
928 int result = 0; 928 int result = 0;
929 929
@@ -1076,7 +1076,7 @@ static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
1076 1076
1077static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) 1077static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
1078{ 1078{
1079 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 1079 struct acpi_battery *battery = seq->private;
1080 int result = 0; 1080 int result = 0;
1081 int cscale; 1081 int cscale;
1082 1082
@@ -1125,8 +1125,8 @@ static ssize_t
1125acpi_battery_write_alarm(struct file *file, const char __user * buffer, 1125acpi_battery_write_alarm(struct file *file, const char __user * buffer,
1126 size_t count, loff_t * ppos) 1126 size_t count, loff_t * ppos)
1127{ 1127{
1128 struct seq_file *seq = (struct seq_file *)file->private_data; 1128 struct seq_file *seq = file->private_data;
1129 struct acpi_battery *battery = (struct acpi_battery *)seq->private; 1129 struct acpi_battery *battery = seq->private;
1130 char alarm_string[12] = { '\0' }; 1130 char alarm_string[12] = { '\0' };
1131 int result, old_alarm, new_alarm; 1131 int result, old_alarm, new_alarm;
1132 1132
@@ -1160,14 +1160,14 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
1160 if (result) { 1160 if (result) {
1161 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1161 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1162 "acpi_battery_set_alarm() failed\n")); 1162 "acpi_battery_set_alarm() failed\n"));
1163 (void)acpi_battery_set_alarm(battery, old_alarm); 1163 acpi_battery_set_alarm(battery, old_alarm);
1164 goto end; 1164 goto end;
1165 } 1165 }
1166 result = acpi_battery_get_alarm(battery); 1166 result = acpi_battery_get_alarm(battery);
1167 if (result) { 1167 if (result) {
1168 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1168 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1169 "acpi_battery_get_alarm() failed\n")); 1169 "acpi_battery_get_alarm() failed\n"));
1170 (void)acpi_battery_set_alarm(battery, old_alarm); 1170 acpi_battery_set_alarm(battery, old_alarm);
1171 goto end; 1171 goto end;
1172 } 1172 }
1173 1173
@@ -1217,7 +1217,7 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
1217 1217
1218static int acpi_ac_read_state(struct seq_file *seq, void *offset) 1218static int acpi_ac_read_state(struct seq_file *seq, void *offset)
1219{ 1219{
1220 struct acpi_sbs *sbs = (struct acpi_sbs *)seq->private; 1220 struct acpi_sbs *sbs = seq->private;
1221 int result; 1221 int result;
1222 1222
1223 if (sbs->zombie) { 1223 if (sbs->zombie) {
@@ -1302,7 +1302,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
1302 battery->init_state = 1; 1302 battery->init_state = 1;
1303 } 1303 }
1304 1304
1305 (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); 1305 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1306 1306
1307 result = acpi_sbs_generic_add_fs(&battery->battery_entry, 1307 result = acpi_sbs_generic_add_fs(&battery->battery_entry,
1308 acpi_battery_dir, 1308 acpi_battery_dir,
@@ -1485,7 +1485,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1485 } 1485 }
1486 1486
1487 if (old_battery_present != new_battery_present) { 1487 if (old_battery_present != new_battery_present) {
1488 (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); 1488 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1489 result = acpi_sbs_generate_event(sbs->device, 1489 result = acpi_sbs_generate_event(sbs->device,
1490 ACPI_SBS_BATTERY_NOTIFY_STATUS, 1490 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1491 new_battery_present, 1491 new_battery_present,
@@ -1498,7 +1498,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int data_type)
1498 } 1498 }
1499 } 1499 }
1500 if (old_remaining_capacity != battery->state.remaining_capacity) { 1500 if (old_remaining_capacity != battery->state.remaining_capacity) {
1501 (void)sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); 1501 sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
1502 result = acpi_sbs_generate_event(sbs->device, 1502 result = acpi_sbs_generate_event(sbs->device,
1503 ACPI_SBS_BATTERY_NOTIFY_STATUS, 1503 ACPI_SBS_BATTERY_NOTIFY_STATUS,
1504 new_battery_present, 1504 new_battery_present,
@@ -1659,7 +1659,7 @@ static int acpi_sbs_add(struct acpi_device *device)
1659 init_timer(&sbs->update_timer); 1659 init_timer(&sbs->update_timer);
1660 if (update_mode == QUEUE_UPDATE_MODE) { 1660 if (update_mode == QUEUE_UPDATE_MODE) {
1661 status = acpi_os_execute(OSL_GPE_HANDLER, 1661 status = acpi_os_execute(OSL_GPE_HANDLER,
1662 acpi_sbs_update_queue, (void *)sbs); 1662 acpi_sbs_update_queue, sbs);
1663 if (status != AE_OK) { 1663 if (status != AE_OK) {
1664 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1664 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1665 "acpi_os_execute() failed\n")); 1665 "acpi_os_execute() failed\n"));
@@ -1685,7 +1685,7 @@ static int acpi_sbs_add(struct acpi_device *device)
1685 1685
1686int acpi_sbs_remove(struct acpi_device *device, int type) 1686int acpi_sbs_remove(struct acpi_device *device, int type)
1687{ 1687{
1688 struct acpi_sbs *sbs = NULL; 1688 struct acpi_sbs *sbs;
1689 int id; 1689 int id;
1690 1690
1691 if (!device) { 1691 if (!device) {
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index af1dbabaf0b1..fab8f2694f03 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -183,11 +183,11 @@ late_initcall(acpi_wakeup_device_init);
183#endif 183#endif
184 184
185/* 185/*
186 * Disable all wakeup GPEs before power off. 186 * Disable all wakeup GPEs before entering requested sleep state.
187 * 187 * @sleep_state: ACPI state
188 * Since acpi_enter_sleep_state() will disable all 188 * Since acpi_enter_sleep_state() will disable all
189 * RUNTIME GPEs, we simply mark all GPES that 189 * RUNTIME GPEs, we simply mark all GPES that
190 * are not enabled for wakeup from S5 as RUNTIME. 190 * are not enabled for wakeup from requested state as RUNTIME.
191 */ 191 */
192void acpi_gpe_sleep_prepare(u32 sleep_state) 192void acpi_gpe_sleep_prepare(u32 sleep_state)
193{ 193{
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index bfb3bfcf9e91..ffa30c9fccbf 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -228,7 +228,7 @@ void acpi_table_print_madt_entry(acpi_table_entry_header * header)
228static int 228static int
229acpi_table_compute_checksum(void *table_pointer, unsigned long length) 229acpi_table_compute_checksum(void *table_pointer, unsigned long length)
230{ 230{
231 u8 *p = (u8 *) table_pointer; 231 u8 *p = table_pointer;
232 unsigned long remains = length; 232 unsigned long remains = length;
233 unsigned long sum = 0; 233 unsigned long sum = 0;
234 234
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5753d06b7860..4d75085ca2d2 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -663,7 +663,7 @@ static void acpi_thermal_run(unsigned long data)
663static void acpi_thermal_check(void *data) 663static void acpi_thermal_check(void *data)
664{ 664{
665 int result = 0; 665 int result = 0;
666 struct acpi_thermal *tz = (struct acpi_thermal *)data; 666 struct acpi_thermal *tz = data;
667 unsigned long sleep_time = 0; 667 unsigned long sleep_time = 0;
668 int i = 0; 668 int i = 0;
669 struct acpi_thermal_state state; 669 struct acpi_thermal_state state;
@@ -778,7 +778,7 @@ static struct proc_dir_entry *acpi_thermal_dir;
778 778
779static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 779static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
780{ 780{
781 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 781 struct acpi_thermal *tz = seq->private;
782 782
783 783
784 if (!tz) 784 if (!tz)
@@ -813,7 +813,7 @@ static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
813static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) 813static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
814{ 814{
815 int result = 0; 815 int result = 0;
816 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 816 struct acpi_thermal *tz = seq->private;
817 817
818 818
819 if (!tz) 819 if (!tz)
@@ -837,7 +837,7 @@ static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
837 837
838static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) 838static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
839{ 839{
840 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 840 struct acpi_thermal *tz = seq->private;
841 int i = 0; 841 int i = 0;
842 int j = 0; 842 int j = 0;
843 843
@@ -893,8 +893,8 @@ acpi_thermal_write_trip_points(struct file *file,
893 const char __user * buffer, 893 const char __user * buffer,
894 size_t count, loff_t * ppos) 894 size_t count, loff_t * ppos)
895{ 895{
896 struct seq_file *m = (struct seq_file *)file->private_data; 896 struct seq_file *m = file->private_data;
897 struct acpi_thermal *tz = (struct acpi_thermal *)m->private; 897 struct acpi_thermal *tz = m->private;
898 898
899 char *limit_string; 899 char *limit_string;
900 int num, critical, hot, passive; 900 int num, critical, hot, passive;
@@ -953,7 +953,7 @@ acpi_thermal_write_trip_points(struct file *file,
953 953
954static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) 954static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
955{ 955{
956 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 956 struct acpi_thermal *tz = seq->private;
957 957
958 958
959 if (!tz) 959 if (!tz)
@@ -984,8 +984,8 @@ acpi_thermal_write_cooling_mode(struct file *file,
984 const char __user * buffer, 984 const char __user * buffer,
985 size_t count, loff_t * ppos) 985 size_t count, loff_t * ppos)
986{ 986{
987 struct seq_file *m = (struct seq_file *)file->private_data; 987 struct seq_file *m = file->private_data;
988 struct acpi_thermal *tz = (struct acpi_thermal *)m->private; 988 struct acpi_thermal *tz = m->private;
989 int result = 0; 989 int result = 0;
990 char mode_string[12] = { '\0' }; 990 char mode_string[12] = { '\0' };
991 991
@@ -1014,7 +1014,7 @@ acpi_thermal_write_cooling_mode(struct file *file,
1014 1014
1015static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) 1015static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1016{ 1016{
1017 struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; 1017 struct acpi_thermal *tz = seq->private;
1018 1018
1019 1019
1020 if (!tz) 1020 if (!tz)
@@ -1043,8 +1043,8 @@ acpi_thermal_write_polling(struct file *file,
1043 const char __user * buffer, 1043 const char __user * buffer,
1044 size_t count, loff_t * ppos) 1044 size_t count, loff_t * ppos)
1045{ 1045{
1046 struct seq_file *m = (struct seq_file *)file->private_data; 1046 struct seq_file *m = file->private_data;
1047 struct acpi_thermal *tz = (struct acpi_thermal *)m->private; 1047 struct acpi_thermal *tz = m->private;
1048 int result = 0; 1048 int result = 0;
1049 char polling_string[12] = { '\0' }; 1049 char polling_string[12] = { '\0' };
1050 int seconds = 0; 1050 int seconds = 0;
@@ -1170,7 +1170,7 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)
1170 1170
1171static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 1171static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
1172{ 1172{
1173 struct acpi_thermal *tz = (struct acpi_thermal *)data; 1173 struct acpi_thermal *tz = data;
1174 struct acpi_device *device = NULL; 1174 struct acpi_device *device = NULL;
1175 1175
1176 1176
@@ -1324,7 +1324,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1324 if (!device || !acpi_driver_data(device)) 1324 if (!device || !acpi_driver_data(device))
1325 return -EINVAL; 1325 return -EINVAL;
1326 1326
1327 tz = (struct acpi_thermal *)acpi_driver_data(device); 1327 tz = acpi_driver_data(device);
1328 1328
1329 /* avoid timer adding new defer task */ 1329 /* avoid timer adding new defer task */
1330 tz->zombie = 1; 1330 tz->zombie = 1;
@@ -1364,7 +1364,7 @@ static int acpi_thermal_resume(struct acpi_device *device, int state)
1364 if (!device || !acpi_driver_data(device)) 1364 if (!device || !acpi_driver_data(device))
1365 return -EINVAL; 1365 return -EINVAL;
1366 1366
1367 tz = (struct acpi_thermal *)acpi_driver_data(device); 1367 tz = acpi_driver_data(device);
1368 1368
1369 acpi_thermal_get_temperature(tz); 1369 acpi_thermal_get_temperature(tz);
1370 1370
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 7fe0b7ae9733..88aeccbafaaf 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -41,6 +41,8 @@
41#include <linux/init.h> 41#include <linux/init.h>
42#include <linux/types.h> 42#include <linux/types.h>
43#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>
44#include <linux/backlight.h>
45
44#include <asm/uaccess.h> 46#include <asm/uaccess.h>
45 47
46#include <acpi/acpi_drivers.h> 48#include <acpi/acpi_drivers.h>
@@ -210,6 +212,7 @@ static acpi_status hci_read1(u32 reg, u32 * out1, u32 * result)
210} 212}
211 213
212static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 214static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
215static struct backlight_device *toshiba_backlight_device;
213static int force_fan; 216static int force_fan;
214static int last_key_event; 217static int last_key_event;
215static int key_event_valid; 218static int key_event_valid;
@@ -271,14 +274,23 @@ dispatch_write(struct file *file, const char __user * buffer,
271 return result; 274 return result;
272} 275}
273 276
274static char *read_lcd(char *p) 277static int get_lcd(struct backlight_device *bd)
275{ 278{
276 u32 hci_result; 279 u32 hci_result;
277 u32 value; 280 u32 value;
278 281
279 hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result); 282 hci_read1(HCI_LCD_BRIGHTNESS, &value, &hci_result);
280 if (hci_result == HCI_SUCCESS) { 283 if (hci_result == HCI_SUCCESS) {
281 value = value >> HCI_LCD_BRIGHTNESS_SHIFT; 284 return (value >> HCI_LCD_BRIGHTNESS_SHIFT);
285 } else
286 return -EFAULT;
287}
288
289static char *read_lcd(char *p)
290{
291 int value = get_lcd(NULL);
292
293 if (value >= 0) {
282 p += sprintf(p, "brightness: %d\n", value); 294 p += sprintf(p, "brightness: %d\n", value);
283 p += sprintf(p, "brightness_levels: %d\n", 295 p += sprintf(p, "brightness_levels: %d\n",
284 HCI_LCD_BRIGHTNESS_LEVELS); 296 HCI_LCD_BRIGHTNESS_LEVELS);
@@ -289,22 +301,34 @@ static char *read_lcd(char *p)
289 return p; 301 return p;
290} 302}
291 303
304static int set_lcd(int value)
305{
306 u32 hci_result;
307
308 value = value << HCI_LCD_BRIGHTNESS_SHIFT;
309 hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result);
310 if (hci_result != HCI_SUCCESS)
311 return -EFAULT;
312
313 return 0;
314}
315
316static int set_lcd_status(struct backlight_device *bd)
317{
318 return set_lcd(bd->props->brightness);
319}
320
292static unsigned long write_lcd(const char *buffer, unsigned long count) 321static unsigned long write_lcd(const char *buffer, unsigned long count)
293{ 322{
294 int value; 323 int value;
295 u32 hci_result; 324 int ret = count;
296 325
297 if (sscanf(buffer, " brightness : %i", &value) == 1 && 326 if (sscanf(buffer, " brightness : %i", &value) == 1 &&
298 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { 327 value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS)
299 value = value << HCI_LCD_BRIGHTNESS_SHIFT; 328 ret = set_lcd(value);
300 hci_write1(HCI_LCD_BRIGHTNESS, value, &hci_result); 329 else
301 if (hci_result != HCI_SUCCESS) 330 ret = -EINVAL;
302 return -EFAULT; 331 return ret;
303 } else {
304 return -EINVAL;
305 }
306
307 return count;
308} 332}
309 333
310static char *read_video(char *p) 334static char *read_video(char *p)
@@ -506,6 +530,26 @@ static acpi_status __exit remove_device(void)
506 return AE_OK; 530 return AE_OK;
507} 531}
508 532
533static struct backlight_properties toshiba_backlight_data = {
534 .owner = THIS_MODULE,
535 .get_brightness = get_lcd,
536 .update_status = set_lcd_status,
537 .max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1,
538};
539
540static void __exit toshiba_acpi_exit(void)
541{
542 if (toshiba_backlight_device)
543 backlight_device_unregister(toshiba_backlight_device);
544
545 remove_device();
546
547 if (toshiba_proc_dir)
548 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
549
550 return;
551}
552
509static int __init toshiba_acpi_init(void) 553static int __init toshiba_acpi_init(void)
510{ 554{
511 acpi_status status = AE_OK; 555 acpi_status status = AE_OK;
@@ -546,17 +590,16 @@ static int __init toshiba_acpi_init(void)
546 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); 590 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
547 } 591 }
548 592
549 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV; 593 toshiba_backlight_device = backlight_device_register("toshiba",NULL,
550} 594 NULL,
551 595 &toshiba_backlight_data);
552static void __exit toshiba_acpi_exit(void) 596 if (IS_ERR(toshiba_backlight_device)) {
553{ 597 printk(KERN_ERR "Could not register toshiba backlight device\n");
554 remove_device(); 598 toshiba_backlight_device = NULL;
555 599 toshiba_acpi_exit();
556 if (toshiba_proc_dir) 600 }
557 remove_proc_entry(PROC_TOSHIBA, acpi_root_dir);
558 601
559 return; 602 return (ACPI_SUCCESS(status)) ? 0 : -ENODEV;
560} 603}
561 604
562module_init(toshiba_acpi_init); 605module_init(toshiba_acpi_init);
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index bb1eaf9aa653..9e9054e155c1 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -180,8 +180,9 @@ acpi_ut_debug_print(u32 requested_debug_level,
180 if (thread_id != acpi_gbl_prev_thread_id) { 180 if (thread_id != acpi_gbl_prev_thread_id) {
181 if (ACPI_LV_THREADS & acpi_dbg_level) { 181 if (ACPI_LV_THREADS & acpi_dbg_level) {
182 acpi_os_printf 182 acpi_os_printf
183 ("\n**** Context Switch from TID %X to TID %X ****\n\n", 183 ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
184 (u32) acpi_gbl_prev_thread_id, (u32) thread_id); 184 (unsigned long) acpi_gbl_prev_thread_id,
185 (unsigned long) thread_id);
185 } 186 }
186 187
187 acpi_gbl_prev_thread_id = thread_id; 188 acpi_gbl_prev_thread_id = thread_id;
diff --git a/drivers/acpi/utilities/utmutex.c b/drivers/acpi/utilities/utmutex.c
index c39062a047cd..180e73ceb6e2 100644
--- a/drivers/acpi/utilities/utmutex.c
+++ b/drivers/acpi/utilities/utmutex.c
@@ -243,23 +243,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
243#endif 243#endif
244 244
245 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 245 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
246 "Thread %X attempting to acquire Mutex [%s]\n", 246 "Thread %lX attempting to acquire Mutex [%s]\n",
247 (u32) this_thread_id, acpi_ut_get_mutex_name(mutex_id))); 247 (unsigned long) this_thread_id,
248 acpi_ut_get_mutex_name(mutex_id)));
248 249
249 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, 250 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
250 ACPI_WAIT_FOREVER); 251 ACPI_WAIT_FOREVER);
251 if (ACPI_SUCCESS(status)) { 252 if (ACPI_SUCCESS(status)) {
252 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 253 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
253 "Thread %X acquired Mutex [%s]\n", 254 "Thread %lX acquired Mutex [%s]\n",
254 (u32) this_thread_id, 255 (unsigned long) this_thread_id,
255 acpi_ut_get_mutex_name(mutex_id))); 256 acpi_ut_get_mutex_name(mutex_id)));
256 257
257 acpi_gbl_mutex_info[mutex_id].use_count++; 258 acpi_gbl_mutex_info[mutex_id].use_count++;
258 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; 259 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
259 } else { 260 } else {
260 ACPI_EXCEPTION((AE_INFO, status, 261 ACPI_EXCEPTION((AE_INFO, status,
261 "Thread %X could not acquire Mutex [%X]", 262 "Thread %lX could not acquire Mutex [%X]",
262 (u32) this_thread_id, mutex_id)); 263 (unsigned long) this_thread_id, mutex_id));
263 } 264 }
264 265
265 return (status); 266 return (status);
@@ -285,7 +286,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
285 286
286 this_thread_id = acpi_os_get_thread_id(); 287 this_thread_id = acpi_os_get_thread_id();
287 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 288 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
288 "Thread %X releasing Mutex [%s]\n", (u32) this_thread_id, 289 "Thread %lX releasing Mutex [%s]\n",
290 (unsigned long) this_thread_id,
289 acpi_ut_get_mutex_name(mutex_id))); 291 acpi_ut_get_mutex_name(mutex_id)));
290 292
291 if (mutex_id > ACPI_MAX_MUTEX) { 293 if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index d0d84c43a9d4..91fed70a65a6 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -83,7 +83,7 @@ acpi_extract_package(union acpi_object *package,
83 return AE_BAD_DATA; 83 return AE_BAD_DATA;
84 } 84 }
85 85
86 format_string = (char *)format->pointer; 86 format_string = format->pointer;
87 87
88 /* 88 /*
89 * Calculate size_required. 89 * Calculate size_required.
@@ -361,7 +361,7 @@ acpi_evaluate_reference(acpi_handle handle,
361 if (ACPI_FAILURE(status)) 361 if (ACPI_FAILURE(status))
362 goto end; 362 goto end;
363 363
364 package = (union acpi_object *)buffer.pointer; 364 package = buffer.pointer;
365 365
366 if ((buffer.length == 0) || !package) { 366 if ((buffer.length == 0) || !package) {
367 printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", 367 printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n",
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 56666a982476..eb5141f9ef8f 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> 4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org> 5 * Copyright (C) 2004 Bruno Ducrot <ducrot@poupinou.org>
6 * Copyright (C) 2006 Thomas Tuttle <linux-kernel@ttuttle.net>
6 * 7 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 * 9 *
@@ -47,11 +48,11 @@
47#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 48#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83
48#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 49#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84
49 50
50#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 51#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85
51#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 52#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
52#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 53#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
53#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 54#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88
54#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 55#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89
55 56
56#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) 57#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
57#define ACPI_VIDEO_HEAD_END (~0u) 58#define ACPI_VIDEO_HEAD_END (~0u)
@@ -386,7 +387,7 @@ acpi_video_device_EDID(struct acpi_video_device *device,
386 if (ACPI_FAILURE(status)) 387 if (ACPI_FAILURE(status))
387 return -ENODEV; 388 return -ENODEV;
388 389
389 obj = (union acpi_object *)buffer.pointer; 390 obj = buffer.pointer;
390 391
391 if (obj && obj->type == ACPI_TYPE_BUFFER) 392 if (obj && obj->type == ACPI_TYPE_BUFFER)
392 *edid = obj; 393 *edid = obj;
@@ -654,8 +655,7 @@ static struct proc_dir_entry *acpi_video_dir;
654 655
655static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) 656static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset)
656{ 657{
657 struct acpi_video_device *dev = 658 struct acpi_video_device *dev = seq->private;
658 (struct acpi_video_device *)seq->private;
659 659
660 660
661 if (!dev) 661 if (!dev)
@@ -688,8 +688,7 @@ acpi_video_device_info_open_fs(struct inode *inode, struct file *file)
688static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) 688static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset)
689{ 689{
690 int status; 690 int status;
691 struct acpi_video_device *dev = 691 struct acpi_video_device *dev = seq->private;
692 (struct acpi_video_device *)seq->private;
693 unsigned long state; 692 unsigned long state;
694 693
695 694
@@ -727,8 +726,8 @@ acpi_video_device_write_state(struct file *file,
727 size_t count, loff_t * data) 726 size_t count, loff_t * data)
728{ 727{
729 int status; 728 int status;
730 struct seq_file *m = (struct seq_file *)file->private_data; 729 struct seq_file *m = file->private_data;
731 struct acpi_video_device *dev = (struct acpi_video_device *)m->private; 730 struct acpi_video_device *dev = m->private;
732 char str[12] = { 0 }; 731 char str[12] = { 0 };
733 u32 state = 0; 732 u32 state = 0;
734 733
@@ -754,8 +753,7 @@ acpi_video_device_write_state(struct file *file,
754static int 753static int
755acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) 754acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset)
756{ 755{
757 struct acpi_video_device *dev = 756 struct acpi_video_device *dev = seq->private;
758 (struct acpi_video_device *)seq->private;
759 int i; 757 int i;
760 758
761 759
@@ -784,8 +782,8 @@ acpi_video_device_write_brightness(struct file *file,
784 const char __user * buffer, 782 const char __user * buffer,
785 size_t count, loff_t * data) 783 size_t count, loff_t * data)
786{ 784{
787 struct seq_file *m = (struct seq_file *)file->private_data; 785 struct seq_file *m = file->private_data;
788 struct acpi_video_device *dev = (struct acpi_video_device *)m->private; 786 struct acpi_video_device *dev = m->private;
789 char str[4] = { 0 }; 787 char str[4] = { 0 };
790 unsigned int level = 0; 788 unsigned int level = 0;
791 int i; 789 int i;
@@ -817,8 +815,7 @@ acpi_video_device_write_brightness(struct file *file,
817 815
818static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) 816static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
819{ 817{
820 struct acpi_video_device *dev = 818 struct acpi_video_device *dev = seq->private;
821 (struct acpi_video_device *)seq->private;
822 int status; 819 int status;
823 int i; 820 int i;
824 union acpi_object *edid = NULL; 821 union acpi_object *edid = NULL;
@@ -866,7 +863,7 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
866 if (!device) 863 if (!device)
867 return -ENODEV; 864 return -ENODEV;
868 865
869 vid_dev = (struct acpi_video_device *)acpi_driver_data(device); 866 vid_dev = acpi_driver_data(device);
870 if (!vid_dev) 867 if (!vid_dev)
871 return -ENODEV; 868 return -ENODEV;
872 869
@@ -931,7 +928,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
931{ 928{
932 struct acpi_video_device *vid_dev; 929 struct acpi_video_device *vid_dev;
933 930
934 vid_dev = (struct acpi_video_device *)acpi_driver_data(device); 931 vid_dev = acpi_driver_data(device);
935 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) 932 if (!vid_dev || !vid_dev->video || !vid_dev->video->dir)
936 return -ENODEV; 933 return -ENODEV;
937 934
@@ -950,7 +947,7 @@ static int acpi_video_device_remove_fs(struct acpi_device *device)
950/* video bus */ 947/* video bus */
951static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) 948static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset)
952{ 949{
953 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 950 struct acpi_video_bus *video = seq->private;
954 951
955 952
956 if (!video) 953 if (!video)
@@ -975,7 +972,7 @@ static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file)
975 972
976static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) 973static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
977{ 974{
978 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 975 struct acpi_video_bus *video = seq->private;
979 976
980 977
981 if (!video) 978 if (!video)
@@ -995,7 +992,7 @@ static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file)
995 992
996static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) 993static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset)
997{ 994{
998 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 995 struct acpi_video_bus *video = seq->private;
999 unsigned long options; 996 unsigned long options;
1000 int status; 997 int status;
1001 998
@@ -1033,7 +1030,7 @@ acpi_video_bus_POST_info_open_fs(struct inode *inode, struct file *file)
1033 1030
1034static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) 1031static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1035{ 1032{
1036 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1033 struct acpi_video_bus *video = seq->private;
1037 int status; 1034 int status;
1038 unsigned long id; 1035 unsigned long id;
1039 1036
@@ -1054,7 +1051,7 @@ static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset)
1054 1051
1055static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) 1052static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset)
1056{ 1053{
1057 struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; 1054 struct acpi_video_bus *video = seq->private;
1058 1055
1059 1056
1060 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); 1057 seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting);
@@ -1079,8 +1076,8 @@ acpi_video_bus_write_POST(struct file *file,
1079 size_t count, loff_t * data) 1076 size_t count, loff_t * data)
1080{ 1077{
1081 int status; 1078 int status;
1082 struct seq_file *m = (struct seq_file *)file->private_data; 1079 struct seq_file *m = file->private_data;
1083 struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; 1080 struct acpi_video_bus *video = m->private;
1084 char str[12] = { 0 }; 1081 char str[12] = { 0 };
1085 unsigned long opt, options; 1082 unsigned long opt, options;
1086 1083
@@ -1119,8 +1116,8 @@ acpi_video_bus_write_DOS(struct file *file,
1119 size_t count, loff_t * data) 1116 size_t count, loff_t * data)
1120{ 1117{
1121 int status; 1118 int status;
1122 struct seq_file *m = (struct seq_file *)file->private_data; 1119 struct seq_file *m = file->private_data;
1123 struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; 1120 struct acpi_video_bus *video = m->private;
1124 char str[12] = { 0 }; 1121 char str[12] = { 0 };
1125 unsigned long opt; 1122 unsigned long opt;
1126 1123
@@ -1150,7 +1147,7 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
1150 struct acpi_video_bus *video; 1147 struct acpi_video_bus *video;
1151 1148
1152 1149
1153 video = (struct acpi_video_bus *)acpi_driver_data(device); 1150 video = acpi_driver_data(device);
1154 1151
1155 if (!acpi_device_dir(device)) { 1152 if (!acpi_device_dir(device)) {
1156 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1153 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
@@ -1226,7 +1223,7 @@ static int acpi_video_bus_remove_fs(struct acpi_device *device)
1226 struct acpi_video_bus *video; 1223 struct acpi_video_bus *video;
1227 1224
1228 1225
1229 video = (struct acpi_video_bus *)acpi_driver_data(device); 1226 video = acpi_driver_data(device);
1230 1227
1231 if (acpi_device_dir(device)) { 1228 if (acpi_device_dir(device)) {
1232 remove_proc_entry("info", acpi_device_dir(device)); 1229 remove_proc_entry("info", acpi_device_dir(device));
@@ -1403,7 +1400,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1403 return status; 1400 return status;
1404 } 1401 }
1405 1402
1406 dod = (union acpi_object *)buffer.pointer; 1403 dod = buffer.pointer;
1407 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { 1404 if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) {
1408 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); 1405 ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data"));
1409 status = -EFAULT; 1406 status = -EFAULT;
@@ -1426,7 +1423,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1426 1423
1427 count = 0; 1424 count = 0;
1428 for (i = 0; i < dod->package.count; i++) { 1425 for (i = 0; i < dod->package.count; i++) {
1429 obj = (union acpi_object *)&dod->package.elements[i]; 1426 obj = &dod->package.elements[i];
1430 1427
1431 if (obj->type != ACPI_TYPE_INTEGER) { 1428 if (obj->type != ACPI_TYPE_INTEGER) {
1432 printk(KERN_ERR PREFIX "Invalid _DOD data\n"); 1429 printk(KERN_ERR PREFIX "Invalid _DOD data\n");
@@ -1509,8 +1506,34 @@ static int
1509acpi_video_get_next_level(struct acpi_video_device *device, 1506acpi_video_get_next_level(struct acpi_video_device *device,
1510 u32 level_current, u32 event) 1507 u32 level_current, u32 event)
1511{ 1508{
1512 /*Fix me */ 1509 int min, max, min_above, max_below, i, l;
1513 return level_current; 1510 max = max_below = 0;
1511 min = min_above = 255;
1512 for (i = 0; i < device->brightness->count; i++) {
1513 l = device->brightness->levels[i];
1514 if (l < min)
1515 min = l;
1516 if (l > max)
1517 max = l;
1518 if (l < min_above && l > level_current)
1519 min_above = l;
1520 if (l > max_below && l < level_current)
1521 max_below = l;
1522 }
1523
1524 switch (event) {
1525 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS:
1526 return (level_current < max) ? min_above : min;
1527 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS:
1528 return (level_current < max) ? min_above : max;
1529 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS:
1530 return (level_current > min) ? max_below : min;
1531 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:
1532 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF:
1533 return 0;
1534 default:
1535 return level_current;
1536 }
1514} 1537}
1515 1538
1516static void 1539static void
@@ -1612,7 +1635,7 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
1612 1635
1613static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) 1636static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1614{ 1637{
1615 struct acpi_video_bus *video = (struct acpi_video_bus *)data; 1638 struct acpi_video_bus *video = data;
1616 struct acpi_device *device = NULL; 1639 struct acpi_device *device = NULL;
1617 1640
1618 printk("video bus notify\n"); 1641 printk("video bus notify\n");
@@ -1654,8 +1677,7 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1654 1677
1655static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) 1678static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1656{ 1679{
1657 struct acpi_video_device *video_device = 1680 struct acpi_video_device *video_device = data;
1658 (struct acpi_video_device *)data;
1659 struct acpi_device *device = NULL; 1681 struct acpi_device *device = NULL;
1660 1682
1661 1683
@@ -1757,7 +1779,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1757 if (!device || !acpi_driver_data(device)) 1779 if (!device || !acpi_driver_data(device))
1758 return -EINVAL; 1780 return -EINVAL;
1759 1781
1760 video = (struct acpi_video_bus *)acpi_driver_data(device); 1782 video = acpi_driver_data(device);
1761 1783
1762 acpi_video_bus_stop_devices(video); 1784 acpi_video_bus_stop_devices(video);
1763 1785
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index fdb7153f4426..8e5e07e4c1cf 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -317,7 +317,8 @@ static int __init msi_init(void)
317 317
318 /* Register backlight stuff */ 318 /* Register backlight stuff */
319 319
320 msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props); 320 msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL,
321 &msibl_props);
321 if (IS_ERR(msibl_device)) 322 if (IS_ERR(msibl_device))
322 return PTR_ERR(msibl_device); 323 return PTR_ERR(msibl_device);
323 324
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 02cbb7fff24f..a7932a72d298 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -281,7 +281,7 @@ static int appledisplay_probe(struct usb_interface *iface,
281 /* Register backlight device */ 281 /* Register backlight device */
282 snprintf(bl_name, sizeof(bl_name), "appledisplay%d", 282 snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
283 atomic_inc_return(&count_displays) - 1); 283 atomic_inc_return(&count_displays) - 1);
284 pdata->bd = backlight_device_register(bl_name, pdata, 284 pdata->bd = backlight_device_register(bl_name, NULL, NULL,
285 &appledisplay_bl_data); 285 &appledisplay_bl_data);
286 if (IS_ERR(pdata->bd)) { 286 if (IS_ERR(pdata->bd)) {
287 err("appledisplay: Backlight registration failed"); 287 err("appledisplay: Backlight registration failed");
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 3feddf89d100..2e976ffcde0f 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1834,7 +1834,7 @@ static void aty128_bl_init(struct aty128fb_par *par)
1834 1834
1835 snprintf(name, sizeof(name), "aty128bl%d", info->node); 1835 snprintf(name, sizeof(name), "aty128bl%d", info->node);
1836 1836
1837 bd = backlight_device_register(name, par, &aty128_bl_data); 1837 bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
1838 if (IS_ERR(bd)) { 1838 if (IS_ERR(bd)) {
1839 info->bl_dev = NULL; 1839 info->bl_dev = NULL;
1840 printk(KERN_WARNING "aty128: Backlight registration failed\n"); 1840 printk(KERN_WARNING "aty128: Backlight registration failed\n");
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 09684d7a7ce9..f2ebdd880085 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2211,7 +2211,7 @@ static void aty_bl_init(struct atyfb_par *par)
2211 2211
2212 snprintf(name, sizeof(name), "atybl%d", info->node); 2212 snprintf(name, sizeof(name), "atybl%d", info->node);
2213 2213
2214 bd = backlight_device_register(name, par, &aty_bl_data); 2214 bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
2215 if (IS_ERR(bd)) { 2215 if (IS_ERR(bd)) {
2216 info->bl_dev = NULL; 2216 info->bl_dev = NULL;
2217 printk(KERN_WARNING "aty: Backlight registration failed\n"); 2217 printk(KERN_WARNING "aty: Backlight registration failed\n");
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 585eb7b9e636..3abfd4a380cc 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -163,7 +163,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
163 163
164 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node); 164 snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
165 165
166 bd = backlight_device_register(name, pdata, &radeon_bl_data); 166 bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
167 if (IS_ERR(bd)) { 167 if (IS_ERR(bd)) {
168 rinfo->info->bl_dev = NULL; 168 rinfo->info->bl_dev = NULL;
169 printk("radeonfb: Backlight registration failed\n"); 169 printk("radeonfb: Backlight registration failed\n");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index db8c191b1201..9601bfe309ac 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -216,8 +216,10 @@ static const struct class_device_attribute bl_class_device_attributes[] = {
216 * Creates and registers new backlight class_device. Returns either an 216 * Creates and registers new backlight class_device. Returns either an
217 * ERR_PTR() or a pointer to the newly allocated device. 217 * ERR_PTR() or a pointer to the newly allocated device.
218 */ 218 */
219struct backlight_device *backlight_device_register(const char *name, void *devdata, 219struct backlight_device *backlight_device_register(const char *name,
220 struct backlight_properties *bp) 220 struct device *dev,
221 void *devdata,
222 struct backlight_properties *bp)
221{ 223{
222 int i, rc; 224 int i, rc;
223 struct backlight_device *new_bd; 225 struct backlight_device *new_bd;
@@ -232,6 +234,7 @@ struct backlight_device *backlight_device_register(const char *name, void *devda
232 new_bd->props = bp; 234 new_bd->props = bp;
233 memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev)); 235 memset(&new_bd->class_dev, 0, sizeof(new_bd->class_dev));
234 new_bd->class_dev.class = &backlight_class; 236 new_bd->class_dev.class = &backlight_class;
237 new_bd->class_dev.dev = dev;
235 strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN); 238 strlcpy(new_bd->class_dev.class_id, name, KOBJ_NAME_LEN);
236 class_set_devdata(&new_bd->class_dev, devdata); 239 class_set_devdata(&new_bd->class_dev, devdata);
237 240
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c
index 5b75ae4e9457..df934bd21899 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/nvidia/nv_backlight.c
@@ -141,7 +141,7 @@ void nvidia_bl_init(struct nvidia_par *par)
141 141
142 snprintf(name, sizeof(name), "nvidiabl%d", info->node); 142 snprintf(name, sizeof(name), "nvidiabl%d", info->node);
143 143
144 bd = backlight_device_register(name, par, &nvidia_bl_data); 144 bd = backlight_device_register(name, info->dev, par, &nvidia_bl_data);
145 if (IS_ERR(bd)) { 145 if (IS_ERR(bd)) {
146 info->bl_dev = NULL; 146 info->bl_dev = NULL;
147 printk(KERN_WARNING "nvidia: Backlight registration failed\n"); 147 printk(KERN_WARNING "nvidia: Backlight registration failed\n");
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 345e8b1c1af8..1a13966b7d5b 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -384,7 +384,7 @@ static void riva_bl_init(struct riva_par *par)
384 384
385 snprintf(name, sizeof(name), "rivabl%d", info->node); 385 snprintf(name, sizeof(name), "rivabl%d", info->node);
386 386
387 bd = backlight_device_register(name, par, &riva_bl_data); 387 bd = backlight_device_register(name, info->dev, par, &riva_bl_data);
388 if (IS_ERR(bd)) { 388 if (IS_ERR(bd)) {
389 info->bl_dev = NULL; 389 info->bl_dev = NULL;
390 printk(KERN_WARNING "riva: Backlight registration failed\n"); 390 printk(KERN_WARNING "riva: Backlight registration failed\n");
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index c80b3a94511a..7cfad93edf10 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -56,30 +56,8 @@
56#define ACPI_ENABLE_IRQS() local_irq_enable() 56#define ACPI_ENABLE_IRQS() local_irq_enable()
57#define ACPI_FLUSH_CPU_CACHE() wbinvd() 57#define ACPI_FLUSH_CPU_CACHE() wbinvd()
58 58
59 59int __acpi_acquire_global_lock(unsigned int *lock);
60static inline int 60int __acpi_release_global_lock(unsigned int *lock);
61__acpi_acquire_global_lock (unsigned int *lock)
62{
63 unsigned int old, new, val;
64 do {
65 old = *lock;
66 new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
67 val = cmpxchg(lock, old, new);
68 } while (unlikely (val != old));
69 return (new < 3) ? -1 : 0;
70}
71
72static inline int
73__acpi_release_global_lock (unsigned int *lock)
74{
75 unsigned int old, new, val;
76 do {
77 old = *lock;
78 new = old & ~0x3;
79 val = cmpxchg(lock, old, new);
80 } while (unlikely (val != old));
81 return old & 0x1;
82}
83 61
84#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ 62#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
85 ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) 63 ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h
index 9d1916e59c04..6b6fc6f8be7e 100644
--- a/include/asm-x86_64/acpi.h
+++ b/include/asm-x86_64/acpi.h
@@ -54,30 +54,8 @@
54#define ACPI_ENABLE_IRQS() local_irq_enable() 54#define ACPI_ENABLE_IRQS() local_irq_enable()
55#define ACPI_FLUSH_CPU_CACHE() wbinvd() 55#define ACPI_FLUSH_CPU_CACHE() wbinvd()
56 56
57 57int __acpi_acquire_global_lock(unsigned int *lock);
58static inline int 58int __acpi_release_global_lock(unsigned int *lock);
59__acpi_acquire_global_lock (unsigned int *lock)
60{
61 unsigned int old, new, val;
62 do {
63 old = *lock;
64 new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
65 val = cmpxchg(lock, old, new);
66 } while (unlikely (val != old));
67 return (new < 3) ? -1 : 0;
68}
69
70static inline int
71__acpi_release_global_lock (unsigned int *lock)
72{
73 unsigned int old, new, val;
74 do {
75 old = *lock;
76 new = old & ~0x3;
77 val = cmpxchg(lock, old, new);
78 } while (unlikely (val != old));
79 return old & 0x1;
80}
81 59
82#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ 60#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
83 ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr)) 61 ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index 75e91f5b6a04..a5cf1beacb44 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -54,7 +54,7 @@ struct backlight_device {
54}; 54};
55 55
56extern struct backlight_device *backlight_device_register(const char *name, 56extern struct backlight_device *backlight_device_register(const char *name,
57 void *devdata, struct backlight_properties *bp); 57 struct device *dev,void *devdata,struct backlight_properties *bp);
58extern void backlight_device_unregister(struct backlight_device *bd); 58extern void backlight_device_unregister(struct backlight_device *bd);
59 59
60#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev) 60#define to_backlight_device(obj) container_of(obj, struct backlight_device, class_dev)
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 0b00f56c2ad0..88fc5d7ac737 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -60,9 +60,11 @@ static void power_down(suspend_disk_method_t mode)
60{ 60{
61 switch(mode) { 61 switch(mode) {
62 case PM_DISK_PLATFORM: 62 case PM_DISK_PLATFORM:
63 kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); 63 if (pm_ops && pm_ops->enter) {
64 pm_ops->enter(PM_SUSPEND_DISK); 64 kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
65 break; 65 pm_ops->enter(PM_SUSPEND_DISK);
66 break;
67 }
66 case PM_DISK_SHUTDOWN: 68 case PM_DISK_SHUTDOWN:
67 kernel_power_off(); 69 kernel_power_off();
68 break; 70 break;
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 500eb87f643d..ff3a6182f5f0 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -29,7 +29,7 @@
29DEFINE_MUTEX(pm_mutex); 29DEFINE_MUTEX(pm_mutex);
30 30
31struct pm_ops *pm_ops; 31struct pm_ops *pm_ops;
32suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; 32suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM;
33 33
34/** 34/**
35 * pm_set_ops - Set the global power method table. 35 * pm_set_ops - Set the global power method table.