aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-15 14:02:52 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-15 14:02:52 -0400
commit0b269d8462a9f0058afb46eaee56e0732acf16c4 (patch)
treef6f5d801b0f991b34b7a71394370fc31746883bb
parented75ded7dd3fdb647df4efefc5d11158e3d182be (diff)
parent9aaed2b42d00d4abb2748d72d599a8033600e2bf (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (28 commits) ACPI: check battery status on resume for un/plug events during sleep ACPICA: Fix incorrect handling of PCI Express Root Bridge _HID ACPI: asus_acpi: don't printk on writing garbage to proc files ACPI: asus_acpi: fix proc files parsing ACPI: SCI interrupt source override ACPI: fix printk format warnings ACPI: fix section for CPU init functions ACPI: update comments in motherboard.c ACPI: acpi_pci_link_set() can allocate with either GFP_ATOMIC or GFP_KERNEL ACPI: fix potential OOPS in power driver with CONFIG_ACPI_DEBUG ACPI: ibm_acpi: delete obsolete documentation ACPI: created a dedicated workqueue for notify() execution ACPI: Remove deferred execution from global lock acquire wakeup path MSI S270 Laptop support: backlight, wlan, bluetooth states ACPI: EC: export ec_transaction() for msi-laptop driver ACPI: EC: Simplify acpi_hw_low_level*() with inb()/outb(). ACPI: EC: Unify poll and interrupt gpe handlers ACPI: EC: Unify poll and interrupt mode transaction functions ACPI: EC: Remove unused variables and duplicated code ACPI: EC: Remove unnecessary delay added by previous transation patch. ...
-rw-r--r--Documentation/ibm-acpi.txt75
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/i386/kernel/acpi/boot.c10
-rw-r--r--arch/i386/kernel/acpi/cstate.c122
-rw-r--r--arch/i386/kernel/process.c22
-rw-r--r--arch/x86_64/kernel/process.c22
-rw-r--r--drivers/acpi/asus_acpi.c67
-rw-r--r--drivers/acpi/battery.c14
-rw-r--r--drivers/acpi/ec.c1096
-rw-r--r--drivers/acpi/events/evmisc.c14
-rw-r--r--drivers/acpi/events/evrgnini.c13
-rw-r--r--drivers/acpi/ibm_acpi.c2
-rw-r--r--drivers/acpi/motherboard.c6
-rw-r--r--drivers/acpi/osl.c34
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/power.c9
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/processor_idle.c103
-rw-r--r--drivers/acpi/sbs.c20
-rw-r--r--drivers/acpi/tables/tbget.c2
-rw-r--r--drivers/acpi/tables/tbrsdt.c2
-rw-r--r--drivers/misc/Kconfig19
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/msi-laptop.c395
-rw-r--r--include/acpi/pdc_intel.h9
-rw-r--r--include/acpi/processor.h18
-rw-r--r--include/asm-i386/processor.h2
-rw-r--r--include/asm-x86_64/processor.h2
-rw-r--r--include/linux/acpi.h3
29 files changed, 1088 insertions, 1005 deletions
diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt
index 71aa40345272..e50595bfd8ea 100644
--- a/Documentation/ibm-acpi.txt
+++ b/Documentation/ibm-acpi.txt
@@ -30,9 +30,10 @@ detailed description):
30 - ACPI sounds 30 - ACPI sounds
31 - temperature sensors 31 - temperature sensors
32 - Experimental: embedded controller register dump 32 - Experimental: embedded controller register dump
33 - Experimental: LCD brightness control 33 - LCD brightness control
34 - Experimental: volume control 34 - Volume control
35 - Experimental: fan speed, fan enable/disable 35 - Experimental: fan speed, fan enable/disable
36 - Experimental: WAN enable and disable
36 37
37A compatibility table by model and feature is maintained on the web 38A compatibility table by model and feature is maintained on the web
38site, http://ibm-acpi.sf.net/. I appreciate any success or failure 39site, http://ibm-acpi.sf.net/. I appreciate any success or failure
@@ -52,40 +53,7 @@ Installation
52 53
53If you are compiling this driver as included in the Linux kernel 54If you are compiling this driver as included in the Linux kernel
54sources, simply enable the CONFIG_ACPI_IBM option (Power Management / 55sources, simply enable the CONFIG_ACPI_IBM option (Power Management /
55ACPI / IBM ThinkPad Laptop Extras). The rest of this section describes 56ACPI / IBM ThinkPad Laptop Extras).
56how to install this driver when downloaded from the web site.
57
58First, you need to get a kernel with ACPI support up and running.
59Please refer to http://acpi.sourceforge.net/ for help with this
60step. How successful you will be depends a lot on you ThinkPad model,
61the kernel you are using and any additional patches applied. The
62kernel provided with your distribution may not be good enough. I
63needed to compile a 2.6.7 kernel with the 20040715 ACPI patch to get
64ACPI working reliably on my ThinkPad X40. Old ThinkPad models may not
65be supported at all.
66
67Assuming you have the basic ACPI support working (e.g. you can see the
68/proc/acpi directory), follow the following steps to install this
69driver:
70
71 - unpack the archive:
72
73 tar xzvf ibm-acpi-x.y.tar.gz; cd ibm-acpi-x.y
74
75 - compile the driver:
76
77 make
78
79 - install the module in your kernel modules directory:
80
81 make install
82
83 - load the module:
84
85 modprobe ibm_acpi
86
87After loading the module, check the "dmesg" output for any error messages.
88
89 57
90Features 58Features
91-------- 59--------
@@ -523,13 +491,8 @@ registers contain the current battery capacity, etc. If you experiment
523with this, do send me your results (including some complete dumps with 491with this, do send me your results (including some complete dumps with
524a description of the conditions when they were taken.) 492a description of the conditions when they were taken.)
525 493
526EXPERIMENTAL: LCD brightness control -- /proc/acpi/ibm/brightness 494LCD brightness control -- /proc/acpi/ibm/brightness
527----------------------------------------------------------------- 495---------------------------------------------------
528
529This feature is marked EXPERIMENTAL because the implementation
530directly accesses hardware registers and may not work as expected. USE
531WITH CAUTION! To use this feature, you need to supply the
532experimental=1 parameter when loading the module.
533 496
534This feature allows software control of the LCD brightness on ThinkPad 497This feature allows software control of the LCD brightness on ThinkPad
535models which don't have a hardware brightness slider. The available 498models which don't have a hardware brightness slider. The available
@@ -542,13 +505,8 @@ commands are:
542The <level> number range is 0 to 7, although not all of them may be 505The <level> number range is 0 to 7, although not all of them may be
543distinct. The current brightness level is shown in the file. 506distinct. The current brightness level is shown in the file.
544 507
545EXPERIMENTAL: Volume control -- /proc/acpi/ibm/volume 508Volume control -- /proc/acpi/ibm/volume
546----------------------------------------------------- 509---------------------------------------
547
548This feature is marked EXPERIMENTAL because the implementation
549directly accesses hardware registers and may not work as expected. USE
550WITH CAUTION! To use this feature, you need to supply the
551experimental=1 parameter when loading the module.
552 510
553This feature allows volume control on ThinkPad models which don't have 511This feature allows volume control on ThinkPad models which don't have
554a hardware volume knob. The available commands are: 512a hardware volume knob. The available commands are:
@@ -611,6 +569,23 @@ with the following command:
611 569
612 echo 'level <level>' > /proc/acpi/ibm/thermal 570 echo 'level <level>' > /proc/acpi/ibm/thermal
613 571
572EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan
573---------------------------------------
574
575This feature is marked EXPERIMENTAL because the implementation
576directly accesses hardware registers and may not work as expected. USE
577WITH CAUTION! To use this feature, you need to supply the
578experimental=1 parameter when loading the module.
579
580This feature shows the presence and current state of a WAN (Sierra
581Wireless EV-DO) device. If WAN is installed, the following commands can
582be used:
583
584 echo enable > /proc/acpi/ibm/wan
585 echo disable > /proc/acpi/ibm/wan
586
587It was tested on a Lenovo Thinkpad X60. It should probably work on other
588Thinkpad models which come with this module installed.
614 589
615Multiple Commands, Module Parameters 590Multiple Commands, Module Parameters
616------------------------------------ 591------------------------------------
diff --git a/MAINTAINERS b/MAINTAINERS
index 1b5430a49fdd..a2b6d9fa3502 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1998,6 +1998,13 @@ M: rubini@ipvvis.unipv.it
1998L: linux-kernel@vger.kernel.org 1998L: linux-kernel@vger.kernel.org
1999S: Maintained 1999S: Maintained
2000 2000
2001MSI LAPTOP SUPPORT
2002P: Lennart Poettering
2003M: mzxreary@0pointer.de
2004L: https://tango.0pointer.de/mailman/listinfo/s270-linux
2005W: http://0pointer.de/lennart/tchibo.html
2006S: Maintained
2007
2001MTRR AND SIMILAR SUPPORT [i386] 2008MTRR AND SIMILAR SUPPORT [i386]
2002P: Richard Gooch 2009P: Richard Gooch
2003M: rgooch@atnf.csiro.au 2010M: rgooch@atnf.csiro.au
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 92f79cdd9a48..ab974ff97073 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -332,7 +332,7 @@ acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end)
332/* 332/*
333 * Parse Interrupt Source Override for the ACPI SCI 333 * Parse Interrupt Source Override for the ACPI SCI
334 */ 334 */
335static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) 335static void acpi_sci_ioapic_setup(u32 bus_irq, u32 gsi, u16 polarity, u16 trigger)
336{ 336{
337 if (trigger == 0) /* compatible SCI trigger is level */ 337 if (trigger == 0) /* compatible SCI trigger is level */
338 trigger = 3; 338 trigger = 3;
@@ -352,13 +352,13 @@ static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
352 * If GSI is < 16, this will update its flags, 352 * If GSI is < 16, this will update its flags,
353 * else it will create a new mp_irqs[] entry. 353 * else it will create a new mp_irqs[] entry.
354 */ 354 */
355 mp_override_legacy_irq(gsi, polarity, trigger, gsi); 355 mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
356 356
357 /* 357 /*
358 * stash over-ride to indicate we've been here 358 * stash over-ride to indicate we've been here
359 * and for later update of acpi_fadt 359 * and for later update of acpi_fadt
360 */ 360 */
361 acpi_sci_override_gsi = gsi; 361 acpi_sci_override_gsi = bus_irq;
362 return; 362 return;
363} 363}
364 364
@@ -376,7 +376,7 @@ acpi_parse_int_src_ovr(acpi_table_entry_header * header,
376 acpi_table_print_madt_entry(header); 376 acpi_table_print_madt_entry(header);
377 377
378 if (intsrc->bus_irq == acpi_fadt.sci_int) { 378 if (intsrc->bus_irq == acpi_fadt.sci_int) {
379 acpi_sci_ioapic_setup(intsrc->global_irq, 379 acpi_sci_ioapic_setup(intsrc->bus_irq, intsrc->global_irq,
380 intsrc->flags.polarity, 380 intsrc->flags.polarity,
381 intsrc->flags.trigger); 381 intsrc->flags.trigger);
382 return 0; 382 return 0;
@@ -879,7 +879,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
879 * pretend we got one so we can set the SCI flags. 879 * pretend we got one so we can set the SCI flags.
880 */ 880 */
881 if (!acpi_sci_override_gsi) 881 if (!acpi_sci_override_gsi)
882 acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); 882 acpi_sci_ioapic_setup(acpi_fadt.sci_int, acpi_fadt.sci_int, 0, 0);
883 883
884 /* Fill in identity legacy mapings where no override */ 884 /* Fill in identity legacy mapings where no override */
885 mp_config_acpi_legacy_irqs(); 885 mp_config_acpi_legacy_irqs();
diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c
index 25db49ef1770..20563e52c622 100644
--- a/arch/i386/kernel/acpi/cstate.c
+++ b/arch/i386/kernel/acpi/cstate.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/acpi.h> 12#include <linux/acpi.h>
13#include <linux/cpu.h>
13 14
14#include <acpi/processor.h> 15#include <acpi/processor.h>
15#include <asm/acpi.h> 16#include <asm/acpi.h>
@@ -41,5 +42,124 @@ void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
41 flags->bm_check = 1; 42 flags->bm_check = 1;
42 } 43 }
43} 44}
44
45EXPORT_SYMBOL(acpi_processor_power_init_bm_check); 45EXPORT_SYMBOL(acpi_processor_power_init_bm_check);
46
47/* The code below handles cstate entry with monitor-mwait pair on Intel*/
48
49struct cstate_entry_s {
50 struct {
51 unsigned int eax;
52 unsigned int ecx;
53 } states[ACPI_PROCESSOR_MAX_POWER];
54};
55static struct cstate_entry_s *cpu_cstate_entry; /* per CPU ptr */
56
57static short mwait_supported[ACPI_PROCESSOR_MAX_POWER];
58
59#define MWAIT_SUBSTATE_MASK (0xf)
60#define MWAIT_SUBSTATE_SIZE (4)
61
62#define CPUID_MWAIT_LEAF (5)
63#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
64#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
65
66#define MWAIT_ECX_INTERRUPT_BREAK (0x1)
67
68#define NATIVE_CSTATE_BEYOND_HALT (2)
69
70int acpi_processor_ffh_cstate_probe(unsigned int cpu,
71 struct acpi_processor_cx *cx, struct acpi_power_register *reg)
72{
73 struct cstate_entry_s *percpu_entry;
74 struct cpuinfo_x86 *c = cpu_data + cpu;
75
76 cpumask_t saved_mask;
77 int retval;
78 unsigned int eax, ebx, ecx, edx;
79 unsigned int edx_part;
80 unsigned int cstate_type; /* C-state type and not ACPI C-state type */
81 unsigned int num_cstate_subtype;
82
83 if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF )
84 return -1;
85
86 if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT)
87 return -1;
88
89 percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
90 percpu_entry->states[cx->index].eax = 0;
91 percpu_entry->states[cx->index].ecx = 0;
92
93 /* Make sure we are running on right CPU */
94 saved_mask = current->cpus_allowed;
95 retval = set_cpus_allowed(current, cpumask_of_cpu(cpu));
96 if (retval)
97 return -1;
98
99 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
100
101 /* Check whether this particular cx_type (in CST) is supported or not */
102 cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1;
103 edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE);
104 num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK;
105
106 retval = 0;
107 if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) {
108 retval = -1;
109 goto out;
110 }
111
112 /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */
113 if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
114 !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) {
115 retval = -1;
116 goto out;
117 }
118 percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK;
119
120 /* Use the hint in CST */
121 percpu_entry->states[cx->index].eax = cx->address;
122
123 if (!mwait_supported[cstate_type]) {
124 mwait_supported[cstate_type] = 1;
125 printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d "
126 "state\n", cx->type);
127 }
128
129out:
130 set_cpus_allowed(current, saved_mask);
131 return retval;
132}
133EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
134
135void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
136{
137 unsigned int cpu = smp_processor_id();
138 struct cstate_entry_s *percpu_entry;
139
140 percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
141 mwait_idle_with_hints(percpu_entry->states[cx->index].eax,
142 percpu_entry->states[cx->index].ecx);
143}
144EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter);
145
146static int __init ffh_cstate_init(void)
147{
148 struct cpuinfo_x86 *c = &boot_cpu_data;
149 if (c->x86_vendor != X86_VENDOR_INTEL)
150 return -1;
151
152 cpu_cstate_entry = alloc_percpu(struct cstate_entry_s);
153 return 0;
154}
155
156static void __exit ffh_cstate_exit(void)
157{
158 if (cpu_cstate_entry) {
159 free_percpu(cpu_cstate_entry);
160 cpu_cstate_entry = NULL;
161 }
162}
163
164arch_initcall(ffh_cstate_init);
165__exitcall(ffh_cstate_exit);
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index b0a07801d9df..57d375900afb 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -236,20 +236,28 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
236 * We execute MONITOR against need_resched and enter optimized wait state 236 * We execute MONITOR against need_resched and enter optimized wait state
237 * through MWAIT. Whenever someone changes need_resched, we would be woken 237 * through MWAIT. Whenever someone changes need_resched, we would be woken
238 * up from MWAIT (without an IPI). 238 * up from MWAIT (without an IPI).
239 *
240 * New with Core Duo processors, MWAIT can take some hints based on CPU
241 * capability.
239 */ 242 */
240static void mwait_idle(void) 243void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
241{ 244{
242 local_irq_enable(); 245 if (!need_resched()) {
243
244 while (!need_resched()) {
245 __monitor((void *)&current_thread_info()->flags, 0, 0); 246 __monitor((void *)&current_thread_info()->flags, 0, 0);
246 smp_mb(); 247 smp_mb();
247 if (need_resched()) 248 if (!need_resched())
248 break; 249 __mwait(eax, ecx);
249 __mwait(0, 0);
250 } 250 }
251} 251}
252 252
253/* Default MONITOR/MWAIT with no hints, used for default C1 state */
254static void mwait_idle(void)
255{
256 local_irq_enable();
257 while (!need_resched())
258 mwait_idle_with_hints(0, 0);
259}
260
253void __devinit select_idle_routine(const struct cpuinfo_x86 *c) 261void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
254{ 262{
255 if (cpu_has(c, X86_FEATURE_MWAIT)) { 263 if (cpu_has(c, X86_FEATURE_MWAIT)) {
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 5e95b257ee26..49f7fac6229e 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -238,20 +238,28 @@ void cpu_idle (void)
238 * We execute MONITOR against need_resched and enter optimized wait state 238 * We execute MONITOR against need_resched and enter optimized wait state
239 * through MWAIT. Whenever someone changes need_resched, we would be woken 239 * through MWAIT. Whenever someone changes need_resched, we would be woken
240 * up from MWAIT (without an IPI). 240 * up from MWAIT (without an IPI).
241 *
242 * New with Core Duo processors, MWAIT can take some hints based on CPU
243 * capability.
241 */ 244 */
242static void mwait_idle(void) 245void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
243{ 246{
244 local_irq_enable(); 247 if (!need_resched()) {
245
246 while (!need_resched()) {
247 __monitor((void *)&current_thread_info()->flags, 0, 0); 248 __monitor((void *)&current_thread_info()->flags, 0, 0);
248 smp_mb(); 249 smp_mb();
249 if (need_resched()) 250 if (!need_resched())
250 break; 251 __mwait(eax, ecx);
251 __mwait(0, 0);
252 } 252 }
253} 253}
254 254
255/* Default MONITOR/MWAIT with no hints, used for default C1 state */
256static void mwait_idle(void)
257{
258 local_irq_enable();
259 while (!need_resched())
260 mwait_idle_with_hints(0,0);
261}
262
255void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) 263void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
256{ 264{
257 static int printed; 265 static int printed;
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index e9ee4c52a5f6..c7ac9297a204 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -138,6 +138,7 @@ struct asus_hotk {
138 S2x, //S200 (J1 reported), Victor MP-XP7210 138 S2x, //S200 (J1 reported), Victor MP-XP7210
139 W1N, //W1000N 139 W1N, //W1000N
140 W5A, //W5A 140 W5A, //W5A
141 W3V, //W3030V
141 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N 142 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
142 //(Centrino) 143 //(Centrino)
143 END_MODEL 144 END_MODEL
@@ -376,6 +377,17 @@ static struct model_data model_conf[END_MODEL] = {
376 .display_get = "\\ADVG"}, 377 .display_get = "\\ADVG"},
377 378
378 { 379 {
380 .name = "W3V",
381 .mt_mled = "MLED",
382 .mt_wled = "WLED",
383 .mt_lcd_switch = xxN_PREFIX "_Q10",
384 .lcd_status = "\\BKLT",
385 .brightness_set = "SPLV",
386 .brightness_get = "GPLV",
387 .display_set = "SDSP",
388 .display_get = "\\INFB"},
389
390 {
379 .name = "xxN", 391 .name = "xxN",
380 .mt_mled = "MLED", 392 .mt_mled = "MLED",
381/* WLED present, but not controlled by ACPI */ 393/* WLED present, but not controlled by ACPI */
@@ -555,11 +567,11 @@ static int
555write_led(const char __user * buffer, unsigned long count, 567write_led(const char __user * buffer, unsigned long count,
556 char *ledname, int ledmask, int invert) 568 char *ledname, int ledmask, int invert)
557{ 569{
558 int value; 570 int rv, value;
559 int led_out = 0; 571 int led_out = 0;
560 572
561 count = parse_arg(buffer, count, &value); 573 rv = parse_arg(buffer, count, &value);
562 if (count > 0) 574 if (rv > 0)
563 led_out = value ? 1 : 0; 575 led_out = value ? 1 : 0;
564 576
565 hotk->status = 577 hotk->status =
@@ -572,7 +584,7 @@ write_led(const char __user * buffer, unsigned long count,
572 printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n", 584 printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
573 ledname); 585 ledname);
574 586
575 return count; 587 return rv;
576} 588}
577 589
578/* 590/*
@@ -607,20 +619,18 @@ static int
607proc_write_ledd(struct file *file, const char __user * buffer, 619proc_write_ledd(struct file *file, const char __user * buffer,
608 unsigned long count, void *data) 620 unsigned long count, void *data)
609{ 621{
610 int value; 622 int rv, value;
611 623
612 count = parse_arg(buffer, count, &value); 624 rv = parse_arg(buffer, count, &value);
613 if (count > 0) { 625 if (rv > 0) {
614 if (!write_acpi_int 626 if (!write_acpi_int
615 (hotk->handle, hotk->methods->mt_ledd, value, NULL)) 627 (hotk->handle, hotk->methods->mt_ledd, value, NULL))
616 printk(KERN_WARNING 628 printk(KERN_WARNING
617 "Asus ACPI: LED display write failed\n"); 629 "Asus ACPI: LED display write failed\n");
618 else 630 else
619 hotk->ledd_status = (u32) value; 631 hotk->ledd_status = (u32) value;
620 } else if (count < 0) 632 }
621 printk(KERN_WARNING "Asus ACPI: Error reading user input\n"); 633 return rv;
622
623 return count;
624} 634}
625 635
626/* 636/*
@@ -761,12 +771,12 @@ static int
761proc_write_lcd(struct file *file, const char __user * buffer, 771proc_write_lcd(struct file *file, const char __user * buffer,
762 unsigned long count, void *data) 772 unsigned long count, void *data)
763{ 773{
764 int value; 774 int rv, value;
765 775
766 count = parse_arg(buffer, count, &value); 776 rv = parse_arg(buffer, count, &value);
767 if (count > 0) 777 if (rv > 0)
768 set_lcd_state(value); 778 set_lcd_state(value);
769 return count; 779 return rv;
770} 780}
771 781
772static int read_brightness(void) 782static int read_brightness(void)
@@ -830,18 +840,15 @@ static int
830proc_write_brn(struct file *file, const char __user * buffer, 840proc_write_brn(struct file *file, const char __user * buffer,
831 unsigned long count, void *data) 841 unsigned long count, void *data)
832{ 842{
833 int value; 843 int rv, value;
834 844
835 count = parse_arg(buffer, count, &value); 845 rv = parse_arg(buffer, count, &value);
836 if (count > 0) { 846 if (rv > 0) {
837 value = (0 < value) ? ((15 < value) ? 15 : value) : 0; 847 value = (0 < value) ? ((15 < value) ? 15 : value) : 0;
838 /* 0 <= value <= 15 */ 848 /* 0 <= value <= 15 */
839 set_brightness(value); 849 set_brightness(value);
840 } else if (count < 0) {
841 printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
842 } 850 }
843 851 return rv;
844 return count;
845} 852}
846 853
847static void set_display(int value) 854static void set_display(int value)
@@ -880,15 +887,12 @@ static int
880proc_write_disp(struct file *file, const char __user * buffer, 887proc_write_disp(struct file *file, const char __user * buffer,
881 unsigned long count, void *data) 888 unsigned long count, void *data)
882{ 889{
883 int value; 890 int rv, value;
884 891
885 count = parse_arg(buffer, count, &value); 892 rv = parse_arg(buffer, count, &value);
886 if (count > 0) 893 if (rv > 0)
887 set_display(value); 894 set_display(value);
888 else if (count < 0) 895 return rv;
889 printk(KERN_WARNING "Asus ACPI: Error reading user input\n");
890
891 return count;
892} 896}
893 897
894typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, 898typedef int (proc_readfunc) (char *page, char **start, off_t off, int count,
@@ -1097,6 +1101,8 @@ static int asus_model_match(char *model)
1097 return A4G; 1101 return A4G;
1098 else if (strncmp(model, "W1N", 3) == 0) 1102 else if (strncmp(model, "W1N", 3) == 0)
1099 return W1N; 1103 return W1N;
1104 else if (strncmp(model, "W3V", 3) == 0)
1105 return W3V;
1100 else if (strncmp(model, "W5A", 3) == 0) 1106 else if (strncmp(model, "W5A", 3) == 0)
1101 return W5A; 1107 return W5A;
1102 else 1108 else
@@ -1200,9 +1206,10 @@ static int asus_hotk_get_info(void)
1200 hotk->methods->mt_wled = NULL; 1206 hotk->methods->mt_wled = NULL;
1201 /* L5D's WLED is not controlled by ACPI */ 1207 /* L5D's WLED is not controlled by ACPI */
1202 else if (strncmp(string, "M2N", 3) == 0 || 1208 else if (strncmp(string, "M2N", 3) == 0 ||
1209 strncmp(string, "W3V", 3) == 0 ||
1203 strncmp(string, "S1N", 3) == 0) 1210 strncmp(string, "S1N", 3) == 0)
1204 hotk->methods->mt_wled = "WLED"; 1211 hotk->methods->mt_wled = "WLED";
1205 /* M2N and S1N have a usable WLED */ 1212 /* M2N, S1N and W3V have a usable WLED */
1206 else if (asus_info) { 1213 else if (asus_info) {
1207 if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) 1214 if (strncmp(asus_info->oem_table_id, "L1", 2) == 0)
1208 hotk->methods->mled_status = NULL; 1215 hotk->methods->mled_status = NULL;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9810e2a55d0a..026e40755cdd 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -64,6 +64,7 @@ extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
64 64
65static int acpi_battery_add(struct acpi_device *device); 65static int acpi_battery_add(struct acpi_device *device);
66static int acpi_battery_remove(struct acpi_device *device, int type); 66static int acpi_battery_remove(struct acpi_device *device, int type);
67static int acpi_battery_resume(struct acpi_device *device, int status);
67 68
68static struct acpi_driver acpi_battery_driver = { 69static struct acpi_driver acpi_battery_driver = {
69 .name = ACPI_BATTERY_DRIVER_NAME, 70 .name = ACPI_BATTERY_DRIVER_NAME,
@@ -71,6 +72,7 @@ static struct acpi_driver acpi_battery_driver = {
71 .ids = ACPI_BATTERY_HID, 72 .ids = ACPI_BATTERY_HID,
72 .ops = { 73 .ops = {
73 .add = acpi_battery_add, 74 .add = acpi_battery_add,
75 .resume = acpi_battery_resume,
74 .remove = acpi_battery_remove, 76 .remove = acpi_battery_remove,
75 }, 77 },
76}; 78};
@@ -753,6 +755,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
753 return 0; 755 return 0;
754} 756}
755 757
758/* this is needed to learn about changes made in suspended state */
759static int acpi_battery_resume(struct acpi_device *device, int state)
760{
761 struct acpi_battery *battery;
762
763 if (!device)
764 return -EINVAL;
765
766 battery = device->driver_data;
767 return acpi_battery_check(battery);
768}
769
756static int __init acpi_battery_init(void) 770static int __init acpi_battery_init(void)
757{ 771{
758 int result; 772 int result;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index e5d796362854..e6d4b084dca2 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -45,206 +45,143 @@ 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
49/* EC status register */
48#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 50#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
49#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 51#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
50#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ 52#define ACPI_EC_FLAG_BURST 0x10 /* burst mode */
51#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ 53#define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */
52#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ 54
53#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ 55/* EC commands */
54#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
55#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
56#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */
57#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */
58#define ACPI_EC_COMMAND_READ 0x80 56#define ACPI_EC_COMMAND_READ 0x80
59#define ACPI_EC_COMMAND_WRITE 0x81 57#define ACPI_EC_COMMAND_WRITE 0x81
60#define ACPI_EC_BURST_ENABLE 0x82 58#define ACPI_EC_BURST_ENABLE 0x82
61#define ACPI_EC_BURST_DISABLE 0x83 59#define ACPI_EC_BURST_DISABLE 0x83
62#define ACPI_EC_COMMAND_QUERY 0x84 60#define ACPI_EC_COMMAND_QUERY 0x84
63#define EC_POLL 0xFF 61
64#define EC_INTR 0x00 62/* EC events */
63enum {
64 ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */
65 ACPI_EC_EVENT_IBF_0, /* Input buffer empty */
66};
67
68#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */
69#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
73enum {
74 EC_INTR = 1, /* Output buffer full */
75 EC_POLL, /* Input buffer empty */
76};
77
65static int acpi_ec_remove(struct acpi_device *device, int type); 78static int acpi_ec_remove(struct acpi_device *device, int type);
66static int acpi_ec_start(struct acpi_device *device); 79static int acpi_ec_start(struct acpi_device *device);
67static int acpi_ec_stop(struct acpi_device *device, int type); 80static int acpi_ec_stop(struct acpi_device *device, int type);
68static int acpi_ec_intr_add(struct acpi_device *device); 81static int acpi_ec_add(struct acpi_device *device);
69static int acpi_ec_poll_add(struct acpi_device *device);
70 82
71static struct acpi_driver acpi_ec_driver = { 83static struct acpi_driver acpi_ec_driver = {
72 .name = ACPI_EC_DRIVER_NAME, 84 .name = ACPI_EC_DRIVER_NAME,
73 .class = ACPI_EC_CLASS, 85 .class = ACPI_EC_CLASS,
74 .ids = ACPI_EC_HID, 86 .ids = ACPI_EC_HID,
75 .ops = { 87 .ops = {
76 .add = acpi_ec_intr_add, 88 .add = acpi_ec_add,
77 .remove = acpi_ec_remove, 89 .remove = acpi_ec_remove,
78 .start = acpi_ec_start, 90 .start = acpi_ec_start,
79 .stop = acpi_ec_stop, 91 .stop = acpi_ec_stop,
80 }, 92 },
81}; 93};
82union acpi_ec {
83 struct {
84 u32 mode;
85 acpi_handle handle;
86 unsigned long uid;
87 unsigned long gpe_bit;
88 struct acpi_generic_address status_addr;
89 struct acpi_generic_address command_addr;
90 struct acpi_generic_address data_addr;
91 unsigned long global_lock;
92 } common;
93
94 struct {
95 u32 mode;
96 acpi_handle handle;
97 unsigned long uid;
98 unsigned long gpe_bit;
99 struct acpi_generic_address status_addr;
100 struct acpi_generic_address command_addr;
101 struct acpi_generic_address data_addr;
102 unsigned long global_lock;
103 unsigned int expect_event;
104 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
105 atomic_t pending_gpe;
106 struct semaphore sem;
107 wait_queue_head_t wait;
108 } intr;
109
110 struct {
111 u32 mode;
112 acpi_handle handle;
113 unsigned long uid;
114 unsigned long gpe_bit;
115 struct acpi_generic_address status_addr;
116 struct acpi_generic_address command_addr;
117 struct acpi_generic_address data_addr;
118 unsigned long global_lock;
119 struct semaphore sem;
120 } poll;
121};
122 94
123static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event);
124static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event);
125static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data);
126static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data);
127static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data);
128static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data);
129static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data);
130static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data);
131static void acpi_ec_gpe_poll_query(void *ec_cxt);
132static void acpi_ec_gpe_intr_query(void *ec_cxt);
133static u32 acpi_ec_gpe_poll_handler(void *data);
134static u32 acpi_ec_gpe_intr_handler(void *data);
135static acpi_status __init
136acpi_fake_ecdt_poll_callback(acpi_handle handle,
137 u32 Level, void *context, void **retval);
138
139static acpi_status __init
140acpi_fake_ecdt_intr_callback(acpi_handle handle,
141 u32 Level, void *context, void **retval);
142
143static int __init acpi_ec_poll_get_real_ecdt(void);
144static int __init acpi_ec_intr_get_real_ecdt(void);
145/* If we find an EC via the ECDT, we need to keep a ptr to its context */ 95/* If we find an EC via the ECDT, we need to keep a ptr to its context */
146static union acpi_ec *ec_ecdt; 96struct acpi_ec {
97 acpi_handle handle;
98 unsigned long uid;
99 unsigned long gpe_bit;
100 unsigned long command_addr;
101 unsigned long data_addr;
102 unsigned long global_lock;
103 struct semaphore sem;
104 unsigned int expect_event;
105 atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */
106 wait_queue_head_t wait;
107} *ec_ecdt;
147 108
148/* External interfaces use first EC only, so remember */ 109/* External interfaces use first EC only, so remember */
149static struct acpi_device *first_ec; 110static struct acpi_device *first_ec;
150static int acpi_ec_poll_mode = EC_INTR; 111static int acpi_ec_mode = EC_INTR;
151 112
152/* -------------------------------------------------------------------------- 113/* --------------------------------------------------------------------------
153 Transaction Management 114 Transaction Management
154 -------------------------------------------------------------------------- */ 115 -------------------------------------------------------------------------- */
155 116
156static u32 acpi_ec_read_status(union acpi_ec *ec) 117static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
157{ 118{
158 u32 status = 0; 119 return inb(ec->command_addr);
159
160 acpi_hw_low_level_read(8, &status, &ec->common.status_addr);
161 return status;
162} 120}
163 121
164static int acpi_ec_wait(union acpi_ec *ec, u8 event) 122static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
165{ 123{
166 if (acpi_ec_poll_mode) 124 return inb(ec->data_addr);
167 return acpi_ec_poll_wait(ec, event);
168 else
169 return acpi_ec_intr_wait(ec, event);
170} 125}
171 126
172static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) 127static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
173{ 128{
174 u32 acpi_ec_status = 0; 129 outb(command, ec->command_addr);
175 u32 i = ACPI_EC_UDELAY_COUNT; 130}
176 131
177 if (!ec) 132static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
178 return -EINVAL; 133{
134 outb(data, ec->data_addr);
135}
179 136
180 /* Poll the EC status register waiting for the event to occur. */ 137static int acpi_ec_check_status(u8 status, u8 event)
138{
181 switch (event) { 139 switch (event) {
182 case ACPI_EC_EVENT_OBF: 140 case ACPI_EC_EVENT_OBF_1:
183 do { 141 if (status & ACPI_EC_FLAG_OBF)
184 acpi_hw_low_level_read(8, &acpi_ec_status, 142 return 1;
185 &ec->common.status_addr);
186 if (acpi_ec_status & ACPI_EC_FLAG_OBF)
187 return 0;
188 udelay(ACPI_EC_UDELAY);
189 } while (--i > 0);
190 break; 143 break;
191 case ACPI_EC_EVENT_IBE: 144 case ACPI_EC_EVENT_IBF_0:
192 do { 145 if (!(status & ACPI_EC_FLAG_IBF))
193 acpi_hw_low_level_read(8, &acpi_ec_status, 146 return 1;
194 &ec->common.status_addr);
195 if (!(acpi_ec_status & ACPI_EC_FLAG_IBF))
196 return 0;
197 udelay(ACPI_EC_UDELAY);
198 } while (--i > 0);
199 break; 147 break;
200 default: 148 default:
201 return -EINVAL; 149 break;
202 } 150 }
203 151
204 return -ETIME; 152 return 0;
205} 153}
206static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
207{
208 int result = 0;
209
210 154
211 ec->intr.expect_event = event; 155static int acpi_ec_wait(struct acpi_ec *ec, u8 event)
212 smp_mb(); 156{
157 int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0;
158 long time_left;
213 159
214 switch (event) { 160 ec->expect_event = event;
215 case ACPI_EC_EVENT_IBE: 161 if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
216 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) { 162 ec->expect_event = 0;
217 ec->intr.expect_event = 0; 163 return 0;
218 return 0;
219 }
220 break;
221 default:
222 break;
223 } 164 }
224 165
225 result = wait_event_timeout(ec->intr.wait, 166 do {
226 !ec->intr.expect_event, 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,
227 msecs_to_jiffies(ACPI_EC_DELAY)); 172 msecs_to_jiffies(ACPI_EC_DELAY));
228 173 if (time_left > 0) {
229 ec->intr.expect_event = 0; 174 ec->expect_event = 0;
230 smp_mb(); 175 return 0;
231 176 }
232 /* 177 }
233 * Verify that the event in question has actually happened by 178 if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) {
234 * querying EC status. Do the check even if operation timed-out 179 ec->expect_event = 0;
235 * to make sure that we did not miss interrupt.
236 */
237 switch (event) {
238 case ACPI_EC_EVENT_OBF:
239 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
240 return 0; 180 return 0;
241 break; 181 }
182 } while (--i > 0);
242 183
243 case ACPI_EC_EVENT_IBE: 184 ec->expect_event = 0;
244 if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
245 return 0;
246 break;
247 }
248 185
249 return -ETIME; 186 return -ETIME;
250} 187}
@@ -254,272 +191,150 @@ static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event)
254 * Note: samsung nv5000 doesn't work with ec burst mode. 191 * Note: samsung nv5000 doesn't work with ec burst mode.
255 * http://bugzilla.kernel.org/show_bug.cgi?id=4980 192 * http://bugzilla.kernel.org/show_bug.cgi?id=4980
256 */ 193 */
257int acpi_ec_enter_burst_mode(union acpi_ec *ec) 194int acpi_ec_enter_burst_mode(struct acpi_ec *ec)
258{ 195{
259 u32 tmp = 0; 196 u8 tmp = 0;
260 int status = 0; 197 u8 status = 0;
261 198
262 199
263 status = acpi_ec_read_status(ec); 200 status = acpi_ec_read_status(ec);
264 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { 201 if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) {
265 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 202 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
266 if (status) 203 if (status)
267 goto end; 204 goto end;
268 acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, 205 acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE);
269 &ec->common.command_addr); 206 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
270 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 207 tmp = acpi_ec_read_data(ec);
271 acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr);
272 if (tmp != 0x90) { /* Burst ACK byte */ 208 if (tmp != 0x90) { /* Burst ACK byte */
273 return -EINVAL; 209 return -EINVAL;
274 } 210 }
275 } 211 }
276 212
277 atomic_set(&ec->intr.leaving_burst, 0); 213 atomic_set(&ec->leaving_burst, 0);
278 return 0; 214 return 0;
279 end: 215 end:
280 ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode"); 216 ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode"));
281 return -1; 217 return -1;
282} 218}
283 219
284int acpi_ec_leave_burst_mode(union acpi_ec *ec) 220int acpi_ec_leave_burst_mode(struct acpi_ec *ec)
285{ 221{
286 int status = 0; 222 u8 status = 0;
287 223
288 224
289 status = acpi_ec_read_status(ec); 225 status = acpi_ec_read_status(ec);
290 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ 226 if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){
291 status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); 227 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
292 if(status) 228 if(status)
293 goto end; 229 goto end;
294 acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); 230 acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE);
295 acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); 231 acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
296 } 232 }
297 atomic_set(&ec->intr.leaving_burst, 1); 233 atomic_set(&ec->leaving_burst, 1);
298 return 0; 234 return 0;
299end: 235 end:
300 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"); 236 ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"));
301 return -1; 237 return -1;
302} 238}
303#endif /* ACPI_FUTURE_USAGE */ 239#endif /* ACPI_FUTURE_USAGE */
304 240
305static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) 241static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
306{ 242 const u8 *wdata, unsigned wdata_len,
307 if (acpi_ec_poll_mode) 243 u8 *rdata, unsigned rdata_len)
308 return acpi_ec_poll_read(ec, address, data);
309 else
310 return acpi_ec_intr_read(ec, address, data);
311}
312static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data)
313{
314 if (acpi_ec_poll_mode)
315 return acpi_ec_poll_write(ec, address, data);
316 else
317 return acpi_ec_intr_write(ec, address, data);
318}
319static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data)
320{ 244{
321 acpi_status status = AE_OK; 245 int result;
322 int result = 0;
323 u32 glk = 0;
324 246
247 acpi_ec_write_cmd(ec, command);
325 248
326 if (!ec || !data) 249 for (; wdata_len > 0; wdata_len --) {
327 return -EINVAL; 250 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
328 251 if (result)
329 *data = 0; 252 return result;
330 253 acpi_ec_write_data(ec, *(wdata++));
331 if (ec->common.global_lock) {
332 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
333 if (ACPI_FAILURE(status))
334 return -ENODEV;
335 } 254 }
336 255
337 if (down_interruptible(&ec->poll.sem)) { 256 if (command == ACPI_EC_COMMAND_WRITE) {
338 result = -ERESTARTSYS; 257 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
339 goto end_nosem; 258 if (result)
259 return result;
340 } 260 }
341
342 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
343 &ec->common.command_addr);
344 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
345 if (result)
346 goto end;
347
348 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
349 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
350 if (result)
351 goto end;
352
353 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
354
355 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
356 *data, address));
357
358 end:
359 up(&ec->poll.sem);
360end_nosem:
361 if (ec->common.global_lock)
362 acpi_release_global_lock(glk);
363
364 return result;
365}
366
367static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data)
368{
369 int result = 0;
370 acpi_status status = AE_OK;
371 u32 glk = 0;
372 261
262 for (; rdata_len > 0; rdata_len --) {
263 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1);
264 if (result)
265 return result;
373 266
374 if (!ec) 267 *(rdata++) = acpi_ec_read_data(ec);
375 return -EINVAL;
376
377 if (ec->common.global_lock) {
378 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
379 if (ACPI_FAILURE(status))
380 return -ENODEV;
381 }
382
383 if (down_interruptible(&ec->poll.sem)) {
384 result = -ERESTARTSYS;
385 goto end_nosem;
386 } 268 }
387
388 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
389 &ec->common.command_addr);
390 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
391 if (result)
392 goto end;
393
394 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
395 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
396 if (result)
397 goto end;
398
399 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
400 result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
401 if (result)
402 goto end;
403 269
404 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 270 return 0;
405 data, address));
406
407 end:
408 up(&ec->poll.sem);
409end_nosem:
410 if (ec->common.global_lock)
411 acpi_release_global_lock(glk);
412
413 return result;
414} 271}
415 272
416static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) 273static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
274 const u8 *wdata, unsigned wdata_len,
275 u8 *rdata, unsigned rdata_len)
417{ 276{
418 int status = 0; 277 int status;
419 u32 glk; 278 u32 glk;
420 279
421 280 if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata))
422 if (!ec || !data)
423 return -EINVAL; 281 return -EINVAL;
424 282
425 *data = 0; 283 if (rdata)
284 memset(rdata, 0, rdata_len);
426 285
427 if (ec->common.global_lock) { 286 if (ec->global_lock) {
428 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 287 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
429 if (ACPI_FAILURE(status)) 288 if (ACPI_FAILURE(status))
430 return -ENODEV; 289 return -ENODEV;
431 } 290 }
291 down(&ec->sem);
432 292
433 WARN_ON(in_interrupt()); 293 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0);
434 down(&ec->intr.sem);
435
436 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
437 if (status) { 294 if (status) {
438 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); 295 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
439 goto end; 296 goto end;
440 } 297 }
441 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ,
442 &ec->common.command_addr);
443 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
444 if (status) {
445 printk(KERN_DEBUG PREFIX "read EC, IB not empty\n");
446 }
447 298
448 acpi_hw_low_level_write(8, address, &ec->common.data_addr); 299 status = acpi_ec_transaction_unlocked(ec, command,
449 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); 300 wdata, wdata_len,
450 if (status) { 301 rdata, rdata_len);
451 printk(KERN_DEBUG PREFIX "read EC, OB not full\n");
452 goto end;
453 }
454 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
455 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n",
456 *data, address));
457 302
458 end: 303end:
459 up(&ec->intr.sem); 304 up(&ec->sem);
460 305
461 if (ec->common.global_lock) 306 if (ec->global_lock)
462 acpi_release_global_lock(glk); 307 acpi_release_global_lock(glk);
463 308
464 return status; 309 return status;
465} 310}
466 311
467static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) 312static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
468{ 313{
469 int status = 0; 314 int result;
470 u32 glk; 315 u8 d;
471
472
473 if (!ec)
474 return -EINVAL;
475
476 if (ec->common.global_lock) {
477 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
478 if (ACPI_FAILURE(status))
479 return -ENODEV;
480 }
481
482 WARN_ON(in_interrupt());
483 down(&ec->intr.sem);
484
485 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
486 if (status) {
487 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
488 }
489 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE,
490 &ec->common.command_addr);
491 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
492 if (status) {
493 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
494 }
495
496 acpi_hw_low_level_write(8, address, &ec->common.data_addr);
497 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE);
498 if (status) {
499 printk(KERN_DEBUG PREFIX "write EC, IB not empty\n");
500 }
501
502 acpi_hw_low_level_write(8, data, &ec->common.data_addr);
503 316
504 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", 317 result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ,
505 data, address)); 318 &address, 1, &d, 1);
506 319 *data = d;
507 up(&ec->intr.sem); 320 return result;
508 321}
509 if (ec->common.global_lock)
510 acpi_release_global_lock(glk);
511 322
512 return status; 323static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
324{
325 u8 wdata[2] = { address, data };
326 return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE,
327 wdata, 2, NULL, 0);
513} 328}
514 329
515/* 330/*
516 * Externally callable EC access functions. For now, assume 1 EC only 331 * Externally callable EC access functions. For now, assume 1 EC only
517 */ 332 */
518int ec_read(u8 addr, u8 * val) 333int ec_read(u8 addr, u8 *val)
519{ 334{
520 union acpi_ec *ec; 335 struct acpi_ec *ec;
521 int err; 336 int err;
522 u32 temp_data; 337 u8 temp_data;
523 338
524 if (!first_ec) 339 if (!first_ec)
525 return -ENODEV; 340 return -ENODEV;
@@ -539,7 +354,7 @@ EXPORT_SYMBOL(ec_read);
539 354
540int ec_write(u8 addr, u8 val) 355int ec_write(u8 addr, u8 val)
541{ 356{
542 union acpi_ec *ec; 357 struct acpi_ec *ec;
543 int err; 358 int err;
544 359
545 if (!first_ec) 360 if (!first_ec)
@@ -554,255 +369,106 @@ int ec_write(u8 addr, u8 val)
554 369
555EXPORT_SYMBOL(ec_write); 370EXPORT_SYMBOL(ec_write);
556 371
557static int acpi_ec_query(union acpi_ec *ec, u32 * data) 372extern int ec_transaction(u8 command,
558{ 373 const u8 *wdata, unsigned wdata_len,
559 if (acpi_ec_poll_mode) 374 u8 *rdata, unsigned rdata_len)
560 return acpi_ec_poll_query(ec, data);
561 else
562 return acpi_ec_intr_query(ec, data);
563}
564static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data)
565{ 375{
566 int result = 0; 376 struct acpi_ec *ec;
567 acpi_status status = AE_OK;
568 u32 glk = 0;
569
570
571 if (!ec || !data)
572 return -EINVAL;
573
574 *data = 0;
575
576 if (ec->common.global_lock) {
577 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
578 if (ACPI_FAILURE(status))
579 return -ENODEV;
580 }
581 377
582 /* 378 if (!first_ec)
583 * Query the EC to find out which _Qxx method we need to evaluate. 379 return -ENODEV;
584 * Note that successful completion of the query causes the ACPI_EC_SCI
585 * bit to be cleared (and thus clearing the interrupt source).
586 */
587 if (down_interruptible(&ec->poll.sem)) {
588 result = -ERESTARTSYS;
589 goto end_nosem;
590 }
591
592 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
593 &ec->common.command_addr);
594 result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
595 if (result)
596 goto end;
597
598 acpi_hw_low_level_read(8, data, &ec->common.data_addr);
599 if (!*data)
600 result = -ENODATA;
601 380
602 end: 381 ec = acpi_driver_data(first_ec);
603 up(&ec->poll.sem);
604end_nosem:
605 if (ec->common.global_lock)
606 acpi_release_global_lock(glk);
607 382
608 return result; 383 return acpi_ec_transaction(ec, command, wdata,
384 wdata_len, rdata, rdata_len);
609} 385}
610static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data)
611{
612 int status = 0;
613 u32 glk;
614
615 386
616 if (!ec || !data) 387EXPORT_SYMBOL(ec_transaction);
617 return -EINVAL;
618 *data = 0;
619
620 if (ec->common.global_lock) {
621 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
622 if (ACPI_FAILURE(status))
623 return -ENODEV;
624 }
625 388
626 down(&ec->intr.sem); 389static int acpi_ec_query(struct acpi_ec *ec, u8 *data)
390{
391 int result;
392 u8 d;
627 393
628 status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); 394 if (!ec || !data)
629 if (status) { 395 return -EINVAL;
630 printk(KERN_DEBUG PREFIX "query EC, IB not empty\n");
631 goto end;
632 }
633 /*
634 * Query the EC to find out which _Qxx method we need to evaluate.
635 * Note that successful completion of the query causes the ACPI_EC_SCI
636 * bit to be cleared (and thus clearing the interrupt source).
637 */
638 acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY,
639 &ec->common.command_addr);
640 status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF);
641 if (status) {
642 printk(KERN_DEBUG PREFIX "query EC, OB not full\n");
643 goto end;
644 }
645 396
646 acpi_hw_low_level_read(8, data, &ec->common.data_addr); 397 /*
647 if (!*data) 398 * Query the EC to find out which _Qxx method we need to evaluate.
648 status = -ENODATA; 399 * Note that successful completion of the query causes the ACPI_EC_SCI
400 * bit to be cleared (and thus clearing the interrupt source).
401 */
649 402
650 end: 403 result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1);
651 up(&ec->intr.sem); 404 if (result)
405 return result;
652 406
653 if (ec->common.global_lock) 407 if (!d)
654 acpi_release_global_lock(glk); 408 return -ENODATA;
655 409
656 return status; 410 *data = d;
411 return 0;
657} 412}
658 413
659/* -------------------------------------------------------------------------- 414/* --------------------------------------------------------------------------
660 Event Management 415 Event Management
661 -------------------------------------------------------------------------- */ 416 -------------------------------------------------------------------------- */
662 417
663union acpi_ec_query_data { 418struct acpi_ec_query_data {
664 acpi_handle handle; 419 acpi_handle handle;
665 u8 data; 420 u8 data;
666}; 421};
667 422
668static void acpi_ec_gpe_query(void *ec_cxt) 423static void acpi_ec_gpe_query(void *ec_cxt)
669{ 424{
670 if (acpi_ec_poll_mode) 425 struct acpi_ec *ec = (struct acpi_ec *)ec_cxt;
671 acpi_ec_gpe_poll_query(ec_cxt); 426 u8 value = 0;
672 else 427 static char object_name[8];
673 acpi_ec_gpe_intr_query(ec_cxt);
674}
675
676static void acpi_ec_gpe_poll_query(void *ec_cxt)
677{
678 union acpi_ec *ec = (union acpi_ec *)ec_cxt;
679 u32 value = 0;
680 static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
681 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
682 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
683 };
684
685 428
686 if (!ec_cxt) 429 if (!ec)
687 goto end; 430 goto end;
688 431
689 if (down_interruptible (&ec->poll.sem)) { 432 value = acpi_ec_read_status(ec);
690 return; 433
691 }
692 acpi_hw_low_level_read(8, &value, &ec->common.command_addr);
693 up(&ec->poll.sem);
694
695 /* TBD: Implement asynch events!
696 * NOTE: All we care about are EC-SCI's. Other EC events are
697 * handled via polling (yuck!). This is because some systems
698 * treat EC-SCIs as level (versus EDGE!) triggered, preventing
699 * a purely interrupt-driven approach (grumble, grumble).
700 */
701 if (!(value & ACPI_EC_FLAG_SCI)) 434 if (!(value & ACPI_EC_FLAG_SCI))
702 goto end; 435 goto end;
703 436
704 if (acpi_ec_query(ec, &value)) 437 if (acpi_ec_query(ec, &value))
705 goto end; 438 goto end;
706 439
707 object_name[2] = hex[((value >> 4) & 0x0F)]; 440 snprintf(object_name, 8, "_Q%2.2X", value);
708 object_name[3] = hex[(value & 0x0F)];
709
710 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
711 441
712 acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); 442 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name));
713 443
714 end: 444 acpi_evaluate_object(ec->handle, object_name, NULL, NULL);
715 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR);
716}
717static void acpi_ec_gpe_intr_query(void *ec_cxt)
718{
719 union acpi_ec *ec = (union acpi_ec *)ec_cxt;
720 u32 value;
721 int result = -ENODATA;
722 static char object_name[5] = { '_', 'Q', '0', '0', '\0' };
723 const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7',
724 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
725 };
726 445
727
728 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI)
729 result = acpi_ec_query(ec, &value);
730
731 if (result)
732 goto end;
733
734 object_name[2] = hex[((value >> 4) & 0x0F)];
735 object_name[3] = hex[(value & 0x0F)];
736
737 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name));
738
739 acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL);
740 end: 446 end:
741 atomic_dec(&ec->intr.pending_gpe); 447 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
742 return;
743} 448}
744 449
745static u32 acpi_ec_gpe_handler(void *data) 450static u32 acpi_ec_gpe_handler(void *data)
746{ 451{
747 if (acpi_ec_poll_mode)
748 return acpi_ec_gpe_poll_handler(data);
749 else
750 return acpi_ec_gpe_intr_handler(data);
751}
752static u32 acpi_ec_gpe_poll_handler(void *data)
753{
754 acpi_status status = AE_OK; 452 acpi_status status = AE_OK;
755 union acpi_ec *ec = (union acpi_ec *)data; 453 u8 value;
756 454 struct acpi_ec *ec = (struct acpi_ec *)data;
757 if (!ec)
758 return ACPI_INTERRUPT_NOT_HANDLED;
759
760 acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR);
761
762 status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec);
763
764 if (status == AE_OK)
765 return ACPI_INTERRUPT_HANDLED;
766 else
767 return ACPI_INTERRUPT_NOT_HANDLED;
768}
769static u32 acpi_ec_gpe_intr_handler(void *data)
770{
771 acpi_status status = AE_OK;
772 u32 value;
773 union acpi_ec *ec = (union acpi_ec *)data;
774
775 if (!ec)
776 return ACPI_INTERRUPT_NOT_HANDLED;
777 455
778 acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); 456 acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR);
779 value = acpi_ec_read_status(ec); 457 value = acpi_ec_read_status(ec);
780 458
781 switch (ec->intr.expect_event) { 459 if (acpi_ec_mode == EC_INTR) {
782 case ACPI_EC_EVENT_OBF: 460 if (acpi_ec_check_status(value, ec->expect_event)) {
783 if (!(value & ACPI_EC_FLAG_OBF)) 461 ec->expect_event = 0;
784 break; 462 wake_up(&ec->wait);
785 ec->intr.expect_event = 0; 463 }
786 wake_up(&ec->intr.wait);
787 break;
788 case ACPI_EC_EVENT_IBE:
789 if ((value & ACPI_EC_FLAG_IBF))
790 break;
791 ec->intr.expect_event = 0;
792 wake_up(&ec->intr.wait);
793 break;
794 default:
795 break;
796 } 464 }
797 465
798 if (value & ACPI_EC_FLAG_SCI) { 466 if (value & ACPI_EC_FLAG_SCI) {
799 atomic_add(1, &ec->intr.pending_gpe); 467 status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
800 status = acpi_os_execute(OSL_EC_BURST_HANDLER,
801 acpi_ec_gpe_query, ec);
802 return status == AE_OK ? 468 return status == AE_OK ?
803 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 469 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
804 } 470 }
805 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); 471 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR);
806 return status == AE_OK ? 472 return status == AE_OK ?
807 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; 473 ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
808} 474}
@@ -833,7 +499,7 @@ acpi_ec_space_handler(u32 function,
833 void *handler_context, void *region_context) 499 void *handler_context, void *region_context)
834{ 500{
835 int result = 0; 501 int result = 0;
836 union acpi_ec *ec = NULL; 502 struct acpi_ec *ec = NULL;
837 u64 temp = *value; 503 u64 temp = *value;
838 acpi_integer f_v = 0; 504 acpi_integer f_v = 0;
839 int i = 0; 505 int i = 0;
@@ -843,18 +509,16 @@ acpi_ec_space_handler(u32 function,
843 return AE_BAD_PARAMETER; 509 return AE_BAD_PARAMETER;
844 510
845 if (bit_width != 8 && acpi_strict) { 511 if (bit_width != 8 && acpi_strict) {
846 printk(KERN_WARNING PREFIX
847 "acpi_ec_space_handler: bit_width should be 8\n");
848 return AE_BAD_PARAMETER; 512 return AE_BAD_PARAMETER;
849 } 513 }
850 514
851 ec = (union acpi_ec *)handler_context; 515 ec = (struct acpi_ec *)handler_context;
852 516
853 next_byte: 517 next_byte:
854 switch (function) { 518 switch (function) {
855 case ACPI_READ: 519 case ACPI_READ:
856 temp = 0; 520 temp = 0;
857 result = acpi_ec_read(ec, (u8) address, (u32 *) & temp); 521 result = acpi_ec_read(ec, (u8) address, (u8 *) &temp);
858 break; 522 break;
859 case ACPI_WRITE: 523 case ACPI_WRITE:
860 result = acpi_ec_write(ec, (u8) address, (u8) temp); 524 result = acpi_ec_write(ec, (u8) address, (u8) temp);
@@ -905,20 +569,20 @@ static struct proc_dir_entry *acpi_ec_dir;
905 569
906static int acpi_ec_read_info(struct seq_file *seq, void *offset) 570static int acpi_ec_read_info(struct seq_file *seq, void *offset)
907{ 571{
908 union acpi_ec *ec = (union acpi_ec *)seq->private; 572 struct acpi_ec *ec = (struct acpi_ec *)seq->private;
909 573
910 574
911 if (!ec) 575 if (!ec)
912 goto end; 576 goto end;
913 577
914 seq_printf(seq, "gpe bit: 0x%02x\n", 578 seq_printf(seq, "gpe bit: 0x%02x\n",
915 (u32) ec->common.gpe_bit); 579 (u32) ec->gpe_bit);
916 seq_printf(seq, "ports: 0x%02x, 0x%02x\n", 580 seq_printf(seq, "ports: 0x%02x, 0x%02x\n",
917 (u32) ec->common.status_addr.address, 581 (u32) ec->command_addr,
918 (u32) ec->common.data_addr.address); 582 (u32) ec->data_addr);
919 seq_printf(seq, "use global lock: %s\n", 583 seq_printf(seq, "use global lock: %s\n",
920 ec->common.global_lock ? "yes" : "no"); 584 ec->global_lock ? "yes" : "no");
921 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 585 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
922 586
923 end: 587 end:
924 return 0; 588 return 0;
@@ -929,7 +593,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
929 return single_open(file, acpi_ec_read_info, PDE(inode)->data); 593 return single_open(file, acpi_ec_read_info, PDE(inode)->data);
930} 594}
931 595
932static const struct file_operations acpi_ec_info_ops = { 596static struct file_operations acpi_ec_info_ops = {
933 .open = acpi_ec_info_open_fs, 597 .open = acpi_ec_info_open_fs,
934 .read = seq_read, 598 .read = seq_read,
935 .llseek = seq_lseek, 599 .llseek = seq_lseek,
@@ -978,101 +642,35 @@ static int acpi_ec_remove_fs(struct acpi_device *device)
978 Driver Interface 642 Driver Interface
979 -------------------------------------------------------------------------- */ 643 -------------------------------------------------------------------------- */
980 644
981static int acpi_ec_poll_add(struct acpi_device *device) 645static int acpi_ec_add(struct acpi_device *device)
982{ 646{
983 int result = 0; 647 int result = 0;
984 acpi_status status = AE_OK; 648 acpi_status status = AE_OK;
985 union acpi_ec *ec = NULL; 649 struct acpi_ec *ec = NULL;
986 650
987 651
988 if (!device) 652 if (!device)
989 return -EINVAL; 653 return -EINVAL;
990 654
991 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); 655 ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
992 if (!ec) 656 if (!ec)
993 return -ENOMEM; 657 return -ENOMEM;
994 memset(ec, 0, sizeof(union acpi_ec)); 658 memset(ec, 0, sizeof(struct acpi_ec));
995 659
996 ec->common.handle = device->handle; 660 ec->handle = device->handle;
997 ec->common.uid = -1; 661 ec->uid = -1;
998 init_MUTEX(&ec->poll.sem); 662 init_MUTEX(&ec->sem);
999 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 663 if (acpi_ec_mode == EC_INTR) {
1000 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 664 atomic_set(&ec->leaving_burst, 1);
1001 acpi_driver_data(device) = ec; 665 init_waitqueue_head(&ec->wait);
1002
1003 /* Use the global lock for all EC transactions? */
1004 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL,
1005 &ec->common.global_lock);
1006
1007 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1008 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
1009 if (ec_ecdt) {
1010 acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
1011 ACPI_ADR_SPACE_EC,
1012 &acpi_ec_space_handler);
1013
1014 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit,
1015 &acpi_ec_gpe_handler);
1016
1017 kfree(ec_ecdt);
1018 } 666 }
1019
1020 /* Get GPE bit assignment (EC events). */
1021 /* TODO: Add support for _GPE returning a package */
1022 status =
1023 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL,
1024 &ec->common.gpe_bit);
1025 if (ACPI_FAILURE(status)) {
1026 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit"));
1027 result = -ENODEV;
1028 goto end;
1029 }
1030
1031 result = acpi_ec_add_fs(device);
1032 if (result)
1033 goto end;
1034
1035 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n",
1036 acpi_device_name(device), acpi_device_bid(device),
1037 (u32) ec->common.gpe_bit);
1038
1039 if (!first_ec)
1040 first_ec = device;
1041
1042 end:
1043 if (result)
1044 kfree(ec);
1045
1046 return result;
1047}
1048static int acpi_ec_intr_add(struct acpi_device *device)
1049{
1050 int result = 0;
1051 acpi_status status = AE_OK;
1052 union acpi_ec *ec = NULL;
1053
1054
1055 if (!device)
1056 return -EINVAL;
1057
1058 ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1059 if (!ec)
1060 return -ENOMEM;
1061 memset(ec, 0, sizeof(union acpi_ec));
1062
1063 ec->common.handle = device->handle;
1064 ec->common.uid = -1;
1065 atomic_set(&ec->intr.pending_gpe, 0);
1066 atomic_set(&ec->intr.leaving_burst, 1);
1067 init_MUTEX(&ec->intr.sem);
1068 init_waitqueue_head(&ec->intr.wait);
1069 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 667 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
1070 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 668 strcpy(acpi_device_class(device), ACPI_EC_CLASS);
1071 acpi_driver_data(device) = ec; 669 acpi_driver_data(device) = ec;
1072 670
1073 /* Use the global lock for all EC transactions? */ 671 /* Use the global lock for all EC transactions? */
1074 acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, 672 acpi_evaluate_integer(ec->handle, "_GLK", NULL,
1075 &ec->common.global_lock); 673 &ec->global_lock);
1076 674
1077 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: 675 /* XXX we don't test uids, because on some boxes ecdt uid = 0, see:
1078 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ 676 http://bugzilla.kernel.org/show_bug.cgi?id=6111 */
@@ -1081,7 +679,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1081 ACPI_ADR_SPACE_EC, 679 ACPI_ADR_SPACE_EC,
1082 &acpi_ec_space_handler); 680 &acpi_ec_space_handler);
1083 681
1084 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, 682 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
1085 &acpi_ec_gpe_handler); 683 &acpi_ec_gpe_handler);
1086 684
1087 kfree(ec_ecdt); 685 kfree(ec_ecdt);
@@ -1090,10 +688,10 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1090 /* Get GPE bit assignment (EC events). */ 688 /* Get GPE bit assignment (EC events). */
1091 /* TODO: Add support for _GPE returning a package */ 689 /* TODO: Add support for _GPE returning a package */
1092 status = 690 status =
1093 acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, 691 acpi_evaluate_integer(ec->handle, "_GPE", NULL,
1094 &ec->common.gpe_bit); 692 &ec->gpe_bit);
1095 if (ACPI_FAILURE(status)) { 693 if (ACPI_FAILURE(status)) {
1096 printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n"); 694 ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment"));
1097 result = -ENODEV; 695 result = -ENODEV;
1098 goto end; 696 goto end;
1099 } 697 }
@@ -1102,14 +700,14 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1102 if (result) 700 if (result)
1103 goto end; 701 goto end;
1104 702
1105 printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n", 703 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.",
1106 acpi_device_name(device), acpi_device_bid(device), 704 acpi_device_name(device), acpi_device_bid(device),
1107 (u32) ec->common.gpe_bit); 705 (u32) ec->gpe_bit));
1108 706
1109 if (!first_ec) 707 if (!first_ec)
1110 first_ec = device; 708 first_ec = device;
1111 709
1112 end: 710 end:
1113 if (result) 711 if (result)
1114 kfree(ec); 712 kfree(ec);
1115 713
@@ -1118,7 +716,7 @@ static int acpi_ec_intr_add(struct acpi_device *device)
1118 716
1119static int acpi_ec_remove(struct acpi_device *device, int type) 717static int acpi_ec_remove(struct acpi_device *device, int type)
1120{ 718{
1121 union acpi_ec *ec = NULL; 719 struct acpi_ec *ec = NULL;
1122 720
1123 721
1124 if (!device) 722 if (!device)
@@ -1136,8 +734,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
1136static acpi_status 734static acpi_status
1137acpi_ec_io_ports(struct acpi_resource *resource, void *context) 735acpi_ec_io_ports(struct acpi_resource *resource, void *context)
1138{ 736{
1139 union acpi_ec *ec = (union acpi_ec *)context; 737 struct acpi_ec *ec = (struct acpi_ec *)context;
1140 struct acpi_generic_address *addr;
1141 738
1142 if (resource->type != ACPI_RESOURCE_TYPE_IO) { 739 if (resource->type != ACPI_RESOURCE_TYPE_IO) {
1143 return AE_OK; 740 return AE_OK;
@@ -1148,26 +745,21 @@ acpi_ec_io_ports(struct acpi_resource *resource, void *context)
1148 * the second address region returned is the status/command 745 * the second address region returned is the status/command
1149 * port. 746 * port.
1150 */ 747 */
1151 if (ec->common.data_addr.register_bit_width == 0) { 748 if (ec->data_addr == 0) {
1152 addr = &ec->common.data_addr; 749 ec->data_addr = resource->data.io.minimum;
1153 } else if (ec->common.command_addr.register_bit_width == 0) { 750 } else if (ec->command_addr == 0) {
1154 addr = &ec->common.command_addr; 751 ec->command_addr = resource->data.io.minimum;
1155 } else { 752 } else {
1156 return AE_CTRL_TERMINATE; 753 return AE_CTRL_TERMINATE;
1157 } 754 }
1158 755
1159 addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO;
1160 addr->register_bit_width = 8;
1161 addr->register_bit_offset = 0;
1162 addr->address = resource->data.io.minimum;
1163
1164 return AE_OK; 756 return AE_OK;
1165} 757}
1166 758
1167static int acpi_ec_start(struct acpi_device *device) 759static int acpi_ec_start(struct acpi_device *device)
1168{ 760{
1169 acpi_status status = AE_OK; 761 acpi_status status = AE_OK;
1170 union acpi_ec *ec = NULL; 762 struct acpi_ec *ec = NULL;
1171 763
1172 764
1173 if (!device) 765 if (!device)
@@ -1181,39 +773,35 @@ static int acpi_ec_start(struct acpi_device *device)
1181 /* 773 /*
1182 * Get I/O port addresses. Convert to GAS format. 774 * Get I/O port addresses. Convert to GAS format.
1183 */ 775 */
1184 status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, 776 status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS,
1185 acpi_ec_io_ports, ec); 777 acpi_ec_io_ports, ec);
1186 if (ACPI_FAILURE(status) 778 if (ACPI_FAILURE(status) || ec->command_addr == 0) {
1187 || ec->common.command_addr.register_bit_width == 0) { 779 ACPI_EXCEPTION((AE_INFO, status,
1188 printk(KERN_ERR PREFIX "Error getting I/O port addresses\n"); 780 "Error getting I/O port addresses"));
1189 return -ENODEV; 781 return -ENODEV;
1190 } 782 }
1191 783
1192 ec->common.status_addr = ec->common.command_addr; 784 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx",
1193 785 ec->gpe_bit, ec->command_addr, ec->data_addr));
1194 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n",
1195 (u32) ec->common.gpe_bit,
1196 (u32) ec->common.command_addr.address,
1197 (u32) ec->common.data_addr.address));
1198 786
1199 /* 787 /*
1200 * Install GPE handler 788 * Install GPE handler
1201 */ 789 */
1202 status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, 790 status = acpi_install_gpe_handler(NULL, ec->gpe_bit,
1203 ACPI_GPE_EDGE_TRIGGERED, 791 ACPI_GPE_EDGE_TRIGGERED,
1204 &acpi_ec_gpe_handler, ec); 792 &acpi_ec_gpe_handler, ec);
1205 if (ACPI_FAILURE(status)) { 793 if (ACPI_FAILURE(status)) {
1206 return -ENODEV; 794 return -ENODEV;
1207 } 795 }
1208 acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); 796 acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1209 acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); 797 acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR);
1210 798
1211 status = acpi_install_address_space_handler(ec->common.handle, 799 status = acpi_install_address_space_handler(ec->handle,
1212 ACPI_ADR_SPACE_EC, 800 ACPI_ADR_SPACE_EC,
1213 &acpi_ec_space_handler, 801 &acpi_ec_space_handler,
1214 &acpi_ec_space_setup, ec); 802 &acpi_ec_space_setup, ec);
1215 if (ACPI_FAILURE(status)) { 803 if (ACPI_FAILURE(status)) {
1216 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, 804 acpi_remove_gpe_handler(NULL, ec->gpe_bit,
1217 &acpi_ec_gpe_handler); 805 &acpi_ec_gpe_handler);
1218 return -ENODEV; 806 return -ENODEV;
1219 } 807 }
@@ -1224,7 +812,7 @@ static int acpi_ec_start(struct acpi_device *device)
1224static int acpi_ec_stop(struct acpi_device *device, int type) 812static int acpi_ec_stop(struct acpi_device *device, int type)
1225{ 813{
1226 acpi_status status = AE_OK; 814 acpi_status status = AE_OK;
1227 union acpi_ec *ec = NULL; 815 struct acpi_ec *ec = NULL;
1228 816
1229 817
1230 if (!device) 818 if (!device)
@@ -1232,14 +820,14 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
1232 820
1233 ec = acpi_driver_data(device); 821 ec = acpi_driver_data(device);
1234 822
1235 status = acpi_remove_address_space_handler(ec->common.handle, 823 status = acpi_remove_address_space_handler(ec->handle,
1236 ACPI_ADR_SPACE_EC, 824 ACPI_ADR_SPACE_EC,
1237 &acpi_ec_space_handler); 825 &acpi_ec_space_handler);
1238 if (ACPI_FAILURE(status)) 826 if (ACPI_FAILURE(status))
1239 return -ENODEV; 827 return -ENODEV;
1240 828
1241 status = 829 status =
1242 acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, 830 acpi_remove_gpe_handler(NULL, ec->gpe_bit,
1243 &acpi_ec_gpe_handler); 831 &acpi_ec_gpe_handler);
1244 if (ACPI_FAILURE(status)) 832 if (ACPI_FAILURE(status))
1245 return -ENODEV; 833 return -ENODEV;
@@ -1251,76 +839,30 @@ static acpi_status __init
1251acpi_fake_ecdt_callback(acpi_handle handle, 839acpi_fake_ecdt_callback(acpi_handle handle,
1252 u32 Level, void *context, void **retval) 840 u32 Level, void *context, void **retval)
1253{ 841{
1254
1255 if (acpi_ec_poll_mode)
1256 return acpi_fake_ecdt_poll_callback(handle,
1257 Level, context, retval);
1258 else
1259 return acpi_fake_ecdt_intr_callback(handle,
1260 Level, context, retval);
1261}
1262
1263static acpi_status __init
1264acpi_fake_ecdt_poll_callback(acpi_handle handle,
1265 u32 Level, void *context, void **retval)
1266{
1267 acpi_status status;
1268
1269 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
1270 acpi_ec_io_ports, ec_ecdt);
1271 if (ACPI_FAILURE(status))
1272 return status;
1273 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1274
1275 ec_ecdt->common.uid = -1;
1276 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid);
1277
1278 status =
1279 acpi_evaluate_integer(handle, "_GPE", NULL,
1280 &ec_ecdt->common.gpe_bit);
1281 if (ACPI_FAILURE(status))
1282 return status;
1283 init_MUTEX(&ec_ecdt->poll.sem);
1284 ec_ecdt->common.global_lock = TRUE;
1285 ec_ecdt->common.handle = handle;
1286
1287 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n",
1288 (u32) ec_ecdt->common.gpe_bit,
1289 (u32) ec_ecdt->common.command_addr.address,
1290 (u32) ec_ecdt->common.data_addr.address);
1291
1292 return AE_CTRL_TERMINATE;
1293}
1294
1295static acpi_status __init
1296acpi_fake_ecdt_intr_callback(acpi_handle handle,
1297 u32 Level, void *context, void **retval)
1298{
1299 acpi_status status; 842 acpi_status status;
1300 843
1301 init_MUTEX(&ec_ecdt->intr.sem); 844 init_MUTEX(&ec_ecdt->sem);
1302 init_waitqueue_head(&ec_ecdt->intr.wait); 845 if (acpi_ec_mode == EC_INTR) {
846 init_waitqueue_head(&ec_ecdt->wait);
847 }
1303 status = acpi_walk_resources(handle, METHOD_NAME__CRS, 848 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
1304 acpi_ec_io_ports, ec_ecdt); 849 acpi_ec_io_ports, ec_ecdt);
1305 if (ACPI_FAILURE(status)) 850 if (ACPI_FAILURE(status))
1306 return status; 851 return status;
1307 ec_ecdt->common.status_addr = ec_ecdt->common.command_addr;
1308 852
1309 ec_ecdt->common.uid = -1; 853 ec_ecdt->uid = -1;
1310 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); 854 acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid);
1311 855
1312 status = 856 status =
1313 acpi_evaluate_integer(handle, "_GPE", NULL, 857 acpi_evaluate_integer(handle, "_GPE", NULL,
1314 &ec_ecdt->common.gpe_bit); 858 &ec_ecdt->gpe_bit);
1315 if (ACPI_FAILURE(status)) 859 if (ACPI_FAILURE(status))
1316 return status; 860 return status;
1317 ec_ecdt->common.global_lock = TRUE; 861 ec_ecdt->global_lock = TRUE;
1318 ec_ecdt->common.handle = handle; 862 ec_ecdt->handle = handle;
1319 863
1320 printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", 864 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx",
1321 (u32) ec_ecdt->common.gpe_bit, 865 ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr));
1322 (u32) ec_ecdt->common.command_addr.address,
1323 (u32) ec_ecdt->common.data_addr.address);
1324 866
1325 return AE_CTRL_TERMINATE; 867 return AE_CTRL_TERMINATE;
1326} 868}
@@ -1340,14 +882,14 @@ static int __init acpi_ec_fake_ecdt(void)
1340 acpi_status status; 882 acpi_status status;
1341 int ret = 0; 883 int ret = 0;
1342 884
1343 printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); 885 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT"));
1344 886
1345 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); 887 ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
1346 if (!ec_ecdt) { 888 if (!ec_ecdt) {
1347 ret = -ENOMEM; 889 ret = -ENOMEM;
1348 goto error; 890 goto error;
1349 } 891 }
1350 memset(ec_ecdt, 0, sizeof(union acpi_ec)); 892 memset(ec_ecdt, 0, sizeof(struct acpi_ec));
1351 893
1352 status = acpi_get_devices(ACPI_EC_HID, 894 status = acpi_get_devices(ACPI_EC_HID,
1353 acpi_fake_ecdt_callback, NULL, NULL); 895 acpi_fake_ecdt_callback, NULL, NULL);
@@ -1355,24 +897,16 @@ static int __init acpi_ec_fake_ecdt(void)
1355 kfree(ec_ecdt); 897 kfree(ec_ecdt);
1356 ec_ecdt = NULL; 898 ec_ecdt = NULL;
1357 ret = -ENODEV; 899 ret = -ENODEV;
900 ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT"));
1358 goto error; 901 goto error;
1359 } 902 }
1360 return 0; 903 return 0;
1361 error: 904 error:
1362 printk(KERN_ERR PREFIX "Can't make an fake ECDT\n");
1363 return ret; 905 return ret;
1364} 906}
1365 907
1366static int __init acpi_ec_get_real_ecdt(void) 908static int __init acpi_ec_get_real_ecdt(void)
1367{ 909{
1368 if (acpi_ec_poll_mode)
1369 return acpi_ec_poll_get_real_ecdt();
1370 else
1371 return acpi_ec_intr_get_real_ecdt();
1372}
1373
1374static int __init acpi_ec_poll_get_real_ecdt(void)
1375{
1376 acpi_status status; 910 acpi_status status;
1377 struct acpi_table_ecdt *ecdt_ptr; 911 struct acpi_table_ecdt *ecdt_ptr;
1378 912
@@ -1382,80 +916,36 @@ static int __init acpi_ec_poll_get_real_ecdt(void)
1382 if (ACPI_FAILURE(status)) 916 if (ACPI_FAILURE(status))
1383 return -ENODEV; 917 return -ENODEV;
1384 918
1385 printk(KERN_INFO PREFIX "Found ECDT\n"); 919 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT"));
1386 920
1387 /* 921 /*
1388 * Generate a temporary ec context to use until the namespace is scanned 922 * Generate a temporary ec context to use until the namespace is scanned
1389 */ 923 */
1390 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); 924 ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
1391 if (!ec_ecdt) 925 if (!ec_ecdt)
1392 return -ENOMEM; 926 return -ENOMEM;
1393 memset(ec_ecdt, 0, sizeof(union acpi_ec)); 927 memset(ec_ecdt, 0, sizeof(struct acpi_ec));
1394
1395 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1396 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1397 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1398 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
1399 init_MUTEX(&ec_ecdt->poll.sem);
1400 /* use the GL just to be safe */
1401 ec_ecdt->common.global_lock = TRUE;
1402 ec_ecdt->common.uid = ecdt_ptr->uid;
1403 928
1404 status = 929 init_MUTEX(&ec_ecdt->sem);
1405 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); 930 if (acpi_ec_mode == EC_INTR) {
1406 if (ACPI_FAILURE(status)) { 931 init_waitqueue_head(&ec_ecdt->wait);
1407 goto error;
1408 } 932 }
1409 933 ec_ecdt->command_addr = ecdt_ptr->ec_control.address;
1410 return 0; 934 ec_ecdt->data_addr = ecdt_ptr->ec_data.address;
1411 error: 935 ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit;
1412 printk(KERN_ERR PREFIX "Could not use ECDT\n");
1413 kfree(ec_ecdt);
1414 ec_ecdt = NULL;
1415
1416 return -ENODEV;
1417}
1418
1419static int __init acpi_ec_intr_get_real_ecdt(void)
1420{
1421 acpi_status status;
1422 struct acpi_table_ecdt *ecdt_ptr;
1423
1424 status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
1425 (struct acpi_table_header **)
1426 &ecdt_ptr);
1427 if (ACPI_FAILURE(status))
1428 return -ENODEV;
1429
1430 printk(KERN_INFO PREFIX "Found ECDT\n");
1431
1432 /*
1433 * Generate a temporary ec context to use until the namespace is scanned
1434 */
1435 ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL);
1436 if (!ec_ecdt)
1437 return -ENOMEM;
1438 memset(ec_ecdt, 0, sizeof(union acpi_ec));
1439
1440 init_MUTEX(&ec_ecdt->intr.sem);
1441 init_waitqueue_head(&ec_ecdt->intr.wait);
1442 ec_ecdt->common.command_addr = ecdt_ptr->ec_control;
1443 ec_ecdt->common.status_addr = ecdt_ptr->ec_control;
1444 ec_ecdt->common.data_addr = ecdt_ptr->ec_data;
1445 ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit;
1446 /* use the GL just to be safe */ 936 /* use the GL just to be safe */
1447 ec_ecdt->common.global_lock = TRUE; 937 ec_ecdt->global_lock = TRUE;
1448 ec_ecdt->common.uid = ecdt_ptr->uid; 938 ec_ecdt->uid = ecdt_ptr->uid;
1449 939
1450 status = 940 status =
1451 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); 941 acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle);
1452 if (ACPI_FAILURE(status)) { 942 if (ACPI_FAILURE(status)) {
1453 goto error; 943 goto error;
1454 } 944 }
1455 945
1456 return 0; 946 return 0;
1457 error: 947 error:
1458 printk(KERN_ERR PREFIX "Could not use ECDT\n"); 948 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
1459 kfree(ec_ecdt); 949 kfree(ec_ecdt);
1460 ec_ecdt = NULL; 950 ec_ecdt = NULL;
1461 951
@@ -1480,14 +970,14 @@ int __init acpi_ec_ecdt_probe(void)
1480 /* 970 /*
1481 * Install GPE handler 971 * Install GPE handler
1482 */ 972 */
1483 status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, 973 status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit,
1484 ACPI_GPE_EDGE_TRIGGERED, 974 ACPI_GPE_EDGE_TRIGGERED,
1485 &acpi_ec_gpe_handler, ec_ecdt); 975 &acpi_ec_gpe_handler, ec_ecdt);
1486 if (ACPI_FAILURE(status)) { 976 if (ACPI_FAILURE(status)) {
1487 goto error; 977 goto error;
1488 } 978 }
1489 acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); 979 acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME);
1490 acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); 980 acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR);
1491 981
1492 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, 982 status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
1493 ACPI_ADR_SPACE_EC, 983 ACPI_ADR_SPACE_EC,
@@ -1495,7 +985,7 @@ int __init acpi_ec_ecdt_probe(void)
1495 &acpi_ec_space_setup, 985 &acpi_ec_space_setup,
1496 ec_ecdt); 986 ec_ecdt);
1497 if (ACPI_FAILURE(status)) { 987 if (ACPI_FAILURE(status)) {
1498 acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, 988 acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit,
1499 &acpi_ec_gpe_handler); 989 &acpi_ec_gpe_handler);
1500 goto error; 990 goto error;
1501 } 991 }
@@ -1503,7 +993,7 @@ int __init acpi_ec_ecdt_probe(void)
1503 return 0; 993 return 0;
1504 994
1505 error: 995 error:
1506 printk(KERN_ERR PREFIX "Could not use ECDT\n"); 996 ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT"));
1507 kfree(ec_ecdt); 997 kfree(ec_ecdt);
1508 ec_ecdt = NULL; 998 ec_ecdt = NULL;
1509 999
@@ -1562,13 +1052,13 @@ static int __init acpi_ec_set_intr_mode(char *str)
1562 return 0; 1052 return 0;
1563 1053
1564 if (intr) { 1054 if (intr) {
1565 acpi_ec_poll_mode = EC_INTR; 1055 acpi_ec_mode = EC_INTR;
1566 acpi_ec_driver.ops.add = acpi_ec_intr_add;
1567 } else { 1056 } else {
1568 acpi_ec_poll_mode = EC_POLL; 1057 acpi_ec_mode = EC_POLL;
1569 acpi_ec_driver.ops.add = acpi_ec_poll_add;
1570 } 1058 }
1571 printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); 1059 acpi_ec_driver.ops.add = acpi_ec_add;
1060 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling"));
1061
1572 return 1; 1062 return 1;
1573} 1063}
1574 1064
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 6eef4efddcf6..ee2a10bf9077 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(void *context)
342 if (acquired) { 342 if (acquired) {
343 343
344 /* Got the lock, now wake all threads waiting for it */ 344 /* Got the lock, now wake all threads waiting for it */
345
346 acpi_gbl_global_lock_acquired = TRUE; 345 acpi_gbl_global_lock_acquired = TRUE;
347 346 acpi_ev_global_lock_thread(context);
348 /* Run the Global Lock thread which will signal all waiting threads */
349
350 status =
351 acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER,
352 acpi_ev_global_lock_thread, context);
353 if (ACPI_FAILURE(status)) {
354 ACPI_EXCEPTION((AE_INFO, status,
355 "Could not queue Global Lock thread"));
356
357 return (ACPI_INTERRUPT_NOT_HANDLED);
358 }
359 } 347 }
360 348
361 return (ACPI_INTERRUPT_HANDLED); 349 return (ACPI_INTERRUPT_HANDLED);
diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c
index 5b3c7a85eb9a..203d1359190a 100644
--- a/drivers/acpi/events/evrgnini.c
+++ b/drivers/acpi/events/evrgnini.c
@@ -225,13 +225,12 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
225 if (! 225 if (!
226 (ACPI_STRNCMP 226 (ACPI_STRNCMP
227 (object_hID.value, PCI_ROOT_HID_STRING, 227 (object_hID.value, PCI_ROOT_HID_STRING,
228 sizeof(PCI_ROOT_HID_STRING)) 228 sizeof(PCI_ROOT_HID_STRING)))
229 || 229 ||
230 !(ACPI_STRNCMP 230 !(ACPI_STRNCMP
231 (object_hID.value, 231 (object_hID.value,
232 PCI_EXPRESS_ROOT_HID_STRING, 232 PCI_EXPRESS_ROOT_HID_STRING,
233 sizeof(PCI_EXPRESS_ROOT_HID_STRING))))) 233 sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
234 {
235 234
236 /* Install a handler for this PCI root bridge */ 235 /* Install a handler for this PCI root bridge */
237 236
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 15fc12482ba0..003a9876c968 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -1702,13 +1702,11 @@ static struct ibm_struct ibms[] = {
1702 .name = "brightness", 1702 .name = "brightness",
1703 .read = brightness_read, 1703 .read = brightness_read,
1704 .write = brightness_write, 1704 .write = brightness_write,
1705 .experimental = 1,
1706 }, 1705 },
1707 { 1706 {
1708 .name = "volume", 1707 .name = "volume",
1709 .read = volume_read, 1708 .read = volume_read,
1710 .write = volume_write, 1709 .write = volume_write,
1711 .experimental = 1,
1712 }, 1710 },
1713 { 1711 {
1714 .name = "fan", 1712 .name = "fan",
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c
index ec6b7f9ede34..2e17ec75af03 100644
--- a/drivers/acpi/motherboard.c
+++ b/drivers/acpi/motherboard.c
@@ -48,6 +48,12 @@ ACPI_MODULE_NAME("acpi_motherboard")
48 * the io ports if they really know they can use it, while 48 * the io ports if they really know they can use it, while
49 * still preventing hotplug PCI devices from using it. 49 * still preventing hotplug PCI devices from using it.
50 */ 50 */
51
52/*
53 * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01
54 * and PNP0C02, redundant with acpi_reserve_io_ranges().
55 * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP.
56 */
51static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) 57static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data)
52{ 58{
53 struct resource *requested_res = NULL; 59 struct resource *requested_res = NULL;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 068fe4f100b0..c84286cbbe25 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -73,6 +73,7 @@ static unsigned int acpi_irq_irq;
73static acpi_osd_handler acpi_irq_handler; 73static acpi_osd_handler acpi_irq_handler;
74static void *acpi_irq_context; 74static void *acpi_irq_context;
75static struct workqueue_struct *kacpid_wq; 75static struct workqueue_struct *kacpid_wq;
76static struct workqueue_struct *kacpi_notify_wq;
76 77
77acpi_status acpi_os_initialize(void) 78acpi_status acpi_os_initialize(void)
78{ 79{
@@ -91,8 +92,9 @@ acpi_status acpi_os_initialize1(void)
91 return AE_NULL_ENTRY; 92 return AE_NULL_ENTRY;
92 } 93 }
93 kacpid_wq = create_singlethread_workqueue("kacpid"); 94 kacpid_wq = create_singlethread_workqueue("kacpid");
95 kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
94 BUG_ON(!kacpid_wq); 96 BUG_ON(!kacpid_wq);
95 97 BUG_ON(!kacpi_notify_wq);
96 return AE_OK; 98 return AE_OK;
97} 99}
98 100
@@ -104,6 +106,7 @@ acpi_status acpi_os_terminate(void)
104 } 106 }
105 107
106 destroy_workqueue(kacpid_wq); 108 destroy_workqueue(kacpid_wq);
109 destroy_workqueue(kacpi_notify_wq);
107 110
108 return AE_OK; 111 return AE_OK;
109} 112}
@@ -566,10 +569,7 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */
566 569
567static void acpi_os_execute_deferred(void *context) 570static void acpi_os_execute_deferred(void *context)
568{ 571{
569 struct acpi_os_dpc *dpc = NULL; 572 struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
570
571
572 dpc = (struct acpi_os_dpc *)context;
573 if (!dpc) { 573 if (!dpc) {
574 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 574 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
575 return; 575 return;
@@ -604,14 +604,12 @@ acpi_status acpi_os_execute(acpi_execute_type type,
604 struct acpi_os_dpc *dpc; 604 struct acpi_os_dpc *dpc;
605 struct work_struct *task; 605 struct work_struct *task;
606 606
607 ACPI_FUNCTION_TRACE("os_queue_for_execution");
608
609 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 607 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
610 "Scheduling function [%p(%p)] for deferred execution.\n", 608 "Scheduling function [%p(%p)] for deferred execution.\n",
611 function, context)); 609 function, context));
612 610
613 if (!function) 611 if (!function)
614 return_ACPI_STATUS(AE_BAD_PARAMETER); 612 return AE_BAD_PARAMETER;
615 613
616 /* 614 /*
617 * Allocate/initialize DPC structure. Note that this memory will be 615 * Allocate/initialize DPC structure. Note that this memory will be
@@ -624,26 +622,20 @@ acpi_status acpi_os_execute(acpi_execute_type type,
624 * from the same memory. 622 * from the same memory.
625 */ 623 */
626 624
627 dpc = 625 dpc = kmalloc(sizeof(struct acpi_os_dpc) +
628 kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), 626 sizeof(struct work_struct), GFP_ATOMIC);
629 GFP_ATOMIC);
630 if (!dpc) 627 if (!dpc)
631 return_ACPI_STATUS(AE_NO_MEMORY); 628 return AE_NO_MEMORY;
632
633 dpc->function = function; 629 dpc->function = function;
634 dpc->context = context; 630 dpc->context = context;
635
636 task = (void *)(dpc + 1); 631 task = (void *)(dpc + 1);
637 INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); 632 INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
638 633 if (!queue_work((type == OSL_NOTIFY_HANDLER)?
639 if (!queue_work(kacpid_wq, task)) { 634 kacpi_notify_wq : kacpid_wq, task)) {
640 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
641 "Call to queue_work() failed.\n"));
642 kfree(dpc);
643 status = AE_ERROR; 635 status = AE_ERROR;
636 kfree(dpc);
644 } 637 }
645 638 return status;
646 return_ACPI_STATUS(status);
647} 639}
648 640
649EXPORT_SYMBOL(acpi_os_execute); 641EXPORT_SYMBOL(acpi_os_execute);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 7f3e7e77e794..d53bd9878ca2 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
307 if (!link || !irq) 307 if (!link || !irq)
308 return -EINVAL; 308 return -EINVAL;
309 309
310 resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC); 310 resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
311 if (!resource) 311 if (!resource)
312 return -ENOMEM; 312 return -ENOMEM;
313 313
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index fec225d1b6b7..fe67a8af520e 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -216,10 +216,8 @@ static int acpi_power_off_device(acpi_handle handle)
216{ 216{
217 int result = 0; 217 int result = 0;
218 acpi_status status = AE_OK; 218 acpi_status status = AE_OK;
219 struct acpi_device *device = NULL;
220 struct acpi_power_resource *resource = NULL; 219 struct acpi_power_resource *resource = NULL;
221 220
222
223 result = acpi_power_get_context(handle, &resource); 221 result = acpi_power_get_context(handle, &resource);
224 if (result) 222 if (result)
225 return result; 223 return result;
@@ -230,13 +228,13 @@ static int acpi_power_off_device(acpi_handle handle)
230 if (resource->references) { 228 if (resource->references) {
231 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 229 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
232 "Resource [%s] is still in use, dereferencing\n", 230 "Resource [%s] is still in use, dereferencing\n",
233 device->pnp.bus_id)); 231 resource->device->pnp.bus_id));
234 return 0; 232 return 0;
235 } 233 }
236 234
237 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { 235 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
238 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", 236 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
239 device->pnp.bus_id)); 237 resource->device->pnp.bus_id));
240 return 0; 238 return 0;
241 } 239 }
242 240
@@ -251,8 +249,7 @@ static int acpi_power_off_device(acpi_handle handle)
251 return -ENOEXEC; 249 return -ENOEXEC;
252 250
253 /* Update the power resource's _device_ power state */ 251 /* Update the power resource's _device_ power state */
254 device = resource->device; 252 resource->device->power.state = ACPI_STATE_D3;
255 device->power.state = ACPI_STATE_D3;
256 253
257 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", 254 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n",
258 resource->name)); 255 resource->name));
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index b13d64415b7a..1908e0d20222 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -519,7 +519,7 @@ static int acpi_processor_get_info(struct acpi_processor *pr)
519 519
520static void *processor_device_array[NR_CPUS]; 520static void *processor_device_array[NR_CPUS];
521 521
522static int acpi_processor_start(struct acpi_device *device) 522static int __cpuinit acpi_processor_start(struct acpi_device *device)
523{ 523{
524 int result = 0; 524 int result = 0;
525 acpi_status status = AE_OK; 525 acpi_status status = AE_OK;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 0a395fca843b..526387dc3799 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -219,6 +219,23 @@ static void acpi_safe_halt(void)
219 219
220static atomic_t c3_cpu_count; 220static atomic_t c3_cpu_count;
221 221
222/* Common C-state entry for C2, C3, .. */
223static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
224{
225 if (cstate->space_id == ACPI_CSTATE_FFH) {
226 /* Call into architectural FFH based C-state */
227 acpi_processor_ffh_cstate_enter(cstate);
228 } else {
229 int unused;
230 /* IO port based C-state */
231 inb(cstate->address);
232 /* Dummy wait op - must do something useless after P_LVL2 read
233 because chipsets cannot guarantee that STPCLK# signal
234 gets asserted in time to freeze execution properly. */
235 unused = inl(acpi_fadt.xpm_tmr_blk.address);
236 }
237}
238
222static void acpi_processor_idle(void) 239static void acpi_processor_idle(void)
223{ 240{
224 struct acpi_processor *pr = NULL; 241 struct acpi_processor *pr = NULL;
@@ -361,11 +378,7 @@ static void acpi_processor_idle(void)
361 /* Get start time (ticks) */ 378 /* Get start time (ticks) */
362 t1 = inl(acpi_fadt.xpm_tmr_blk.address); 379 t1 = inl(acpi_fadt.xpm_tmr_blk.address);
363 /* Invoke C2 */ 380 /* Invoke C2 */
364 inb(cx->address); 381 acpi_cstate_enter(cx);
365 /* Dummy wait op - must do something useless after P_LVL2 read
366 because chipsets cannot guarantee that STPCLK# signal
367 gets asserted in time to freeze execution properly. */
368 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
369 /* Get end time (ticks) */ 382 /* Get end time (ticks) */
370 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 383 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
371 384
@@ -401,9 +414,7 @@ static void acpi_processor_idle(void)
401 /* Get start time (ticks) */ 414 /* Get start time (ticks) */
402 t1 = inl(acpi_fadt.xpm_tmr_blk.address); 415 t1 = inl(acpi_fadt.xpm_tmr_blk.address);
403 /* Invoke C3 */ 416 /* Invoke C3 */
404 inb(cx->address); 417 acpi_cstate_enter(cx);
405 /* Dummy wait op (see above) */
406 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
407 /* Get end time (ticks) */ 418 /* Get end time (ticks) */
408 t2 = inl(acpi_fadt.xpm_tmr_blk.address); 419 t2 = inl(acpi_fadt.xpm_tmr_blk.address);
409 if (pr->flags.bm_check) { 420 if (pr->flags.bm_check) {
@@ -628,20 +639,16 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
628 return 0; 639 return 0;
629} 640}
630 641
631static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) 642static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
632{ 643{
633 644 if (!pr->power.states[ACPI_STATE_C1].valid) {
634 /* Zero initialize all the C-states info. */ 645 /* set the first C-State to C1 */
635 memset(pr->power.states, 0, sizeof(pr->power.states)); 646 /* all processors need to support C1 */
636 647 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
637 /* set the first C-State to C1 */ 648 pr->power.states[ACPI_STATE_C1].valid = 1;
638 pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; 649 }
639 650 /* the C0 state only exists as a filler in our array */
640 /* the C0 state only exists as a filler in our array,
641 * and all processors need to support C1 */
642 pr->power.states[ACPI_STATE_C0].valid = 1; 651 pr->power.states[ACPI_STATE_C0].valid = 1;
643 pr->power.states[ACPI_STATE_C1].valid = 1;
644
645 return 0; 652 return 0;
646} 653}
647 654
@@ -658,12 +665,7 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
658 if (nocst) 665 if (nocst)
659 return -ENODEV; 666 return -ENODEV;
660 667
661 current_count = 1; 668 current_count = 0;
662
663 /* Zero initialize C2 onwards and prepare for fresh CST lookup */
664 for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++)
665 memset(&(pr->power.states[i]), 0,
666 sizeof(struct acpi_processor_cx));
667 669
668 status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); 670 status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);
669 if (ACPI_FAILURE(status)) { 671 if (ACPI_FAILURE(status)) {
@@ -718,22 +720,39 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
718 (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) 720 (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))
719 continue; 721 continue;
720 722
721 cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ?
722 0 : reg->address;
723
724 /* There should be an easy way to extract an integer... */ 723 /* There should be an easy way to extract an integer... */
725 obj = (union acpi_object *)&(element->package.elements[1]); 724 obj = (union acpi_object *)&(element->package.elements[1]);
726 if (obj->type != ACPI_TYPE_INTEGER) 725 if (obj->type != ACPI_TYPE_INTEGER)
727 continue; 726 continue;
728 727
729 cx.type = obj->integer.value; 728 cx.type = obj->integer.value;
730 729 /*
731 if ((cx.type != ACPI_STATE_C1) && 730 * Some buggy BIOSes won't list C1 in _CST -
732 (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) 731 * Let acpi_processor_get_power_info_default() handle them later
733 continue; 732 */
734 733 if (i == 1 && cx.type != ACPI_STATE_C1)
735 if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) 734 current_count++;
736 continue; 735
736 cx.address = reg->address;
737 cx.index = current_count + 1;
738
739 cx.space_id = ACPI_CSTATE_SYSTEMIO;
740 if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
741 if (acpi_processor_ffh_cstate_probe
742 (pr->id, &cx, reg) == 0) {
743 cx.space_id = ACPI_CSTATE_FFH;
744 } else if (cx.type != ACPI_STATE_C1) {
745 /*
746 * C1 is a special case where FIXED_HARDWARE
747 * can be handled in non-MWAIT way as well.
748 * In that case, save this _CST entry info.
749 * That is, we retain space_id of SYSTEM_IO for
750 * halt based C1.
751 * Otherwise, ignore this info and continue.
752 */
753 continue;
754 }
755 }
737 756
738 obj = (union acpi_object *)&(element->package.elements[2]); 757 obj = (union acpi_object *)&(element->package.elements[2]);
739 if (obj->type != ACPI_TYPE_INTEGER) 758 if (obj->type != ACPI_TYPE_INTEGER)
@@ -938,12 +957,18 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
938 /* NOTE: the idle thread may not be running while calling 957 /* NOTE: the idle thread may not be running while calling
939 * this function */ 958 * this function */
940 959
941 /* Adding C1 state */ 960 /* Zero initialize all the C-states info. */
942 acpi_processor_get_power_info_default_c1(pr); 961 memset(pr->power.states, 0, sizeof(pr->power.states));
962
943 result = acpi_processor_get_power_info_cst(pr); 963 result = acpi_processor_get_power_info_cst(pr);
944 if (result == -ENODEV) 964 if (result == -ENODEV)
945 acpi_processor_get_power_info_fadt(pr); 965 acpi_processor_get_power_info_fadt(pr);
946 966
967 if (result)
968 return result;
969
970 acpi_processor_get_power_info_default(pr);
971
947 pr->power.count = acpi_processor_power_verify(pr); 972 pr->power.count = acpi_processor_power_verify(pr);
948 973
949 /* 974 /*
@@ -1105,7 +1130,7 @@ static struct notifier_block acpi_processor_latency_notifier = {
1105 .notifier_call = acpi_processor_latency_notify, 1130 .notifier_call = acpi_processor_latency_notify,
1106}; 1131};
1107 1132
1108int acpi_processor_power_init(struct acpi_processor *pr, 1133int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1109 struct acpi_device *device) 1134 struct acpi_device *device)
1110{ 1135{
1111 acpi_status status = 0; 1136 acpi_status status = 0;
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 62bef0b3b614..8908a975e575 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INFO_MODE;
98static int update_time = UPDATE_TIME; 98static int update_time = UPDATE_TIME;
99static int update_time2 = UPDATE_TIME2; 99static int update_time2 = UPDATE_TIME2;
100 100
101module_param(capacity_mode, int, CAPACITY_UNIT); 101module_param(capacity_mode, int, 0);
102module_param(update_mode, int, UPDATE_MODE); 102module_param(update_mode, int, 0);
103module_param(update_info_mode, int, UPDATE_INFO_MODE); 103module_param(update_info_mode, int, 0);
104module_param(update_time, int, UPDATE_TIME); 104module_param(update_time, int, 0);
105module_param(update_time2, int, UPDATE_TIME2); 105module_param(update_time2, int, 0);
106 106
107static int acpi_sbs_add(struct acpi_device *device); 107static int acpi_sbs_add(struct acpi_device *device);
108static int acpi_sbs_remove(struct acpi_device *device, int type); 108static int acpi_sbs_remove(struct acpi_device *device, int type);
@@ -1685,10 +1685,16 @@ 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 = (struct acpi_sbs *)acpi_driver_data(device); 1688 struct acpi_sbs *sbs = NULL;
1689 int id; 1689 int id;
1690 1690
1691 if (!device || !sbs) { 1691 if (!device) {
1692 return -EINVAL;
1693 }
1694
1695 sbs = (struct acpi_sbs *)acpi_driver_data(device);
1696
1697 if (!sbs) {
1692 return -EINVAL; 1698 return -EINVAL;
1693 } 1699 }
1694 1700
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 7856db759af0..11e2d4454e05 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -324,7 +324,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
324 324
325 if (header->length < sizeof(struct acpi_table_header)) { 325 if (header->length < sizeof(struct acpi_table_header)) {
326 ACPI_ERROR((AE_INFO, 326 ACPI_ERROR((AE_INFO,
327 "Table length (%X) is smaller than minimum (%X)", 327 "Table length (%X) is smaller than minimum (%zX)",
328 header->length, sizeof(struct acpi_table_header))); 328 header->length, sizeof(struct acpi_table_header)));
329 329
330 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); 330 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index 0ad3dbb9ebca..86a5fca9b739 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -187,7 +187,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
187 187
188 if (table_ptr->length < sizeof(struct acpi_table_header)) { 188 if (table_ptr->length < sizeof(struct acpi_table_header)) {
189 ACPI_ERROR((AE_INFO, 189 ACPI_ERROR((AE_INFO,
190 "RSDT/XSDT length (%X) is smaller than minimum (%X)", 190 "RSDT/XSDT length (%X) is smaller than minimum (%zX)",
191 table_ptr->length, 191 table_ptr->length,
192 sizeof(struct acpi_table_header))); 192 sizeof(struct acpi_table_header)));
193 193
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 3df0e7a07c46..fa7acc2c5c6d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -57,4 +57,23 @@ config TIFM_7XX1
57 To compile this driver as a module, choose M here: the module will 57 To compile this driver as a module, choose M here: the module will
58 be called tifm_7xx1. 58 be called tifm_7xx1.
59 59
60config MSI_LAPTOP
61 tristate "MSI Laptop Extras"
62 depends on X86
63 depends on ACPI_EC
64 depends on BACKLIGHT_CLASS_DEVICE
65 ---help---
66 This is a driver for laptops built by MSI (MICRO-STAR
67 INTERNATIONAL):
68
69 MSI MegaBook S270 (MS-1013)
70 Cytron/TCM/Medion/Tchibo MD96100/SAM2000
71
72 It adds support for Bluetooth, WLAN and LCD brightness control.
73
74 More information about this driver is available at
75 <http://0pointer.de/lennart/tchibo.html>.
76
77 If you have an MSI S270 laptop, say Y or M here.
78
60endmenu 79endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index d65ece76095a..9a91c1ee8497 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -5,6 +5,7 @@ obj- := misc.o # Dummy rule to force built-in.o to be made
5 5
6obj-$(CONFIG_IBM_ASM) += ibmasm/ 6obj-$(CONFIG_IBM_ASM) += ibmasm/
7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ 7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
8obj-$(CONFIG_LKDTM) += lkdtm.o 9obj-$(CONFIG_LKDTM) += lkdtm.o
9obj-$(CONFIG_TIFM_CORE) += tifm_core.o 10obj-$(CONFIG_TIFM_CORE) += tifm_core.o
10obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 11obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
new file mode 100644
index 000000000000..fdb7153f4426
--- /dev/null
+++ b/drivers/misc/msi-laptop.c
@@ -0,0 +1,395 @@
1/*-*-linux-c-*-*/
2
3/*
4 Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
20 */
21
22/*
23 * msi-laptop.c - MSI S270 laptop support. This laptop is sold under
24 * various brands, including "Cytron/TCM/Medion/Tchibo MD96100".
25 *
26 * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/:
27 *
28 * lcd_level - Screen brightness: contains a single integer in the
29 * range 0..8. (rw)
30 *
31 * auto_brightness - Enable automatic brightness control: contains
32 * either 0 or 1. If set to 1 the hardware adjusts the screen
33 * brightness automatically when the power cord is
34 * plugged/unplugged. (rw)
35 *
36 * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro)
37 *
38 * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1
39 * Please note that this file is constantly 0 if no Bluetooth
40 * hardware is available. (ro)
41 *
42 * In addition to these platform device attributes the driver
43 * registers itself in the Linux backlight control subsystem and is
44 * available to userspace under /sys/class/backlight/msi-laptop-bl/.
45 *
46 * This driver might work on other laptops produced by MSI. If you
47 * want to try it you can pass force=1 as argument to the module which
48 * will force it to load even when the DMI data doesn't identify the
49 * laptop as MSI S270. YMMV.
50 */
51
52#include <linux/module.h>
53#include <linux/kernel.h>
54#include <linux/init.h>
55#include <linux/acpi.h>
56#include <linux/dmi.h>
57#include <linux/backlight.h>
58#include <linux/platform_device.h>
59#include <linux/autoconf.h>
60
61#define MSI_DRIVER_VERSION "0.5"
62
63#define MSI_LCD_LEVEL_MAX 9
64
65#define MSI_EC_COMMAND_WIRELESS 0x10
66#define MSI_EC_COMMAND_LCD_LEVEL 0x11
67
68static int force;
69module_param(force, bool, 0);
70MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
71
72static int auto_brightness;
73module_param(auto_brightness, int, 0);
74MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
75
76/* Hardware access */
77
78static int set_lcd_level(int level)
79{
80 u8 buf[2];
81
82 if (level < 0 || level >= MSI_LCD_LEVEL_MAX)
83 return -EINVAL;
84
85 buf[0] = 0x80;
86 buf[1] = (u8) (level*31);
87
88 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0);
89}
90
91static int get_lcd_level(void)
92{
93 u8 wdata = 0, rdata;
94 int result;
95
96 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1);
97 if (result < 0)
98 return result;
99
100 return (int) rdata / 31;
101}
102
103static int get_auto_brightness(void)
104{
105 u8 wdata = 4, rdata;
106 int result;
107
108 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1);
109 if (result < 0)
110 return result;
111
112 return !!(rdata & 8);
113}
114
115static int set_auto_brightness(int enable)
116{
117 u8 wdata[2], rdata;
118 int result;
119
120 wdata[0] = 4;
121
122 result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1);
123 if (result < 0)
124 return result;
125
126 wdata[0] = 0x84;
127 wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0);
128
129 return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0);
130}
131
132static int get_wireless_state(int *wlan, int *bluetooth)
133{
134 u8 wdata = 0, rdata;
135 int result;
136
137 result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1);
138 if (result < 0)
139 return -1;
140
141 if (wlan)
142 *wlan = !!(rdata & 8);
143
144 if (bluetooth)
145 *bluetooth = !!(rdata & 128);
146
147 return 0;
148}
149
150/* Backlight device stuff */
151
152static int bl_get_brightness(struct backlight_device *b)
153{
154 return get_lcd_level();
155}
156
157
158static int bl_update_status(struct backlight_device *b)
159{
160 return set_lcd_level(b->props->brightness);
161}
162
163static struct backlight_properties msibl_props = {
164 .owner = THIS_MODULE,
165 .get_brightness = bl_get_brightness,
166 .update_status = bl_update_status,
167 .max_brightness = MSI_LCD_LEVEL_MAX-1,
168};
169
170static struct backlight_device *msibl_device;
171
172/* Platform device */
173
174static ssize_t show_wlan(struct device *dev,
175 struct device_attribute *attr, char *buf)
176{
177
178 int ret, enabled;
179
180 ret = get_wireless_state(&enabled, NULL);
181 if (ret < 0)
182 return ret;
183
184 return sprintf(buf, "%i\n", enabled);
185}
186
187static ssize_t show_bluetooth(struct device *dev,
188 struct device_attribute *attr, char *buf)
189{
190
191 int ret, enabled;
192
193 ret = get_wireless_state(NULL, &enabled);
194 if (ret < 0)
195 return ret;
196
197 return sprintf(buf, "%i\n", enabled);
198}
199
200static ssize_t show_lcd_level(struct device *dev,
201 struct device_attribute *attr, char *buf)
202{
203
204 int ret;
205
206 ret = get_lcd_level();
207 if (ret < 0)
208 return ret;
209
210 return sprintf(buf, "%i\n", ret);
211}
212
213static ssize_t store_lcd_level(struct device *dev,
214 struct device_attribute *attr, const char *buf, size_t count)
215{
216
217 int level, ret;
218
219 if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX))
220 return -EINVAL;
221
222 ret = set_lcd_level(level);
223 if (ret < 0)
224 return ret;
225
226 return count;
227}
228
229static ssize_t show_auto_brightness(struct device *dev,
230 struct device_attribute *attr, char *buf)
231{
232
233 int ret;
234
235 ret = get_auto_brightness();
236 if (ret < 0)
237 return ret;
238
239 return sprintf(buf, "%i\n", ret);
240}
241
242static ssize_t store_auto_brightness(struct device *dev,
243 struct device_attribute *attr, const char *buf, size_t count)
244{
245
246 int enable, ret;
247
248 if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1)))
249 return -EINVAL;
250
251 ret = set_auto_brightness(enable);
252 if (ret < 0)
253 return ret;
254
255 return count;
256}
257
258static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
259static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness);
260static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL);
261static DEVICE_ATTR(wlan, 0444, show_wlan, NULL);
262
263static struct attribute *msipf_attributes[] = {
264 &dev_attr_lcd_level.attr,
265 &dev_attr_auto_brightness.attr,
266 &dev_attr_bluetooth.attr,
267 &dev_attr_wlan.attr,
268 NULL
269};
270
271static struct attribute_group msipf_attribute_group = {
272 .attrs = msipf_attributes
273};
274
275static struct platform_driver msipf_driver = {
276 .driver = {
277 .name = "msi-laptop-pf",
278 .owner = THIS_MODULE,
279 }
280};
281
282static struct platform_device *msipf_device;
283
284/* Initialization */
285
286static struct dmi_system_id __initdata msi_dmi_table[] = {
287 {
288 .ident = "MSI S270",
289 .matches = {
290 DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"),
291 DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"),
292 }
293 },
294 {
295 .ident = "Medion MD96100",
296 .matches = {
297 DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"),
298 DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"),
299 }
300 },
301 { }
302};
303
304
305static int __init msi_init(void)
306{
307 int ret;
308
309 if (acpi_disabled)
310 return -ENODEV;
311
312 if (!force && !dmi_check_system(msi_dmi_table))
313 return -ENODEV;
314
315 if (auto_brightness < 0 || auto_brightness > 2)
316 return -EINVAL;
317
318 /* Register backlight stuff */
319
320 msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props);
321 if (IS_ERR(msibl_device))
322 return PTR_ERR(msibl_device);
323
324 ret = platform_driver_register(&msipf_driver);
325 if (ret)
326 goto fail_backlight;
327
328 /* Register platform stuff */
329
330 msipf_device = platform_device_alloc("msi-laptop-pf", -1);
331 if (!msipf_device) {
332 ret = -ENOMEM;
333 goto fail_platform_driver;
334 }
335
336 ret = platform_device_add(msipf_device);
337 if (ret)
338 goto fail_platform_device1;
339
340 ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group);
341 if (ret)
342 goto fail_platform_device2;
343
344 /* Disable automatic brightness control by default because
345 * this module was probably loaded to do brightness control in
346 * software. */
347
348 if (auto_brightness != 2)
349 set_auto_brightness(auto_brightness);
350
351 printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n");
352
353 return 0;
354
355fail_platform_device2:
356
357 platform_device_del(msipf_device);
358
359fail_platform_device1:
360
361 platform_device_put(msipf_device);
362
363fail_platform_driver:
364
365 platform_driver_unregister(&msipf_driver);
366
367fail_backlight:
368
369 backlight_device_unregister(msibl_device);
370
371 return ret;
372}
373
374static void __exit msi_cleanup(void)
375{
376
377 sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group);
378 platform_device_unregister(msipf_device);
379 platform_driver_unregister(&msipf_driver);
380 backlight_device_unregister(msibl_device);
381
382 /* Enable automatic brightness control again */
383 if (auto_brightness != 2)
384 set_auto_brightness(1);
385
386 printk(KERN_INFO "msi-laptop: driver unloaded.\n");
387}
388
389module_init(msi_init);
390module_exit(msi_cleanup);
391
392MODULE_AUTHOR("Lennart Poettering");
393MODULE_DESCRIPTION("MSI Laptop Support");
394MODULE_VERSION(MSI_DRIVER_VERSION);
395MODULE_LICENSE("GPL");
diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h
index c5472be6f3a2..e72bfdd887f9 100644
--- a/include/acpi/pdc_intel.h
+++ b/include/acpi/pdc_intel.h
@@ -13,6 +13,7 @@
13#define ACPI_PDC_SMP_C_SWCOORD (0x0040) 13#define ACPI_PDC_SMP_C_SWCOORD (0x0040)
14#define ACPI_PDC_SMP_T_SWCOORD (0x0080) 14#define ACPI_PDC_SMP_T_SWCOORD (0x0080)
15#define ACPI_PDC_C_C1_FFH (0x0100) 15#define ACPI_PDC_C_C1_FFH (0x0100)
16#define ACPI_PDC_C_C2C3_FFH (0x0200)
16 17
17#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ 18#define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \
18 ACPI_PDC_C_C1_HALT | \ 19 ACPI_PDC_C_C1_HALT | \
@@ -23,8 +24,10 @@
23 ACPI_PDC_SMP_P_SWCOORD | \ 24 ACPI_PDC_SMP_P_SWCOORD | \
24 ACPI_PDC_P_FFH) 25 ACPI_PDC_P_FFH)
25 26
26#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ 27#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \
27 ACPI_PDC_SMP_C1PT | \ 28 ACPI_PDC_SMP_C1PT | \
28 ACPI_PDC_C_C1_HALT) 29 ACPI_PDC_C_C1_HALT | \
30 ACPI_PDC_C_C1_FFH | \
31 ACPI_PDC_C_C2C3_FFH)
29 32
30#endif /* __PDC_INTEL_H__ */ 33#endif /* __PDC_INTEL_H__ */
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 9dd5b75961f8..7798d2a9f793 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -29,6 +29,9 @@
29#define DOMAIN_COORD_TYPE_SW_ANY 0xfd 29#define DOMAIN_COORD_TYPE_SW_ANY 0xfd
30#define DOMAIN_COORD_TYPE_HW_ALL 0xfe 30#define DOMAIN_COORD_TYPE_HW_ALL 0xfe
31 31
32#define ACPI_CSTATE_SYSTEMIO (0)
33#define ACPI_CSTATE_FFH (1)
34
32/* Power Management */ 35/* Power Management */
33 36
34struct acpi_processor_cx; 37struct acpi_processor_cx;
@@ -58,6 +61,8 @@ struct acpi_processor_cx {
58 u8 valid; 61 u8 valid;
59 u8 type; 62 u8 type;
60 u32 address; 63 u32 address;
64 u8 space_id;
65 u8 index;
61 u32 latency; 66 u32 latency;
62 u32 latency_ticks; 67 u32 latency_ticks;
63 u32 power; 68 u32 power;
@@ -206,6 +211,9 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr);
206#ifdef ARCH_HAS_POWER_INIT 211#ifdef ARCH_HAS_POWER_INIT
207void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, 212void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
208 unsigned int cpu); 213 unsigned int cpu);
214int acpi_processor_ffh_cstate_probe(unsigned int cpu,
215 struct acpi_processor_cx *cx, struct acpi_power_register *reg);
216void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cstate);
209#else 217#else
210static inline void acpi_processor_power_init_bm_check(struct 218static inline void acpi_processor_power_init_bm_check(struct
211 acpi_processor_flags 219 acpi_processor_flags
@@ -214,6 +222,16 @@ static inline void acpi_processor_power_init_bm_check(struct
214 flags->bm_check = 1; 222 flags->bm_check = 1;
215 return; 223 return;
216} 224}
225static inline int acpi_processor_ffh_cstate_probe(unsigned int cpu,
226 struct acpi_processor_cx *cx, struct acpi_power_register *reg)
227{
228 return -1;
229}
230static inline void acpi_processor_ffh_cstate_enter(
231 struct acpi_processor_cx *cstate)
232{
233 return;
234}
217#endif 235#endif
218 236
219/* in processor_perflib.c */ 237/* in processor_perflib.c */
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 2277127696d2..e0ddca94d50c 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -306,6 +306,8 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
306 : :"a" (eax), "c" (ecx)); 306 : :"a" (eax), "c" (ecx));
307} 307}
308 308
309extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
310
309/* from system description table in BIOS. Mostly for MCA use, but 311/* from system description table in BIOS. Mostly for MCA use, but
310others may find it useful. */ 312others may find it useful. */
311extern unsigned int machine_id; 313extern unsigned int machine_id;
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h
index de9c3147ee4c..cef17e0f828c 100644
--- a/include/asm-x86_64/processor.h
+++ b/include/asm-x86_64/processor.h
@@ -475,6 +475,8 @@ static inline void __mwait(unsigned long eax, unsigned long ecx)
475 : :"a" (eax), "c" (ecx)); 475 : :"a" (eax), "c" (ecx));
476} 476}
477 477
478extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
479
478#define stack_current() \ 480#define stack_current() \
479({ \ 481({ \
480 struct thread_info *ti; \ 482 struct thread_info *ti; \
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 88b5dfd8ee12..2b0c955590fe 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -494,6 +494,9 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
494 494
495extern int ec_read(u8 addr, u8 *val); 495extern int ec_read(u8 addr, u8 *val);
496extern int ec_write(u8 addr, u8 val); 496extern int ec_write(u8 addr, u8 val);
497extern int ec_transaction(u8 command,
498 const u8 *wdata, unsigned wdata_len,
499 u8 *rdata, unsigned rdata_len);
497 500
498#endif /*CONFIG_ACPI_EC*/ 501#endif /*CONFIG_ACPI_EC*/
499 502