GIT 650b8eee7b88d45f7933bc2aeb6234d17b16ef24 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git#test commit f31ae0e2fa45e44932a49fcc1687a648723e07cd Author: Lennart Poettering Date: Fri Oct 6 01:27:02 2006 -0400 MSI S270 Laptop support: backlight, wlan, bluetooth states Create a driver to support the platform-specific features of MSI S270 laptops (and maybe other MSI laptops). This driver implements a backlight device for controlling LCD brightness (/sys/class/backlight/msi-laptop-bl/). In addition it allows access to the WLAN and Bluetooth states through a platform driver (/sys/devices/platform/msi-laptop-pf/). Signed-off-by: Lennart Poettering Cc: Dmitry Torokhov Signed-off-by: Andrew Morton Signed-off-by: Len Brown commit 2056802f302791feb3aace64ceb9949097826468 Author: Len Brown Date: Thu Sep 14 17:16:22 2006 -0400 ACPI: update comments in motherboard.c Signed-off-by: Len Brown commit be5ba98762c1b3607d31c80fa0a223be2eaa7774 Author: Pavel Machek Date: Thu Aug 31 14:15:54 2006 +0200 ACPI_IBM: delete obsolete documentation As this module is now part of the kernel tree, there is no need for instructions on how to download it and build an external module. Signed-off-by: Pavel Machek Signed-off-by: Len Brown commit e3a5df855fb03e0fa78212183a01e43ddef43c71 Author: Randy Dunlap Date: Mon Sep 25 21:47:20 2006 -0700 ACPI: cm_sbs: use NULL instead of 0 for ptr to quiet sparse warnings Signed-off-by: Randy Dunlap Signed-off-by: Len Brown commit abff0881b847fd8c94c153a057ba101576047b3f Author: Jiri Kosina Date: Thu Aug 24 00:36:19 2006 -0400 ACPI: acpi_pci_link_set() can allocate with either GFP_ATOMIC or GFP_KERNEL acpi_pci_link_set() allocates both with interrupts on and with interrupts off (resume-time), so check interrupts and decide on GFP_ATOMIC or GFP_KERNEL at run-time. Signed-off-by: Jiri Kosina Signed-off-by: Len Brown commit de1bddaa0cfc1797a1550acad9f19e4ca681c38d Author: Dmitry Torokhov Date: Wed Aug 23 23:18:06 2006 -0400 ACPI: fix potential OOPS in power driver with CONFIG_ACPI_DEBUG device was set to null and used before set in a debug printk Signed-off-by: Dmitry Torokhov Signed-off-by: Len Brown commit faa6445caf6e9855b2f8f3aa0e510a7fb1729afe Author: Venkatesh Pallipadi Date: Mon Sep 25 16:28:13 2006 -0700 ACPI: Processor native C-states using MWAIT Intel processors starting with the Core Duo support support processor native C-state using the MWAIT instruction. Refer: Intel Architecture Software Developer's Manual http://www.intel.com/design/Pentium4/manuals/253668.htm Platform firmware exports the support for Native C-state to OS using ACPI _PDC and _CST methods. Refer: Intel Processor Vendor-Specific ACPI: Interface Specification http://www.intel.com/technology/iapc/acpi/downloads/302223.htm With Processor Native C-state, we use 'MWAIT' instruction on the processor to enter different C-states (C1, C2, C3). We won't use the special IO ports to enter C-state and no SMM mode etc required to enter C-state. Overall this will mean better C-state support. One major advantage of using MWAIT for all C-states is, with this and "treat interrupt as break event" feature of MWAIT, we can now get accurate timing for the time spent in C1, C2, .. states. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Andrew Morton Signed-off-by: Len Brown commit 47e47e559329a9e1368d6f82be7a5ab59f5098c9 Author: Stefan Schmidt Date: Fri Sep 22 12:19:16 2006 +0200 ACPI: ibm_acpi: Documentation the wan feature. Document the wan feature Jeremy Fitzhardinge added to ibm_acpi. Signed-off-by: Stefan Schmidt Acked-by: Borislav Deianov Signed-off-by: Len Brown commit 934bf877cbec07b0cdf4e2d55e95db30d6085b4a Author: Stefan Schmidt Date: Fri Sep 22 12:19:15 2006 +0200 ACPI: ibm_acpi: Update documentation for brightness and volume. Document the change of the experimental flag for brightness and volume. Signed-off-by: Stefan Schmidt Acked-by: Borislav Deianov Signed-off-by: Len Brown commit 60b6eaef6f844684d02f9075144aebae6fd34aac Author: Stefan Schmidt Date: Fri Sep 22 12:19:14 2006 +0200 ACPI: ibm_acpi: Remove experimental status for brightness and volume. The brightness and volume features from ibm-acpi are stable. The experimental flag is no longer needed. Signed-off-by: Stefan Schmidt Acked-by: Borislav Deianov Signed-off-by: Len Brown commit 47dc67b08365b2d196de469e55b7f6404b5ac6b6 Author: Lennart Poettering Date: Tue Oct 3 22:49:00 2006 -0400 ACPI: EC: export ec_transaction() for msi-laptop driver Signed-off-by: Lennart Poettering Signed-off-by: Len Brown commit a3028e346016244d92f948347bad9619ca180f9c Author: Denis M. Sadykov Date: Tue Sep 26 19:50:33 2006 +0400 ACPI: EC: Simplify acpi_hw_low_level*() with inb()/outb(). Simplify acpi_hw_low_level_xxx() functions to inb() and outb(). Signed-off-by: Alexey Y. Starikovskiy Signed-off-by: Len Brown commit 73fa7bc258820284ea720fd9404e977f3e3fc7c0 Author: Denis M. Sadykov Date: Tue Sep 26 19:50:33 2006 +0400 ACPI: EC: Unify poll and interrupt gpe handlers Signed-off-by: Alexey Y. Starikovskiy Signed-off-by: Len Brown commit 9a95d211dd6000ce72f06722a5e92979281f8c09 Author: Denis M. Sadykov Date: Tue Sep 26 19:50:33 2006 +0400 ACPI: EC: Unify poll and interrupt mode transaction functions Signed-off-by: Alexey Y. Starikovskiy Signed-off-by: Len Brown commit cd41b44317f4c3647bcf1f48fba16b60c643d7d5 Author: Denis M. Sadykov Date: Tue Sep 26 19:50:33 2006 +0400 ACPI: EC: Remove unused variables and duplicated code Signed-off-by: Alexey Y. Starikovskiy Signed-off-by: Len Brown commit a5a1e1cebf7200a56f6c06f7660e219ad95cb69b Author: Denis M. Sadykov Date: Tue Sep 26 19:50:33 2006 +0400 ACPI: EC: Remove unnecessary delay added by previous transation patch. Remove unnecessary delay (50 ms) while reading data from EC in interrupt mode. Signed-off-by: Alexey Y. Starikovskiy Signed-off-by: Len Brown commit 8a9119dfeea2b93a9de4579aa05d53a5875eb38a Author: Lennart Poettering Date: Tue Sep 5 12:12:24 2006 -0400 ACPI: consolidate functions in acpi ec driver Unify the following functions: acpi_ec_poll_read() acpi_ec_poll_write() acpi_ec_poll_query() acpi_ec_intr_read() acpi_ec_intr_write() acpi_ec_intr_query() into: acpi_ec_poll_transaction() acpi_ec_intr_transaction() These new functions take as arguments an ACPI EC command, a few bytes to write to the EC data register and a buffer for a few bytes to read from the EC data register. The old _read(), _write(), _query() are just special cases of these functions. Then unified the code in acpi_ec_poll_transaction() and acpi_ec_intr_transaction() a little more. Both functions are now just wrappers around the new acpi_ec_transaction_unlocked() function. The latter contains the EC access logic, the two original function now just do their special way of locking and call the the new function for the actual work. This saves a lot of very similar code. The primary reason for doing this, however, is that my driver for MSI 270 laptops needs to issue some non-standard EC commands in a safe way. Due to this I added a new exported function similar to ec_write()/ec_write() which is called ec_transaction() and is essentially just a wrapper around acpi_ec_{poll,intr}_transaction(). Signed-off-by: Lennart Poettering Acked-by: Luming Yu Signed-off-by: Andrew Morton Signed-off-by: Len Brown commit 2237984b72e76edcdc84867555fa7230dfe037fb Author: Alexey Y. Starikovskiy Date: Tue Sep 26 04:20:47 2006 -0400 ACPI: created a dedicated workqueue for notify() execution http://bugzilla.kernel.org/show_bug.cgi?id=5534#c160 Signed-off-by: Len Brown commit ab4b96b45cd0c01f2efc0ca25af9fa550d8ec71b Author: Alexey Y. Starikovskiy Date: Tue Sep 26 04:18:16 2006 -0400 ACPI: Remove deferred execution from global lock acquire wakeup path On acquiring the ACPI global lock, if there were sleepers on the lock, we used to use acpi_os_execute() to defer a thread which would signal sleepers. Now just signal the semaphore directly. http://bugzilla.kernel.org/show_bug.cgi?id=5534#c159 Signed-off-by: Len Brown commit 2e61baa6a69b05585a16a6824b76da3a22f42705 Author: Lebedev, Vladimir P Date: Tue Sep 5 19:59:22 2006 +0400 ACPI: sbs: fix module_param() initializers Signed-off-by: Len Brown commit 0501496ac5d29d42807df77fc91a0d48038af848 Author: Lebedev, Vladimir P Date: Tue Sep 5 19:49:13 2006 +0400 ACPI: sbs: check for NULL device pointer Signed-off-by: Len Brown commit 8583aced384dc617e169ce4933b9cccdce9198ac Author: Marek W Date: Mon Aug 14 22:37:20 2006 -0700 ACPI: asus_acpi: W3000 support Add support for W3000 (W3V) and indirectly fixes an issue with kmilo under KDE (it was triggering excessive LCD read error messages by querying asus_acpi module) allowing people (I am probably the only one who tested this) with W3000 to run kmilo. Cc: Karol Kozimor Signed-off-by: Andrew Morton Signed-off-by: Len Brown commit c090af8fdd6e42a3b4c70ff804980d8a7bc117c9 Author: Jan Engelhardt Date: Sun Oct 1 00:28:50 2006 +0200 ACPI: Remove unnecessary from/to-void* and to-void casts in drivers/acpi Signed-off-by: Jan Engelhardt Signed-off-by: Len Brown Documentation/ibm-acpi.txt | 75 +- MAINTAINERS | 7 arch/i386/kernel/acpi/cstate.c | 122 ++++ arch/i386/kernel/process.c | 22 - arch/x86_64/kernel/process.c | 22 - drivers/acpi/ac.c | 6 drivers/acpi/acpi_memhotplug.c | 2 drivers/acpi/asus_acpi.c | 24 + drivers/acpi/battery.c | 22 - drivers/acpi/button.c | 8 drivers/acpi/cm_sbs.c | 4 drivers/acpi/container.c | 2 drivers/acpi/dock.c | 6 drivers/acpi/ec.c | 1096 +++++++++-------------------------- drivers/acpi/events/evmisc.c | 14 drivers/acpi/fan.c | 6 drivers/acpi/glue.c | 4 drivers/acpi/hotkey.c | 5 drivers/acpi/i2c_ec.c | 2 drivers/acpi/ibm_acpi.c | 8 drivers/acpi/motherboard.c | 6 drivers/acpi/numa.c | 2 drivers/acpi/osl.c | 35 - drivers/acpi/pci_bind.c | 4 drivers/acpi/pci_irq.c | 2 drivers/acpi/pci_link.c | 10 drivers/acpi/pci_root.c | 4 drivers/acpi/power.c | 15 drivers/acpi/processor_core.c | 10 drivers/acpi/processor_idle.c | 115 ++-- drivers/acpi/processor_perflib.c | 10 drivers/acpi/processor_thermal.c | 6 drivers/acpi/processor_throttling.c | 6 drivers/acpi/sbs.c | 20 - drivers/acpi/tables.c | 2 drivers/acpi/thermal.c | 30 - drivers/acpi/utils.c | 4 drivers/acpi/video.c | 59 +- drivers/misc/Kconfig | 19 + drivers/misc/Makefile | 1 drivers/misc/msi-laptop.c | 395 +++++++++++++ include/acpi/pdc_intel.h | 9 include/acpi/processor.h | 18 + include/asm-i386/processor.h | 2 include/asm-x86_64/processor.h | 2 include/linux/acpi.h | 3 46 files changed, 1159 insertions(+), 1087 deletions(-) diff --git a/Documentation/ibm-acpi.txt b/Documentation/ibm-acpi.txt index 71aa403..e50595b 100644 --- a/Documentation/ibm-acpi.txt +++ b/Documentation/ibm-acpi.txt @@ -30,9 +30,10 @@ detailed description): - ACPI sounds - temperature sensors - Experimental: embedded controller register dump - - Experimental: LCD brightness control - - Experimental: volume control + - LCD brightness control + - Volume control - Experimental: fan speed, fan enable/disable + - Experimental: WAN enable and disable A compatibility table by model and feature is maintained on the web site, http://ibm-acpi.sf.net/. I appreciate any success or failure @@ -52,40 +53,7 @@ Installation If you are compiling this driver as included in the Linux kernel sources, simply enable the CONFIG_ACPI_IBM option (Power Management / -ACPI / IBM ThinkPad Laptop Extras). The rest of this section describes -how to install this driver when downloaded from the web site. - -First, you need to get a kernel with ACPI support up and running. -Please refer to http://acpi.sourceforge.net/ for help with this -step. How successful you will be depends a lot on you ThinkPad model, -the kernel you are using and any additional patches applied. The -kernel provided with your distribution may not be good enough. I -needed to compile a 2.6.7 kernel with the 20040715 ACPI patch to get -ACPI working reliably on my ThinkPad X40. Old ThinkPad models may not -be supported at all. - -Assuming you have the basic ACPI support working (e.g. you can see the -/proc/acpi directory), follow the following steps to install this -driver: - - - unpack the archive: - - tar xzvf ibm-acpi-x.y.tar.gz; cd ibm-acpi-x.y - - - compile the driver: - - make - - - install the module in your kernel modules directory: - - make install - - - load the module: - - modprobe ibm_acpi - -After loading the module, check the "dmesg" output for any error messages. - +ACPI / IBM ThinkPad Laptop Extras). Features -------- @@ -523,13 +491,8 @@ registers contain the current battery ca with this, do send me your results (including some complete dumps with a description of the conditions when they were taken.) -EXPERIMENTAL: LCD brightness control -- /proc/acpi/ibm/brightness ------------------------------------------------------------------ - -This feature is marked EXPERIMENTAL because the implementation -directly accesses hardware registers and may not work as expected. USE -WITH CAUTION! To use this feature, you need to supply the -experimental=1 parameter when loading the module. +LCD brightness control -- /proc/acpi/ibm/brightness +--------------------------------------------------- This feature allows software control of the LCD brightness on ThinkPad models which don't have a hardware brightness slider. The available @@ -542,13 +505,8 @@ commands are: The number range is 0 to 7, although not all of them may be distinct. The current brightness level is shown in the file. -EXPERIMENTAL: Volume control -- /proc/acpi/ibm/volume ------------------------------------------------------ - -This feature is marked EXPERIMENTAL because the implementation -directly accesses hardware registers and may not work as expected. USE -WITH CAUTION! To use this feature, you need to supply the -experimental=1 parameter when loading the module. +Volume control -- /proc/acpi/ibm/volume +--------------------------------------- This feature allows volume control on ThinkPad models which don't have a hardware volume knob. The available commands are: @@ -611,6 +569,23 @@ with the following command: echo 'level ' > /proc/acpi/ibm/thermal +EXPERIMENTAL: WAN -- /proc/acpi/ibm/wan +--------------------------------------- + +This feature is marked EXPERIMENTAL because the implementation +directly accesses hardware registers and may not work as expected. USE +WITH CAUTION! To use this feature, you need to supply the +experimental=1 parameter when loading the module. + +This feature shows the presence and current state of a WAN (Sierra +Wireless EV-DO) device. If WAN is installed, the following commands can +be used: + + echo enable > /proc/acpi/ibm/wan + echo disable > /proc/acpi/ibm/wan + +It was tested on a Lenovo Thinkpad X60. It should probably work on other +Thinkpad models which come with this module installed. Multiple Commands, Module Parameters ------------------------------------ diff --git a/MAINTAINERS b/MAINTAINERS index 50fb3ae..5862beb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1996,6 +1996,13 @@ M: rubini@ipvvis.unipv.it L: linux-kernel@vger.kernel.org S: Maintained +MSI LAPTOP SUPPORT +P: Lennart Poettering +M: mzxreary@0pointer.de +L: https://tango.0pointer.de/mailman/listinfo/s270-linux +W: http://0pointer.de/lennart/tchibo.html +S: Maintained + MTRR AND SIMILAR SUPPORT [i386] P: Richard Gooch M: rgooch@atnf.csiro.au diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c index 25db49e..20563e5 100644 --- a/arch/i386/kernel/acpi/cstate.c +++ b/arch/i386/kernel/acpi/cstate.c @@ -10,6 +10,7 @@ #include #include #include #include +#include #include #include @@ -41,5 +42,124 @@ void acpi_processor_power_init_bm_check( flags->bm_check = 1; } } - EXPORT_SYMBOL(acpi_processor_power_init_bm_check); + +/* The code below handles cstate entry with monitor-mwait pair on Intel*/ + +struct cstate_entry_s { + struct { + unsigned int eax; + unsigned int ecx; + } states[ACPI_PROCESSOR_MAX_POWER]; +}; +static struct cstate_entry_s *cpu_cstate_entry; /* per CPU ptr */ + +static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; + +#define MWAIT_SUBSTATE_MASK (0xf) +#define MWAIT_SUBSTATE_SIZE (4) + +#define CPUID_MWAIT_LEAF (5) +#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1) +#define CPUID5_ECX_INTERRUPT_BREAK (0x2) + +#define MWAIT_ECX_INTERRUPT_BREAK (0x1) + +#define NATIVE_CSTATE_BEYOND_HALT (2) + +int acpi_processor_ffh_cstate_probe(unsigned int cpu, + struct acpi_processor_cx *cx, struct acpi_power_register *reg) +{ + struct cstate_entry_s *percpu_entry; + struct cpuinfo_x86 *c = cpu_data + cpu; + + cpumask_t saved_mask; + int retval; + unsigned int eax, ebx, ecx, edx; + unsigned int edx_part; + unsigned int cstate_type; /* C-state type and not ACPI C-state type */ + unsigned int num_cstate_subtype; + + if (!cpu_cstate_entry || c->cpuid_level < CPUID_MWAIT_LEAF ) + return -1; + + if (reg->bit_offset != NATIVE_CSTATE_BEYOND_HALT) + return -1; + + percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); + percpu_entry->states[cx->index].eax = 0; + percpu_entry->states[cx->index].ecx = 0; + + /* Make sure we are running on right CPU */ + saved_mask = current->cpus_allowed; + retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (retval) + return -1; + + cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); + + /* Check whether this particular cx_type (in CST) is supported or not */ + cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1; + edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE); + num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK; + + retval = 0; + if (num_cstate_subtype < (cx->address & MWAIT_SUBSTATE_MASK)) { + retval = -1; + goto out; + } + + /* mwait ecx extensions INTERRUPT_BREAK should be supported for C2/C3 */ + if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) || + !(ecx & CPUID5_ECX_INTERRUPT_BREAK)) { + retval = -1; + goto out; + } + percpu_entry->states[cx->index].ecx = MWAIT_ECX_INTERRUPT_BREAK; + + /* Use the hint in CST */ + percpu_entry->states[cx->index].eax = cx->address; + + if (!mwait_supported[cstate_type]) { + mwait_supported[cstate_type] = 1; + printk(KERN_DEBUG "Monitor-Mwait will be used to enter C-%d " + "state\n", cx->type); + } + +out: + set_cpus_allowed(current, saved_mask); + return retval; +} +EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); + +void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) +{ + unsigned int cpu = smp_processor_id(); + struct cstate_entry_s *percpu_entry; + + percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu); + mwait_idle_with_hints(percpu_entry->states[cx->index].eax, + percpu_entry->states[cx->index].ecx); +} +EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_enter); + +static int __init ffh_cstate_init(void) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + if (c->x86_vendor != X86_VENDOR_INTEL) + return -1; + + cpu_cstate_entry = alloc_percpu(struct cstate_entry_s); + return 0; +} + +static void __exit ffh_cstate_exit(void) +{ + if (cpu_cstate_entry) { + free_percpu(cpu_cstate_entry); + cpu_cstate_entry = NULL; + } +} + +arch_initcall(ffh_cstate_init); +__exitcall(ffh_cstate_exit); diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index b0a0780..57d3759 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -236,20 +236,28 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); * We execute MONITOR against need_resched and enter optimized wait state * through MWAIT. Whenever someone changes need_resched, we would be woken * up from MWAIT (without an IPI). + * + * New with Core Duo processors, MWAIT can take some hints based on CPU + * capability. */ -static void mwait_idle(void) +void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) { - local_irq_enable(); - - while (!need_resched()) { + if (!need_resched()) { __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); - if (need_resched()) - break; - __mwait(0, 0); + if (!need_resched()) + __mwait(eax, ecx); } } +/* Default MONITOR/MWAIT with no hints, used for default C1 state */ +static void mwait_idle(void) +{ + local_irq_enable(); + while (!need_resched()) + mwait_idle_with_hints(0, 0); +} + void __devinit select_idle_routine(const struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_MWAIT)) { diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 5e95b25..49f7fac 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -238,20 +238,28 @@ void cpu_idle (void) * We execute MONITOR against need_resched and enter optimized wait state * through MWAIT. Whenever someone changes need_resched, we would be woken * up from MWAIT (without an IPI). + * + * New with Core Duo processors, MWAIT can take some hints based on CPU + * capability. */ -static void mwait_idle(void) +void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) { - local_irq_enable(); - - while (!need_resched()) { + if (!need_resched()) { __monitor((void *)¤t_thread_info()->flags, 0, 0); smp_mb(); - if (need_resched()) - break; - __mwait(0, 0); + if (!need_resched()) + __mwait(eax, ecx); } } +/* Default MONITOR/MWAIT with no hints, used for default C1 state */ +static void mwait_idle(void) +{ + local_irq_enable(); + while (!need_resched()) + mwait_idle_with_hints(0,0); +} + void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { static int printed; diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 11abc7b..46e5866 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -109,7 +109,7 @@ static struct proc_dir_entry *acpi_ac_di static int acpi_ac_seq_show(struct seq_file *seq, void *offset) { - struct acpi_ac *ac = (struct acpi_ac *)seq->private; + struct acpi_ac *ac = seq->private; if (!ac) @@ -187,7 +187,7 @@ static int acpi_ac_remove_fs(struct acpi static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_ac *ac = (struct acpi_ac *)data; + struct acpi_ac *ac = data; struct acpi_device *device = NULL; @@ -269,7 +269,7 @@ static int acpi_ac_remove(struct acpi_de if (!device || !acpi_driver_data(device)) return -EINVAL; - ac = (struct acpi_ac *)acpi_driver_data(device); + ac = acpi_driver_data(device); status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_ac_notify); diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 98099de..1368783 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -427,7 +427,7 @@ static int acpi_memory_device_remove(str if (!device || !acpi_driver_data(device)) return -EINVAL; - mem_device = (struct acpi_memory_device *)acpi_driver_data(device); + mem_device = acpi_driver_data(device); kfree(mem_device); return 0; diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index e9ee4c5..6c7ecb1 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -138,6 +138,7 @@ struct asus_hotk { S2x, //S200 (J1 reported), Victor MP-XP7210 W1N, //W1000N W5A, //W5A + W3V, //W3030V xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N //(Centrino) END_MODEL @@ -376,6 +377,17 @@ static struct model_data model_conf[END_ .display_get = "\\ADVG"}, { + .name = "W3V", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_lcd_switch = xxN_PREFIX "_Q10", + .lcd_status = "\\BKLT", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\INFB"}, + + { .name = "xxN", .mt_mled = "MLED", /* WLED present, but not controlled by ACPI */ @@ -1097,6 +1109,8 @@ static int asus_model_match(char *model) return A4G; else if (strncmp(model, "W1N", 3) == 0) return W1N; + else if (strncmp(model, "W3V", 3) == 0) + return W3V; else if (strncmp(model, "W5A", 3) == 0) return W5A; else @@ -1128,7 +1142,7 @@ static int asus_hotk_get_info(void) if (ACPI_FAILURE(status)) printk(KERN_WARNING " Couldn't get the DSDT table header\n"); else - asus_info = (struct acpi_table_header *)dsdt.pointer; + asus_info = dsdt.pointer; /* We have to write 0 on init this far for all ASUS models */ if (!write_acpi_int(hotk->handle, "INIT", 0, &buffer)) { @@ -1150,7 +1164,7 @@ static int asus_hotk_get_info(void) * asus_model_match() and try something completely different. */ if (buffer.pointer) { - model = (union acpi_object *)buffer.pointer; + model = buffer.pointer; switch (model->type) { case ACPI_TYPE_STRING: string = model->string.pointer; @@ -1200,9 +1214,10 @@ static int asus_hotk_get_info(void) hotk->methods->mt_wled = NULL; /* L5D's WLED is not controlled by ACPI */ else if (strncmp(string, "M2N", 3) == 0 || + strncmp(string, "W3V", 3) == 0 || strncmp(string, "S1N", 3) == 0) hotk->methods->mt_wled = "WLED"; - /* M2N and S1N have a usable WLED */ + /* M2N, S1N and W3V have a usable WLED */ else if (asus_info) { if (strncmp(asus_info->oem_table_id, "L1", 2) == 0) hotk->methods->mled_status = NULL; @@ -1245,8 +1260,7 @@ static int asus_hotk_add(struct acpi_dev printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n", ASUS_ACPI_VERSION); - hotk = - (struct asus_hotk *)kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); + hotk = kmalloc(sizeof(struct asus_hotk), GFP_KERNEL); if (!hotk) return -ENOMEM; memset(hotk, 0, sizeof(struct asus_hotk)); diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9810e2a..adb0d27 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -147,7 +147,7 @@ acpi_battery_get_info(struct acpi_batter return -ENODEV; } - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; /* Extract Package Data */ @@ -177,7 +177,7 @@ acpi_battery_get_info(struct acpi_batter kfree(buffer.pointer); if (!result) - (*bif) = (struct acpi_battery_info *)data.pointer; + (*bif) = data.pointer; return result; } @@ -207,7 +207,7 @@ acpi_battery_get_status(struct acpi_batt return -ENODEV; } - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; /* Extract Package Data */ @@ -237,7 +237,7 @@ acpi_battery_get_status(struct acpi_batt kfree(buffer.pointer); if (!result) - (*bst) = (struct acpi_battery_status *)data.pointer; + (*bst) = data.pointer; return result; } @@ -332,7 +332,7 @@ static struct proc_dir_entry *acpi_batte static int acpi_battery_read_info(struct seq_file *seq, void *offset) { int result = 0; - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; struct acpi_battery_info *bif = NULL; char *units = "?"; @@ -416,7 +416,7 @@ static int acpi_battery_info_open_fs(str static int acpi_battery_read_state(struct seq_file *seq, void *offset) { int result = 0; - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; struct acpi_battery_status *bst = NULL; char *units = "?"; @@ -492,7 +492,7 @@ static int acpi_battery_state_open_fs(st static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) { - struct acpi_battery *battery = (struct acpi_battery *)seq->private; + struct acpi_battery *battery = seq->private; char *units = "?"; @@ -529,8 +529,8 @@ acpi_battery_write_alarm(struct file *fi { int result = 0; char alarm_string[12] = { '\0' }; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_battery *battery = (struct acpi_battery *)m->private; + struct seq_file *m = file->private_data; + struct acpi_battery *battery = m->private; if (!battery || (count > sizeof(alarm_string) - 1)) @@ -656,7 +656,7 @@ static int acpi_battery_remove_fs(struct static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_battery *battery = (struct acpi_battery *)data; + struct acpi_battery *battery = data; struct acpi_device *device = NULL; @@ -740,7 +740,7 @@ static int acpi_battery_remove(struct ac if (!device || !acpi_driver_data(device)) return -EINVAL; - battery = (struct acpi_battery *)acpi_driver_data(device); + battery = acpi_driver_data(device); status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 5ef885e..fe914eb 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -109,7 +109,7 @@ static struct proc_dir_entry *acpi_butto static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_button *button = (struct acpi_button *)seq->private; + struct acpi_button *button = seq->private; if (!button || !button->device) @@ -128,7 +128,7 @@ static int acpi_button_info_open_fs(stru static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) { - struct acpi_button *button = (struct acpi_button *)seq->private; + struct acpi_button *button = seq->private; acpi_status status; unsigned long state; @@ -253,7 +253,7 @@ static int acpi_button_remove_fs(struct static void acpi_button_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_button *button = (struct acpi_button *)data; + struct acpi_button *button = data; if (!button || !button->device) @@ -275,7 +275,7 @@ static void acpi_button_notify(acpi_hand static acpi_status acpi_button_notify_fixed(void *data) { - struct acpi_button *button = (struct acpi_button *)data; + struct acpi_button *button = data; if (!button) diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index a01ce67..4a9b7bf 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -67,7 +67,7 @@ void acpi_unlock_ac_dir(struct proc_dir_ lock_ac_dir_cnt--; if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); - acpi_ac_dir = 0; + acpi_ac_dir = NULL; } mutex_unlock(&cm_sbs_mutex); } @@ -99,7 +99,7 @@ void acpi_unlock_battery_dir(struct proc if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param && acpi_battery_dir) { remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); - acpi_battery_dir = 0; + acpi_battery_dir = NULL; } mutex_unlock(&cm_sbs_mutex); return; diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 871aa52..a153817 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -117,7 +117,7 @@ static int acpi_container_remove(struct acpi_status status = AE_OK; struct acpi_container *pc = NULL; - pc = (struct acpi_container *)acpi_driver_data(device); + pc = acpi_driver_data(device); kfree(pc); return status; } diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 578b99b..3c3dee8 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -524,7 +524,7 @@ EXPORT_SYMBOL_GPL(unregister_hotplug_doc */ static void dock_notify(acpi_handle handle, u32 event, void *data) { - struct dock_station *ds = (struct dock_station *)data; + struct dock_station *ds = data; switch (event) { case ACPI_NOTIFY_BUS_CHECK: @@ -587,7 +587,7 @@ find_dock_devices(acpi_handle handle, u3 { acpi_status status; acpi_handle tmp; - struct dock_station *ds = (struct dock_station *)context; + struct dock_station *ds = context; struct dock_dependent_device *dd; status = acpi_bus_get_ejd(handle, &tmp); @@ -702,7 +702,7 @@ static int dock_remove(void) static acpi_status find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) { - int *count = (int *)context; + int *count = context; acpi_status status = AE_OK; if (is_dock(handle)) { diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e5d7963..e6d4b08 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -45,206 +45,143 @@ #define ACPI_EC_HID "PNP0C09" #define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" + +/* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ #define ACPI_EC_FLAG_BURST 0x10 /* burst mode */ #define ACPI_EC_FLAG_SCI 0x20 /* EC-SCI occurred */ -#define ACPI_EC_EVENT_OBF 0x01 /* Output buffer full */ -#define ACPI_EC_EVENT_IBE 0x02 /* Input buffer empty */ -#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ -#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ -#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ -#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ + +/* EC commands */ #define ACPI_EC_COMMAND_READ 0x80 #define ACPI_EC_COMMAND_WRITE 0x81 #define ACPI_EC_BURST_ENABLE 0x82 #define ACPI_EC_BURST_DISABLE 0x83 #define ACPI_EC_COMMAND_QUERY 0x84 -#define EC_POLL 0xFF -#define EC_INTR 0x00 + +/* EC events */ +enum { + ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ + ACPI_EC_EVENT_IBF_0, /* Input buffer empty */ +}; + +#define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ +#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ +#define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ +#define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ + +enum { + EC_INTR = 1, /* Output buffer full */ + EC_POLL, /* Input buffer empty */ +}; + static int acpi_ec_remove(struct acpi_device *device, int type); static int acpi_ec_start(struct acpi_device *device); static int acpi_ec_stop(struct acpi_device *device, int type); -static int acpi_ec_intr_add(struct acpi_device *device); -static int acpi_ec_poll_add(struct acpi_device *device); +static int acpi_ec_add(struct acpi_device *device); static struct acpi_driver acpi_ec_driver = { .name = ACPI_EC_DRIVER_NAME, .class = ACPI_EC_CLASS, .ids = ACPI_EC_HID, .ops = { - .add = acpi_ec_intr_add, + .add = acpi_ec_add, .remove = acpi_ec_remove, .start = acpi_ec_start, .stop = acpi_ec_stop, }, }; -union acpi_ec { - struct { - u32 mode; - acpi_handle handle; - unsigned long uid; - unsigned long gpe_bit; - struct acpi_generic_address status_addr; - struct acpi_generic_address command_addr; - struct acpi_generic_address data_addr; - unsigned long global_lock; - } common; - - struct { - u32 mode; - acpi_handle handle; - unsigned long uid; - unsigned long gpe_bit; - struct acpi_generic_address status_addr; - struct acpi_generic_address command_addr; - struct acpi_generic_address data_addr; - unsigned long global_lock; - unsigned int expect_event; - atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ - atomic_t pending_gpe; - struct semaphore sem; - wait_queue_head_t wait; - } intr; - - struct { - u32 mode; - acpi_handle handle; - unsigned long uid; - unsigned long gpe_bit; - struct acpi_generic_address status_addr; - struct acpi_generic_address command_addr; - struct acpi_generic_address data_addr; - unsigned long global_lock; - struct semaphore sem; - } poll; -}; -static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event); -static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event); -static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data); -static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data); -static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data); -static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data); -static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data); -static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data); -static void acpi_ec_gpe_poll_query(void *ec_cxt); -static void acpi_ec_gpe_intr_query(void *ec_cxt); -static u32 acpi_ec_gpe_poll_handler(void *data); -static u32 acpi_ec_gpe_intr_handler(void *data); -static acpi_status __init -acpi_fake_ecdt_poll_callback(acpi_handle handle, - u32 Level, void *context, void **retval); - -static acpi_status __init -acpi_fake_ecdt_intr_callback(acpi_handle handle, - u32 Level, void *context, void **retval); - -static int __init acpi_ec_poll_get_real_ecdt(void); -static int __init acpi_ec_intr_get_real_ecdt(void); /* If we find an EC via the ECDT, we need to keep a ptr to its context */ -static union acpi_ec *ec_ecdt; +struct acpi_ec { + acpi_handle handle; + unsigned long uid; + unsigned long gpe_bit; + unsigned long command_addr; + unsigned long data_addr; + unsigned long global_lock; + struct semaphore sem; + unsigned int expect_event; + atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort */ + wait_queue_head_t wait; +} *ec_ecdt; /* External interfaces use first EC only, so remember */ static struct acpi_device *first_ec; -static int acpi_ec_poll_mode = EC_INTR; +static int acpi_ec_mode = EC_INTR; /* -------------------------------------------------------------------------- Transaction Management -------------------------------------------------------------------------- */ -static u32 acpi_ec_read_status(union acpi_ec *ec) +static inline u8 acpi_ec_read_status(struct acpi_ec *ec) { - u32 status = 0; - - acpi_hw_low_level_read(8, &status, &ec->common.status_addr); - return status; + return inb(ec->command_addr); } -static int acpi_ec_wait(union acpi_ec *ec, u8 event) +static inline u8 acpi_ec_read_data(struct acpi_ec *ec) { - if (acpi_ec_poll_mode) - return acpi_ec_poll_wait(ec, event); - else - return acpi_ec_intr_wait(ec, event); + return inb(ec->data_addr); } -static int acpi_ec_poll_wait(union acpi_ec *ec, u8 event) +static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) { - u32 acpi_ec_status = 0; - u32 i = ACPI_EC_UDELAY_COUNT; + outb(command, ec->command_addr); +} - if (!ec) - return -EINVAL; +static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) +{ + outb(data, ec->data_addr); +} - /* Poll the EC status register waiting for the event to occur. */ +static int acpi_ec_check_status(u8 status, u8 event) +{ switch (event) { - case ACPI_EC_EVENT_OBF: - do { - acpi_hw_low_level_read(8, &acpi_ec_status, - &ec->common.status_addr); - if (acpi_ec_status & ACPI_EC_FLAG_OBF) - return 0; - udelay(ACPI_EC_UDELAY); - } while (--i > 0); + case ACPI_EC_EVENT_OBF_1: + if (status & ACPI_EC_FLAG_OBF) + return 1; break; - case ACPI_EC_EVENT_IBE: - do { - acpi_hw_low_level_read(8, &acpi_ec_status, - &ec->common.status_addr); - if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) - return 0; - udelay(ACPI_EC_UDELAY); - } while (--i > 0); + case ACPI_EC_EVENT_IBF_0: + if (!(status & ACPI_EC_FLAG_IBF)) + return 1; break; default: - return -EINVAL; + break; } - return -ETIME; + return 0; } -static int acpi_ec_intr_wait(union acpi_ec *ec, unsigned int event) -{ - int result = 0; - - ec->intr.expect_event = event; - smp_mb(); +static int acpi_ec_wait(struct acpi_ec *ec, u8 event) +{ + int i = (acpi_ec_mode == EC_POLL) ? ACPI_EC_UDELAY_COUNT : 0; + long time_left; - switch (event) { - case ACPI_EC_EVENT_IBE: - if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) { - ec->intr.expect_event = 0; - return 0; - } - break; - default: - break; + ec->expect_event = event; + if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { + ec->expect_event = 0; + return 0; } - result = wait_event_timeout(ec->intr.wait, - !ec->intr.expect_event, + do { + if (acpi_ec_mode == EC_POLL) { + udelay(ACPI_EC_UDELAY); + } else { + time_left = wait_event_timeout(ec->wait, + !ec->expect_event, msecs_to_jiffies(ACPI_EC_DELAY)); - - ec->intr.expect_event = 0; - smp_mb(); - - /* - * Verify that the event in question has actually happened by - * querying EC status. Do the check even if operation timed-out - * to make sure that we did not miss interrupt. - */ - switch (event) { - case ACPI_EC_EVENT_OBF: - if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF) + if (time_left > 0) { + ec->expect_event = 0; + return 0; + } + } + if (acpi_ec_check_status(acpi_ec_read_status(ec), event)) { + ec->expect_event = 0; return 0; - break; + } + } while (--i > 0); - case ACPI_EC_EVENT_IBE: - if (~acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) - return 0; - break; - } + ec->expect_event = 0; return -ETIME; } @@ -254,272 +191,150 @@ #ifdef ACPI_FUTURE_USAGE * Note: samsung nv5000 doesn't work with ec burst mode. * http://bugzilla.kernel.org/show_bug.cgi?id=4980 */ -int acpi_ec_enter_burst_mode(union acpi_ec *ec) +int acpi_ec_enter_burst_mode(struct acpi_ec *ec) { - u32 tmp = 0; - int status = 0; + u8 tmp = 0; + u8 status = 0; status = acpi_ec_read_status(ec); if (status != -EINVAL && !(status & ACPI_EC_FLAG_BURST)) { - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (status) goto end; - acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, - &ec->common.command_addr); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); + acpi_ec_write_cmd(ec, ACPI_EC_BURST_ENABLE); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); + tmp = acpi_ec_read_data(ec); if (tmp != 0x90) { /* Burst ACK byte */ return -EINVAL; } } - atomic_set(&ec->intr.leaving_burst, 0); + atomic_set(&ec->leaving_burst, 0); return 0; - end: - ACPI_EXCEPTION ((AE_INFO, status, "EC wait, burst mode"); + end: + ACPI_EXCEPTION((AE_INFO, status, "EC wait, burst mode")); return -1; } -int acpi_ec_leave_burst_mode(union acpi_ec *ec) +int acpi_ec_leave_burst_mode(struct acpi_ec *ec) { - int status = 0; + u8 status = 0; status = acpi_ec_read_status(ec); if (status != -EINVAL && (status & ACPI_EC_FLAG_BURST)){ - status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if(status) goto end; - acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); - acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); - } - atomic_set(&ec->intr.leaving_burst, 1); + acpi_ec_write_cmd(ec, ACPI_EC_BURST_DISABLE); + acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); + } + atomic_set(&ec->leaving_burst, 1); return 0; -end: - ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode"); + end: + ACPI_EXCEPTION((AE_INFO, status, "EC leave burst mode")); return -1; } #endif /* ACPI_FUTURE_USAGE */ -static int acpi_ec_read(union acpi_ec *ec, u8 address, u32 * data) -{ - if (acpi_ec_poll_mode) - return acpi_ec_poll_read(ec, address, data); - else - return acpi_ec_intr_read(ec, address, data); -} -static int acpi_ec_write(union acpi_ec *ec, u8 address, u8 data) -{ - if (acpi_ec_poll_mode) - return acpi_ec_poll_write(ec, address, data); - else - return acpi_ec_intr_write(ec, address, data); -} -static int acpi_ec_poll_read(union acpi_ec *ec, u8 address, u32 * data) +static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, + const u8 *wdata, unsigned wdata_len, + u8 *rdata, unsigned rdata_len) { - acpi_status status = AE_OK; - int result = 0; - u32 glk = 0; + int result; + acpi_ec_write_cmd(ec, command); - if (!ec || !data) - return -EINVAL; - - *data = 0; - - if (ec->common.global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return -ENODEV; + for (; wdata_len > 0; wdata_len --) { + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); + if (result) + return result; + acpi_ec_write_data(ec, *(wdata++)); } - if (down_interruptible(&ec->poll.sem)) { - result = -ERESTARTSYS; - goto end_nosem; + if (command == ACPI_EC_COMMAND_WRITE) { + result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); + if (result) + return result; } - - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, - &ec->common.command_addr); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (result) - goto end; - - acpi_hw_low_level_write(8, address, &ec->common.data_addr); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (result) - goto end; - - acpi_hw_low_level_read(8, data, &ec->common.data_addr); - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", - *data, address)); - - end: - up(&ec->poll.sem); -end_nosem: - if (ec->common.global_lock) - acpi_release_global_lock(glk); - - return result; -} - -static int acpi_ec_poll_write(union acpi_ec *ec, u8 address, u8 data) -{ - int result = 0; - acpi_status status = AE_OK; - u32 glk = 0; + for (; rdata_len > 0; rdata_len --) { + result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1); + if (result) + return result; - if (!ec) - return -EINVAL; - - if (ec->common.global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return -ENODEV; - } - - if (down_interruptible(&ec->poll.sem)) { - result = -ERESTARTSYS; - goto end_nosem; + *(rdata++) = acpi_ec_read_data(ec); } - - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, - &ec->common.command_addr); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (result) - goto end; - - acpi_hw_low_level_write(8, address, &ec->common.data_addr); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (result) - goto end; - - acpi_hw_low_level_write(8, data, &ec->common.data_addr); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (result) - goto end; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", - data, address)); - - end: - up(&ec->poll.sem); -end_nosem: - if (ec->common.global_lock) - acpi_release_global_lock(glk); - - return result; + return 0; } -static int acpi_ec_intr_read(union acpi_ec *ec, u8 address, u32 * data) +static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, + const u8 *wdata, unsigned wdata_len, + u8 *rdata, unsigned rdata_len) { - int status = 0; + int status; u32 glk; - - if (!ec || !data) + if (!ec || (wdata_len && !wdata) || (rdata_len && !rdata)) return -EINVAL; - *data = 0; + if (rdata) + memset(rdata, 0, rdata_len); - if (ec->common.global_lock) { + if (ec->global_lock) { status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); if (ACPI_FAILURE(status)) return -ENODEV; } + down(&ec->sem); - WARN_ON(in_interrupt()); - down(&ec->intr.sem); - - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); + status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0); if (status) { printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); goto end; } - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, - &ec->common.command_addr); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (status) { - printk(KERN_DEBUG PREFIX "read EC, IB not empty\n"); - } - acpi_hw_low_level_write(8, address, &ec->common.data_addr); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (status) { - printk(KERN_DEBUG PREFIX "read EC, OB not full\n"); - goto end; - } - acpi_hw_low_level_read(8, data, &ec->common.data_addr); - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", - *data, address)); + status = acpi_ec_transaction_unlocked(ec, command, + wdata, wdata_len, + rdata, rdata_len); - end: - up(&ec->intr.sem); +end: + up(&ec->sem); - if (ec->common.global_lock) + if (ec->global_lock) acpi_release_global_lock(glk); return status; } -static int acpi_ec_intr_write(union acpi_ec *ec, u8 address, u8 data) +static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) { - int status = 0; - u32 glk; - - - if (!ec) - return -EINVAL; - - if (ec->common.global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return -ENODEV; - } - - WARN_ON(in_interrupt()); - down(&ec->intr.sem); - - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (status) { - printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); - } - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, - &ec->common.command_addr); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (status) { - printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); - } - - acpi_hw_low_level_write(8, address, &ec->common.data_addr); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (status) { - printk(KERN_DEBUG PREFIX "write EC, IB not empty\n"); - } - - acpi_hw_low_level_write(8, data, &ec->common.data_addr); + int result; + u8 d; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", - data, address)); - - up(&ec->intr.sem); - - if (ec->common.global_lock) - acpi_release_global_lock(glk); + result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_READ, + &address, 1, &d, 1); + *data = d; + return result; +} - return status; +static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) +{ + u8 wdata[2] = { address, data }; + return acpi_ec_transaction(ec, ACPI_EC_COMMAND_WRITE, + wdata, 2, NULL, 0); } /* * Externally callable EC access functions. For now, assume 1 EC only */ -int ec_read(u8 addr, u8 * val) +int ec_read(u8 addr, u8 *val) { - union acpi_ec *ec; + struct acpi_ec *ec; int err; - u32 temp_data; + u8 temp_data; if (!first_ec) return -ENODEV; @@ -539,7 +354,7 @@ EXPORT_SYMBOL(ec_read); int ec_write(u8 addr, u8 val) { - union acpi_ec *ec; + struct acpi_ec *ec; int err; if (!first_ec) @@ -554,255 +369,106 @@ int ec_write(u8 addr, u8 val) EXPORT_SYMBOL(ec_write); -static int acpi_ec_query(union acpi_ec *ec, u32 * data) -{ - if (acpi_ec_poll_mode) - return acpi_ec_poll_query(ec, data); - else - return acpi_ec_intr_query(ec, data); -} -static int acpi_ec_poll_query(union acpi_ec *ec, u32 * data) +extern int ec_transaction(u8 command, + const u8 *wdata, unsigned wdata_len, + u8 *rdata, unsigned rdata_len) { - int result = 0; - acpi_status status = AE_OK; - u32 glk = 0; - - - if (!ec || !data) - return -EINVAL; - - *data = 0; - - if (ec->common.global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return -ENODEV; - } + struct acpi_ec *ec; - /* - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the ACPI_EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ - if (down_interruptible(&ec->poll.sem)) { - result = -ERESTARTSYS; - goto end_nosem; - } - - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, - &ec->common.command_addr); - result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (result) - goto end; - - acpi_hw_low_level_read(8, data, &ec->common.data_addr); - if (!*data) - result = -ENODATA; + if (!first_ec) + return -ENODEV; - end: - up(&ec->poll.sem); -end_nosem: - if (ec->common.global_lock) - acpi_release_global_lock(glk); + ec = acpi_driver_data(first_ec); - return result; + return acpi_ec_transaction(ec, command, wdata, + wdata_len, rdata, rdata_len); } -static int acpi_ec_intr_query(union acpi_ec *ec, u32 * data) -{ - int status = 0; - u32 glk; - - if (!ec || !data) - return -EINVAL; - *data = 0; - - if (ec->common.global_lock) { - status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); - if (ACPI_FAILURE(status)) - return -ENODEV; - } +EXPORT_SYMBOL(ec_transaction); - down(&ec->intr.sem); +static int acpi_ec_query(struct acpi_ec *ec, u8 *data) +{ + int result; + u8 d; - status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); - if (status) { - printk(KERN_DEBUG PREFIX "query EC, IB not empty\n"); - goto end; - } - /* - * Query the EC to find out which _Qxx method we need to evaluate. - * Note that successful completion of the query causes the ACPI_EC_SCI - * bit to be cleared (and thus clearing the interrupt source). - */ - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, - &ec->common.command_addr); - status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); - if (status) { - printk(KERN_DEBUG PREFIX "query EC, OB not full\n"); - goto end; - } + if (!ec || !data) + return -EINVAL; - acpi_hw_low_level_read(8, data, &ec->common.data_addr); - if (!*data) - status = -ENODATA; + /* + * Query the EC to find out which _Qxx method we need to evaluate. + * Note that successful completion of the query causes the ACPI_EC_SCI + * bit to be cleared (and thus clearing the interrupt source). + */ - end: - up(&ec->intr.sem); + result = acpi_ec_transaction(ec, ACPI_EC_COMMAND_QUERY, NULL, 0, &d, 1); + if (result) + return result; - if (ec->common.global_lock) - acpi_release_global_lock(glk); + if (!d) + return -ENODATA; - return status; + *data = d; + return 0; } /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ -union acpi_ec_query_data { +struct acpi_ec_query_data { acpi_handle handle; u8 data; }; static void acpi_ec_gpe_query(void *ec_cxt) { - if (acpi_ec_poll_mode) - acpi_ec_gpe_poll_query(ec_cxt); - else - acpi_ec_gpe_intr_query(ec_cxt); -} - -static void acpi_ec_gpe_poll_query(void *ec_cxt) -{ - union acpi_ec *ec = (union acpi_ec *)ec_cxt; - u32 value = 0; - static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; - const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - + struct acpi_ec *ec = (struct acpi_ec *)ec_cxt; + u8 value = 0; + static char object_name[8]; - if (!ec_cxt) + if (!ec) goto end; - if (down_interruptible (&ec->poll.sem)) { - return; - } - acpi_hw_low_level_read(8, &value, &ec->common.command_addr); - up(&ec->poll.sem); - - /* TBD: Implement asynch events! - * NOTE: All we care about are EC-SCI's. Other EC events are - * handled via polling (yuck!). This is because some systems - * treat EC-SCIs as level (versus EDGE!) triggered, preventing - * a purely interrupt-driven approach (grumble, grumble). - */ + value = acpi_ec_read_status(ec); + if (!(value & ACPI_EC_FLAG_SCI)) goto end; if (acpi_ec_query(ec, &value)) goto end; - object_name[2] = hex[((value >> 4) & 0x0F)]; - object_name[3] = hex[(value & 0x0F)]; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); + snprintf(object_name, 8, "_Q%2.2X", value); - acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); - end: - acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); -} -static void acpi_ec_gpe_intr_query(void *ec_cxt) -{ - union acpi_ec *ec = (union acpi_ec *)ec_cxt; - u32 value; - int result = -ENODATA; - static char object_name[5] = { '_', 'Q', '0', '0', '\0' }; - const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; + acpi_evaluate_object(ec->handle, object_name, NULL, NULL); - - if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) - result = acpi_ec_query(ec, &value); - - if (result) - goto end; - - object_name[2] = hex[((value >> 4) & 0x0F)]; - object_name[3] = hex[(value & 0x0F)]; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); - - acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); end: - atomic_dec(&ec->intr.pending_gpe); - return; + acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); } static u32 acpi_ec_gpe_handler(void *data) { - if (acpi_ec_poll_mode) - return acpi_ec_gpe_poll_handler(data); - else - return acpi_ec_gpe_intr_handler(data); -} -static u32 acpi_ec_gpe_poll_handler(void *data) -{ acpi_status status = AE_OK; - union acpi_ec *ec = (union acpi_ec *)data; - - if (!ec) - return ACPI_INTERRUPT_NOT_HANDLED; - - acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); - - status = acpi_os_execute(OSL_EC_POLL_HANDLER, acpi_ec_gpe_query, ec); - - if (status == AE_OK) - return ACPI_INTERRUPT_HANDLED; - else - return ACPI_INTERRUPT_NOT_HANDLED; -} -static u32 acpi_ec_gpe_intr_handler(void *data) -{ - acpi_status status = AE_OK; - u32 value; - union acpi_ec *ec = (union acpi_ec *)data; - - if (!ec) - return ACPI_INTERRUPT_NOT_HANDLED; + u8 value; + struct acpi_ec *ec = (struct acpi_ec *)data; - acpi_clear_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); + acpi_clear_gpe(NULL, ec->gpe_bit, ACPI_ISR); value = acpi_ec_read_status(ec); - switch (ec->intr.expect_event) { - case ACPI_EC_EVENT_OBF: - if (!(value & ACPI_EC_FLAG_OBF)) - break; - ec->intr.expect_event = 0; - wake_up(&ec->intr.wait); - break; - case ACPI_EC_EVENT_IBE: - if ((value & ACPI_EC_FLAG_IBF)) - break; - ec->intr.expect_event = 0; - wake_up(&ec->intr.wait); - break; - default: - break; + if (acpi_ec_mode == EC_INTR) { + if (acpi_ec_check_status(value, ec->expect_event)) { + ec->expect_event = 0; + wake_up(&ec->wait); + } } if (value & ACPI_EC_FLAG_SCI) { - atomic_add(1, &ec->intr.pending_gpe); - status = acpi_os_execute(OSL_EC_BURST_HANDLER, - acpi_ec_gpe_query, ec); + status = acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } - acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); + acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); return status == AE_OK ? ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; } @@ -833,7 +499,7 @@ acpi_ec_space_handler(u32 function, void *handler_context, void *region_context) { int result = 0; - union acpi_ec *ec = NULL; + struct acpi_ec *ec = NULL; u64 temp = *value; acpi_integer f_v = 0; int i = 0; @@ -843,18 +509,16 @@ acpi_ec_space_handler(u32 function, return AE_BAD_PARAMETER; if (bit_width != 8 && acpi_strict) { - printk(KERN_WARNING PREFIX - "acpi_ec_space_handler: bit_width should be 8\n"); return AE_BAD_PARAMETER; } - ec = (union acpi_ec *)handler_context; + ec = (struct acpi_ec *)handler_context; next_byte: switch (function) { case ACPI_READ: temp = 0; - result = acpi_ec_read(ec, (u8) address, (u32 *) & temp); + result = acpi_ec_read(ec, (u8) address, (u8 *) &temp); break; case ACPI_WRITE: result = acpi_ec_write(ec, (u8) address, (u8) temp); @@ -905,20 +569,20 @@ static struct proc_dir_entry *acpi_ec_di static int acpi_ec_read_info(struct seq_file *seq, void *offset) { - union acpi_ec *ec = (union acpi_ec *)seq->private; + struct acpi_ec *ec = (struct acpi_ec *)seq->private; if (!ec) goto end; seq_printf(seq, "gpe bit: 0x%02x\n", - (u32) ec->common.gpe_bit); + (u32) ec->gpe_bit); seq_printf(seq, "ports: 0x%02x, 0x%02x\n", - (u32) ec->common.status_addr.address, - (u32) ec->common.data_addr.address); + (u32) ec->command_addr, + (u32) ec->data_addr); seq_printf(seq, "use global lock: %s\n", - ec->common.global_lock ? "yes" : "no"); - acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); + ec->global_lock ? "yes" : "no"); + acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); end: return 0; @@ -929,7 +593,7 @@ static int acpi_ec_info_open_fs(struct i return single_open(file, acpi_ec_read_info, PDE(inode)->data); } -static const struct file_operations acpi_ec_info_ops = { +static struct file_operations acpi_ec_info_ops = { .open = acpi_ec_info_open_fs, .read = seq_read, .llseek = seq_lseek, @@ -978,101 +642,35 @@ static int acpi_ec_remove_fs(struct acpi Driver Interface -------------------------------------------------------------------------- */ -static int acpi_ec_poll_add(struct acpi_device *device) +static int acpi_ec_add(struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; - union acpi_ec *ec = NULL; + struct acpi_ec *ec = NULL; if (!device) return -EINVAL; - ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); + ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!ec) return -ENOMEM; - memset(ec, 0, sizeof(union acpi_ec)); - - ec->common.handle = device->handle; - ec->common.uid = -1; - init_MUTEX(&ec->poll.sem); - strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_EC_CLASS); - acpi_driver_data(device) = ec; - - /* Use the global lock for all EC transactions? */ - acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, - &ec->common.global_lock); - - /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: - http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ - if (ec_ecdt) { - acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, - ACPI_ADR_SPACE_EC, - &acpi_ec_space_handler); - - acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, - &acpi_ec_gpe_handler); - - kfree(ec_ecdt); + memset(ec, 0, sizeof(struct acpi_ec)); + + ec->handle = device->handle; + ec->uid = -1; + init_MUTEX(&ec->sem); + if (acpi_ec_mode == EC_INTR) { + atomic_set(&ec->leaving_burst, 1); + init_waitqueue_head(&ec->wait); } - - /* Get GPE bit assignment (EC events). */ - /* TODO: Add support for _GPE returning a package */ - status = - acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, - &ec->common.gpe_bit); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit")); - result = -ENODEV; - goto end; - } - - result = acpi_ec_add_fs(device); - if (result) - goto end; - - printk(KERN_INFO PREFIX "%s [%s] (gpe %d) polling mode.\n", - acpi_device_name(device), acpi_device_bid(device), - (u32) ec->common.gpe_bit); - - if (!first_ec) - first_ec = device; - - end: - if (result) - kfree(ec); - - return result; -} -static int acpi_ec_intr_add(struct acpi_device *device) -{ - int result = 0; - acpi_status status = AE_OK; - union acpi_ec *ec = NULL; - - - if (!device) - return -EINVAL; - - ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); - if (!ec) - return -ENOMEM; - memset(ec, 0, sizeof(union acpi_ec)); - - ec->common.handle = device->handle; - ec->common.uid = -1; - atomic_set(&ec->intr.pending_gpe, 0); - atomic_set(&ec->intr.leaving_burst, 1); - init_MUTEX(&ec->intr.sem); - init_waitqueue_head(&ec->intr.wait); strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); acpi_driver_data(device) = ec; /* Use the global lock for all EC transactions? */ - acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, - &ec->common.global_lock); + acpi_evaluate_integer(ec->handle, "_GLK", NULL, + &ec->global_lock); /* XXX we don't test uids, because on some boxes ecdt uid = 0, see: http://bugzilla.kernel.org/show_bug.cgi?id=6111 */ @@ -1081,7 +679,7 @@ static int acpi_ec_intr_add(struct acpi_ ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); - acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, + acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler); kfree(ec_ecdt); @@ -1090,10 +688,10 @@ static int acpi_ec_intr_add(struct acpi_ /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = - acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, - &ec->common.gpe_bit); + acpi_evaluate_integer(ec->handle, "_GPE", NULL, + &ec->gpe_bit); if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "Obtaining GPE bit assignment\n"); + ACPI_EXCEPTION((AE_INFO, status, "Obtaining GPE bit assignment")); result = -ENODEV; goto end; } @@ -1102,14 +700,14 @@ static int acpi_ec_intr_add(struct acpi_ if (result) goto end; - printk(KERN_INFO PREFIX "%s [%s] (gpe %d) interrupt mode.\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", acpi_device_name(device), acpi_device_bid(device), - (u32) ec->common.gpe_bit); + (u32) ec->gpe_bit)); if (!first_ec) first_ec = device; - end: + end: if (result) kfree(ec); @@ -1118,7 +716,7 @@ static int acpi_ec_intr_add(struct acpi_ static int acpi_ec_remove(struct acpi_device *device, int type) { - union acpi_ec *ec = NULL; + struct acpi_ec *ec = NULL; if (!device) @@ -1136,8 +734,7 @@ static int acpi_ec_remove(struct acpi_de static acpi_status acpi_ec_io_ports(struct acpi_resource *resource, void *context) { - union acpi_ec *ec = (union acpi_ec *)context; - struct acpi_generic_address *addr; + struct acpi_ec *ec = (struct acpi_ec *)context; if (resource->type != ACPI_RESOURCE_TYPE_IO) { return AE_OK; @@ -1148,26 +745,21 @@ acpi_ec_io_ports(struct acpi_resource *r * the second address region returned is the status/command * port. */ - if (ec->common.data_addr.register_bit_width == 0) { - addr = &ec->common.data_addr; - } else if (ec->common.command_addr.register_bit_width == 0) { - addr = &ec->common.command_addr; + if (ec->data_addr == 0) { + ec->data_addr = resource->data.io.minimum; + } else if (ec->command_addr == 0) { + ec->command_addr = resource->data.io.minimum; } else { return AE_CTRL_TERMINATE; } - addr->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; - addr->register_bit_width = 8; - addr->register_bit_offset = 0; - addr->address = resource->data.io.minimum; - return AE_OK; } static int acpi_ec_start(struct acpi_device *device) { acpi_status status = AE_OK; - union acpi_ec *ec = NULL; + struct acpi_ec *ec = NULL; if (!device) @@ -1181,39 +773,35 @@ static int acpi_ec_start(struct acpi_dev /* * Get I/O port addresses. Convert to GAS format. */ - status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, + status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec); - if (ACPI_FAILURE(status) - || ec->common.command_addr.register_bit_width == 0) { - printk(KERN_ERR PREFIX "Error getting I/O port addresses\n"); + if (ACPI_FAILURE(status) || ec->command_addr == 0) { + ACPI_EXCEPTION((AE_INFO, status, + "Error getting I/O port addresses")); return -ENODEV; } - ec->common.status_addr = ec->common.command_addr; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", - (u32) ec->common.gpe_bit, - (u32) ec->common.command_addr.address, - (u32) ec->common.data_addr.address)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", + ec->gpe_bit, ec->command_addr, ec->data_addr)); /* * Install GPE handler */ - status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, + status = acpi_install_gpe_handler(NULL, ec->gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); if (ACPI_FAILURE(status)) { return -ENODEV; } - acpi_set_gpe_type(NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); + acpi_set_gpe_type(NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); - status = acpi_install_address_space_handler(ec->common.handle, + status = acpi_install_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, &acpi_ec_space_setup, ec); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, + acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler); return -ENODEV; } @@ -1224,7 +812,7 @@ static int acpi_ec_start(struct acpi_dev static int acpi_ec_stop(struct acpi_device *device, int type) { acpi_status status = AE_OK; - union acpi_ec *ec = NULL; + struct acpi_ec *ec = NULL; if (!device) @@ -1232,14 +820,14 @@ static int acpi_ec_stop(struct acpi_devi ec = acpi_driver_data(device); - status = acpi_remove_address_space_handler(ec->common.handle, + status = acpi_remove_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); if (ACPI_FAILURE(status)) return -ENODEV; status = - acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, + acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler); if (ACPI_FAILURE(status)) return -ENODEV; @@ -1251,76 +839,30 @@ static acpi_status __init acpi_fake_ecdt_callback(acpi_handle handle, u32 Level, void *context, void **retval) { - - if (acpi_ec_poll_mode) - return acpi_fake_ecdt_poll_callback(handle, - Level, context, retval); - else - return acpi_fake_ecdt_intr_callback(handle, - Level, context, retval); -} - -static acpi_status __init -acpi_fake_ecdt_poll_callback(acpi_handle handle, - u32 Level, void *context, void **retval) -{ - acpi_status status; - - status = acpi_walk_resources(handle, METHOD_NAME__CRS, - acpi_ec_io_ports, ec_ecdt); - if (ACPI_FAILURE(status)) - return status; - ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; - - ec_ecdt->common.uid = -1; - acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); - - status = - acpi_evaluate_integer(handle, "_GPE", NULL, - &ec_ecdt->common.gpe_bit); - if (ACPI_FAILURE(status)) - return status; - init_MUTEX(&ec_ecdt->poll.sem); - ec_ecdt->common.global_lock = TRUE; - ec_ecdt->common.handle = handle; - - printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", - (u32) ec_ecdt->common.gpe_bit, - (u32) ec_ecdt->common.command_addr.address, - (u32) ec_ecdt->common.data_addr.address); - - return AE_CTRL_TERMINATE; -} - -static acpi_status __init -acpi_fake_ecdt_intr_callback(acpi_handle handle, - u32 Level, void *context, void **retval) -{ acpi_status status; - init_MUTEX(&ec_ecdt->intr.sem); - init_waitqueue_head(&ec_ecdt->intr.wait); + init_MUTEX(&ec_ecdt->sem); + if (acpi_ec_mode == EC_INTR) { + init_waitqueue_head(&ec_ecdt->wait); + } status = acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_ec_io_ports, ec_ecdt); if (ACPI_FAILURE(status)) return status; - ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; - ec_ecdt->common.uid = -1; - acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); + ec_ecdt->uid = -1; + acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); status = acpi_evaluate_integer(handle, "_GPE", NULL, - &ec_ecdt->common.gpe_bit); + &ec_ecdt->gpe_bit); if (ACPI_FAILURE(status)) return status; - ec_ecdt->common.global_lock = TRUE; - ec_ecdt->common.handle = handle; + ec_ecdt->global_lock = TRUE; + ec_ecdt->handle = handle; - printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", - (u32) ec_ecdt->common.gpe_bit, - (u32) ec_ecdt->common.command_addr.address, - (u32) ec_ecdt->common.data_addr.address); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", + ec_ecdt->gpe_bit, ec_ecdt->command_addr, ec_ecdt->data_addr)); return AE_CTRL_TERMINATE; } @@ -1340,14 +882,14 @@ static int __init acpi_ec_fake_ecdt(void acpi_status status; int ret = 0; - printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Try to make an fake ECDT")); - ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); + ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!ec_ecdt) { ret = -ENOMEM; goto error; } - memset(ec_ecdt, 0, sizeof(union acpi_ec)); + memset(ec_ecdt, 0, sizeof(struct acpi_ec)); status = acpi_get_devices(ACPI_EC_HID, acpi_fake_ecdt_callback, NULL, NULL); @@ -1355,24 +897,16 @@ static int __init acpi_ec_fake_ecdt(void kfree(ec_ecdt); ec_ecdt = NULL; ret = -ENODEV; + ACPI_EXCEPTION((AE_INFO, status, "Can't make an fake ECDT")); goto error; } return 0; - error: - printk(KERN_ERR PREFIX "Can't make an fake ECDT\n"); + error: return ret; } static int __init acpi_ec_get_real_ecdt(void) { - if (acpi_ec_poll_mode) - return acpi_ec_poll_get_real_ecdt(); - else - return acpi_ec_intr_get_real_ecdt(); -} - -static int __init acpi_ec_poll_get_real_ecdt(void) -{ acpi_status status; struct acpi_table_ecdt *ecdt_ptr; @@ -1382,80 +916,36 @@ static int __init acpi_ec_poll_get_real_ if (ACPI_FAILURE(status)) return -ENODEV; - printk(KERN_INFO PREFIX "Found ECDT\n"); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); /* * Generate a temporary ec context to use until the namespace is scanned */ - ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); + ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); if (!ec_ecdt) return -ENOMEM; - memset(ec_ecdt, 0, sizeof(union acpi_ec)); - - ec_ecdt->common.command_addr = ecdt_ptr->ec_control; - ec_ecdt->common.status_addr = ecdt_ptr->ec_control; - ec_ecdt->common.data_addr = ecdt_ptr->ec_data; - ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; - init_MUTEX(&ec_ecdt->poll.sem); - /* use the GL just to be safe */ - ec_ecdt->common.global_lock = TRUE; - ec_ecdt->common.uid = ecdt_ptr->uid; + memset(ec_ecdt, 0, sizeof(struct acpi_ec)); - status = - acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); - if (ACPI_FAILURE(status)) { - goto error; + init_MUTEX(&ec_ecdt->sem); + if (acpi_ec_mode == EC_INTR) { + init_waitqueue_head(&ec_ecdt->wait); } - - return 0; - error: - printk(KERN_ERR PREFIX "Could not use ECDT\n"); - kfree(ec_ecdt); - ec_ecdt = NULL; - - return -ENODEV; -} - -static int __init acpi_ec_intr_get_real_ecdt(void) -{ - acpi_status status; - struct acpi_table_ecdt *ecdt_ptr; - - status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, - (struct acpi_table_header **) - &ecdt_ptr); - if (ACPI_FAILURE(status)) - return -ENODEV; - - printk(KERN_INFO PREFIX "Found ECDT\n"); - - /* - * Generate a temporary ec context to use until the namespace is scanned - */ - ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); - if (!ec_ecdt) - return -ENOMEM; - memset(ec_ecdt, 0, sizeof(union acpi_ec)); - - init_MUTEX(&ec_ecdt->intr.sem); - init_waitqueue_head(&ec_ecdt->intr.wait); - ec_ecdt->common.command_addr = ecdt_ptr->ec_control; - ec_ecdt->common.status_addr = ecdt_ptr->ec_control; - ec_ecdt->common.data_addr = ecdt_ptr->ec_data; - ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; + ec_ecdt->command_addr = ecdt_ptr->ec_control.address; + ec_ecdt->data_addr = ecdt_ptr->ec_data.address; + ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; /* use the GL just to be safe */ - ec_ecdt->common.global_lock = TRUE; - ec_ecdt->common.uid = ecdt_ptr->uid; + ec_ecdt->global_lock = TRUE; + ec_ecdt->uid = ecdt_ptr->uid; status = - acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); + acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); if (ACPI_FAILURE(status)) { goto error; } return 0; - error: - printk(KERN_ERR PREFIX "Could not use ECDT\n"); + error: + ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); kfree(ec_ecdt); ec_ecdt = NULL; @@ -1480,14 +970,14 @@ int __init acpi_ec_ecdt_probe(void) /* * Install GPE handler */ - status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, + status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec_ecdt); if (ACPI_FAILURE(status)) { goto error; } - acpi_set_gpe_type(NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); - acpi_enable_gpe(NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); + acpi_set_gpe_type(NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); + acpi_enable_gpe(NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_EC, @@ -1495,7 +985,7 @@ int __init acpi_ec_ecdt_probe(void) &acpi_ec_space_setup, ec_ecdt); if (ACPI_FAILURE(status)) { - acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, + acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler); goto error; } @@ -1503,7 +993,7 @@ int __init acpi_ec_ecdt_probe(void) return 0; error: - printk(KERN_ERR PREFIX "Could not use ECDT\n"); + ACPI_EXCEPTION((AE_INFO, status, "Could not use ECDT")); kfree(ec_ecdt); ec_ecdt = NULL; @@ -1562,13 +1052,13 @@ static int __init acpi_ec_set_intr_mode( return 0; if (intr) { - acpi_ec_poll_mode = EC_INTR; - acpi_ec_driver.ops.add = acpi_ec_intr_add; + acpi_ec_mode = EC_INTR; } else { - acpi_ec_poll_mode = EC_POLL; - acpi_ec_driver.ops.add = acpi_ec_poll_add; + acpi_ec_mode = EC_POLL; } - printk(KERN_INFO PREFIX "EC %s mode.\n", intr ? "interrupt" : "polling"); + acpi_ec_driver.ops.add = acpi_ec_add; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "EC %s mode.\n", intr ? "interrupt" : "polling")); + return 1; } diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 6eef4ef..ee2a10b 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -342,20 +342,8 @@ static u32 acpi_ev_global_lock_handler(v if (acquired) { /* Got the lock, now wake all threads waiting for it */ - acpi_gbl_global_lock_acquired = TRUE; - - /* Run the Global Lock thread which will signal all waiting threads */ - - status = - acpi_os_execute(OSL_GLOBAL_LOCK_HANDLER, - acpi_ev_global_lock_thread, context); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, - "Could not queue Global Lock thread")); - - return (ACPI_INTERRUPT_NOT_HANDLED); - } + acpi_ev_global_lock_thread(context); } return (ACPI_INTERRUPT_HANDLED); diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 045c894..c413e69 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -99,8 +99,8 @@ acpi_fan_write_state(struct file *file, size_t count, loff_t * ppos) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_fan *fan = (struct acpi_fan *)m->private; + struct seq_file *m = file->private_data; + struct acpi_fan *fan = m->private; char state_string[12] = { '\0' }; @@ -229,7 +229,7 @@ static int acpi_fan_remove(struct acpi_d if (!device || !acpi_driver_data(device)) return -EINVAL; - fan = (struct acpi_fan *)acpi_driver_data(device); + fan = acpi_driver_data(device); acpi_fan_remove_fs(device); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f160d..ba5686f 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -96,7 +96,7 @@ struct acpi_find_pci_root { static acpi_status do_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { - unsigned long *busnr = (unsigned long *)data; + unsigned long *busnr = data; struct acpi_resource_address64 address; if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && @@ -217,7 +217,7 @@ do_acpi_find_child(acpi_handle handle, u acpi_status status; struct acpi_device_info *info; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_find_child *find = (struct acpi_find_child *)context; + struct acpi_find_child *find = context; status = acpi_get_object_info(handle, &buffer); if (ACPI_SUCCESS(status)) { diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c index 1ba2db6..8edfb92 100644 --- a/drivers/acpi/hotkey.c +++ b/drivers/acpi/hotkey.c @@ -265,8 +265,7 @@ static char *format_result(union acpi_ob static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_polling_hotkey *poll_hotkey = - (struct acpi_polling_hotkey *)seq->private; + struct acpi_polling_hotkey *poll_hotkey = seq->private; char *buf; @@ -577,7 +576,7 @@ init_poll_hotkey_device(union acpi_hotke if (ACPI_FAILURE(status)) goto do_fail_zero; key->poll_hotkey.poll_result = - (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); + kmalloc(sizeof(union acpi_object), GFP_KERNEL); if (!key->poll_hotkey.poll_result) goto do_fail_zero; return AE_OK; diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c index 6342e61..82e3e64 100644 --- a/drivers/acpi/i2c_ec.c +++ b/drivers/acpi/i2c_ec.c @@ -393,7 +393,7 @@ static void __exit acpi_ec_hc_exit(void) struct acpi_ec_hc *acpi_get_ec_hc(struct acpi_device *device) { - return ((struct acpi_ec_hc *)acpi_driver_data(device->parent)); + return acpi_driver_data(device->parent); } EXPORT_SYMBOL(acpi_get_ec_hc); diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 15fc124..440bce1 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c @@ -1702,13 +1702,11 @@ #endif .name = "brightness", .read = brightness_read, .write = brightness_write, - .experimental = 1, }, { .name = "volume", .read = volume_read, .write = volume_write, - .experimental = 1, }, { .name = "fan", @@ -1721,7 +1719,7 @@ #endif static int dispatch_read(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct ibm_struct *ibm = (struct ibm_struct *)data; + struct ibm_struct *ibm = data; int len; if (!ibm || !ibm->read) @@ -1746,7 +1744,7 @@ static int dispatch_read(char *page, cha static int dispatch_write(struct file *file, const char __user * userbuf, unsigned long count, void *data) { - struct ibm_struct *ibm = (struct ibm_struct *)data; + struct ibm_struct *ibm = data; char *kernbuf; int ret; @@ -1775,7 +1773,7 @@ static int dispatch_write(struct file *f static void dispatch_notify(acpi_handle handle, u32 event, void *data) { - struct ibm_struct *ibm = (struct ibm_struct *)data; + struct ibm_struct *ibm = data; if (!ibm || !ibm->notify) return; diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c index ec6b7f9..2e17ec7 100644 --- a/drivers/acpi/motherboard.c +++ b/drivers/acpi/motherboard.c @@ -48,6 +48,12 @@ #define IS_RESERVED_ADDR(base, len) \ * the io ports if they really know they can use it, while * still preventing hotplug PCI devices from using it. */ + +/* + * When CONFIG_PNP is enabled, pnp/system.c binds to PNP0C01 + * and PNP0C02, redundant with acpi_reserve_io_ranges(). + * But acpi_reserve_io_ranges() is necessary for !CONFIG_PNP. + */ static acpi_status acpi_reserve_io_ranges(struct acpi_resource *res, void *data) { struct resource *requested_res = NULL; diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e5e448e..bd96a70 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c @@ -248,7 +248,7 @@ int acpi_get_pxm(acpi_handle h) handle = phandle; status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm); if (ACPI_SUCCESS(status)) - return (int)pxm; + return pxm; status = acpi_get_parent(handle, &phandle); } while (ACPI_SUCCESS(status)); return -1; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 068fe4f..60b386c 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -73,6 +73,7 @@ static unsigned int acpi_irq_irq; static acpi_osd_handler acpi_irq_handler; static void *acpi_irq_context; static struct workqueue_struct *kacpid_wq; +static struct workqueue_struct *kacpi_notify_wq; acpi_status acpi_os_initialize(void) { @@ -91,8 +92,9 @@ acpi_status acpi_os_initialize1(void) return AE_NULL_ENTRY; } kacpid_wq = create_singlethread_workqueue("kacpid"); + kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); BUG_ON(!kacpid_wq); - + BUG_ON(!kacpi_notify_wq); return AE_OK; } @@ -104,6 +106,7 @@ acpi_status acpi_os_terminate(void) } destroy_workqueue(kacpid_wq); + destroy_workqueue(kacpi_notify_wq); return AE_OK; } @@ -566,10 +569,8 @@ void acpi_os_derive_pci_id(acpi_handle r static void acpi_os_execute_deferred(void *context) { - struct acpi_os_dpc *dpc = NULL; - + struct acpi_os_dpc *dpc = context; - dpc = (struct acpi_os_dpc *)context; if (!dpc) { printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); return; @@ -604,14 +605,12 @@ acpi_status acpi_os_execute(acpi_execute struct acpi_os_dpc *dpc; struct work_struct *task; - ACPI_FUNCTION_TRACE("os_queue_for_execution"); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); if (!function) - return_ACPI_STATUS(AE_BAD_PARAMETER); + return AE_BAD_PARAMETER; /* * Allocate/initialize DPC structure. Note that this memory will be @@ -624,26 +623,20 @@ acpi_status acpi_os_execute(acpi_execute * from the same memory. */ - dpc = - kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), - GFP_ATOMIC); + dpc = kmalloc(sizeof(struct acpi_os_dpc) + + sizeof(struct work_struct), GFP_ATOMIC); if (!dpc) - return_ACPI_STATUS(AE_NO_MEMORY); - + return AE_NO_MEMORY; dpc->function = function; dpc->context = context; - task = (void *)(dpc + 1); INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); - - if (!queue_work(kacpid_wq, task)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Call to queue_work() failed.\n")); - kfree(dpc); + if (!queue_work((type == OSL_NOTIFY_HANDLER)? + kacpi_notify_wq : kacpid_wq, task)) { status = AE_ERROR; + kfree(dpc); } - - return_ACPI_STATUS(status); + return status; } EXPORT_SYMBOL(acpi_os_execute); @@ -1060,7 +1053,7 @@ acpi_os_create_cache(char *name, u16 siz acpi_status acpi_os_purge_cache(acpi_cache_t * cache) { - (void)kmem_cache_shrink(cache); + kmem_cache_shrink(cache); return (AE_OK); } diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 1e2ae6e..70b440f 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -281,7 +281,7 @@ int acpi_pci_unbind(struct acpi_device * if (!device || !device->parent) return -EINVAL; - pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; memset(pathname, 0, ACPI_PATHNAME_MAX); @@ -332,7 +332,7 @@ acpi_pci_bind_root(struct acpi_device *d struct acpi_buffer buffer = { 0, NULL }; - pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; memset(pathname, 0, ACPI_PATHNAME_MAX); diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index feda034..226892e 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -161,7 +161,7 @@ int acpi_pci_irq_add_prt(acpi_handle han static int first_time = 1; - pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); + pathname = kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if (!pathname) return -ENOMEM; memset(pathname, 0, ACPI_PATHNAME_MAX); diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 7f3e7e7..812d733 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -103,7 +103,7 @@ DEFINE_MUTEX(acpi_link_lock); static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource, void *context) { - struct acpi_pci_link *link = (struct acpi_pci_link *)context; + struct acpi_pci_link *link = context; u32 i = 0; @@ -307,7 +307,7 @@ static int acpi_pci_link_set(struct acpi if (!link || !irq) return -EINVAL; - resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC); + resource = kmalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL); if (!resource) return -ENOMEM; @@ -613,7 +613,7 @@ acpi_pci_link_allocate_irq(acpi_handle h return -1; } - link = (struct acpi_pci_link *)acpi_driver_data(device); + link = acpi_driver_data(device); if (!link) { printk(KERN_ERR PREFIX "Invalid link context\n"); return -1; @@ -668,7 +668,7 @@ int acpi_pci_link_free_irq(acpi_handle h return -1; } - link = (struct acpi_pci_link *)acpi_driver_data(device); + link = acpi_driver_data(device); if (!link) { printk(KERN_ERR PREFIX "Invalid link context\n"); return -1; @@ -808,7 +808,7 @@ static int acpi_pci_link_remove(struct a if (!device || !acpi_driver_data(device)) return -EINVAL; - link = (struct acpi_pci_link *)acpi_driver_data(device); + link = acpi_driver_data(device); mutex_lock(&acpi_link_lock); list_del(&link->node); diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0984a1e..03e0374 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -119,7 +119,7 @@ EXPORT_SYMBOL(acpi_pci_unregister_driver static acpi_status get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) { - int *busnr = (int *)data; + int *busnr = data; struct acpi_resource_address64 address; if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 && @@ -331,7 +331,7 @@ static int acpi_pci_root_remove(struct a if (!device || !acpi_driver_data(device)) return -EINVAL; - root = (struct acpi_pci_root *)acpi_driver_data(device); + root = acpi_driver_data(device); kfree(root); diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fec225d..23a8a92 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -108,7 +108,7 @@ acpi_power_get_context(acpi_handle handl return result; } - *resource = (struct acpi_power_resource *)acpi_driver_data(device); + *resource = acpi_driver_data(device); if (!resource) return -ENODEV; @@ -216,10 +216,8 @@ static int acpi_power_off_device(acpi_ha { int result = 0; acpi_status status = AE_OK; - struct acpi_device *device = NULL; struct acpi_power_resource *resource = NULL; - result = acpi_power_get_context(handle, &resource); if (result) return result; @@ -230,13 +228,13 @@ static int acpi_power_off_device(acpi_ha if (resource->references) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is still in use, dereferencing\n", - device->pnp.bus_id)); + resource->device->pnp.bus_id)); return 0; } if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", - device->pnp.bus_id)); + resource->device->pnp.bus_id)); return 0; } @@ -251,8 +249,7 @@ static int acpi_power_off_device(acpi_ha return -ENOEXEC; /* Update the power resource's _device_ power state */ - device = resource->device; - device->power.state = ACPI_STATE_D3; + resource->device->power.state = ACPI_STATE_D3; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", resource->name)); @@ -445,7 +442,7 @@ static int acpi_power_seq_show(struct se struct acpi_power_resource *resource = NULL; - resource = (struct acpi_power_resource *)seq->private; + resource = seq->private; if (!resource) goto end; @@ -593,7 +590,7 @@ static int acpi_power_remove(struct acpi if (!device || !acpi_driver_data(device)) return -EINVAL; - resource = (struct acpi_power_resource *)acpi_driver_data(device); + resource = acpi_driver_data(device); acpi_power_remove_fs(device); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index b13d644..44c624b 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -277,7 +277,7 @@ static struct proc_dir_entry *acpi_proce static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; if (!pr) @@ -542,12 +542,12 @@ static int acpi_processor_start(struct a * Don't trust it blindly */ if (processor_device_array[pr->id] != NULL && - processor_device_array[pr->id] != (void *)device) { + processor_device_array[pr->id] != device) { printk(KERN_WARNING "BIOS reported wrong ACPI id" "for the processor\n"); return -ENODEV; } - processor_device_array[pr->id] = (void *)device; + processor_device_array[pr->id] = device; processors[pr->id] = pr; @@ -578,7 +578,7 @@ static int acpi_processor_start(struct a static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_processor *pr = (struct acpi_processor *)data; + struct acpi_processor *pr = data; struct acpi_device *device = NULL; @@ -637,7 +637,7 @@ static int acpi_processor_remove(struct if (!device || !acpi_driver_data(device)) return -EINVAL; - pr = (struct acpi_processor *)acpi_driver_data(device); + pr = acpi_driver_data(device); if (pr->id >= NR_CPUS) { kfree(pr); diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 0a395fc..26b0acc 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -219,6 +219,23 @@ static void acpi_safe_halt(void) static atomic_t c3_cpu_count; +/* Common C-state entry for C2, C3, .. */ +static void acpi_cstate_enter(struct acpi_processor_cx *cstate) +{ + if (cstate->space_id == ACPI_CSTATE_FFH) { + /* Call into architectural FFH based C-state */ + acpi_processor_ffh_cstate_enter(cstate); + } else { + int unused; + /* IO port based C-state */ + inb(cstate->address); + /* Dummy wait op - must do something useless after P_LVL2 read + because chipsets cannot guarantee that STPCLK# signal + gets asserted in time to freeze execution properly. */ + unused = inl(acpi_fadt.xpm_tmr_blk.address); + } +} + static void acpi_processor_idle(void) { struct acpi_processor *pr = NULL; @@ -361,11 +378,7 @@ #endif /* Get start time (ticks) */ t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C2 */ - inb(cx->address); - /* Dummy wait op - must do something useless after P_LVL2 read - because chipsets cannot guarantee that STPCLK# signal - gets asserted in time to freeze execution properly. */ - t2 = inl(acpi_fadt.xpm_tmr_blk.address); + acpi_cstate_enter(cx); /* Get end time (ticks) */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); @@ -401,9 +414,7 @@ #endif /* Get start time (ticks) */ t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C3 */ - inb(cx->address); - /* Dummy wait op (see above) */ - t2 = inl(acpi_fadt.xpm_tmr_blk.address); + acpi_cstate_enter(cx); /* Get end time (ticks) */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); if (pr->flags.bm_check) { @@ -628,20 +639,16 @@ #endif return 0; } -static int acpi_processor_get_power_info_default_c1(struct acpi_processor *pr) +static int acpi_processor_get_power_info_default(struct acpi_processor *pr) { - - /* Zero initialize all the C-states info. */ - memset(pr->power.states, 0, sizeof(pr->power.states)); - - /* set the first C-State to C1 */ - pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; - - /* the C0 state only exists as a filler in our array, - * and all processors need to support C1 */ + if (!pr->power.states[ACPI_STATE_C1].valid) { + /* set the first C-State to C1 */ + /* all processors need to support C1 */ + pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; + pr->power.states[ACPI_STATE_C1].valid = 1; + } + /* the C0 state only exists as a filler in our array */ pr->power.states[ACPI_STATE_C0].valid = 1; - pr->power.states[ACPI_STATE_C1].valid = 1; - return 0; } @@ -658,12 +665,7 @@ static int acpi_processor_get_power_info if (nocst) return -ENODEV; - current_count = 1; - - /* Zero initialize C2 onwards and prepare for fresh CST lookup */ - for (i = 2; i < ACPI_PROCESSOR_MAX_POWER; i++) - memset(&(pr->power.states[i]), 0, - sizeof(struct acpi_processor_cx)); + current_count = 0; status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); if (ACPI_FAILURE(status)) { @@ -671,7 +673,7 @@ static int acpi_processor_get_power_info return -ENODEV; } - cst = (union acpi_object *)buffer.pointer; + cst = buffer.pointer; /* There must be at least 2 elements */ if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) { @@ -700,14 +702,14 @@ static int acpi_processor_get_power_info memset(&cx, 0, sizeof(cx)); - element = (union acpi_object *)&(cst->package.elements[i]); + element = &(cst->package.elements[i]); if (element->type != ACPI_TYPE_PACKAGE) continue; if (element->package.count != 4) continue; - obj = (union acpi_object *)&(element->package.elements[0]); + obj = &(element->package.elements[0]); if (obj->type != ACPI_TYPE_BUFFER) continue; @@ -718,30 +720,47 @@ static int acpi_processor_get_power_info (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) continue; - cx.address = (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) ? - 0 : reg->address; - /* There should be an easy way to extract an integer... */ - obj = (union acpi_object *)&(element->package.elements[1]); + obj = &(element->package.elements[1]); if (obj->type != ACPI_TYPE_INTEGER) continue; cx.type = obj->integer.value; + /* + * Some buggy BIOSes won't list C1 in _CST - + * Let acpi_processor_get_power_info_default() handle them later + */ + if (i == 1 && cx.type != ACPI_STATE_C1) + current_count++; + + cx.address = reg->address; + cx.index = current_count + 1; + + cx.space_id = ACPI_CSTATE_SYSTEMIO; + if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { + if (acpi_processor_ffh_cstate_probe + (pr->id, &cx, reg) == 0) { + cx.space_id = ACPI_CSTATE_FFH; + } else if (cx.type != ACPI_STATE_C1) { + /* + * C1 is a special case where FIXED_HARDWARE + * can be handled in non-MWAIT way as well. + * In that case, save this _CST entry info. + * That is, we retain space_id of SYSTEM_IO for + * halt based C1. + * Otherwise, ignore this info and continue. + */ + continue; + } + } - if ((cx.type != ACPI_STATE_C1) && - (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) - continue; - - if ((cx.type < ACPI_STATE_C2) || (cx.type > ACPI_STATE_C3)) - continue; - - obj = (union acpi_object *)&(element->package.elements[2]); + obj = &(element->package.elements[2]); if (obj->type != ACPI_TYPE_INTEGER) continue; cx.latency = obj->integer.value; - obj = (union acpi_object *)&(element->package.elements[3]); + obj = &(element->package.elements[3]); if (obj->type != ACPI_TYPE_INTEGER) continue; @@ -938,12 +957,18 @@ static int acpi_processor_get_power_info /* NOTE: the idle thread may not be running while calling * this function */ - /* Adding C1 state */ - acpi_processor_get_power_info_default_c1(pr); + /* Zero initialize all the C-states info. */ + memset(pr->power.states, 0, sizeof(pr->power.states)); + result = acpi_processor_get_power_info_cst(pr); if (result == -ENODEV) acpi_processor_get_power_info_fadt(pr); + if (result) + return result; + + acpi_processor_get_power_info_default(pr); + pr->power.count = acpi_processor_power_verify(pr); /* @@ -1004,7 +1029,7 @@ int acpi_processor_cst_has_changed(struc static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; unsigned int i; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 7ba5e49..39fdbcc 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -238,7 +238,7 @@ static int acpi_processor_get_performanc return -ENODEV; } - pss = (union acpi_object *)buffer.pointer; + pss = buffer.pointer; if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) { printk(KERN_ERR PREFIX "Invalid _PSS data\n"); result = -EFAULT; @@ -412,7 +412,7 @@ static struct file_operations acpi_proce static int acpi_processor_perf_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; int i; @@ -453,8 +453,8 @@ acpi_processor_write_performance(struct size_t count, loff_t * data) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_processor *pr = (struct acpi_processor *)m->private; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; struct acpi_processor_performance *perf; char state_string[12] = { '\0' }; unsigned int new_state = 0; @@ -553,7 +553,7 @@ static int acpi_processor_get_psd(struct return -ENODEV; } - psd = (union acpi_object *) buffer.pointer; + psd = buffer.pointer; if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); result = -EFAULT; diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ef5e0f6..40fecd6 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -208,7 +208,7 @@ int acpi_processor_set_thermal_limit(acp if (result) return result; - pr = (struct acpi_processor *)acpi_driver_data(device); + pr = acpi_driver_data(device); if (!pr) return -ENODEV; @@ -348,8 +348,8 @@ static ssize_t acpi_processor_write_limi size_t count, loff_t * data) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_processor *pr = (struct acpi_processor *)m->private; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; char limit_string[25] = { '\0' }; int px = 0; int tx = 0; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d044ec5..0ec7dcd 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -259,7 +259,7 @@ int acpi_processor_get_throttling_info(s static int acpi_processor_throttling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_processor *pr = (struct acpi_processor *)seq->private; + struct acpi_processor *pr = seq->private; int i = 0; int result = 0; @@ -307,8 +307,8 @@ static ssize_t acpi_processor_write_thro size_t count, loff_t * data) { int result = 0; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_processor *pr = (struct acpi_processor *)m->private; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; char state_string[12] = { '\0' }; diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 62bef0b..8908a97 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -98,11 +98,11 @@ static int update_info_mode = UPDATE_INF static int update_time = UPDATE_TIME; static int update_time2 = UPDATE_TIME2; -module_param(capacity_mode, int, CAPACITY_UNIT); -module_param(update_mode, int, UPDATE_MODE); -module_param(update_info_mode, int, UPDATE_INFO_MODE); -module_param(update_time, int, UPDATE_TIME); -module_param(update_time2, int, UPDATE_TIME2); +module_param(capacity_mode, int, 0); +module_param(update_mode, int, 0); +module_param(update_info_mode, int, 0); +module_param(update_time, int, 0); +module_param(update_time2, int, 0); static int acpi_sbs_add(struct acpi_device *device); static int acpi_sbs_remove(struct acpi_device *device, int type); @@ -1685,10 +1685,16 @@ static int acpi_sbs_add(struct acpi_devi int acpi_sbs_remove(struct acpi_device *device, int type) { - struct acpi_sbs *sbs = (struct acpi_sbs *)acpi_driver_data(device); + struct acpi_sbs *sbs = NULL; int id; - if (!device || !sbs) { + if (!device) { + return -EINVAL; + } + + sbs = (struct acpi_sbs *)acpi_driver_data(device); + + if (!sbs) { return -EINVAL; } diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index bfb3bfc..ffa30c9 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -228,7 +228,7 @@ void acpi_table_print_madt_entry(acpi_ta static int acpi_table_compute_checksum(void *table_pointer, unsigned long length) { - u8 *p = (u8 *) table_pointer; + u8 *p = table_pointer; unsigned long remains = length; unsigned long sum = 0; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5753d06..4d75085 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -663,7 +663,7 @@ static void acpi_thermal_run(unsigned lo static void acpi_thermal_check(void *data) { int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *)data; + struct acpi_thermal *tz = data; unsigned long sleep_time = 0; int i = 0; struct acpi_thermal_state state; @@ -778,7 +778,7 @@ static struct proc_dir_entry *acpi_therm static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -813,7 +813,7 @@ static int acpi_thermal_state_open_fs(st static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) { int result = 0; - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -837,7 +837,7 @@ static int acpi_thermal_temp_open_fs(str static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; int i = 0; int j = 0; @@ -893,8 +893,8 @@ acpi_thermal_write_trip_points(struct fi const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; char *limit_string; int num, critical, hot, passive; @@ -953,7 +953,7 @@ acpi_thermal_write_trip_points(struct fi static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -984,8 +984,8 @@ acpi_thermal_write_cooling_mode(struct f const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; int result = 0; char mode_string[12] = { '\0' }; @@ -1014,7 +1014,7 @@ acpi_thermal_write_cooling_mode(struct f static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) { - struct acpi_thermal *tz = (struct acpi_thermal *)seq->private; + struct acpi_thermal *tz = seq->private; if (!tz) @@ -1043,8 +1043,8 @@ acpi_thermal_write_polling(struct file * const char __user * buffer, size_t count, loff_t * ppos) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_thermal *tz = (struct acpi_thermal *)m->private; + struct seq_file *m = file->private_data; + struct acpi_thermal *tz = m->private; int result = 0; char polling_string[12] = { '\0' }; int seconds = 0; @@ -1170,7 +1170,7 @@ static int acpi_thermal_remove_fs(struct static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_thermal *tz = (struct acpi_thermal *)data; + struct acpi_thermal *tz = data; struct acpi_device *device = NULL; @@ -1324,7 +1324,7 @@ static int acpi_thermal_remove(struct ac if (!device || !acpi_driver_data(device)) return -EINVAL; - tz = (struct acpi_thermal *)acpi_driver_data(device); + tz = acpi_driver_data(device); /* avoid timer adding new defer task */ tz->zombie = 1; @@ -1364,7 +1364,7 @@ static int acpi_thermal_resume(struct ac if (!device || !acpi_driver_data(device)) return -EINVAL; - tz = (struct acpi_thermal *)acpi_driver_data(device); + tz = acpi_driver_data(device); acpi_thermal_get_temperature(tz); diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index d0d84c4..91fed70 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -83,7 +83,7 @@ acpi_extract_package(union acpi_object * return AE_BAD_DATA; } - format_string = (char *)format->pointer; + format_string = format->pointer; /* * Calculate size_required. @@ -361,7 +361,7 @@ acpi_evaluate_reference(acpi_handle hand if (ACPI_FAILURE(status)) goto end; - package = (union acpi_object *)buffer.pointer; + package = buffer.pointer; if ((buffer.length == 0) || !package) { printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n", diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 56666a9..53a9eb0 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -386,7 +386,7 @@ acpi_video_device_EDID(struct acpi_video if (ACPI_FAILURE(status)) return -ENODEV; - obj = (union acpi_object *)buffer.pointer; + obj = buffer.pointer; if (obj && obj->type == ACPI_TYPE_BUFFER) *edid = obj; @@ -654,8 +654,7 @@ static struct proc_dir_entry *acpi_video static int acpi_video_device_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; if (!dev) @@ -688,8 +687,7 @@ acpi_video_device_info_open_fs(struct in static int acpi_video_device_state_seq_show(struct seq_file *seq, void *offset) { int status; - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; unsigned long state; @@ -727,8 +725,8 @@ acpi_video_device_write_state(struct fil size_t count, loff_t * data) { int status; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_device *dev = (struct acpi_video_device *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_device *dev = m->private; char str[12] = { 0 }; u32 state = 0; @@ -754,8 +752,7 @@ acpi_video_device_write_state(struct fil static int acpi_video_device_brightness_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; int i; @@ -784,8 +781,8 @@ acpi_video_device_write_brightness(struc const char __user * buffer, size_t count, loff_t * data) { - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_device *dev = (struct acpi_video_device *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_device *dev = m->private; char str[4] = { 0 }; unsigned int level = 0; int i; @@ -817,8 +814,7 @@ acpi_video_device_write_brightness(struc static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_device *dev = - (struct acpi_video_device *)seq->private; + struct acpi_video_device *dev = seq->private; int status; int i; union acpi_object *edid = NULL; @@ -866,7 +862,7 @@ static int acpi_video_device_add_fs(stru if (!device) return -ENODEV; - vid_dev = (struct acpi_video_device *)acpi_driver_data(device); + vid_dev = acpi_driver_data(device); if (!vid_dev) return -ENODEV; @@ -931,7 +927,7 @@ static int acpi_video_device_remove_fs(s { struct acpi_video_device *vid_dev; - vid_dev = (struct acpi_video_device *)acpi_driver_data(device); + vid_dev = acpi_driver_data(device); if (!vid_dev || !vid_dev->video || !vid_dev->video->dir) return -ENODEV; @@ -950,7 +946,7 @@ static int acpi_video_device_remove_fs(s /* video bus */ static int acpi_video_bus_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; if (!video) @@ -975,7 +971,7 @@ static int acpi_video_bus_info_open_fs(s static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; if (!video) @@ -995,7 +991,7 @@ static int acpi_video_bus_ROM_open_fs(st static int acpi_video_bus_POST_info_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; unsigned long options; int status; @@ -1033,7 +1029,7 @@ acpi_video_bus_POST_info_open_fs(struct static int acpi_video_bus_POST_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; int status; unsigned long id; @@ -1054,7 +1050,7 @@ static int acpi_video_bus_POST_seq_show( static int acpi_video_bus_DOS_seq_show(struct seq_file *seq, void *offset) { - struct acpi_video_bus *video = (struct acpi_video_bus *)seq->private; + struct acpi_video_bus *video = seq->private; seq_printf(seq, "DOS setting: <%d>\n", video->dos_setting); @@ -1079,8 +1075,8 @@ acpi_video_bus_write_POST(struct file *f size_t count, loff_t * data) { int status; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_bus *video = m->private; char str[12] = { 0 }; unsigned long opt, options; @@ -1119,8 +1115,8 @@ acpi_video_bus_write_DOS(struct file *fi size_t count, loff_t * data) { int status; - struct seq_file *m = (struct seq_file *)file->private_data; - struct acpi_video_bus *video = (struct acpi_video_bus *)m->private; + struct seq_file *m = file->private_data; + struct acpi_video_bus *video = m->private; char str[12] = { 0 }; unsigned long opt; @@ -1150,7 +1146,7 @@ static int acpi_video_bus_add_fs(struct struct acpi_video_bus *video; - video = (struct acpi_video_bus *)acpi_driver_data(device); + video = acpi_driver_data(device); if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), @@ -1226,7 +1222,7 @@ static int acpi_video_bus_remove_fs(stru struct acpi_video_bus *video; - video = (struct acpi_video_bus *)acpi_driver_data(device); + video = acpi_driver_data(device); if (acpi_device_dir(device)) { remove_proc_entry("info", acpi_device_dir(device)); @@ -1403,7 +1399,7 @@ static int acpi_video_device_enumerate(s return status; } - dod = (union acpi_object *)buffer.pointer; + dod = buffer.pointer; if (!dod || (dod->type != ACPI_TYPE_PACKAGE)) { ACPI_EXCEPTION((AE_INFO, status, "Invalid _DOD data")); status = -EFAULT; @@ -1426,7 +1422,7 @@ static int acpi_video_device_enumerate(s count = 0; for (i = 0; i < dod->package.count; i++) { - obj = (union acpi_object *)&dod->package.elements[i]; + obj = &dod->package.elements[i]; if (obj->type != ACPI_TYPE_INTEGER) { printk(KERN_ERR PREFIX "Invalid _DOD data\n"); @@ -1612,7 +1608,7 @@ static int acpi_video_bus_stop_devices(s static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_video_bus *video = (struct acpi_video_bus *)data; + struct acpi_video_bus *video = data; struct acpi_device *device = NULL; printk("video bus notify\n"); @@ -1654,8 +1650,7 @@ static void acpi_video_bus_notify(acpi_h static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_video_device *video_device = - (struct acpi_video_device *)data; + struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; @@ -1757,7 +1752,7 @@ static int acpi_video_bus_remove(struct if (!device || !acpi_driver_data(device)) return -EINVAL; - video = (struct acpi_video_bus *)acpi_driver_data(device); + video = acpi_driver_data(device); acpi_video_bus_stop_devices(video); diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3df0e7a..fa7acc2 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -57,4 +57,23 @@ config TIFM_7XX1 To compile this driver as a module, choose M here: the module will be called tifm_7xx1. +config MSI_LAPTOP + tristate "MSI Laptop Extras" + depends on X86 + depends on ACPI_EC + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is a driver for laptops built by MSI (MICRO-STAR + INTERNATIONAL): + + MSI MegaBook S270 (MS-1013) + Cytron/TCM/Medion/Tchibo MD96100/SAM2000 + + It adds support for Bluetooth, WLAN and LCD brightness control. + + More information about this driver is available at + . + + If you have an MSI S270 laptop, say Y or M here. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index d65ece7..9a91c1e 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -5,6 +5,7 @@ obj- := misc.o # Dummy rule to force bui obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ +obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(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 0000000..fdb7153 --- /dev/null +++ b/drivers/misc/msi-laptop.c @@ -0,0 +1,395 @@ +/*-*-linux-c-*-*/ + +/* + Copyright (C) 2006 Lennart Poettering + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + */ + +/* + * msi-laptop.c - MSI S270 laptop support. This laptop is sold under + * various brands, including "Cytron/TCM/Medion/Tchibo MD96100". + * + * This driver exports a few files in /sys/devices/platform/msi-laptop-pf/: + * + * lcd_level - Screen brightness: contains a single integer in the + * range 0..8. (rw) + * + * auto_brightness - Enable automatic brightness control: contains + * either 0 or 1. If set to 1 the hardware adjusts the screen + * brightness automatically when the power cord is + * plugged/unplugged. (rw) + * + * wlan - WLAN subsystem enabled: contains either 0 or 1. (ro) + * + * bluetooth - Bluetooth subsystem enabled: contains either 0 or 1 + * Please note that this file is constantly 0 if no Bluetooth + * hardware is available. (ro) + * + * In addition to these platform device attributes the driver + * registers itself in the Linux backlight control subsystem and is + * available to userspace under /sys/class/backlight/msi-laptop-bl/. + * + * This driver might work on other laptops produced by MSI. If you + * want to try it you can pass force=1 as argument to the module which + * will force it to load even when the DMI data doesn't identify the + * laptop as MSI S270. YMMV. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MSI_DRIVER_VERSION "0.5" + +#define MSI_LCD_LEVEL_MAX 9 + +#define MSI_EC_COMMAND_WIRELESS 0x10 +#define MSI_EC_COMMAND_LCD_LEVEL 0x11 + +static int force; +module_param(force, bool, 0); +MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); + +static int auto_brightness; +module_param(auto_brightness, int, 0); +MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)"); + +/* Hardware access */ + +static int set_lcd_level(int level) +{ + u8 buf[2]; + + if (level < 0 || level >= MSI_LCD_LEVEL_MAX) + return -EINVAL; + + buf[0] = 0x80; + buf[1] = (u8) (level*31); + + return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf), NULL, 0); +} + +static int get_lcd_level(void) +{ + u8 wdata = 0, rdata; + int result; + + result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); + if (result < 0) + return result; + + return (int) rdata / 31; +} + +static int get_auto_brightness(void) +{ + u8 wdata = 4, rdata; + int result; + + result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1, &rdata, 1); + if (result < 0) + return result; + + return !!(rdata & 8); +} + +static int set_auto_brightness(int enable) +{ + u8 wdata[2], rdata; + int result; + + wdata[0] = 4; + + result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1, &rdata, 1); + if (result < 0) + return result; + + wdata[0] = 0x84; + wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0); + + return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2, NULL, 0); +} + +static int get_wireless_state(int *wlan, int *bluetooth) +{ + u8 wdata = 0, rdata; + int result; + + result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1); + if (result < 0) + return -1; + + if (wlan) + *wlan = !!(rdata & 8); + + if (bluetooth) + *bluetooth = !!(rdata & 128); + + return 0; +} + +/* Backlight device stuff */ + +static int bl_get_brightness(struct backlight_device *b) +{ + return get_lcd_level(); +} + + +static int bl_update_status(struct backlight_device *b) +{ + return set_lcd_level(b->props->brightness); +} + +static struct backlight_properties msibl_props = { + .owner = THIS_MODULE, + .get_brightness = bl_get_brightness, + .update_status = bl_update_status, + .max_brightness = MSI_LCD_LEVEL_MAX-1, +}; + +static struct backlight_device *msibl_device; + +/* Platform device */ + +static ssize_t show_wlan(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + int ret, enabled; + + ret = get_wireless_state(&enabled, NULL); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", enabled); +} + +static ssize_t show_bluetooth(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + int ret, enabled; + + ret = get_wireless_state(NULL, &enabled); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", enabled); +} + +static ssize_t show_lcd_level(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + int ret; + + ret = get_lcd_level(); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", ret); +} + +static ssize_t store_lcd_level(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + + int level, ret; + + if (sscanf(buf, "%i", &level) != 1 || (level < 0 || level >= MSI_LCD_LEVEL_MAX)) + return -EINVAL; + + ret = set_lcd_level(level); + if (ret < 0) + return ret; + + return count; +} + +static ssize_t show_auto_brightness(struct device *dev, + struct device_attribute *attr, char *buf) +{ + + int ret; + + ret = get_auto_brightness(); + if (ret < 0) + return ret; + + return sprintf(buf, "%i\n", ret); +} + +static ssize_t store_auto_brightness(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + + int enable, ret; + + if (sscanf(buf, "%i", &enable) != 1 || (enable != (enable & 1))) + return -EINVAL; + + ret = set_auto_brightness(enable); + if (ret < 0) + return ret; + + return count; +} + +static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); +static DEVICE_ATTR(auto_brightness, 0644, show_auto_brightness, store_auto_brightness); +static DEVICE_ATTR(bluetooth, 0444, show_bluetooth, NULL); +static DEVICE_ATTR(wlan, 0444, show_wlan, NULL); + +static struct attribute *msipf_attributes[] = { + &dev_attr_lcd_level.attr, + &dev_attr_auto_brightness.attr, + &dev_attr_bluetooth.attr, + &dev_attr_wlan.attr, + NULL +}; + +static struct attribute_group msipf_attribute_group = { + .attrs = msipf_attributes +}; + +static struct platform_driver msipf_driver = { + .driver = { + .name = "msi-laptop-pf", + .owner = THIS_MODULE, + } +}; + +static struct platform_device *msipf_device; + +/* Initialization */ + +static struct dmi_system_id __initdata msi_dmi_table[] = { + { + .ident = "MSI S270", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), + } + }, + { + .ident = "Medion MD96100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), + DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), + } + }, + { } +}; + + +static int __init msi_init(void) +{ + int ret; + + if (acpi_disabled) + return -ENODEV; + + if (!force && !dmi_check_system(msi_dmi_table)) + return -ENODEV; + + if (auto_brightness < 0 || auto_brightness > 2) + return -EINVAL; + + /* Register backlight stuff */ + + msibl_device = backlight_device_register("msi-laptop-bl", NULL, &msibl_props); + if (IS_ERR(msibl_device)) + return PTR_ERR(msibl_device); + + ret = platform_driver_register(&msipf_driver); + if (ret) + goto fail_backlight; + + /* Register platform stuff */ + + msipf_device = platform_device_alloc("msi-laptop-pf", -1); + if (!msipf_device) { + ret = -ENOMEM; + goto fail_platform_driver; + } + + ret = platform_device_add(msipf_device); + if (ret) + goto fail_platform_device1; + + ret = sysfs_create_group(&msipf_device->dev.kobj, &msipf_attribute_group); + if (ret) + goto fail_platform_device2; + + /* Disable automatic brightness control by default because + * this module was probably loaded to do brightness control in + * software. */ + + if (auto_brightness != 2) + set_auto_brightness(auto_brightness); + + printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n"); + + return 0; + +fail_platform_device2: + + platform_device_del(msipf_device); + +fail_platform_device1: + + platform_device_put(msipf_device); + +fail_platform_driver: + + platform_driver_unregister(&msipf_driver); + +fail_backlight: + + backlight_device_unregister(msibl_device); + + return ret; +} + +static void __exit msi_cleanup(void) +{ + + sysfs_remove_group(&msipf_device->dev.kobj, &msipf_attribute_group); + platform_device_unregister(msipf_device); + platform_driver_unregister(&msipf_driver); + backlight_device_unregister(msibl_device); + + /* Enable automatic brightness control again */ + if (auto_brightness != 2) + set_auto_brightness(1); + + printk(KERN_INFO "msi-laptop: driver unloaded.\n"); +} + +module_init(msi_init); +module_exit(msi_cleanup); + +MODULE_AUTHOR("Lennart Poettering"); +MODULE_DESCRIPTION("MSI Laptop Support"); +MODULE_VERSION(MSI_DRIVER_VERSION); +MODULE_LICENSE("GPL"); diff --git a/include/acpi/pdc_intel.h b/include/acpi/pdc_intel.h index c5472be..e72bfdd 100644 --- a/include/acpi/pdc_intel.h +++ b/include/acpi/pdc_intel.h @@ -13,6 +13,7 @@ #define ACPI_PDC_SMP_P_SWCOORD (0x0020) #define ACPI_PDC_SMP_C_SWCOORD (0x0040) #define ACPI_PDC_SMP_T_SWCOORD (0x0080) #define ACPI_PDC_C_C1_FFH (0x0100) +#define ACPI_PDC_C_C2C3_FFH (0x0200) #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT | \ @@ -23,8 +24,10 @@ #define ACPI_PDC_EST_CAPABILITY_SWSMP (A ACPI_PDC_SMP_P_SWCOORD | \ ACPI_PDC_P_FFH) -#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ - ACPI_PDC_SMP_C1PT | \ - ACPI_PDC_C_C1_HALT) +#define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ + ACPI_PDC_SMP_C1PT | \ + ACPI_PDC_C_C1_HALT | \ + ACPI_PDC_C_C1_FFH | \ + ACPI_PDC_C_C2C3_FFH) #endif /* __PDC_INTEL_H__ */ diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 9dd5b75..7798d2a 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -29,6 +29,9 @@ #define DOMAIN_COORD_TYPE_SW_ALL 0xfc #define DOMAIN_COORD_TYPE_SW_ANY 0xfd #define DOMAIN_COORD_TYPE_HW_ALL 0xfe +#define ACPI_CSTATE_SYSTEMIO (0) +#define ACPI_CSTATE_FFH (1) + /* Power Management */ struct acpi_processor_cx; @@ -58,6 +61,8 @@ struct acpi_processor_cx { u8 valid; u8 type; u32 address; + u8 space_id; + u8 index; u32 latency; u32 latency_ticks; u32 power; @@ -206,6 +211,9 @@ void arch_acpi_processor_init_pdc(struct #ifdef ARCH_HAS_POWER_INIT void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags, unsigned int cpu); +int acpi_processor_ffh_cstate_probe(unsigned int cpu, + struct acpi_processor_cx *cx, struct acpi_power_register *reg); +void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cstate); #else static inline void acpi_processor_power_init_bm_check(struct acpi_processor_flags @@ -214,6 +222,16 @@ static inline void acpi_processor_power_ flags->bm_check = 1; return; } +static inline int acpi_processor_ffh_cstate_probe(unsigned int cpu, + struct acpi_processor_cx *cx, struct acpi_power_register *reg) +{ + return -1; +} +static inline void acpi_processor_ffh_cstate_enter( + struct acpi_processor_cx *cstate) +{ + return; +} #endif /* in processor_perflib.c */ diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 2277127..e0ddca9 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -306,6 +306,8 @@ static inline void __mwait(unsigned long : :"a" (eax), "c" (ecx)); } +extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); + /* from system description table in BIOS. Mostly for MCA use, but others may find it useful. */ extern unsigned int machine_id; diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index de9c314..cef17e0 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 : :"a" (eax), "c" (ecx)); } +extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); + #define stack_current() \ ({ \ struct thread_info *ti; \ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 88b5dfd..2b0c955 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -494,6 +494,9 @@ #ifdef CONFIG_ACPI_EC extern int ec_read(u8 addr, u8 *val); extern int ec_write(u8 addr, u8 val); +extern int ec_transaction(u8 command, + const u8 *wdata, unsigned wdata_len, + u8 *rdata, unsigned rdata_len); #endif /*CONFIG_ACPI_EC*/