From 33f6f92bedcf7aa2c96e7b219cfe77369573a178 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 14 Jun 2007 17:43:07 +0800 Subject: [PATCH] --- yaml --- r: 62581 b: refs/heads/master c: d4c5f047ae2a33296774e41abc2ac5c89283f736 h: refs/heads/master i: 62579: ee6859b4c0b9d7bc0fa3e772fafc09337a82e7b7 v: v3 --- [refs] | 2 +- .../feature-removal-schedule.txt | 21 +- trunk/Documentation/thinkpad-acpi.txt | 353 ++------- trunk/MAINTAINERS | 6 +- trunk/arch/i386/kernel/acpi/boot.c | 8 + .../i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 4 +- trunk/drivers/acpi/Kconfig | 23 +- trunk/drivers/acpi/battery.c | 673 ++++++------------ trunk/drivers/acpi/bay.c | 19 +- trunk/drivers/acpi/bus.c | 4 - trunk/drivers/acpi/dock.c | 127 +--- trunk/drivers/acpi/ec.c | 247 +++---- trunk/drivers/acpi/event.c | 153 +--- trunk/drivers/acpi/events/evgpeblk.c | 4 - trunk/drivers/acpi/events/evrgnini.c | 1 - trunk/drivers/acpi/glue.c | 2 +- trunk/drivers/acpi/osl.c | 40 +- trunk/drivers/acpi/pci_link.c | 2 +- trunk/drivers/acpi/processor_core.c | 6 - trunk/drivers/acpi/processor_idle.c | 20 +- trunk/drivers/acpi/processor_throttling.c | 410 +---------- trunk/drivers/acpi/sbs.c | 33 +- trunk/drivers/acpi/sleep/main.c | 5 + trunk/drivers/acpi/system.c | 165 ++++- trunk/drivers/acpi/tables/tbfadt.c | 44 +- trunk/drivers/acpi/utilities/uteval.c | 17 +- trunk/drivers/acpi/video.c | 120 +--- trunk/drivers/misc/Kconfig | 14 - trunk/drivers/misc/sony-laptop.c | 368 ++-------- trunk/drivers/misc/thinkpad_acpi.c | 602 ++-------------- trunk/drivers/misc/thinkpad_acpi.h | 42 +- trunk/drivers/video/Kconfig | 7 - trunk/drivers/video/Makefile | 3 - trunk/include/acpi/acmacros.h | 63 +- trunk/include/acpi/acoutput.h | 4 +- trunk/include/acpi/acpi_bus.h | 3 +- trunk/include/acpi/platform/acenv.h | 2 +- trunk/include/acpi/platform/aclinux.h | 3 - trunk/include/acpi/processor.h | 47 +- trunk/include/linux/pci_ids.h | 2 - 40 files changed, 973 insertions(+), 2696 deletions(-) diff --git a/[refs] b/[refs] index 35752e86dd75..56ca854ef655 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0d090b6819e3559dabb05773c4a6dacc4fa94d0e +refs/heads/master: d4c5f047ae2a33296774e41abc2ac5c89283f736 diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index c175eedadb5f..a5cb7839a679 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -180,11 +180,24 @@ Who: Adrian Bunk --------------------------- +What: /sys/firmware/acpi/namespace +When: 2.6.21 +Why: The ACPI namespace is effectively the symbol list for + the BIOS. The device names are completely arbitrary + and have no place being exposed to user-space. + + For those interested in the BIOS ACPI namespace, + the BIOS can be extracted and disassembled with acpidump + and iasl as documented in the pmtools package here: + http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/utils +Who: Len Brown + +--------------------------- + What: ACPI procfs interface -When: July 2008 -Why: ACPI sysfs conversion should be finished by January 2008. - ACPI procfs interface will be removed in July 2008 so that - there is enough time for the user space to catch up. +When: July 2007 +Why: After ACPI sysfs conversion, ACPI attributes will be duplicated + in sysfs and the ACPI procfs interface should be removed. Who: Zhang Rui --------------------------- diff --git a/trunk/Documentation/thinkpad-acpi.txt b/trunk/Documentation/thinkpad-acpi.txt index 6711fbcf4080..9e6b94face4b 100644 --- a/trunk/Documentation/thinkpad-acpi.txt +++ b/trunk/Documentation/thinkpad-acpi.txt @@ -1,11 +1,11 @@ ThinkPad ACPI Extras Driver - Version 0.15 - July 1st, 2007 + Version 0.14 + April 21st, 2007 Borislav Deianov - Henrique de Moraes Holschuh - http://ibm-acpi.sf.net/ + Henrique de Moraes Holschuh + http://ibm-acpi.sf.net/ This is a Linux driver for the IBM and Lenovo ThinkPad laptops. It @@ -134,68 +134,54 @@ end of this document. Changes to the sysfs interface done by the kernel subsystems are not documented here, nor are they tracked by this attribute. -Changes to the thinkpad-acpi sysfs interface are only considered -non-experimental when they are submitted to Linux mainline, at which -point the changes in this interface are documented and interface_version -may be updated. If you are using any thinkpad-acpi features not yet -sent to mainline for merging, you do so on your own risk: these features -may disappear, or be implemented in a different and incompatible way by -the time they are merged in Linux mainline. - -Changes that are backwards-compatible by nature (e.g. the addition of -attributes that do not change the way the other attributes work) do not -always warrant an update of interface_version. Therefore, one must -expect that an attribute might not be there, and deal with it properly -(an attribute not being there *is* a valid way to make it clear that a -feature is not available in sysfs). - Hot keys -------- procfs: /proc/acpi/ibm/hotkey sysfs device attribute: hotkey_* -In a ThinkPad, the ACPI HKEY handler is responsible for comunicating -some important events and also keyboard hot key presses to the operating -system. Enabling the hotkey functionality of thinkpad-acpi signals the -firmware that such a driver is present, and modifies how the ThinkPad -firmware will behave in many situations. - -When the hotkey feature is enabled and the hot key mask is set (see -below), the various hot keys either generate ACPI events in the +Without this driver, only the Fn-F4 key (sleep button) generates an +ACPI event. With the driver loaded, the hotkey feature enabled and the +mask set (see below), the various hot keys generate ACPI events in the following format: ibm/hotkey HKEY 00000080 0000xxxx -or events over the input layer. The input layer support accepts the -standard IOCTLs to remap the keycodes assigned to each hotkey. - -When the input device is open, the driver will suppress any ACPI hot key -events that get translated into a meaningful input layer event, in order -to avoid sending duplicate events to userspace. Hot keys that are -mapped to KEY_RESERVED in the keymap are not translated, and will always -generate an ACPI ibm/hotkey HKEY event, and no input layer events. - -The hot key bit mask allows some control over which hot keys generate -events. If a key is "masked" (bit set to 0 in the mask), the firmware -will handle it. If it is "unmasked", it signals the firmware that -thinkpad-acpi would prefer to handle it, if the firmware would be so -kind to allow it (and it often doesn't!). - -Not all bits in the mask can be modified. Not all bits that can be -modified do anything. Not all hot keys can be individually controlled -by the mask. Some models do not support the mask at all, and in those -models, hot keys cannot be controlled individually. The behaviour of -the mask is, therefore, higly dependent on the ThinkPad model. - -Note that unmasking some keys prevents their default behavior. For -example, if Fn+F5 is unmasked, that key will no longer enable/disable -Bluetooth by itself. - -Note also that not all Fn key combinations are supported through ACPI. -For example, on the X40, the brightness, volume and "Access IBM" buttons -do not generate ACPI events even with this driver. They *can* be used -through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/ +The last four digits vary depending on the key combination pressed. +All labeled Fn-Fx key combinations generate distinct events. In +addition, the lid microswitch and some docking station buttons may +also generate such events. + +The bit mask allows some control over which hot keys generate ACPI +events. Not all bits in the mask can be modified. Not all bits that +can be modified do anything. Not all hot keys can be individually +controlled by the mask. Most recent ThinkPad models honor the +following bits (assuming the hot keys feature has been enabled): + + key bit behavior when set behavior when unset + + Fn-F3 always generates ACPI event + Fn-F4 always generates ACPI event + Fn-F5 0010 generate ACPI event enable/disable Bluetooth + Fn-F7 0040 generate ACPI event switch LCD and external display + Fn-F8 0080 generate ACPI event expand screen or none + Fn-F9 0100 generate ACPI event none + Fn-F12 always generates ACPI event + +Some models do not support all of the above. For example, the T30 does +not support Fn-F5 and Fn-F9. Other models do not support the mask at +all. On those models, hot keys cannot be controlled individually. + +Note that enabling ACPI events for some keys prevents their default +behavior. For example, if events for Fn-F5 are enabled, that key will +no longer enable/disable Bluetooth by itself. This can still be done +from an acpid handler for the ibm/hotkey event. + +Note also that not all Fn key combinations are supported through +ACPI. For example, on the X40, the brightness, volume and "Access IBM" +buttons do not generate ACPI events even with this driver. They *can* +be used through the "ThinkPad Buttons" utility, see +http://www.nongnu.org/tpb/ procfs notes: @@ -203,9 +189,9 @@ The following commands can be written to the /proc/acpi/ibm/hotkey file: echo enable > /proc/acpi/ibm/hotkey -- enable the hot keys feature echo disable > /proc/acpi/ibm/hotkey -- disable the hot keys feature - echo 0xffffffff > /proc/acpi/ibm/hotkey -- enable all hot keys - echo 0 > /proc/acpi/ibm/hotkey -- disable all possible hot keys - ... any other 8-hex-digit mask ... + echo 0xffff > /proc/acpi/ibm/hotkey -- enable all possible hot keys + echo 0x0000 > /proc/acpi/ibm/hotkey -- disable all possible hot keys + ... any other 4-hex-digit mask ... echo reset > /proc/acpi/ibm/hotkey -- restore the original mask sysfs notes: @@ -216,7 +202,7 @@ sysfs notes: key feature status will be restored to this value. 0: hot keys were disabled - 1: hot keys were enabled (unusual) + 1: hot keys were enabled hotkey_bios_mask: Returns the hot keys mask when thinkpad-acpi was loaded. @@ -231,182 +217,9 @@ sysfs notes: 1: enables the hot keys feature / feature enabled hotkey_mask: - bit mask to enable driver-handling and ACPI event - generation for each hot key (see above). Returns the - current status of the hot keys mask, and allows one to - modify it. - - hotkey_all_mask: - bit mask that should enable event reporting for all - supported hot keys, when echoed to hotkey_mask above. - Unless you know which events need to be handled - passively (because the firmware *will* handle them - anyway), do *not* use hotkey_all_mask. Use - hotkey_recommended_mask, instead. You have been warned. - - hotkey_recommended_mask: - bit mask that should enable event reporting for all - supported hot keys, except those which are always - handled by the firmware anyway. Echo it to - hotkey_mask above, to use. - - hotkey_radio_sw: - if the ThinkPad has a hardware radio switch, this - attribute will read 0 if the switch is in the "radios - disabled" postition, and 1 if the switch is in the - "radios enabled" position. - -input layer notes: - -A Hot key is mapped to a single input layer EV_KEY event, possibly -followed by an EV_MSC MSC_SCAN event that shall contain that key's scan -code. An EV_SYN event will always be generated to mark the end of the -event block. - -Do not use the EV_MSC MSC_SCAN events to process keys. They are to be -used as a helper to remap keys, only. They are particularly useful when -remapping KEY_UNKNOWN keys. - -The events are available in an input device, with the following id: - - Bus: BUS_HOST - vendor: 0x1014 (PCI_VENDOR_ID_IBM) or - 0x17aa (PCI_VENDOR_ID_LENOVO) - product: 0x5054 ("TP") - version: 0x4101 - -The version will have its LSB incremented if the keymap changes in a -backwards-compatible way. The MSB shall always be 0x41 for this input -device. If the MSB is not 0x41, do not use the device as described in -this section, as it is either something else (e.g. another input device -exported by a thinkpad driver, such as HDAPS) or its functionality has -been changed in a non-backwards compatible way. - -Adding other event types for other functionalities shall be considered a -backwards-compatible change for this input device. - -Thinkpad-acpi Hot Key event map (version 0x4101): - -ACPI Scan -event code Key Notes - -0x1001 0x00 FN+F1 - -0x1002 0x01 FN+F2 IBM: battery (rare) - Lenovo: Screen lock - -0x1003 0x02 FN+F3 Many IBM models always report - this hot key, even with hot keys - disabled or with Fn+F3 masked - off - IBM: screen lock - Lenovo: battery - -0x1004 0x03 FN+F4 Sleep button (ACPI sleep button - semanthics, i.e. sleep-to-RAM). - It is always generate some kind - of event, either the hot key - event or a ACPI sleep button - event. The firmware may - refuse to generate further FN+F4 - key presses until a S3 or S4 ACPI - sleep cycle is performed or some - time passes. - -0x1005 0x04 FN+F5 Radio. Enables/disables - the internal BlueTooth hardware - and W-WAN card if left in control - of the firmware. Does not affect - the WLAN card. - Should be used to turn on/off all - radios (bluetooth+W-WAN+WLAN), - really. - -0x1006 0x05 FN+F6 - - -0x1007 0x06 FN+F7 Video output cycle. - Do you feel lucky today? - -0x1008 0x07 FN+F8 IBM: toggle screen expand - Lenovo: configure ultranav - -0x1009 0x08 FN+F9 - - .. .. .. -0x100B 0x0A FN+F11 - - -0x100C 0x0B FN+F12 Sleep to disk. You are always - supposed to handle it yourself, - either through the ACPI event, - or through a hotkey event. - The firmware may refuse to - generate further FN+F4 key - press events until a S3 or S4 - ACPI sleep cycle is performed, - or some time passes. - -0x100D 0x0C FN+BACKSPACE - -0x100E 0x0D FN+INSERT - -0x100F 0x0E FN+DELETE - - -0x1010 0x0F FN+HOME Brightness up. This key is - always handled by the firmware - in IBM ThinkPads, even when - unmasked. Just leave it alone. - For Lenovo ThinkPads with a new - BIOS, it has to be handled either - by the ACPI OSI, or by userspace. -0x1011 0x10 FN+END Brightness down. See brightness - up for details. - -0x1012 0x11 FN+PGUP Thinklight toggle. This key is - always handled by the firmware, - even when unmasked. - -0x1013 0x12 FN+PGDOWN - - -0x1014 0x13 FN+SPACE Zoom key - -0x1015 0x14 VOLUME UP Internal mixer volume up. This - key is always handled by the - firmware, even when unmasked. - NOTE: Lenovo seems to be changing - this. -0x1016 0x15 VOLUME DOWN Internal mixer volume up. This - key is always handled by the - firmware, even when unmasked. - NOTE: Lenovo seems to be changing - this. -0x1017 0x16 MUTE Mute internal mixer. This - key is always handled by the - firmware, even when unmasked. - -0x1018 0x17 THINKPAD Thinkpad/Access IBM/Lenovo key - -0x1019 0x18 unknown -.. .. .. -0x1020 0x1F unknown - -The ThinkPad firmware does not allow one to differentiate when most hot -keys are pressed or released (either that, or we don't know how to, yet). -For these keys, the driver generates a set of events for a key press and -immediately issues the same set of events for a key release. It is -unknown by the driver if the ThinkPad firmware triggered these events on -hot key press or release, but the firmware will do it for either one, not -both. - -If a key is mapped to KEY_RESERVED, it generates no input events at all, -and it may generate a legacy thinkpad-acpi ACPI hotkey event. - -If a key is mapped to KEY_UNKNOWN, it generates an input event that -includes an scan code, and it may also generate a legacy thinkpad-acpi -ACPI hotkey event. - -If a key is mapped to anything else, it will only generate legacy -thinkpad-acpi ACPI hotkey events if nobody has opened the input device. - -Non hot-key ACPI HKEY event map: -0x5001 Lid closed -0x5002 Lid opened -0x7000 Radio Switch may have changed state + bit mask to enable ACPI event generation for each hot + key (see above). Returns the current status of the hot + keys mask, and allows one to modify it. Bluetooth @@ -624,34 +437,27 @@ CMOS control procfs: /proc/acpi/ibm/cmos sysfs device attribute: cmos_command -This feature is mostly used internally by the ACPI firmware to keep the legacy -CMOS NVRAM bits in sync with the current machine state, and to record this -state so that the ThinkPad will retain such settings across reboots. - -Some of these commands actually perform actions in some ThinkPad models, but -this is expected to disappear more and more in newer models. As an example, in -a T43 and in a X40, commands 12 and 13 still control the ThinkLight state for -real, but commands 0 to 2 don't control the mixer anymore (they have been -phased out) and just update the NVRAM. +This feature is used internally by the ACPI firmware to control the +ThinkLight on most newer ThinkPad models. It may also control LCD +brightness, sounds volume and more, but only on some models. The range of valid cmos command numbers is 0 to 21, but not all have an effect and the behavior varies from model to model. Here is the behavior on the X40 (tpb is the ThinkPad Buttons utility): - 0 - Related to "Volume down" key press - 1 - Related to "Volume up" key press - 2 - Related to "Mute on" key press - 3 - Related to "Access IBM" key press - 4 - Related to "LCD brightness up" key pess - 5 - Related to "LCD brightness down" key press - 11 - Related to "toggle screen expansion" key press/function - 12 - Related to "ThinkLight on" - 13 - Related to "ThinkLight off" - 14 - Related to "ThinkLight" key press (toggle thinklight) + 0 - no effect but tpb reports "Volume down" + 1 - no effect but tpb reports "Volume up" + 2 - no effect but tpb reports "Mute on" + 3 - simulate pressing the "Access IBM" button + 4 - LCD brightness up + 5 - LCD brightness down + 11 - toggle screen expansion + 12 - ThinkLight on + 13 - ThinkLight off + 14 - no effect but tpb reports ThinkLight status change The cmos command interface is prone to firmware split-brain problems, as -in newer ThinkPads it is just a compatibility layer. Do not use it, it is -exported just as a debug tool. +in newer ThinkPads it is just a compatibility layer. LED control -- /proc/acpi/ibm/led --------------------------------- @@ -710,15 +516,23 @@ Temperature sensors procfs: /proc/acpi/ibm/thermal sysfs device attributes: (hwmon) temp*_input -Most ThinkPads include six or more separate temperature sensors but only -expose the CPU temperature through the standard ACPI methods. This -feature shows readings from up to eight different sensors on older -ThinkPads, and up to sixteen different sensors on newer ThinkPads. +Most ThinkPads include six or more separate temperature sensors but +only expose the CPU temperature through the standard ACPI methods. +This feature shows readings from up to eight different sensors on older +ThinkPads, and it has experimental support for up to sixteen different +sensors on newer ThinkPads. + +EXPERIMENTAL: The 16-sensors 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. When EXPERIMENTAL +mode is enabled, reading the first 8 sensors on newer ThinkPads will +also use an new experimental thermal sensor access mode. For example, on the X40, a typical output may be: temperatures: 42 42 45 41 36 -128 33 -128 -On the T43/p, a typical output may be: +EXPERIMENTAL: On the T43/p, a typical output may be: temperatures: 48 48 36 52 38 -128 31 -128 48 52 48 -128 -128 -128 -128 -128 The mapping of thermal sensors to physical locations varies depending on @@ -748,8 +562,7 @@ http://thinkwiki.org/wiki/Thermal_Sensors#ThinkPad_T43.2C_T43p 2: System board, left side (near PCMCIA slot), reported as HDAPS temp 3: PCMCIA slot 9: MCH (northbridge) to DRAM Bus -10: Clock-generator, mini-pci card and ICH (southbridge), under Mini-PCI - card, under touchpad +10: ICH (southbridge), under Mini-PCI card, under touchpad 11: Power regulator, underside of system board, below F2 key The A31 has a very atypical layout for the thermal sensors @@ -868,12 +681,6 @@ cannot be controlled. The backlight control has eight levels, ranging from 0 to 7. Some of the levels may not be distinct. -There are two interfaces to the firmware for brightness control, EC and CMOS. -To select which one should be used, use the brightness_mode module parameter: -brightness_mode=1 selects EC mode, brightness_mode=2 selects CMOS mode, -brightness_mode=3 selects both EC and CMOS. The driver tries to autodetect -which interface to use. - Procfs notes: The available commands are: @@ -1169,9 +976,3 @@ Sysfs interface changelog: 0x000100: Initial sysfs support, as a single platform driver and device. -0x000200: Hot key support for 32 hot keys, and radio slider switch - support. -0x010000: Hot keys are now handled by default over the input - layer, the radio switch generates input event EV_RADIO, - and the driver enables hot key handling by default in - the firmware. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index a9b9ef614ae7..773c732b4177 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -225,15 +225,15 @@ T: git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git S: Supported ACPI BATTERY DRIVERS -P: Alexey Starikovskiy -M: astarikovskiy@suse.de +P: Vladimir P. Lebedev +M: vladimir.p.lebedev@intel.com L: linux-acpi@vger.kernel.org W: http://acpi.sourceforge.net/ S: Supported ACPI EC DRIVER P: Alexey Starikovskiy -M: astarikovskiy@suse.de +M: alexey.y.starikovskiy@linux.intel.com L: linux-acpi@vger.kernel.org W: http://acpi.sourceforge.net/ S: Supported diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index cacdd883bf2b..b87cedeaf59b 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -984,6 +984,14 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"), }, }, + { + .callback = force_acpi_ht, + .ident = "DELL GX240", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"), + }, + }, { .callback = force_acpi_ht, .ident = "HP VISUALIZE NT Workstation", diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 6f846bee2103..18c8b67ea3a7 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -665,8 +665,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ for (i=0; istate_count; i++) { - if (i>0 && perf->states[i].core_frequency >= - data->freq_table[valid_states-1].frequency / 1000) + if (i>0 && perf->states[i].core_frequency == + perf->states[i-1].core_frequency) continue; data->freq_table[valid_states].index = i; diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 408b45168aba..139f41f033d8 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -2,12 +2,16 @@ # ACPI Configuration # -menuconfig ACPI - bool "ACPI Support (Advanced Configuration and Power Interface) Support" +menu "ACPI (Advanced Configuration and Power Interface) Support" depends on !X86_NUMAQ depends on !X86_VISWS depends on !IA64_HP_SIM depends on IA64 || X86 + depends on PM + +config ACPI + bool "ACPI Support" + depends on IA64 || X86 depends on PCI depends on PM select PNP @@ -45,6 +49,7 @@ if ACPI config ACPI_SLEEP bool "Sleep States" depends on X86 && (!SMP || SUSPEND_SMP) + depends on PM default y ---help--- This option adds support for ACPI suspend states. @@ -77,6 +82,7 @@ config ACPI_SLEEP_PROC_SLEEP config ACPI_PROCFS bool "Procfs interface (deprecated)" + depends on ACPI default y ---help--- The Procfs interface for ACPI is made optional for backward compatibility. @@ -118,7 +124,7 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" - depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL + depends on X86 && BACKLIGHT_CLASS_DEVICE help This driver implement the ACPI Extensions For Display Adapters for integrated graphics devices on motherboard, as specified in @@ -274,14 +280,6 @@ config ACPI_DEBUG of verbosity. Saying Y enables these statements. This will increase your kernel size by around 50K. -config ACPI_DEBUG_FUNC_TRACE - bool "Additionally enable ACPI function tracing" - default n - depends on ACPI_DEBUG - help - ACPI Debug Statements slow down ACPI processing. Function trace - is about half of the penalty and is rarely useful. - config ACPI_EC bool default y @@ -332,6 +330,7 @@ config ACPI_CONTAINER config ACPI_HOTPLUG_MEMORY tristate "Memory Hotplug" + depends on ACPI depends on MEMORY_HOTPLUG default n help @@ -360,3 +359,5 @@ config ACPI_SBS to today's ACPI "Control Method" battery. endif # ACPI + +endmenu diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index cad932de383d..e64c76c8b726 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -43,30 +43,21 @@ #define ACPI_BATTERY_CLASS "battery" #define ACPI_BATTERY_HID "PNP0C0A" #define ACPI_BATTERY_DEVICE_NAME "Battery" +#define ACPI_BATTERY_FILE_INFO "info" +#define ACPI_BATTERY_FILE_STATUS "state" +#define ACPI_BATTERY_FILE_ALARM "alarm" #define ACPI_BATTERY_NOTIFY_STATUS 0x80 #define ACPI_BATTERY_NOTIFY_INFO 0x81 #define ACPI_BATTERY_UNITS_WATTS "mW" #define ACPI_BATTERY_UNITS_AMPS "mA" #define _COMPONENT ACPI_BATTERY_COMPONENT - -#define ACPI_BATTERY_UPDATE_TIME 0 - -#define ACPI_BATTERY_NONE_UPDATE 0 -#define ACPI_BATTERY_EASY_UPDATE 1 -#define ACPI_BATTERY_INIT_UPDATE 2 - ACPI_MODULE_NAME("battery"); MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI Battery Driver"); MODULE_LICENSE("GPL"); -static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; - -/* 0 - every time, > 0 - by update_time */ -module_param(update_time, uint, 0644); - extern struct proc_dir_entry *acpi_lock_battery_dir(void); extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); @@ -85,7 +76,7 @@ static struct acpi_driver acpi_battery_driver = { }, }; -struct acpi_battery_state { +struct acpi_battery_status { acpi_integer state; acpi_integer present_rate; acpi_integer remaining_capacity; @@ -108,111 +99,33 @@ struct acpi_battery_info { acpi_string oem_info; }; -enum acpi_battery_files{ - ACPI_BATTERY_INFO = 0, - ACPI_BATTERY_STATE, - ACPI_BATTERY_ALARM, - ACPI_BATTERY_NUMFILES, +struct acpi_battery_flags { + u8 present:1; /* Bay occupied? */ + u8 power_unit:1; /* 0=watts, 1=apms */ + u8 alarm:1; /* _BTP present? */ + u8 reserved:5; }; -struct acpi_battery_flags { - u8 battery_present_prev; - u8 alarm_present; - u8 init_update; - u8 update[ACPI_BATTERY_NUMFILES]; - u8 power_unit; +struct acpi_battery_trips { + unsigned long warning; + unsigned long low; }; struct acpi_battery { - struct mutex mutex; - struct acpi_device *device; + struct acpi_device * device; struct acpi_battery_flags flags; - struct acpi_buffer bif_data; - struct acpi_buffer bst_data; + struct acpi_battery_trips trips; unsigned long alarm; - unsigned long update_time[ACPI_BATTERY_NUMFILES]; + struct acpi_battery_info *info; }; -inline int acpi_battery_present(struct acpi_battery *battery) -{ - return battery->device->status.battery_present; -} -inline char *acpi_battery_power_units(struct acpi_battery *battery) -{ - if (battery->flags.power_unit) - return ACPI_BATTERY_UNITS_AMPS; - else - return ACPI_BATTERY_UNITS_WATTS; -} - -inline acpi_handle acpi_battery_handle(struct acpi_battery *battery) -{ - return battery->device->handle; -} - /* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ -static void acpi_battery_check_result(struct acpi_battery *battery, int result) -{ - if (!battery) - return; - - if (result) { - battery->flags.init_update = 1; - } -} - -static int acpi_battery_extract_package(struct acpi_battery *battery, - union acpi_object *package, - struct acpi_buffer *format, - struct acpi_buffer *data, - char *package_name) -{ - acpi_status status = AE_OK; - struct acpi_buffer data_null = { 0, NULL }; - - status = acpi_extract_package(package, format, &data_null); - if (status != AE_BUFFER_OVERFLOW) { - ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", - package_name)); - return -ENODEV; - } - - if (data_null.length != data->length) { - kfree(data->pointer); - data->pointer = kzalloc(data_null.length, GFP_KERNEL); - if (!data->pointer) { - ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); - return -ENOMEM; - } - data->length = data_null.length; - } - - status = acpi_extract_package(package, format, data); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", - package_name)); - return -ENODEV; - } - - return 0; -} - -static int acpi_battery_get_status(struct acpi_battery *battery) -{ - int result = 0; - - result = acpi_bus_get_status(battery->device); - if (result) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); - return -ENODEV; - } - return result; -} - -static int acpi_battery_get_info(struct acpi_battery *battery) +static int +acpi_battery_get_info(struct acpi_battery *battery, + struct acpi_battery_info **bif) { int result = 0; acpi_status status = 0; @@ -220,20 +133,16 @@ static int acpi_battery_get_info(struct acpi_battery *battery) struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), ACPI_BATTERY_FORMAT_BIF }; + struct acpi_buffer data = { 0, NULL }; union acpi_object *package = NULL; - struct acpi_buffer *data = NULL; - struct acpi_battery_info *bif = NULL; - battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); - if (!acpi_battery_present(battery)) - return 0; + if (!battery || !bif) + return -EINVAL; - /* Evaluate _BIF */ + /* Evalute _BIF */ - status = - acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, - &buffer); + status = acpi_evaluate_object(battery->device->handle, "_BIF", NULL, &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); return -ENODEV; @@ -241,29 +150,41 @@ static int acpi_battery_get_info(struct acpi_battery *battery) package = buffer.pointer; - data = &battery->bif_data; - /* Extract Package Data */ - result = - acpi_battery_extract_package(battery, package, &format, data, - "_BIF"); - if (result) + status = acpi_extract_package(package, &format, &data); + if (status != AE_BUFFER_OVERFLOW) { + ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); + result = -ENODEV; goto end; + } - end: + data.pointer = kzalloc(data.length, GFP_KERNEL); + if (!data.pointer) { + result = -ENOMEM; + goto end; + } + + status = acpi_extract_package(package, &format, &data); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Extracting _BIF")); + kfree(data.pointer); + result = -ENODEV; + goto end; + } + end: kfree(buffer.pointer); - if (!result) { - bif = data->pointer; - battery->flags.power_unit = bif->power_unit; - } + if (!result) + (*bif) = data.pointer; return result; } -static int acpi_battery_get_state(struct acpi_battery *battery) +static int +acpi_battery_get_status(struct acpi_battery *battery, + struct acpi_battery_status **bst) { int result = 0; acpi_status status = 0; @@ -271,19 +192,16 @@ static int acpi_battery_get_state(struct acpi_battery *battery) struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), ACPI_BATTERY_FORMAT_BST }; + struct acpi_buffer data = { 0, NULL }; union acpi_object *package = NULL; - struct acpi_buffer *data = NULL; - battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); - if (!acpi_battery_present(battery)) - return 0; + if (!battery || !bst) + return -EINVAL; - /* Evaluate _BST */ + /* Evalute _BST */ - status = - acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, - &buffer); + status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); return -ENODEV; @@ -291,49 +209,55 @@ static int acpi_battery_get_state(struct acpi_battery *battery) package = buffer.pointer; - data = &battery->bst_data; - /* Extract Package Data */ - result = - acpi_battery_extract_package(battery, package, &format, data, - "_BST"); - if (result) + status = acpi_extract_package(package, &format, &data); + if (status != AE_BUFFER_OVERFLOW) { + ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); + result = -ENODEV; + goto end; + } + + data.pointer = kzalloc(data.length, GFP_KERNEL); + if (!data.pointer) { + result = -ENOMEM; + goto end; + } + + status = acpi_extract_package(package, &format, &data); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST")); + kfree(data.pointer); + result = -ENODEV; goto end; + } end: kfree(buffer.pointer); - return result; -} - -static int acpi_battery_get_alarm(struct acpi_battery *battery) -{ - battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); + if (!result) + (*bst) = data.pointer; - return 0; + return result; } -static int acpi_battery_set_alarm(struct acpi_battery *battery, - unsigned long alarm) +static int +acpi_battery_set_alarm(struct acpi_battery *battery, unsigned long alarm) { acpi_status status = 0; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list arg_list = { 1, &arg0 }; - battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); - if (!acpi_battery_present(battery)) - return -ENODEV; + if (!battery) + return -EINVAL; - if (!battery->flags.alarm_present) + if (!battery->flags.alarm) return -ENODEV; arg0.integer.value = alarm; - status = - acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", - &arg_list, NULL); + status = acpi_evaluate_object(battery->device->handle, "_BTP", &arg_list, NULL); if (ACPI_FAILURE(status)) return -ENODEV; @@ -344,114 +268,65 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, return 0; } -static int acpi_battery_init_alarm(struct acpi_battery *battery) +static int acpi_battery_check(struct acpi_battery *battery) { int result = 0; acpi_status status = AE_OK; acpi_handle handle = NULL; - struct acpi_battery_info *bif = battery->bif_data.pointer; - unsigned long alarm = battery->alarm; - - /* See if alarms are supported, and if so, set default */ - - status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); - if (ACPI_SUCCESS(status)) { - battery->flags.alarm_present = 1; - if (!alarm && bif) { - alarm = bif->design_capacity_warning; - } - result = acpi_battery_set_alarm(battery, alarm); - if (result) - goto end; - } else { - battery->flags.alarm_present = 0; - } + struct acpi_device *device = NULL; + struct acpi_battery_info *bif = NULL; - end: - return result; -} + if (!battery) + return -EINVAL; -static int acpi_battery_init_update(struct acpi_battery *battery) -{ - int result = 0; + device = battery->device; - result = acpi_battery_get_status(battery); + result = acpi_bus_get_status(device); if (result) return result; - battery->flags.battery_present_prev = acpi_battery_present(battery); + /* Insertion? */ - if (acpi_battery_present(battery)) { - result = acpi_battery_get_info(battery); - if (result) - return result; - result = acpi_battery_get_state(battery); - if (result) - return result; + if (!battery->flags.present && device->status.battery_present) { - acpi_battery_init_alarm(battery); - } + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery inserted\n")); - return result; -} + /* Evalute _BIF to get certain static information */ -static int acpi_battery_update(struct acpi_battery *battery, - int update, int *update_result_ptr) -{ - int result = 0; - int update_result = ACPI_BATTERY_NONE_UPDATE; + result = acpi_battery_get_info(battery, &bif); + if (result) + return result; - if (!acpi_battery_present(battery)) { - update = 1; - } + battery->flags.power_unit = bif->power_unit; + battery->trips.warning = bif->design_capacity_warning; + battery->trips.low = bif->design_capacity_low; + kfree(bif); - if (battery->flags.init_update) { - result = acpi_battery_init_update(battery); - if (result) - goto end; - update_result = ACPI_BATTERY_INIT_UPDATE; - } else if (update) { - result = acpi_battery_get_status(battery); - if (result) - goto end; - if ((!battery->flags.battery_present_prev & acpi_battery_present(battery)) - || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) { - result = acpi_battery_init_update(battery); - if (result) - goto end; - update_result = ACPI_BATTERY_INIT_UPDATE; - } else { - update_result = ACPI_BATTERY_EASY_UPDATE; + /* See if alarms are supported, and if so, set default */ + + status = acpi_get_handle(battery->device->handle, "_BTP", &handle); + if (ACPI_SUCCESS(status)) { + battery->flags.alarm = 1; + acpi_battery_set_alarm(battery, battery->trips.warning); } } - end: + /* Removal? */ - battery->flags.init_update = (result != 0); + else if (battery->flags.present && !device->status.battery_present) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Battery removed\n")); + } - *update_result_ptr = update_result; + battery->flags.present = device->status.battery_present; return result; } -static void acpi_battery_notify_update(struct acpi_battery *battery) +static void acpi_battery_check_present(struct acpi_battery *battery) { - acpi_battery_get_status(battery); - - if (battery->flags.init_update) { - return; - } - - if ((!battery->flags.battery_present_prev & - acpi_battery_present(battery)) || - (battery->flags.battery_present_prev & - !acpi_battery_present(battery))) { - battery->flags.init_update = 1; - } else { - battery->flags.update[ACPI_BATTERY_INFO] = 1; - battery->flags.update[ACPI_BATTERY_STATE] = 1; - battery->flags.update[ACPI_BATTERY_ALARM] = 1; + if (!battery->flags.present) { + acpi_battery_check(battery); } } @@ -460,33 +335,37 @@ static void acpi_battery_notify_update(struct acpi_battery *battery) -------------------------------------------------------------------------- */ static struct proc_dir_entry *acpi_battery_dir; - -static int acpi_battery_print_info(struct seq_file *seq, int result) +static int acpi_battery_read_info(struct seq_file *seq, void *offset) { + int result = 0; struct acpi_battery *battery = seq->private; struct acpi_battery_info *bif = NULL; char *units = "?"; - if (result) + + if (!battery) goto end; - if (acpi_battery_present(battery)) + acpi_battery_check_present(battery); + + if (battery->flags.present) seq_printf(seq, "present: yes\n"); else { seq_printf(seq, "present: no\n"); goto end; } - bif = battery->bif_data.pointer; - if (!bif) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); - result = -ENODEV; + /* Battery Info (_BIF) */ + + result = acpi_battery_get_info(battery, &bif); + if (result || !bif) { + seq_printf(seq, "ERROR: Unable to read battery information\n"); goto end; } - /* Battery Units */ - - units = acpi_battery_power_units(battery); + units = + bif-> + power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "design capacity: unknown\n"); @@ -517,6 +396,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) else seq_printf(seq, "design voltage: %d mV\n", (u32) bif->design_voltage); + seq_printf(seq, "design capacity warning: %d %sh\n", (u32) bif->design_capacity_warning, units); seq_printf(seq, "design capacity low: %d %sh\n", @@ -531,39 +411,49 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) seq_printf(seq, "OEM info: %s\n", bif->oem_info); end: + kfree(bif); - if (result) - seq_printf(seq, "ERROR: Unable to read battery info\n"); + return 0; +} - return result; +static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_battery_read_info, PDE(inode)->data); } -static int acpi_battery_print_state(struct seq_file *seq, int result) +static int acpi_battery_read_state(struct seq_file *seq, void *offset) { + int result = 0; struct acpi_battery *battery = seq->private; - struct acpi_battery_state *bst = NULL; + struct acpi_battery_status *bst = NULL; char *units = "?"; - if (result) + + if (!battery) goto end; - if (acpi_battery_present(battery)) + acpi_battery_check_present(battery); + + if (battery->flags.present) seq_printf(seq, "present: yes\n"); else { seq_printf(seq, "present: no\n"); goto end; } - bst = battery->bst_data.pointer; - if (!bst) { - ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); - result = -ENODEV; - goto end; - } - /* Battery Units */ - units = acpi_battery_power_units(battery); + units = + battery->flags. + power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + /* Battery Status (_BST) */ + + result = acpi_battery_get_status(battery, &bst); + if (result || !bst) { + seq_printf(seq, "ERROR: Unable to read battery status\n"); + goto end; + } if (!(bst->state & 0x04)) seq_printf(seq, "capacity state: ok\n"); @@ -600,43 +490,48 @@ static int acpi_battery_print_state(struct seq_file *seq, int result) (u32) bst->present_voltage); end: + kfree(bst); - if (result) { - seq_printf(seq, "ERROR: Unable to read battery state\n"); - } + return 0; +} - return result; +static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_battery_read_state, PDE(inode)->data); } -static int acpi_battery_print_alarm(struct seq_file *seq, int result) +static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) { struct acpi_battery *battery = seq->private; char *units = "?"; - if (result) + + if (!battery) goto end; - if (!acpi_battery_present(battery)) { + acpi_battery_check_present(battery); + + if (!battery->flags.present) { seq_printf(seq, "present: no\n"); goto end; } /* Battery Units */ - units = acpi_battery_power_units(battery); + units = + battery->flags. + power_unit ? ACPI_BATTERY_UNITS_AMPS : ACPI_BATTERY_UNITS_WATTS; + + /* Battery Alarm */ seq_printf(seq, "alarm: "); if (!battery->alarm) seq_printf(seq, "unsupported\n"); else - seq_printf(seq, "%lu %sh\n", battery->alarm, units); + seq_printf(seq, "%d %sh\n", (u32) battery->alarm, units); end: - - if (result) - seq_printf(seq, "ERROR: Unable to read battery alarm\n"); - - return result; + return 0; } static ssize_t @@ -648,113 +543,27 @@ acpi_battery_write_alarm(struct file *file, char alarm_string[12] = { '\0' }; struct seq_file *m = file->private_data; struct acpi_battery *battery = m->private; - int update_result = ACPI_BATTERY_NONE_UPDATE; + if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; - mutex_lock(&battery->mutex); + acpi_battery_check_present(battery); - result = acpi_battery_update(battery, 1, &update_result); - if (result) { - result = -ENODEV; - goto end; - } - - if (!acpi_battery_present(battery)) { - result = -ENODEV; - goto end; - } + if (!battery->flags.present) + return -ENODEV; - if (copy_from_user(alarm_string, buffer, count)) { - result = -EFAULT; - goto end; - } + if (copy_from_user(alarm_string, buffer, count)) + return -EFAULT; alarm_string[count] = '\0'; result = acpi_battery_set_alarm(battery, simple_strtoul(alarm_string, NULL, 0)); if (result) - goto end; - - end: - - acpi_battery_check_result(battery, result); - - if (!result) - result = count; - - mutex_unlock(&battery->mutex); - - return result; -} - -typedef int(*print_func)(struct seq_file *seq, int result); -typedef int(*get_func)(struct acpi_battery *battery); - -static struct acpi_read_mux { - print_func print; - get_func get; -} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = { - {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, - {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, - {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, -}; - -static int acpi_battery_read(int fid, struct seq_file *seq) -{ - struct acpi_battery *battery = seq->private; - int result = 0; - int update_result = ACPI_BATTERY_NONE_UPDATE; - int update = 0; - - mutex_lock(&battery->mutex); - - update = (get_seconds() - battery->update_time[fid] >= update_time); - update = (update | battery->flags.update[fid]); - - result = acpi_battery_update(battery, update, &update_result); - if (result) - goto end; - - if (update_result == ACPI_BATTERY_EASY_UPDATE) { - result = acpi_read_funcs[fid].get(battery); - if (result) - goto end; - } - - end: - result = acpi_read_funcs[fid].print(seq, result); - acpi_battery_check_result(battery, result); - battery->flags.update[fid] = result; - mutex_unlock(&battery->mutex); - return result; -} - -static int acpi_battery_read_info(struct seq_file *seq, void *offset) -{ - return acpi_battery_read(ACPI_BATTERY_INFO, seq); -} - -static int acpi_battery_read_state(struct seq_file *seq, void *offset) -{ - return acpi_battery_read(ACPI_BATTERY_STATE, seq); -} - -static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) -{ - return acpi_battery_read(ACPI_BATTERY_ALARM, seq); -} - -static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_battery_read_info, PDE(inode)->data); -} + return result; -static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_battery_read_state, PDE(inode)->data); + return count; } static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) @@ -762,51 +571,35 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); } -static struct battery_file { - struct file_operations ops; - mode_t mode; - char *name; -} acpi_battery_file[] = { - { - .name = "info", - .mode = S_IRUGO, - .ops = { +static const struct file_operations acpi_battery_info_ops = { .open = acpi_battery_info_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, .owner = THIS_MODULE, - }, - }, - { - .name = "state", - .mode = S_IRUGO, - .ops = { +}; + +static const struct file_operations acpi_battery_state_ops = { .open = acpi_battery_state_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, .owner = THIS_MODULE, - }, - }, - { - .name = "alarm", - .mode = S_IFREG | S_IRUGO | S_IWUSR, - .ops = { +}; + +static const struct file_operations acpi_battery_alarm_ops = { .open = acpi_battery_alarm_open_fs, .read = seq_read, .write = acpi_battery_write_alarm, .llseek = seq_lseek, .release = single_release, .owner = THIS_MODULE, - }, - }, }; static int acpi_battery_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; - int i; + if (!acpi_device_dir(device)) { acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), @@ -816,16 +609,38 @@ static int acpi_battery_add_fs(struct acpi_device *device) acpi_device_dir(device)->owner = THIS_MODULE; } - for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { - entry = create_proc_entry(acpi_battery_file[i].name, - acpi_battery_file[i].mode, acpi_device_dir(device)); - if (!entry) - return -ENODEV; - else { - entry->proc_fops = &acpi_battery_file[i].ops; - entry->data = acpi_driver_data(device); - entry->owner = THIS_MODULE; - } + /* 'info' [R] */ + entry = create_proc_entry(ACPI_BATTERY_FILE_INFO, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + return -ENODEV; + else { + entry->proc_fops = &acpi_battery_info_ops; + entry->data = acpi_driver_data(device); + entry->owner = THIS_MODULE; + } + + /* 'status' [R] */ + entry = create_proc_entry(ACPI_BATTERY_FILE_STATUS, + S_IRUGO, acpi_device_dir(device)); + if (!entry) + return -ENODEV; + else { + entry->proc_fops = &acpi_battery_state_ops; + entry->data = acpi_driver_data(device); + entry->owner = THIS_MODULE; + } + + /* 'alarm' [R/W] */ + entry = create_proc_entry(ACPI_BATTERY_FILE_ALARM, + S_IFREG | S_IRUGO | S_IWUSR, + acpi_device_dir(device)); + if (!entry) + return -ENODEV; + else { + entry->proc_fops = &acpi_battery_alarm_ops; + entry->data = acpi_driver_data(device); + entry->owner = THIS_MODULE; } return 0; @@ -833,12 +648,15 @@ static int acpi_battery_add_fs(struct acpi_device *device) static int acpi_battery_remove_fs(struct acpi_device *device) { - int i; + if (acpi_device_dir(device)) { - for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { - remove_proc_entry(acpi_battery_file[i].name, + remove_proc_entry(ACPI_BATTERY_FILE_ALARM, acpi_device_dir(device)); - } + remove_proc_entry(ACPI_BATTERY_FILE_STATUS, + acpi_device_dir(device)); + remove_proc_entry(ACPI_BATTERY_FILE_INFO, + acpi_device_dir(device)); + remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); acpi_device_dir(device) = NULL; } @@ -855,6 +673,7 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) struct acpi_battery *battery = data; struct acpi_device *device = NULL; + if (!battery) return; @@ -865,10 +684,8 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) case ACPI_BATTERY_NOTIFY_INFO: case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: - device = battery->device; - acpi_battery_notify_update(battery); - acpi_bus_generate_event(device, event, - acpi_battery_present(battery)); + acpi_battery_check(battery); + acpi_bus_generate_event(device, event, battery->flags.present); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -885,6 +702,7 @@ static int acpi_battery_add(struct acpi_device *device) acpi_status status = 0; struct acpi_battery *battery = NULL; + if (!device) return -EINVAL; @@ -892,21 +710,15 @@ static int acpi_battery_add(struct acpi_device *device) if (!battery) return -ENOMEM; - mutex_init(&battery->mutex); - - mutex_lock(&battery->mutex); - battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); acpi_driver_data(device) = battery; - result = acpi_battery_get_status(battery); + result = acpi_battery_check(battery); if (result) goto end; - battery->flags.init_update = 1; - result = acpi_battery_add_fs(device); if (result) goto end; @@ -915,7 +727,6 @@ static int acpi_battery_add(struct acpi_device *device) ACPI_ALL_NOTIFY, acpi_battery_notify, battery); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); result = -ENODEV; goto end; } @@ -925,14 +736,11 @@ static int acpi_battery_add(struct acpi_device *device) device->status.battery_present ? "present" : "absent"); end: - if (result) { acpi_battery_remove_fs(device); kfree(battery); } - mutex_unlock(&battery->mutex); - return result; } @@ -941,27 +749,18 @@ static int acpi_battery_remove(struct acpi_device *device, int type) acpi_status status = 0; struct acpi_battery *battery = NULL; + if (!device || !acpi_driver_data(device)) return -EINVAL; battery = acpi_driver_data(device); - mutex_lock(&battery->mutex); - status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); acpi_battery_remove_fs(device); - kfree(battery->bif_data.pointer); - - kfree(battery->bst_data.pointer); - - mutex_unlock(&battery->mutex); - - mutex_destroy(&battery->mutex); - kfree(battery); return 0; @@ -976,10 +775,7 @@ static int acpi_battery_resume(struct acpi_device *device) return -EINVAL; battery = device->driver_data; - - battery->flags.init_update = 1; - - return 0; + return acpi_battery_check(battery); } static int __init acpi_battery_init(void) @@ -1004,6 +800,7 @@ static int __init acpi_battery_init(void) static void __exit acpi_battery_exit(void) { + acpi_bus_unregister_driver(&acpi_battery_driver); acpi_unlock_battery_dir(acpi_battery_dir); diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c index 56a5b3fffeb3..fb3f31b5e69f 100644 --- a/trunk/drivers/acpi/bay.c +++ b/trunk/drivers/acpi/bay.c @@ -288,11 +288,6 @@ static int bay_add(acpi_handle handle, int id) new_bay->pdev = pdev; platform_set_drvdata(pdev, new_bay); - /* - * we want the bay driver to be able to send uevents - */ - pdev->dev.uevent_suppress = 0; - if (acpi_bay_add_fs(new_bay)) { platform_device_unregister(new_bay->pdev); goto bay_add_err; @@ -333,12 +328,18 @@ static void bay_notify(acpi_handle handle, u32 event, void *data) { struct bay *bay_dev = (struct bay *)data; struct device *dev = &bay_dev->pdev->dev; - char event_string[12]; - char *envp[] = { event_string, NULL }; bay_dprintk(handle, "Bay event"); - sprintf(event_string, "BAY_EVENT=%d\n", event); - kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); + + switch(event) { + case ACPI_NOTIFY_BUS_CHECK: + case ACPI_NOTIFY_DEVICE_CHECK: + case ACPI_NOTIFY_EJECT_REQUEST: + kobject_uevent(&dev->kobj, KOBJ_CHANGE); + break; + default: + printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event); + } } static acpi_status diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 6b2658c96242..e5084ececb6f 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -292,10 +292,6 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) if (!device) return -EINVAL; - if (acpi_bus_generate_genetlink_event(device, type, data)) - printk(KERN_WARNING PREFIX - "Failed to generate an ACPI event via genetlink!\n"); - /* drop event on the floor if no one's listening */ if (!event_is_open) return 0; diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 6192c8be66df..4546bf873aea 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -40,15 +40,8 @@ MODULE_AUTHOR("Kristen Carlson Accardi"); MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); MODULE_LICENSE("GPL"); -static int immediate_undock = 1; -module_param(immediate_undock, bool, 0644); -MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " - "undock immediately when the undock button is pressed, 0 will cause" - " the driver to wait for userspace to write the undock sysfs file " - " before undocking"); - static struct atomic_notifier_head dock_notifier_list; -static struct platform_device *dock_device; +static struct platform_device dock_device; static char dock_device_name[] = "dock"; struct dock_station { @@ -70,7 +63,6 @@ struct dock_dependent_device { }; #define DOCK_DOCKING 0x00000001 -#define DOCK_UNDOCKING 0x00000002 #define DOCK_EVENT 3 #define UNDOCK_EVENT 2 @@ -335,20 +327,12 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event) static void dock_event(struct dock_station *ds, u32 event, int num) { - struct device *dev = &dock_device->dev; - char event_string[7]; - char *envp[] = { event_string, NULL }; - - if (num == UNDOCK_EVENT) - sprintf(event_string, "UNDOCK"); - else - sprintf(event_string, "DOCK"); - + struct device *dev = &dock_device.dev; /* * Indicate that the status of the dock station has * changed. */ - kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); + kobject_uevent(&dev->kobj, KOBJ_CHANGE); } /** @@ -396,11 +380,12 @@ static void handle_dock(struct dock_station *ds, int dock) union acpi_object arg; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); + obj = name_buffer.pointer; - printk(KERN_INFO PREFIX "%s - %s\n", - (char *)name_buffer.pointer, dock ? "docking" : "undocking"); + printk(KERN_INFO PREFIX "%s\n", dock ? "docking" : "undocking"); /* _DCK method has one argument */ arg_list.count = 1; @@ -409,8 +394,7 @@ static void handle_dock(struct dock_station *ds, int dock) arg.integer.value = dock; status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); if (ACPI_FAILURE(status)) - printk(KERN_ERR PREFIX "%s - failed to execute _DCK\n", - (char *)name_buffer.pointer); + pr_debug("%s: failed to execute _DCK\n", obj->string.pointer); kfree(buffer.pointer); kfree(name_buffer.pointer); } @@ -436,16 +420,6 @@ static inline void complete_dock(struct dock_station *ds) ds->last_dock_time = jiffies; } -static inline void begin_undock(struct dock_station *ds) -{ - ds->flags |= DOCK_UNDOCKING; -} - -static inline void complete_undock(struct dock_station *ds) -{ - ds->flags &= ~(DOCK_UNDOCKING); -} - /** * dock_in_progress - see if we are in the middle of handling a dock event * @ds: the dock station @@ -576,7 +550,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event) printk(KERN_ERR PREFIX "Unable to undock!\n"); return -EBUSY; } - complete_undock(ds); + return 0; } @@ -620,11 +594,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) * to the driver who wish to hotplug. */ case ACPI_NOTIFY_EJECT_REQUEST: - begin_undock(ds); - if (immediate_undock) - handle_eject_request(ds, event); - else - dock_event(ds, event, UNDOCK_EVENT); + handle_eject_request(ds, event); break; default: printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); @@ -682,17 +652,6 @@ static ssize_t show_docked(struct device *dev, } DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); -/* - * show_flags - read method for flags file in sysfs - */ -static ssize_t show_flags(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); - -} -DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); - /* * write_undock - write method for "undock" file in sysfs */ @@ -716,15 +675,16 @@ static ssize_t show_dock_uid(struct device *dev, struct device_attribute *attr, char *buf) { unsigned long lbuf; - acpi_status status = acpi_evaluate_integer(dock_station->handle, - "_UID", NULL, &lbuf); - if (ACPI_FAILURE(status)) + acpi_status status = acpi_evaluate_integer(dock_station->handle, "_UID", NULL, &lbuf); + if(ACPI_FAILURE(status)) { return 0; - + } return snprintf(buf, PAGE_SIZE, "%lx\n", lbuf); } DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); + + /** * dock_add - add a new dock station * @handle: the dock station handle @@ -751,53 +711,33 @@ static int dock_add(acpi_handle handle) ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); /* initialize platform device stuff */ - dock_device = - platform_device_register_simple(dock_device_name, 0, NULL, 0); - if (IS_ERR(dock_device)) { - kfree(dock_station); - dock_station = NULL; - return PTR_ERR(dock_device); - } - - /* we want the dock device to send uevents */ - dock_device->dev.uevent_suppress = 0; - - ret = device_create_file(&dock_device->dev, &dev_attr_docked); + dock_device.name = dock_device_name; + ret = platform_device_register(&dock_device); if (ret) { - printk("Error %d adding sysfs file\n", ret); - platform_device_unregister(dock_device); + printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret); kfree(dock_station); - dock_station = NULL; return ret; } - ret = device_create_file(&dock_device->dev, &dev_attr_undock); + ret = device_create_file(&dock_device.dev, &dev_attr_docked); if (ret) { printk("Error %d adding sysfs file\n", ret); - device_remove_file(&dock_device->dev, &dev_attr_docked); - platform_device_unregister(dock_device); + platform_device_unregister(&dock_device); kfree(dock_station); - dock_station = NULL; return ret; } - ret = device_create_file(&dock_device->dev, &dev_attr_uid); + ret = device_create_file(&dock_device.dev, &dev_attr_undock); if (ret) { printk("Error %d adding sysfs file\n", ret); - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - platform_device_unregister(dock_device); + device_remove_file(&dock_device.dev, &dev_attr_docked); + platform_device_unregister(&dock_device); kfree(dock_station); - dock_station = NULL; return ret; } - ret = device_create_file(&dock_device->dev, &dev_attr_flags); + ret = device_create_file(&dock_device.dev, &dev_attr_uid); if (ret) { printk("Error %d adding sysfs file\n", ret); - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - device_remove_file(&dock_device->dev, &dev_attr_uid); - platform_device_unregister(dock_device); + platform_device_unregister(&dock_device); kfree(dock_station); - dock_station = NULL; return ret; } @@ -810,7 +750,6 @@ static int dock_add(acpi_handle handle) dd = alloc_dock_dependent_device(handle); if (!dd) { kfree(dock_station); - dock_station = NULL; ret = -ENOMEM; goto dock_add_err_unregister; } @@ -834,13 +773,10 @@ static int dock_add(acpi_handle handle) dock_add_err: kfree(dd); dock_add_err_unregister: - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - device_remove_file(&dock_device->dev, &dev_attr_uid); - device_remove_file(&dock_device->dev, &dev_attr_flags); - platform_device_unregister(dock_device); + device_remove_file(&dock_device.dev, &dev_attr_docked); + device_remove_file(&dock_device.dev, &dev_attr_undock); + platform_device_unregister(&dock_device); kfree(dock_station); - dock_station = NULL; return ret; } @@ -868,15 +804,12 @@ static int dock_remove(void) printk(KERN_ERR "Error removing notify handler\n"); /* cleanup sysfs */ - device_remove_file(&dock_device->dev, &dev_attr_docked); - device_remove_file(&dock_device->dev, &dev_attr_undock); - device_remove_file(&dock_device->dev, &dev_attr_uid); - device_remove_file(&dock_device->dev, &dev_attr_flags); - platform_device_unregister(dock_device); + device_remove_file(&dock_device.dev, &dev_attr_docked); + device_remove_file(&dock_device.dev, &dev_attr_undock); + platform_device_unregister(&dock_device); /* free dock station memory */ kfree(dock_station); - dock_station = NULL; return 0; } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 10e851021eca..82f496c07675 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -34,26 +34,25 @@ #include #include #include -#include #include #include #include #include +#define _COMPONENT ACPI_EC_COMPONENT +ACPI_MODULE_NAME("ec"); +#define ACPI_EC_COMPONENT 0x00100000 #define ACPI_EC_CLASS "embedded_controller" #define ACPI_EC_HID "PNP0C09" #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" - #undef PREFIX #define PREFIX "ACPI: EC: " - /* 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 */ - /* EC commands */ enum ec_command { ACPI_EC_COMMAND_READ = 0x80, @@ -62,7 +61,6 @@ enum ec_command { ACPI_EC_BURST_DISABLE = 0x83, ACPI_EC_COMMAND_QUERY = 0x84, }; - /* EC events */ enum ec_event { ACPI_EC_EVENT_OBF_1 = 1, /* Output buffer full */ @@ -96,16 +94,6 @@ static struct acpi_driver acpi_ec_driver = { /* If we find an EC via the ECDT, we need to keep a ptr to its context */ /* External interfaces use first EC only, so remember */ -typedef int (*acpi_ec_query_func) (void *data); - -struct acpi_ec_query_handler { - struct list_head node; - acpi_ec_query_func func; - acpi_handle handle; - void *data; - u8 query_bit; -}; - static struct acpi_ec { acpi_handle handle; unsigned long gpe; @@ -116,7 +104,6 @@ static struct acpi_ec { atomic_t query_pending; atomic_t event_count; wait_queue_head_t wait; - struct list_head list; } *boot_ec, *first_ec; /* -------------------------------------------------------------------------- @@ -258,7 +245,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0); if (status) { - printk(KERN_ERR PREFIX + printk(KERN_DEBUG PREFIX "input buffer is not empty, aborting transaction\n"); goto end; } @@ -407,67 +394,21 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ -int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, - acpi_handle handle, acpi_ec_query_func func, - void *data) -{ - struct acpi_ec_query_handler *handler = - kzalloc(sizeof(struct acpi_ec_query_handler), GFP_KERNEL); - if (!handler) - return -ENOMEM; - - handler->query_bit = query_bit; - handler->handle = handle; - handler->func = func; - handler->data = data; - mutex_lock(&ec->lock); - list_add_tail(&handler->node, &ec->list); - mutex_unlock(&ec->lock); - return 0; -} - -EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); - -void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) -{ - struct acpi_ec_query_handler *handler; - mutex_lock(&ec->lock); - list_for_each_entry(handler, &ec->list, node) { - if (query_bit == handler->query_bit) { - list_del(&handler->node); - kfree(handler); - break; - } - } - mutex_unlock(&ec->lock); -} - -EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); static void acpi_ec_gpe_query(void *ec_cxt) { struct acpi_ec *ec = ec_cxt; u8 value = 0; - struct acpi_ec_query_handler *handler, copy; + char object_name[8]; if (!ec || acpi_ec_query(ec, &value)) return; - mutex_lock(&ec->lock); - list_for_each_entry(handler, &ec->list, node) { - if (value == handler->query_bit) { - /* have custom handler for this bit */ - memcpy(©, handler, sizeof(copy)); - mutex_unlock(&ec->lock); - if (copy.func) { - copy.func(copy.data); - } else if (copy.handle) { - acpi_evaluate_object(copy.handle, NULL, NULL, NULL); - } - return; - } - } - mutex_unlock(&ec->lock); - printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value); + + snprintf(object_name, 8, "_Q%2.2X", value); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s", object_name)); + + acpi_evaluate_object(ec->handle, object_name, NULL, NULL); } static u32 acpi_ec_gpe_handler(void *data) @@ -486,7 +427,8 @@ static u32 acpi_ec_gpe_handler(void *data) if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) { atomic_set(&ec->query_pending, 1); status = - acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec); + acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, + ec); } return status == AE_OK ? @@ -512,35 +454,57 @@ acpi_ec_space_setup(acpi_handle region_handle, } static acpi_status -acpi_ec_space_handler(u32 function, acpi_physical_address address, - u32 bits, acpi_integer *value, +acpi_ec_space_handler(u32 function, + acpi_physical_address address, + u32 bit_width, + acpi_integer * value, void *handler_context, void *region_context) { + int result = 0; struct acpi_ec *ec = handler_context; - int result = 0, i = 0; - u8 temp = 0; + u64 temp = *value; + acpi_integer f_v = 0; + int i = 0; if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; - if (function != ACPI_READ && function != ACPI_WRITE) + if (bit_width != 8 && acpi_strict) { return AE_BAD_PARAMETER; + } - if (bits != 8 && acpi_strict) - return AE_BAD_PARAMETER; + next_byte: + switch (function) { + case ACPI_READ: + temp = 0; + result = acpi_ec_read(ec, (u8) address, (u8 *) & temp); + break; + case ACPI_WRITE: + result = acpi_ec_write(ec, (u8) address, (u8) temp); + break; + default: + result = -EINVAL; + goto out; + break; + } - while (bits - i > 0) { - if (function == ACPI_READ) { - result = acpi_ec_read(ec, address, &temp); - (*value) |= ((acpi_integer)temp) << i; - } else { - temp = 0xff & ((*value) >> i); - result = acpi_ec_write(ec, address, temp); - } - i += 8; - ++address; + bit_width -= 8; + if (bit_width) { + if (function == ACPI_READ) + f_v |= temp << 8 * i; + if (function == ACPI_WRITE) + temp >>= 8; + i++; + address++; + goto next_byte; } + if (function == ACPI_READ) { + f_v |= temp << 8 * i; + *value = f_v; + } + + out: switch (result) { case -EINVAL: return AE_BAD_PARAMETER; @@ -633,6 +597,9 @@ static int acpi_ec_remove_fs(struct acpi_device *device) static acpi_status ec_parse_io_ports(struct acpi_resource *resource, void *context); +static acpi_status +ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval); + static struct acpi_ec *make_acpi_ec(void) { struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); @@ -643,52 +610,13 @@ static struct acpi_ec *make_acpi_ec(void) atomic_set(&ec->event_count, 1); mutex_init(&ec->lock); init_waitqueue_head(&ec->wait); - INIT_LIST_HEAD(&ec->list); return ec; } -static acpi_status -acpi_ec_register_query_methods(acpi_handle handle, u32 level, - void *context, void **return_value) -{ - struct acpi_namespace_node *node = handle; - struct acpi_ec *ec = context; - int value = 0; - if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { - acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); - } - return AE_OK; -} - -static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle) -{ - if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS, - ec_parse_io_ports, ec))) - return -EINVAL; - - /* Get GPE bit assignment (EC events). */ - /* TODO: Add support for _GPE returning a package */ - if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe))) - return -EINVAL; - - /* Use the global lock for all EC transactions? */ - acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); - - /* Find and register all query methods */ - acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, - acpi_ec_register_query_methods, ec, NULL); - - ec->handle = handle; - - printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", - ec->gpe, ec->command_addr, ec->data_addr); - - return 0; -} - static int acpi_ec_add(struct acpi_device *device) { + acpi_status status = AE_OK; struct acpi_ec *ec = NULL; if (!device) @@ -701,7 +629,8 @@ static int acpi_ec_add(struct acpi_device *device) if (!ec) return -ENOMEM; - if (ec_parse_device(ec, device->handle)) { + status = ec_parse_device(device->handle, 0, ec, NULL); + if (status != AE_CTRL_TERMINATE) { kfree(ec); return -EINVAL; } @@ -712,8 +641,6 @@ static int acpi_ec_add(struct acpi_device *device) /* We might have incorrect info for GL at boot time */ mutex_lock(&boot_ec->lock); boot_ec->global_lock = ec->global_lock; - /* Copy handlers from new ec into boot ec */ - list_splice(&ec->list, &boot_ec->list); mutex_unlock(&boot_ec->lock); kfree(ec); ec = boot_ec; @@ -724,24 +651,22 @@ static int acpi_ec_add(struct acpi_device *device) acpi_driver_data(device) = ec; acpi_ec_add_fs(device); + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s [%s] (gpe %d) interrupt mode.", + acpi_device_name(device), acpi_device_bid(device), + (u32) ec->gpe)); + return 0; } static int acpi_ec_remove(struct acpi_device *device, int type) { struct acpi_ec *ec; - struct acpi_ec_query_handler *handler; if (!device) return -EINVAL; ec = acpi_driver_data(device); - mutex_lock(&ec->lock); - list_for_each_entry(handler, &ec->list, node) { - list_del(&handler->node); - kfree(handler); - } - mutex_unlock(&ec->lock); acpi_ec_remove_fs(device); acpi_driver_data(device) = NULL; if (ec == first_ec) @@ -797,13 +722,15 @@ static int ec_install_handlers(struct acpi_ec *ec) return -ENODEV; } + /* EC is fully operational, allow queries */ + atomic_set(&ec->query_pending, 0); + return 0; } static int acpi_ec_start(struct acpi_device *device) { struct acpi_ec *ec; - int ret = 0; if (!device) return -EINVAL; @@ -813,14 +740,14 @@ static int acpi_ec_start(struct acpi_device *device) if (!ec) return -EINVAL; - /* Boot EC is already working */ - if (ec != boot_ec) - ret = ec_install_handlers(ec); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02lx, ports=0x%2lx,0x%2lx", + ec->gpe, ec->command_addr, ec->data_addr)); - /* EC is fully operational, allow queries */ - atomic_set(&ec->query_pending, 0); + /* Boot EC is already working */ + if (ec == boot_ec) + return 0; - return ret; + return ec_install_handlers(ec); } static int acpi_ec_stop(struct acpi_device *device, int type) @@ -852,6 +779,34 @@ static int acpi_ec_stop(struct acpi_device *device, int type) return 0; } +static acpi_status +ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) +{ + acpi_status status; + + struct acpi_ec *ec = context; + status = acpi_walk_resources(handle, METHOD_NAME__CRS, + ec_parse_io_ports, ec); + if (ACPI_FAILURE(status)) + return status; + + /* Get GPE bit assignment (EC events). */ + /* TODO: Add support for _GPE returning a package */ + status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); + if (ACPI_FAILURE(status)) + return status; + + /* Use the global lock for all EC transactions? */ + acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); + + ec->handle = handle; + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "GPE=0x%02lx, ports=0x%2lx, 0x%2lx", + ec->gpe, ec->command_addr, ec->data_addr)); + + return AE_CTRL_TERMINATE; +} + int __init acpi_ec_ecdt_probe(void) { int ret; @@ -870,7 +825,7 @@ int __init acpi_ec_ecdt_probe(void) if (ACPI_FAILURE(status)) goto error; - printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found ECDT")); boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; diff --git a/trunk/drivers/acpi/event.c b/trunk/drivers/acpi/event.c index dfa5853b17f0..3b23562e6f92 100644 --- a/trunk/drivers/acpi/event.c +++ b/trunk/drivers/acpi/event.c @@ -11,8 +11,6 @@ #include #include #include -#include -#include #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("event"); @@ -50,6 +48,7 @@ acpi_system_read_event(struct file *file, char __user * buffer, size_t count, static int chars_remaining = 0; static char *ptr; + if (!chars_remaining) { memset(&event, 0, sizeof(struct acpi_bus_event)); @@ -107,161 +106,23 @@ static const struct file_operations acpi_system_event_ops = { .poll = acpi_system_poll_event, }; -#ifdef CONFIG_NET -unsigned int acpi_event_seqnum; -struct acpi_genl_event { - acpi_device_class device_class; - char bus_id[15]; - u32 type; - u32 data; -}; - -/* attributes of acpi_genl_family */ -enum { - ACPI_GENL_ATTR_UNSPEC, - ACPI_GENL_ATTR_EVENT, /* ACPI event info needed by user space */ - __ACPI_GENL_ATTR_MAX, -}; -#define ACPI_GENL_ATTR_MAX (__ACPI_GENL_ATTR_MAX - 1) - -/* commands supported by the acpi_genl_family */ -enum { - ACPI_GENL_CMD_UNSPEC, - ACPI_GENL_CMD_EVENT, /* kernel->user notifications for ACPI events */ - __ACPI_GENL_CMD_MAX, -}; -#define ACPI_GENL_CMD_MAX (__ACPI_GENL_CMD_MAX - 1) - -#define ACPI_GENL_FAMILY_NAME "acpi_event" -#define ACPI_GENL_VERSION 0x01 -#define ACPI_GENL_MCAST_GROUP_NAME "acpi_mc_group" - -static struct genl_family acpi_event_genl_family = { - .id = GENL_ID_GENERATE, - .name = ACPI_GENL_FAMILY_NAME, - .version = ACPI_GENL_VERSION, - .maxattr = ACPI_GENL_ATTR_MAX, -}; - -static struct genl_multicast_group acpi_event_mcgrp = { - .name = ACPI_GENL_MCAST_GROUP_NAME, -}; - -int acpi_bus_generate_genetlink_event(struct acpi_device *device, - u8 type, int data) -{ - struct sk_buff *skb; - struct nlattr *attr; - struct acpi_genl_event *event; - void *msg_header; - int size; - int result; - - /* allocate memory */ - size = nla_total_size(sizeof(struct acpi_genl_event)) + - nla_total_size(0); - - skb = genlmsg_new(size, GFP_ATOMIC); - if (!skb) - return -ENOMEM; - - /* add the genetlink message header */ - msg_header = genlmsg_put(skb, 0, acpi_event_seqnum++, - &acpi_event_genl_family, 0, - ACPI_GENL_CMD_EVENT); - if (!msg_header) { - nlmsg_free(skb); - return -ENOMEM; - } - - /* fill the data */ - attr = - nla_reserve(skb, ACPI_GENL_ATTR_EVENT, - sizeof(struct acpi_genl_event)); - if (!attr) { - nlmsg_free(skb); - return -EINVAL; - } - - event = nla_data(attr); - if (!event) { - nlmsg_free(skb); - return -EINVAL; - } - - memset(event, 0, sizeof(struct acpi_genl_event)); - - strcpy(event->device_class, device->pnp.device_class); - strcpy(event->bus_id, device->dev.bus_id); - event->type = type; - event->data = data; - - /* send multicast genetlink message */ - result = genlmsg_end(skb, msg_header); - if (result < 0) { - nlmsg_free(skb); - return result; - } - - result = - genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC); - if (result) - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Failed to send a Genetlink message!\n")); - return 0; -} - -static int acpi_event_genetlink_init(void) -{ - int result; - - result = genl_register_family(&acpi_event_genl_family); - if (result) - return result; - - result = genl_register_mc_group(&acpi_event_genl_family, - &acpi_event_mcgrp); - if (result) - genl_unregister_family(&acpi_event_genl_family); - - return result; -} - -#else -int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type, - int data) -{ - return 0; -} - -static int acpi_event_genetlink_init(void) -{ - return -ENODEV; -} -#endif - static int __init acpi_event_init(void) { struct proc_dir_entry *entry; int error = 0; + if (acpi_disabled) return 0; - /* create genetlink for acpi event */ - error = acpi_event_genetlink_init(); - if (error) - printk(KERN_WARNING PREFIX - "Failed to create genetlink family for ACPI event\n"); - /* 'event' [R] */ entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); if (entry) entry->proc_fops = &acpi_system_event_ops; - else - return -ENODEV; - - return 0; + else { + error = -ENODEV; + } + return error; } -fs_initcall(acpi_event_init); +subsys_initcall(acpi_event_init); diff --git a/trunk/drivers/acpi/events/evgpeblk.c b/trunk/drivers/acpi/events/evgpeblk.c index 361ebe6c4a6f..902c287b3a4f 100644 --- a/trunk/drivers/acpi/events/evgpeblk.c +++ b/trunk/drivers/acpi/events/evgpeblk.c @@ -586,10 +586,6 @@ acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt) flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); if (gpe_xrupt->previous) { gpe_xrupt->previous->next = gpe_xrupt->next; - } else { - /* No previous, update list head */ - - acpi_gbl_gpe_xrupt_list_head = gpe_xrupt->next; } if (gpe_xrupt->next) { diff --git a/trunk/drivers/acpi/events/evrgnini.c b/trunk/drivers/acpi/events/evrgnini.c index 23ee7bc4a705..400d90fca966 100644 --- a/trunk/drivers/acpi/events/evrgnini.c +++ b/trunk/drivers/acpi/events/evrgnini.c @@ -284,7 +284,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, } if (!pci_device_node) { - ACPI_FREE(pci_id); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 4893e256e399..41427a41f620 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -16,7 +16,7 @@ #if ACPI_GLUE_DEBUG #define DBG(x...) printk(PREFIX x) #else -#define DBG(x...) do { } while(0) +#define DBG(x...) #endif static LIST_HEAD(bus_type_list); static DECLARE_RWSEM(bus_type_sem); diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 12c09fafce9a..00d53c2fd1e8 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -77,7 +77,13 @@ static struct workqueue_struct *kacpi_notify_wq; #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ static char osi_additional_string[OSI_STRING_LENGTH_MAX]; -static int osi_linux; /* disable _OSI(Linux) by default */ +#define OSI_LINUX_ENABLED +#ifdef OSI_LINUX_ENABLED +int osi_linux = 1; /* enable _OSI(Linux) by default */ +#else +int osi_linux; /* disable _OSI(Linux) by default */ +#endif + #ifdef CONFIG_DMI static struct __initdata dmi_system_id acpi_osl_dmi_table[]; @@ -1177,10 +1183,17 @@ acpi_os_validate_interface (char *interface) if (!strcmp("Linux", interface)) { printk(KERN_WARNING PREFIX "System BIOS is requesting _OSI(Linux)\n"); +#ifdef OSI_LINUX_ENABLED + printk(KERN_WARNING PREFIX + "Please test with \"acpi_osi=!Linux\"\n" + "Please send dmidecode " + "to linux-acpi@vger.kernel.org\n"); +#else printk(KERN_WARNING PREFIX "If \"acpi_osi=Linux\" works better,\n" "Please send dmidecode " "to linux-acpi@vger.kernel.org\n"); +#endif if(osi_linux) return AE_OK; } @@ -1214,14 +1227,36 @@ acpi_os_validate_address ( } #ifdef CONFIG_DMI +#ifdef OSI_LINUX_ENABLED +static int dmi_osi_not_linux(struct dmi_system_id *d) +{ + printk(KERN_NOTICE "%s detected: requires not _OSI(Linux)\n", d->ident); + enable_osi_linux(0); + return 0; +} +#else static int dmi_osi_linux(struct dmi_system_id *d) { - printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident); + printk(KERN_NOTICE "%s detected: requires _OSI(Linux)\n", d->ident); enable_osi_linux(1); return 0; } +#endif static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { +#ifdef OSI_LINUX_ENABLED + /* + * Boxes that need NOT _OSI(Linux) + */ + { + .callback = dmi_osi_not_linux, + .ident = "Toshiba Satellite P100", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_BOARD_NAME, "Satellite P100"), + }, + }, +#else /* * Boxes that need _OSI(Linux) */ @@ -1233,6 +1268,7 @@ static struct dmi_system_id acpi_osl_dmi_table[] __initdata = { DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"), }, }, +#endif {} }; #endif /* CONFIG_DMI */ diff --git a/trunk/drivers/acpi/pci_link.c b/trunk/drivers/acpi/pci_link.c index 3448edd61dc4..acc594771379 100644 --- a/trunk/drivers/acpi/pci_link.c +++ b/trunk/drivers/acpi/pci_link.c @@ -733,7 +733,7 @@ static int acpi_pci_link_add(struct acpi_device *device) /* query and set link->irq.active */ acpi_pci_link_get_current(link); - printk(KERN_INFO PREFIX "%s [%s] (IRQs", acpi_device_name(device), + printk(PREFIX "%s [%s] (IRQs", acpi_device_name(device), acpi_device_bid(device)); for (i = 0; i < link->irq.possible_count; i++) { if (link->irq.active == link->irq.possible[i]) { diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 81aceb5da7c7..e1ca86dfdd66 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -66,7 +66,6 @@ #define ACPI_PROCESSOR_FILE_LIMIT "limit" #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80 #define ACPI_PROCESSOR_NOTIFY_POWER 0x81 -#define ACPI_PROCESSOR_NOTIFY_THROTTLING 0x82 #define ACPI_PROCESSOR_LIMIT_USER 0 #define ACPI_PROCESSOR_LIMIT_THERMAL 1 @@ -85,8 +84,6 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); static int acpi_processor_handle_eject(struct acpi_processor *pr); -extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr); - static struct acpi_driver acpi_processor_driver = { .name = "processor", @@ -699,9 +696,6 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) acpi_processor_cst_has_changed(pr); acpi_bus_generate_event(device, event, 0); break; - case ACPI_PROCESSOR_NOTIFY_THROTTLING: - acpi_processor_tstate_has_changed(pr); - acpi_bus_generate_event(device, event, 0); default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index a898991f77cb..bb5d23be4260 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -490,17 +490,7 @@ static void acpi_processor_idle(void) case ACPI_STATE_C3: - /* - * disable bus master - * bm_check implies we need ARB_DIS - * !bm_check implies we need cache flush - * bm_control implies whether we can do ARB_DIS - * - * That leaves a case where bm_check is set and bm_control is - * not set. In that case we cannot do much, we enter C3 - * without doing anything. - */ - if (pr->flags.bm_check && pr->flags.bm_control) { + if (pr->flags.bm_check) { if (atomic_inc_return(&c3_cpu_count) == num_online_cpus()) { /* @@ -509,7 +499,7 @@ static void acpi_processor_idle(void) */ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); } - } else if (!pr->flags.bm_check) { + } else { /* SMP with no shared cache... Invalidate cache */ ACPI_FLUSH_CPU_CACHE(); } @@ -521,7 +511,7 @@ static void acpi_processor_idle(void) acpi_cstate_enter(cx); /* Get end time (ticks) */ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); - if (pr->flags.bm_check && pr->flags.bm_control) { + if (pr->flags.bm_check) { /* Enable bus master arbitration */ atomic_dec(&c3_cpu_count); acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); @@ -971,9 +961,9 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, if (pr->flags.bm_check) { /* bus mastering control is necessary */ if (!pr->flags.bm_control) { - /* In this case we enter C3 without bus mastering */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "C3 support without bus mastering control\n")); + "C3 support requires bus mastering control\n")); + return; } } else { /* diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index 3f55d1f90c11..b33486009f41 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -44,231 +44,17 @@ #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_throttling"); -static int acpi_processor_get_throttling(struct acpi_processor *pr); -int acpi_processor_set_throttling(struct acpi_processor *pr, int state); - -static int acpi_processor_get_platform_limit(struct acpi_processor *pr) -{ - acpi_status status = 0; - unsigned long tpc = 0; - - if (!pr) - return -EINVAL; - status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TPC")); - return -ENODEV; - } - pr->throttling_platform_limit = (int)tpc; - return 0; -} - -int acpi_processor_tstate_has_changed(struct acpi_processor *pr) -{ - return acpi_processor_get_platform_limit(pr); -} - -/* -------------------------------------------------------------------------- - _PTC, _TSS, _TSD support - -------------------------------------------------------------------------- */ -static int acpi_processor_get_throttling_control(struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = 0; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *ptc = NULL; - union acpi_object obj = { 0 }; - - status = acpi_evaluate_object(pr->handle, "_PTC", NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTC")); - return -ENODEV; - } - - ptc = (union acpi_object *)buffer.pointer; - if (!ptc || (ptc->type != ACPI_TYPE_PACKAGE) - || (ptc->package.count != 2)) { - printk(KERN_ERR PREFIX "Invalid _PTC data\n"); - result = -EFAULT; - goto end; - } - - /* - * control_register - */ - - obj = ptc->package.elements[0]; - - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_ptc_register)) - || (obj.buffer.pointer == NULL)) { - printk(KERN_ERR PREFIX - "Invalid _PTC data (control_register)\n"); - result = -EFAULT; - goto end; - } - memcpy(&pr->throttling.control_register, obj.buffer.pointer, - sizeof(struct acpi_ptc_register)); - - /* - * status_register - */ - - obj = ptc->package.elements[1]; - - if ((obj.type != ACPI_TYPE_BUFFER) - || (obj.buffer.length < sizeof(struct acpi_ptc_register)) - || (obj.buffer.pointer == NULL)) { - printk(KERN_ERR PREFIX "Invalid _PTC data (status_register)\n"); - result = -EFAULT; - goto end; - } - - memcpy(&pr->throttling.status_register, obj.buffer.pointer, - sizeof(struct acpi_ptc_register)); - - end: - kfree(buffer.pointer); - - return result; -} -static int acpi_processor_get_throttling_states(struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" }; - struct acpi_buffer state = { 0, NULL }; - union acpi_object *tss = NULL; - int i; - - status = acpi_evaluate_object(pr->handle, "_TSS", NULL, &buffer); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Evaluating _TSS")); - return -ENODEV; - } - - tss = buffer.pointer; - if (!tss || (tss->type != ACPI_TYPE_PACKAGE)) { - printk(KERN_ERR PREFIX "Invalid _TSS data\n"); - result = -EFAULT; - goto end; - } - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n", - tss->package.count)); - - pr->throttling.state_count = tss->package.count; - pr->throttling.states_tss = - kmalloc(sizeof(struct acpi_processor_tx_tss) * tss->package.count, - GFP_KERNEL); - if (!pr->throttling.states_tss) { - result = -ENOMEM; - goto end; - } - - for (i = 0; i < pr->throttling.state_count; i++) { - - struct acpi_processor_tx_tss *tx = - (struct acpi_processor_tx_tss *)&(pr->throttling. - states_tss[i]); - - state.length = sizeof(struct acpi_processor_tx_tss); - state.pointer = tx; - - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i)); - - status = acpi_extract_package(&(tss->package.elements[i]), - &format, &state); - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Invalid _TSS data")); - result = -EFAULT; - kfree(pr->throttling.states_tss); - goto end; - } - - if (!tx->freqpercentage) { - printk(KERN_ERR PREFIX - "Invalid _TSS data: freq is zero\n"); - result = -EFAULT; - kfree(pr->throttling.states_tss); - goto end; - } - } - - end: - kfree(buffer.pointer); - - return result; -} -static int acpi_processor_get_tsd(struct acpi_processor *pr) -{ - int result = 0; - acpi_status status = AE_OK; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_buffer format = { sizeof("NNNNN"), "NNNNN" }; - struct acpi_buffer state = { 0, NULL }; - union acpi_object *tsd = NULL; - struct acpi_tsd_package *pdomain; - - status = acpi_evaluate_object(pr->handle, "_TSD", NULL, &buffer); - if (ACPI_FAILURE(status)) { - return -ENODEV; - } - - tsd = buffer.pointer; - if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); - result = -EFAULT; - goto end; - } - - if (tsd->package.count != 1) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); - result = -EFAULT; - goto end; - } - - pdomain = &(pr->throttling.domain_info); - - state.length = sizeof(struct acpi_tsd_package); - state.pointer = pdomain; - - status = acpi_extract_package(&(tsd->package.elements[0]), - &format, &state); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); - result = -EFAULT; - goto end; - } - - if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n")); - result = -EFAULT; - goto end; - } - - if (pdomain->revision != ACPI_TSD_REV0_REVISION) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n")); - result = -EFAULT; - goto end; - } - - end: - kfree(buffer.pointer); - return result; -} - /* -------------------------------------------------------------------------- Throttling Control -------------------------------------------------------------------------- */ -static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) +static int acpi_processor_get_throttling(struct acpi_processor *pr) { int state = 0; u32 value = 0; u32 duty_mask = 0; u32 duty_value = 0; + if (!pr) return -EINVAL; @@ -308,115 +94,13 @@ static int acpi_processor_get_throttling_fadt(struct acpi_processor *pr) return 0; } -static int acpi_read_throttling_status(struct acpi_processor_throttling - *throttling) -{ - int value = -1; - switch (throttling->status_register.space_id) { - case ACPI_ADR_SPACE_SYSTEM_IO: - acpi_os_read_port((acpi_io_address) throttling->status_register. - address, &value, - (u32) throttling->status_register.bit_width * - 8); - break; - case ACPI_ADR_SPACE_FIXED_HARDWARE: - printk(KERN_ERR PREFIX - "HARDWARE addr space,NOT supported yet\n"); - break; - default: - printk(KERN_ERR PREFIX "Unknown addr space %d\n", - (u32) (throttling->status_register.space_id)); - } - return value; -} - -static int acpi_write_throttling_state(struct acpi_processor_throttling - *throttling, int value) -{ - int ret = -1; - - switch (throttling->control_register.space_id) { - case ACPI_ADR_SPACE_SYSTEM_IO: - acpi_os_write_port((acpi_io_address) throttling-> - control_register.address, value, - (u32) throttling->control_register. - bit_width * 8); - ret = 0; - break; - case ACPI_ADR_SPACE_FIXED_HARDWARE: - printk(KERN_ERR PREFIX - "HARDWARE addr space,NOT supported yet\n"); - break; - default: - printk(KERN_ERR PREFIX "Unknown addr space %d\n", - (u32) (throttling->control_register.space_id)); - } - return ret; -} - -static int acpi_get_throttling_state(struct acpi_processor *pr, int value) -{ - int i; - - for (i = 0; i < pr->throttling.state_count; i++) { - struct acpi_processor_tx_tss *tx = - (struct acpi_processor_tx_tss *)&(pr->throttling. - states_tss[i]); - if (tx->control == value) - break; - } - if (i > pr->throttling.state_count) - i = -1; - return i; -} - -static int acpi_get_throttling_value(struct acpi_processor *pr, int state) -{ - int value = -1; - if (state >= 0 && state <= pr->throttling.state_count) { - struct acpi_processor_tx_tss *tx = - (struct acpi_processor_tx_tss *)&(pr->throttling. - states_tss[state]); - value = tx->control; - } - return value; -} - -static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) -{ - int state = 0; - u32 value = 0; - - if (!pr) - return -EINVAL; - - if (!pr->flags.throttling) - return -ENODEV; - - pr->throttling.state = 0; - local_irq_disable(); - value = acpi_read_throttling_status(&pr->throttling); - if (value >= 0) { - state = acpi_get_throttling_state(pr, value); - pr->throttling.state = state; - } - local_irq_enable(); - - return 0; -} - -static int acpi_processor_get_throttling(struct acpi_processor *pr) -{ - return pr->throttling.acpi_processor_get_throttling(pr); -} - -static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, - int state) +int acpi_processor_set_throttling(struct acpi_processor *pr, int state) { u32 value = 0; u32 duty_mask = 0; u32 duty_value = 0; + if (!pr) return -EINVAL; @@ -429,8 +113,6 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, if (state == pr->throttling.state) return 0; - if (state < pr->throttling_platform_limit) - return -EPERM; /* * Calculate the duty_value and duty_mask. */ @@ -483,51 +165,12 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, return 0; } -static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, - int state) -{ - u32 value = 0; - - if (!pr) - return -EINVAL; - - if ((state < 0) || (state > (pr->throttling.state_count - 1))) - return -EINVAL; - - if (!pr->flags.throttling) - return -ENODEV; - - if (state == pr->throttling.state) - return 0; - - if (state < pr->throttling_platform_limit) - return -EPERM; - - local_irq_disable(); - - value = acpi_get_throttling_value(pr, state); - if (value >= 0) { - acpi_write_throttling_state(&pr->throttling, value); - pr->throttling.state = state; - } - local_irq_enable(); - - return 0; -} - -int acpi_processor_set_throttling(struct acpi_processor *pr, int state) -{ - return pr->throttling.acpi_processor_set_throttling(pr, state); -} - int acpi_processor_get_throttling_info(struct acpi_processor *pr) { int result = 0; int step = 0; int i = 0; - int no_ptc = 0; - int no_tss = 0; - int no_tsd = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n", @@ -539,21 +182,6 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) return -EINVAL; /* TBD: Support ACPI 2.0 objects */ - no_ptc = acpi_processor_get_throttling_control(pr); - no_tss = acpi_processor_get_throttling_states(pr); - no_tsd = acpi_processor_get_tsd(pr); - - if (no_ptc || no_tss) { - pr->throttling.acpi_processor_get_throttling = - &acpi_processor_get_throttling_fadt; - pr->throttling.acpi_processor_set_throttling = - &acpi_processor_set_throttling_fadt; - } else { - pr->throttling.acpi_processor_get_throttling = - &acpi_processor_get_throttling_ptc; - pr->throttling.acpi_processor_set_throttling = - &acpi_processor_set_throttling_ptc; - } if (!pr->throttling.address) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n")); @@ -634,6 +262,7 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq, int i = 0; int result = 0; + if (!pr) goto end; @@ -651,25 +280,15 @@ static int acpi_processor_throttling_seq_show(struct seq_file *seq, } seq_printf(seq, "state count: %d\n" - "active state: T%d\n" - "state available: T%d to T%d\n", - pr->throttling.state_count, pr->throttling.state, - pr->throttling_platform_limit, - pr->throttling.state_count - 1); + "active state: T%d\n", + pr->throttling.state_count, pr->throttling.state); seq_puts(seq, "states:\n"); - if (acpi_processor_get_throttling == acpi_processor_get_throttling_fadt) - for (i = 0; i < pr->throttling.state_count; i++) - seq_printf(seq, " %cT%d: %02d%%\n", - (i == pr->throttling.state ? '*' : ' '), i, - (pr->throttling.states[i].performance ? pr-> - throttling.states[i].performance / 10 : 0)); - else - for (i = 0; i < pr->throttling.state_count; i++) - seq_printf(seq, " %cT%d: %02d%%\n", - (i == pr->throttling.state ? '*' : ' '), i, - (int)pr->throttling.states_tss[i]. - freqpercentage); + for (i = 0; i < pr->throttling.state_count; i++) + seq_printf(seq, " %cT%d: %02d%%\n", + (i == pr->throttling.state ? '*' : ' '), i, + (pr->throttling.states[i].performance ? pr-> + throttling.states[i].performance / 10 : 0)); end: return 0; @@ -682,7 +301,7 @@ static int acpi_processor_throttling_open_fs(struct inode *inode, PDE(inode)->data); } -static ssize_t acpi_processor_write_throttling(struct file *file, +static ssize_t acpi_processor_write_throttling(struct file * file, const char __user * buffer, size_t count, loff_t * data) { @@ -691,6 +310,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file, struct acpi_processor *pr = m->private; char state_string[12] = { '\0' }; + if (!pr || (count > sizeof(state_string) - 1)) return -EINVAL; diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 974d00ccfe84..c1bae106833c 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -127,7 +127,7 @@ static int acpi_sbs_resume(struct acpi_device *device); static struct acpi_driver acpi_sbs_driver = { .name = "sbs", .class = ACPI_SBS_CLASS, - .ids = "ACPI0001,ACPI0005", + .ids = ACPI_SBS_HID, .ops = { .add = acpi_sbs_add, .remove = acpi_sbs_remove, @@ -176,8 +176,10 @@ struct acpi_battery { }; struct acpi_sbs { + acpi_handle handle; int base; struct acpi_device *device; + struct acpi_ec_smbus *smbus; struct mutex mutex; int sbsm_present; int sbsm_batteries_supported; @@ -509,7 +511,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) "acpi_sbs_read_word() failed")); goto end; } - sbs->sbsm_present = 1; + sbs->sbsm_batteries_supported = battery_system_info & 0x000f; end: @@ -1628,12 +1630,13 @@ static int acpi_sbs_add(struct acpi_device *device) { struct acpi_sbs *sbs = NULL; int result = 0, remove_result = 0; + unsigned long sbs_obj; int id; acpi_status status = AE_OK; unsigned long val; status = - acpi_evaluate_integer(device->handle, "_EC", NULL, &val); + acpi_evaluate_integer(device->parent->handle, "_EC", NULL, &val); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); return -EIO; @@ -1650,7 +1653,7 @@ static int acpi_sbs_add(struct acpi_device *device) sbs_mutex_lock(sbs); - sbs->base = 0xff & (val >> 8); + sbs->base = (val & 0xff00ull) >> 8; sbs->device = device; strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); @@ -1662,10 +1665,24 @@ static int acpi_sbs_add(struct acpi_device *device) ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); goto end; } + status = acpi_evaluate_integer(device->handle, "_SBS", NULL, &sbs_obj); + if (status) { + ACPI_EXCEPTION((AE_INFO, status, + "acpi_evaluate_integer() failed")); + result = -EIO; + goto end; + } + if (sbs_obj > 0) { + result = acpi_sbsm_get_info(sbs); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbsm_get_info() failed")); + goto end; + } + sbs->sbsm_present = 1; + } - acpi_sbsm_get_info(sbs); - - if (!sbs->sbsm_present) { + if (sbs->sbsm_present == 0) { result = acpi_battery_add(sbs, 0); if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, @@ -1685,6 +1702,8 @@ static int acpi_sbs_add(struct acpi_device *device) } } + sbs->handle = device->handle; + init_timer(&sbs->update_timer); result = acpi_check_update_proc(sbs); if (result) diff --git a/trunk/drivers/acpi/sleep/main.c b/trunk/drivers/acpi/sleep/main.c index 3279e72a94f8..42127c0d612c 100644 --- a/trunk/drivers/acpi/sleep/main.c +++ b/trunk/drivers/acpi/sleep/main.c @@ -210,6 +210,11 @@ static void acpi_hibernation_finish(void) /* reset firmware waking vector */ acpi_set_firmware_waking_vector((acpi_physical_address) 0); + + if (init_8259A_after_S1) { + printk("Broken toshiba laptop -> kicking interrupts\n"); + init_8259A(0); + } } static int acpi_hibernation_pre_restore(void) diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index 83a8d3097904..edee2806e37b 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -39,15 +39,12 @@ ACPI_MODULE_NAME("system"); #define ACPI_SYSTEM_CLASS "system" #define ACPI_SYSTEM_DEVICE_NAME "System" -#define ACPI_SYSTEM_FILE_INFO "info" -#define ACPI_SYSTEM_FILE_EVENT "event" -#define ACPI_SYSTEM_FILE_DSDT "dsdt" -#define ACPI_SYSTEM_FILE_FADT "fadt" /* * Make ACPICA version work as module param */ -static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { +static int param_get_acpica_version(char *buffer, struct kernel_param *kp) +{ int result; result = sprintf(buffer, "%x", ACPI_CA_VERSION); @@ -57,10 +54,127 @@ static int param_get_acpica_version(char *buffer, struct kernel_param *kp) { module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444); +/* -------------------------------------------------------------------------- + FS Interface (/sys) + -------------------------------------------------------------------------- */ +static LIST_HEAD(acpi_table_attr_list); +static struct kobject tables_kobj; + +struct acpi_table_attr { + struct bin_attribute attr; + char name[8]; + int instance; + struct list_head node; +}; + +static ssize_t acpi_table_show(struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t offset, size_t count) +{ + struct acpi_table_attr *table_attr = + container_of(bin_attr, struct acpi_table_attr, attr); + struct acpi_table_header *table_header = NULL; + acpi_status status; + ssize_t ret_count = count; + + status = + acpi_get_table(table_attr->name, table_attr->instance, + &table_header); + if (ACPI_FAILURE(status)) + return -ENODEV; + + if (offset >= table_header->length) { + ret_count = 0; + goto end; + } + + if (offset + ret_count > table_header->length) + ret_count = table_header->length - offset; + + memcpy(buf, ((char *)table_header) + offset, ret_count); + + end: + return ret_count; +} + +static void acpi_table_attr_init(struct acpi_table_attr *table_attr, + struct acpi_table_header *table_header) +{ + struct acpi_table_header *header = NULL; + struct acpi_table_attr *attr = NULL; + + memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE); + + list_for_each_entry(attr, &acpi_table_attr_list, node) { + if (!memcmp(table_header->signature, attr->name, + ACPI_NAME_SIZE)) + if (table_attr->instance < attr->instance) + table_attr->instance = attr->instance; + } + table_attr->instance++; + + if (table_attr->instance > 1 || (table_attr->instance == 1 && + !acpi_get_table(table_header-> + signature, 2, + &header))) + sprintf(table_attr->name + 4, "%d", table_attr->instance); + + table_attr->attr.size = 0; + table_attr->attr.read = acpi_table_show; + table_attr->attr.attr.name = table_attr->name; + table_attr->attr.attr.mode = 0444; + table_attr->attr.attr.owner = THIS_MODULE; + + return; +} + +static int acpi_system_sysfs_init(void) +{ + struct acpi_table_attr *table_attr; + struct acpi_table_header *table_header = NULL; + int table_index = 0; + int result; + + tables_kobj.parent = &acpi_subsys.kobj; + kobject_set_name(&tables_kobj, "tables"); + result = kobject_register(&tables_kobj); + if (result) + return result; + + do { + result = acpi_get_table_by_index(table_index, &table_header); + if (!result) { + table_index++; + table_attr = NULL; + table_attr = + kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL); + if (!table_attr) + return -ENOMEM; + + acpi_table_attr_init(table_attr, table_header); + result = + sysfs_create_bin_file(&tables_kobj, + &table_attr->attr); + if (result) { + kfree(table_attr); + return result; + } else + list_add_tail(&table_attr->node, + &acpi_table_attr_list); + } + } while (!result); + + return 0; +} + /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI_PROCFS +#define ACPI_SYSTEM_FILE_INFO "info" +#define ACPI_SYSTEM_FILE_EVENT "event" +#define ACPI_SYSTEM_FILE_DSDT "dsdt" +#define ACPI_SYSTEM_FILE_FADT "fadt" static int acpi_system_read_info(struct seq_file *seq, void *offset) { @@ -80,7 +194,6 @@ static const struct file_operations acpi_system_info_ops = { .llseek = seq_lseek, .release = single_release, }; -#endif static ssize_t acpi_system_read_dsdt(struct file *, char __user *, size_t, loff_t *); @@ -97,13 +210,11 @@ acpi_system_read_dsdt(struct file *file, struct acpi_table_header *dsdt = NULL; ssize_t res; - status = acpi_get_table(ACPI_SIG_DSDT, 1, &dsdt); if (ACPI_FAILURE(status)) return -ENODEV; - res = simple_read_from_buffer(buffer, count, ppos, - dsdt, dsdt->length); + res = simple_read_from_buffer(buffer, count, ppos, dsdt, dsdt->length); return res; } @@ -123,28 +234,21 @@ acpi_system_read_fadt(struct file *file, struct acpi_table_header *fadt = NULL; ssize_t res; - status = acpi_get_table(ACPI_SIG_FADT, 1, &fadt); if (ACPI_FAILURE(status)) return -ENODEV; - res = simple_read_from_buffer(buffer, count, ppos, - fadt, fadt->length); + res = simple_read_from_buffer(buffer, count, ppos, fadt, fadt->length); return res; } -static int __init acpi_system_init(void) +static int acpi_system_procfs_init(void) { struct proc_dir_entry *entry; int error = 0; char *name; - - if (acpi_disabled) - return 0; - -#ifdef CONFIG_ACPI_PROCFS /* 'info' [R] */ name = ACPI_SYSTEM_FILE_INFO; entry = create_proc_entry(name, S_IRUGO, acpi_root_dir); @@ -153,7 +257,6 @@ static int __init acpi_system_init(void) else { entry->proc_fops = &acpi_system_info_ops; } -#endif /* 'dsdt' [R] */ name = ACPI_SYSTEM_FILE_DSDT; @@ -177,12 +280,32 @@ static int __init acpi_system_init(void) Error: remove_proc_entry(ACPI_SYSTEM_FILE_FADT, acpi_root_dir); remove_proc_entry(ACPI_SYSTEM_FILE_DSDT, acpi_root_dir); -#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_SYSTEM_FILE_INFO, acpi_root_dir); -#endif error = -EFAULT; goto Done; } +#else +static int acpi_system_procfs_init(void) +{ + return 0; +} +#endif + +static int __init acpi_system_init(void) +{ + int result = 0; + + if (acpi_disabled) + return 0; + + result = acpi_system_procfs_init(); + if (result) + return result; + + result = acpi_system_sysfs_init(); + + return result; +} subsys_initcall(acpi_system_init); diff --git a/trunk/drivers/acpi/tables/tbfadt.c b/trunk/drivers/acpi/tables/tbfadt.c index 002bb33003af..1285e91474fb 100644 --- a/trunk/drivers/acpi/tables/tbfadt.c +++ b/trunk/drivers/acpi/tables/tbfadt.c @@ -211,17 +211,14 @@ void acpi_tb_parse_fadt(acpi_native_uint table_index, u8 flags) * DESCRIPTION: Get a local copy of the FADT and convert it to a common format. * Performs validation on some important FADT fields. * - * NOTE: We create a local copy of the FADT regardless of the version. - * ******************************************************************************/ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) { /* - * Check if the FADT is larger than the largest table that we expect - * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue - * a warning. + * Check if the FADT is larger than what we know about (ACPI 2.0 version). + * Truncate the table, but make some noise. */ if (length > sizeof(struct acpi_table_fadt)) { ACPI_WARNING((AE_INFO, @@ -230,12 +227,10 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) sizeof(struct acpi_table_fadt))); } - /* Clear the entire local FADT */ + /* Copy the entire FADT locally. Zero first for tb_convert_fadt */ ACPI_MEMSET(&acpi_gbl_FADT, 0, sizeof(struct acpi_table_fadt)); - /* Copy the original FADT, up to sizeof (struct acpi_table_fadt) */ - ACPI_MEMCPY(&acpi_gbl_FADT, table, ACPI_MIN(length, sizeof(struct acpi_table_fadt))); @@ -256,7 +251,7 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) * RETURN: None * * DESCRIPTION: Converts all versions of the FADT to a common internal format. - * Expand all 32-bit addresses to 64-bit. + * -> Expand all 32-bit addresses to 64-bit. * * NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt), * and must contain a copy of the actual FADT. @@ -297,23 +292,8 @@ static void acpi_tb_convert_fadt(void) } /* - * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which - * should be zero are indeed zero. This will workaround BIOSs that - * inadvertently place values in these fields. - * - * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at - * offset 45, 55, 95, and the word located at offset 109, 110. - */ - if (acpi_gbl_FADT.header.revision < 3) { - acpi_gbl_FADT.preferred_profile = 0; - acpi_gbl_FADT.pstate_control = 0; - acpi_gbl_FADT.cst_control = 0; - acpi_gbl_FADT.boot_flags = 0; - } - - /* - * Expand the ACPI 1.0 32-bit V1.0 addresses to the ACPI 2.0 64-bit "X" - * generic address structures as necessary. + * Expand the 32-bit V1.0 addresses to the 64-bit "X" generic address + * structures as necessary. */ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { target = @@ -369,6 +349,18 @@ static void acpi_tb_convert_fadt(void) acpi_gbl_FADT.xpm1a_event_block.space_id; } + + /* + * For ACPI 1.0 FADTs, ensure that reserved fields (which should be zero) + * are indeed zero. This will workaround BIOSs that inadvertently placed + * values in these fields. + */ + if (acpi_gbl_FADT.header.revision < 3) { + acpi_gbl_FADT.preferred_profile = 0; + acpi_gbl_FADT.pstate_control = 0; + acpi_gbl_FADT.cst_control = 0; + acpi_gbl_FADT.boot_flags = 0; + } } /****************************************************************************** diff --git a/trunk/drivers/acpi/utilities/uteval.c b/trunk/drivers/acpi/utilities/uteval.c index f112af433e36..8ec6f8e48138 100644 --- a/trunk/drivers/acpi/utilities/uteval.c +++ b/trunk/drivers/acpi/utilities/uteval.c @@ -62,13 +62,16 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, static char *acpi_interfaces_supported[] = { /* Operating System Vendor Strings */ - "Windows 2000", /* Windows 2000 */ - "Windows 2001", /* Windows XP */ - "Windows 2001 SP1", /* Windows XP SP1 */ - "Windows 2001 SP2", /* Windows XP SP2 */ - "Windows 2001.1", /* Windows Server 2003 */ - "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */ - "Windows 2006", /* Windows Vista - Added 03/2006 */ + "Windows 2000", + "Windows 2001", + "Windows 2001 SP0", + "Windows 2001 SP1", + "Windows 2001 SP2", + "Windows 2001 SP3", + "Windows 2001 SP4", + "Windows 2001.1", + "Windows 2001.1 SP1", /* Added 03/2006 */ + "Windows 2006", /* Added 03/2006 */ /* Feature Group Strings */ diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 5f014d3764c8..00d25b347255 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -170,7 +169,6 @@ struct acpi_video_device { struct acpi_device *dev; struct acpi_video_device_brightness *brightness; struct backlight_device *backlight; - struct output_device *output_dev; }; /* bus */ @@ -274,10 +272,6 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); static void acpi_video_switch_brightness(struct acpi_video_device *device, int event); -static int acpi_video_device_get_state(struct acpi_video_device *device, - unsigned long *state); -static int acpi_video_output_get(struct output_device *od); -static int acpi_video_device_set_state(struct acpi_video_device *device, int state); /*backlight device sysfs support*/ static int acpi_video_get_brightness(struct backlight_device *bd) @@ -303,28 +297,6 @@ static struct backlight_ops acpi_backlight_ops = { .update_status = acpi_video_set_brightness, }; -/*video output device sysfs support*/ -static int acpi_video_output_get(struct output_device *od) -{ - unsigned long state; - struct acpi_video_device *vd = - (struct acpi_video_device *)class_get_devdata(&od->class_dev); - acpi_video_device_get_state(vd, &state); - return (int)state; -} - -static int acpi_video_output_set(struct output_device *od) -{ - unsigned long state = od->request_state; - struct acpi_video_device *vd= - (struct acpi_video_device *)class_get_devdata(&od->class_dev); - return acpi_video_device_set_state(vd, state); -} - -static struct output_properties acpi_output_properties = { - .set_state = acpi_video_output_set, - .get_status = acpi_video_output_get, -}; /* -------------------------------------------------------------------------- Video Management -------------------------------------------------------------------------- */ @@ -559,6 +531,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) static void acpi_video_device_find_cap(struct acpi_video_device *device) { + acpi_integer status; acpi_handle h_dummy1; int i; u32 max_level = 0; @@ -592,55 +565,50 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) device->cap._DSS = 1; } - if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { - - if (obj->package.count >= 2) { - int count = 0; - union acpi_object *o; - - br = kzalloc(sizeof(*br), GFP_KERNEL); - if (!br) { - printk(KERN_ERR "can't allocate memory\n"); - } else { - br->levels = kmalloc(obj->package.count * - sizeof *(br->levels), GFP_KERNEL); - if (!br->levels) - goto out; - - for (i = 0; i < obj->package.count; i++) { - o = (union acpi_object *)&obj->package. - elements[i]; - if (o->type != ACPI_TYPE_INTEGER) { - printk(KERN_ERR PREFIX "Invalid data\n"); - continue; - } - br->levels[count] = (u32) o->integer.value; - - if (br->levels[count] > max_level) - max_level = br->levels[count]; - count++; - } - out: - if (count < 2) { - kfree(br->levels); - kfree(br); - } else { - br->count = count; - device->brightness = br; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "found %d brightness levels\n", - count)); + status = acpi_video_device_lcd_query_levels(device, &obj); + + if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { + int count = 0; + union acpi_object *o; + + br = kzalloc(sizeof(*br), GFP_KERNEL); + if (!br) { + printk(KERN_ERR "can't allocate memory\n"); + } else { + br->levels = kmalloc(obj->package.count * + sizeof *(br->levels), GFP_KERNEL); + if (!br->levels) + goto out; + + for (i = 0; i < obj->package.count; i++) { + o = (union acpi_object *)&obj->package. + elements[i]; + if (o->type != ACPI_TYPE_INTEGER) { + printk(KERN_ERR PREFIX "Invalid data\n"); + continue; } + br->levels[count] = (u32) o->integer.value; + if (br->levels[count] > max_level) + max_level = br->levels[count]; + count++; + } + out: + if (count < 2) { + kfree(br->levels); + kfree(br); + } else { + br->count = count; + device->brightness = br; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "found %d brightness levels\n", + count)); } } - - } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n")); } kfree(obj); - if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ + if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ unsigned long tmp; static int count = 0; char *name; @@ -658,17 +626,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) kfree(name); } - if (device->cap._DCS && device->cap._DSS){ - static int count = 0; - char *name; - name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); - if (!name) - return; - sprintf(name, "acpi_video%d", count++); - device->output_dev = video_output_register(name, - NULL, device, &acpi_output_properties); - kfree(name); - } return; } @@ -1712,7 +1669,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) ACPI_DEVICE_NOTIFY, acpi_video_device_notify); backlight_device_unregister(device->backlight); - video_output_unregister(device->output_dev); return 0; } diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index aaaa61ea4217..1d516f24ba53 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -150,7 +150,6 @@ config THINKPAD_ACPI depends on X86 && ACPI select BACKLIGHT_CLASS_DEVICE select HWMON - select NVRAM ---help--- This is a driver for the IBM and Lenovo ThinkPad laptops. It adds support for Fn-Fx key combinations, Bluetooth control, video @@ -197,17 +196,4 @@ config THINKPAD_ACPI_BAY If you are not sure, say Y here. -config THINKPAD_ACPI_INPUT_ENABLED - bool "Enable input layer support by default" - depends on THINKPAD_ACPI - default y - ---help--- - Enables hot key handling over the input layer by default. If unset, - the driver does not enable any hot key handling by default, and also - starts up with a mostly empty keymap. - - If you are not sure, say Y here. Say N to retain the deprecated - behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21. - - endif # MISC_DEVICES diff --git a/trunk/drivers/misc/sony-laptop.c b/trunk/drivers/misc/sony-laptop.c index 303e48ca0e8a..9623eaf4f89f 100644 --- a/trunk/drivers/misc/sony-laptop.c +++ b/trunk/drivers/misc/sony-laptop.c @@ -142,124 +142,43 @@ struct sony_laptop_keypress { int key; }; -/* Correspondance table between sonypi events - * and input layer indexes in the keymap - */ -static int sony_laptop_input_index[] = { - -1, /* no event */ - -1, /* SONYPI_EVENT_JOGDIAL_DOWN */ - -1, /* SONYPI_EVENT_JOGDIAL_UP */ - -1, /* SONYPI_EVENT_JOGDIAL_DOWN_PRESSED */ - -1, /* SONYPI_EVENT_JOGDIAL_UP_PRESSED */ - -1, /* SONYPI_EVENT_JOGDIAL_PRESSED */ - -1, /* SONYPI_EVENT_JOGDIAL_RELEASED */ - 0, /* SONYPI_EVENT_CAPTURE_PRESSED */ - 1, /* SONYPI_EVENT_CAPTURE_RELEASED */ - 2, /* SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ - 3, /* SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ - 4, /* SONYPI_EVENT_FNKEY_ESC */ - 5, /* SONYPI_EVENT_FNKEY_F1 */ - 6, /* SONYPI_EVENT_FNKEY_F2 */ - 7, /* SONYPI_EVENT_FNKEY_F3 */ - 8, /* SONYPI_EVENT_FNKEY_F4 */ - 9, /* SONYPI_EVENT_FNKEY_F5 */ - 10, /* SONYPI_EVENT_FNKEY_F6 */ - 11, /* SONYPI_EVENT_FNKEY_F7 */ - 12, /* SONYPI_EVENT_FNKEY_F8 */ - 13, /* SONYPI_EVENT_FNKEY_F9 */ - 14, /* SONYPI_EVENT_FNKEY_F10 */ - 15, /* SONYPI_EVENT_FNKEY_F11 */ - 16, /* SONYPI_EVENT_FNKEY_F12 */ - 17, /* SONYPI_EVENT_FNKEY_1 */ - 18, /* SONYPI_EVENT_FNKEY_2 */ - 19, /* SONYPI_EVENT_FNKEY_D */ - 20, /* SONYPI_EVENT_FNKEY_E */ - 21, /* SONYPI_EVENT_FNKEY_F */ - 22, /* SONYPI_EVENT_FNKEY_S */ - 23, /* SONYPI_EVENT_FNKEY_B */ - 24, /* SONYPI_EVENT_BLUETOOTH_PRESSED */ - 25, /* SONYPI_EVENT_PKEY_P1 */ - 26, /* SONYPI_EVENT_PKEY_P2 */ - 27, /* SONYPI_EVENT_PKEY_P3 */ - 28, /* SONYPI_EVENT_BACK_PRESSED */ - -1, /* SONYPI_EVENT_LID_CLOSED */ - -1, /* SONYPI_EVENT_LID_OPENED */ - 29, /* SONYPI_EVENT_BLUETOOTH_ON */ - 30, /* SONYPI_EVENT_BLUETOOTH_OFF */ - 31, /* SONYPI_EVENT_HELP_PRESSED */ - 32, /* SONYPI_EVENT_FNKEY_ONLY */ - 33, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN */ - 34, /* SONYPI_EVENT_JOGDIAL_FAST_UP */ - 35, /* SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ - 36, /* SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ - 37, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ - 38, /* SONYPI_EVENT_JOGDIAL_VFAST_UP */ - 39, /* SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ - 40, /* SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ - 41, /* SONYPI_EVENT_ZOOM_PRESSED */ - 42, /* SONYPI_EVENT_THUMBPHRASE_PRESSED */ - 43, /* SONYPI_EVENT_MEYE_FACE */ - 44, /* SONYPI_EVENT_MEYE_OPPOSITE */ - 45, /* SONYPI_EVENT_MEMORYSTICK_INSERT */ - 46, /* SONYPI_EVENT_MEMORYSTICK_EJECT */ - -1, /* SONYPI_EVENT_ANYBUTTON_RELEASED */ - -1, /* SONYPI_EVENT_BATTERY_INSERT */ - -1, /* SONYPI_EVENT_BATTERY_REMOVE */ - -1, /* SONYPI_EVENT_FNKEY_RELEASED */ - 47, /* SONYPI_EVENT_WIRELESS_ON */ - 48, /* SONYPI_EVENT_WIRELESS_OFF */ -}; - -static int sony_laptop_input_keycode_map[] = { - KEY_CAMERA, /* 0 SONYPI_EVENT_CAPTURE_PRESSED */ - KEY_RESERVED, /* 1 SONYPI_EVENT_CAPTURE_RELEASED */ - KEY_RESERVED, /* 2 SONYPI_EVENT_CAPTURE_PARTIALPRESSED */ - KEY_RESERVED, /* 3 SONYPI_EVENT_CAPTURE_PARTIALRELEASED */ - KEY_FN_ESC, /* 4 SONYPI_EVENT_FNKEY_ESC */ - KEY_FN_F1, /* 5 SONYPI_EVENT_FNKEY_F1 */ - KEY_FN_F2, /* 6 SONYPI_EVENT_FNKEY_F2 */ - KEY_FN_F3, /* 7 SONYPI_EVENT_FNKEY_F3 */ - KEY_FN_F4, /* 8 SONYPI_EVENT_FNKEY_F4 */ - KEY_FN_F5, /* 9 SONYPI_EVENT_FNKEY_F5 */ - KEY_FN_F6, /* 10 SONYPI_EVENT_FNKEY_F6 */ - KEY_FN_F7, /* 11 SONYPI_EVENT_FNKEY_F7 */ - KEY_FN_F8, /* 12 SONYPI_EVENT_FNKEY_F8 */ - KEY_FN_F9, /* 13 SONYPI_EVENT_FNKEY_F9 */ - KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ - KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ - KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ - KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ - KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ - KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ - KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ - KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ - KEY_FN_S, /* 22 SONYPI_EVENT_FNKEY_S */ - KEY_FN_B, /* 23 SONYPI_EVENT_FNKEY_B */ - KEY_BLUETOOTH, /* 24 SONYPI_EVENT_BLUETOOTH_PRESSED */ - KEY_PROG1, /* 25 SONYPI_EVENT_PKEY_P1 */ - KEY_PROG2, /* 26 SONYPI_EVENT_PKEY_P2 */ - KEY_PROG3, /* 27 SONYPI_EVENT_PKEY_P3 */ - KEY_BACK, /* 28 SONYPI_EVENT_BACK_PRESSED */ - KEY_BLUETOOTH, /* 29 SONYPI_EVENT_BLUETOOTH_ON */ - KEY_BLUETOOTH, /* 30 SONYPI_EVENT_BLUETOOTH_OFF */ - KEY_HELP, /* 31 SONYPI_EVENT_HELP_PRESSED */ - KEY_FN, /* 32 SONYPI_EVENT_FNKEY_ONLY */ - KEY_RESERVED, /* 33 SONYPI_EVENT_JOGDIAL_FAST_DOWN */ - KEY_RESERVED, /* 34 SONYPI_EVENT_JOGDIAL_FAST_UP */ - KEY_RESERVED, /* 35 SONYPI_EVENT_JOGDIAL_FAST_DOWN_PRESSED */ - KEY_RESERVED, /* 36 SONYPI_EVENT_JOGDIAL_FAST_UP_PRESSED */ - KEY_RESERVED, /* 37 SONYPI_EVENT_JOGDIAL_VFAST_DOWN */ - KEY_RESERVED, /* 38 SONYPI_EVENT_JOGDIAL_VFAST_UP */ - KEY_RESERVED, /* 39 SONYPI_EVENT_JOGDIAL_VFAST_DOWN_PRESSED */ - KEY_RESERVED, /* 40 SONYPI_EVENT_JOGDIAL_VFAST_UP_PRESSED */ - KEY_ZOOM, /* 41 SONYPI_EVENT_ZOOM_PRESSED */ - BTN_THUMB, /* 42 SONYPI_EVENT_THUMBPHRASE_PRESSED */ - KEY_RESERVED, /* 43 SONYPI_EVENT_MEYE_FACE */ - KEY_RESERVED, /* 44 SONYPI_EVENT_MEYE_OPPOSITE */ - KEY_RESERVED, /* 45 SONYPI_EVENT_MEMORYSTICK_INSERT */ - KEY_RESERVED, /* 46 SONYPI_EVENT_MEMORYSTICK_EJECT */ - KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */ - KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */ +/* Correspondance table between sonypi events and input layer events */ +static struct { + int sonypiev; + int inputev; +} sony_laptop_inputkeys[] = { + { SONYPI_EVENT_CAPTURE_PRESSED, KEY_CAMERA }, + { SONYPI_EVENT_FNKEY_ONLY, KEY_FN }, + { SONYPI_EVENT_FNKEY_ESC, KEY_FN_ESC }, + { SONYPI_EVENT_FNKEY_F1, KEY_FN_F1 }, + { SONYPI_EVENT_FNKEY_F2, KEY_FN_F2 }, + { SONYPI_EVENT_FNKEY_F3, KEY_FN_F3 }, + { SONYPI_EVENT_FNKEY_F4, KEY_FN_F4 }, + { SONYPI_EVENT_FNKEY_F5, KEY_FN_F5 }, + { SONYPI_EVENT_FNKEY_F6, KEY_FN_F6 }, + { SONYPI_EVENT_FNKEY_F7, KEY_FN_F7 }, + { SONYPI_EVENT_FNKEY_F8, KEY_FN_F8 }, + { SONYPI_EVENT_FNKEY_F9, KEY_FN_F9 }, + { SONYPI_EVENT_FNKEY_F10, KEY_FN_F10 }, + { SONYPI_EVENT_FNKEY_F11, KEY_FN_F11 }, + { SONYPI_EVENT_FNKEY_F12, KEY_FN_F12 }, + { SONYPI_EVENT_FNKEY_1, KEY_FN_1 }, + { SONYPI_EVENT_FNKEY_2, KEY_FN_2 }, + { SONYPI_EVENT_FNKEY_D, KEY_FN_D }, + { SONYPI_EVENT_FNKEY_E, KEY_FN_E }, + { SONYPI_EVENT_FNKEY_F, KEY_FN_F }, + { SONYPI_EVENT_FNKEY_S, KEY_FN_S }, + { SONYPI_EVENT_FNKEY_B, KEY_FN_B }, + { SONYPI_EVENT_BLUETOOTH_PRESSED, KEY_BLUE }, + { SONYPI_EVENT_BLUETOOTH_ON, KEY_BLUE }, + { SONYPI_EVENT_PKEY_P1, KEY_PROG1 }, + { SONYPI_EVENT_PKEY_P2, KEY_PROG2 }, + { SONYPI_EVENT_PKEY_P3, KEY_PROG3 }, + { SONYPI_EVENT_BACK_PRESSED, KEY_BACK }, + { SONYPI_EVENT_HELP_PRESSED, KEY_HELP }, + { SONYPI_EVENT_ZOOM_PRESSED, KEY_ZOOM }, + { SONYPI_EVENT_THUMBPHRASE_PRESSED, BTN_THUMB }, + { 0, 0 }, }; /* release buttons after a short delay if pressed */ @@ -283,6 +202,7 @@ static void sony_laptop_report_input_event(u8 event) struct input_dev *jog_dev = sony_laptop_input.jog_dev; struct input_dev *key_dev = sony_laptop_input.key_dev; struct sony_laptop_keypress kp = { NULL }; + int i; if (event == SONYPI_EVENT_FNKEY_RELEASED) { /* Nothing, not all VAIOs generate this event */ @@ -311,22 +231,17 @@ static void sony_laptop_report_input_event(u8 event) break; default: - if (event > ARRAY_SIZE (sony_laptop_input_keycode_map)) { - dprintk("sony_laptop_report_input_event, event not known: %d\n", event); - break; - } - if (sony_laptop_input_index[event] != -1) { - kp.key = sony_laptop_input_keycode_map[sony_laptop_input_index[event]]; - if (kp.key != KEY_UNKNOWN) + for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) + if (event == sony_laptop_inputkeys[i].sonypiev) { kp.dev = key_dev; - } + kp.key = sony_laptop_inputkeys[i].inputev; + break; + } break; } if (kp.dev) { input_report_key(kp.dev, kp.key, 1); - /* we emit the scancode so we can always remap the key */ - input_event(kp.dev, EV_MSC, MSC_SCAN, event); input_sync(kp.dev); kfifo_put(sony_laptop_input.fifo, (unsigned char *)&kp, sizeof(kp)); @@ -381,18 +296,11 @@ static int sony_laptop_setup_input(void) key_dev->id.vendor = PCI_VENDOR_ID_SONY; /* Initialize the Input Drivers: special keys */ - set_bit(EV_KEY, key_dev->evbit); - set_bit(EV_MSC, key_dev->evbit); - set_bit(MSC_SCAN, key_dev->mscbit); - key_dev->keycodesize = sizeof(sony_laptop_input_keycode_map[0]); - key_dev->keycodemax = ARRAY_SIZE(sony_laptop_input_keycode_map); - key_dev->keycode = &sony_laptop_input_keycode_map; - for (i = 0; i < ARRAY_SIZE(sony_laptop_input_keycode_map); i++) { - if (sony_laptop_input_keycode_map[i] != KEY_RESERVED) { - set_bit(sony_laptop_input_keycode_map[i], - key_dev->keybit); - } - } + key_dev->evbit[0] = BIT(EV_KEY); + for (i = 0; sony_laptop_inputkeys[i].sonypiev; i++) + if (sony_laptop_inputkeys[i].inputev) + set_bit(sony_laptop_inputkeys[i].inputev, + key_dev->keybit); error = input_register_device(key_dev); if (error) @@ -579,14 +487,6 @@ SNC_HANDLE_NAMES(audiopower_set, "AZPW"); SNC_HANDLE_NAMES(lanpower_get, "GLNP"); SNC_HANDLE_NAMES(lanpower_set, "LNPW"); -SNC_HANDLE_NAMES(lidstate_get, "GLID"); - -SNC_HANDLE_NAMES(indicatorlamp_get, "GILS"); -SNC_HANDLE_NAMES(indicatorlamp_set, "SILS"); - -SNC_HANDLE_NAMES(gainbass_get, "GMGB"); -SNC_HANDLE_NAMES(gainbass_set, "CMGB"); - SNC_HANDLE_NAMES(PID_get, "GPID"); SNC_HANDLE_NAMES(CTR_get, "GCTR"); @@ -607,12 +507,6 @@ static struct sony_nc_value sony_nc_values[] = { boolean_validate, 0), SNC_HANDLE(lanpower, snc_lanpower_get, snc_lanpower_set, boolean_validate, 1), - SNC_HANDLE(lidstate, snc_lidstate_get, NULL, - boolean_validate, 0), - SNC_HANDLE(indicatorlamp, snc_indicatorlamp_get, snc_indicatorlamp_set, - boolean_validate, 0), - SNC_HANDLE(gainbass, snc_gainbass_get, snc_gainbass_set, - boolean_validate, 0), /* unknown methods */ SNC_HANDLE(PID, snc_PID_get, NULL, NULL, 1), SNC_HANDLE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1), @@ -794,117 +688,14 @@ static struct backlight_ops sony_backlight_ops = { .get_brightness = sony_backlight_get_brightness, }; -/* - * New SNC-only Vaios event mapping to driver known keys - */ -struct sony_nc_event { - u8 data; - u8 event; -}; - -static struct sony_nc_event *sony_nc_events; - -/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence - * for Fn keys - */ -static int sony_nc_C_enable(struct dmi_system_id *id) -{ - int result = 0; - - printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident); - - sony_nc_events = id->driver_data; - - if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0 - || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0 - || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0 - || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0 - || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0 - || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) { - printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some " - "functionalities may be missing\n"); - return 1; - } - return 0; -} - -static struct sony_nc_event sony_C_events[] = { - { 0x81, SONYPI_EVENT_FNKEY_F1 }, - { 0x01, SONYPI_EVENT_FNKEY_RELEASED }, - { 0x85, SONYPI_EVENT_FNKEY_F5 }, - { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, - { 0x86, SONYPI_EVENT_FNKEY_F6 }, - { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, - { 0x87, SONYPI_EVENT_FNKEY_F7 }, - { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, - { 0x8A, SONYPI_EVENT_FNKEY_F10 }, - { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, - { 0x8C, SONYPI_EVENT_FNKEY_F12 }, - { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, - { 0, 0 }, -}; - -/* SNC-only model map */ -struct dmi_system_id sony_nc_ids[] = { - { - .ident = "Sony Vaio FE Series", - .callback = sony_nc_C_enable, - .driver_data = sony_C_events, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"), - }, - }, - { - .ident = "Sony Vaio C Series", - .callback = sony_nc_C_enable, - .driver_data = sony_C_events, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"), - }, - }, - { } -}; - /* * ACPI callbacks */ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) { - struct sony_nc_event *evmap; - u32 ev = event; - int result; - - if (ev == 0x92) { - /* read the key pressed from EC.GECR - * A call to SN07 with 0x0202 will do it as well respecting - * the current protocol on different OSes - * - * Note: the path for GECR may be - * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends) - * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR) - * - * TODO: we may want to do the same for the older GHKE -need - * dmi list- so this snippet may become one more callback. - */ - if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0) - dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev); - else - ev = result & 0xFF; - } - - if (sony_nc_events) - for (evmap = sony_nc_events; evmap->event; evmap++) { - if (evmap->data == ev) { - ev = evmap->event; - break; - } - } - - dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); - sony_laptop_report_input_event(ev); - acpi_bus_generate_event(sony_nc_acpi_device, 1, ev); + dprintk("sony_acpi_notify, event: %d\n", event); + sony_laptop_report_input_event(event); + acpi_bus_generate_event(sony_nc_acpi_device, 1, event); } static acpi_status sony_walk_callback(acpi_handle handle, u32 level, @@ -941,10 +732,6 @@ static int sony_nc_resume(struct acpi_device *device) break; } } - - /* re-initialize models with specific requirements */ - dmi_check_system(sony_nc_ids); - return 0; } @@ -963,15 +750,6 @@ static int sony_nc_add(struct acpi_device *device) sony_nc_acpi_handle = device->handle; - /* read device status */ - result = acpi_bus_get_status(device); - /* bail IFF the above call was successful and the device is not present */ - if (!result && !device->status.present) { - dprintk("Device not present\n"); - result = -ENODEV; - goto outwalk; - } - if (debug) { status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle, 1, sony_walk_callback, NULL, NULL); @@ -982,15 +760,6 @@ static int sony_nc_add(struct acpi_device *device) } } - /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1 - * should be respected as we already checked for the device presence above */ - if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) { - dprintk("Invoking _INI\n"); - if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI, - NULL, NULL))) - dprintk("_INI Method failed\n"); - } - /* setup input devices and helper fifo */ result = sony_laptop_setup_input(); if (result) { @@ -1003,7 +772,7 @@ static int sony_nc_add(struct acpi_device *device) ACPI_DEVICE_NOTIFY, sony_acpi_notify, NULL); if (ACPI_FAILURE(status)) { - printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status); + printk(KERN_WARNING DRV_PFX "unable to install notify handler\n"); result = -ENODEV; goto outinput; } @@ -1026,9 +795,6 @@ static int sony_nc_add(struct acpi_device *device) } - /* initialize models with specific requirements */ - dmi_check_system(sony_nc_ids); - result = sony_pf_add(); if (result) goto outbacklight; @@ -1142,9 +908,7 @@ static struct acpi_driver sony_nc_driver = { #define SONYPI_DEVICE_TYPE2 0x00000002 #define SONYPI_DEVICE_TYPE3 0x00000004 -#define SONYPI_TYPE1_OFFSET 0x04 -#define SONYPI_TYPE2_OFFSET 0x12 -#define SONYPI_TYPE3_OFFSET 0x12 +#define SONY_PIC_EV_MASK 0xff struct sony_pic_ioport { struct acpi_resource_io io; @@ -1158,7 +922,6 @@ struct sony_pic_irq { struct sony_pic_dev { int model; - u16 evport_offset; u8 camera_power; u8 bluetooth_power; u8 wwan_power; @@ -2236,17 +1999,20 @@ static int sony_pic_enable(struct acpi_device *device, static irqreturn_t sony_pic_irq(int irq, void *dev_id) { int i, j; + u32 port_val = 0; u8 ev = 0; u8 data_mask = 0; u8 device_event = 0; struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; - ev = inb_p(dev->cur_ioport->io.minimum); - data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); + acpi_os_read_port(dev->cur_ioport->io.minimum, &port_val, + dev->cur_ioport->io.address_length); + ev = port_val & SONY_PIC_EV_MASK; + data_mask = 0xff & (port_val >> (dev->cur_ioport->io.address_length - 8)); - dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", - ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); + dprintk("event (0x%.8x [%.2x] [%.2x]) at port 0x%.4x\n", + port_val, ev, data_mask, dev->cur_ioport->io.minimum); if (ev == 0x00 || ev == 0xff) return IRQ_HANDLED; @@ -2337,20 +2103,6 @@ static int sony_pic_add(struct acpi_device *device) spic_dev.model = sony_pic_detect_device_type(); mutex_init(&spic_dev.lock); - /* model specific characteristics */ - switch(spic_dev.model) { - case SONYPI_DEVICE_TYPE1: - spic_dev.evport_offset = SONYPI_TYPE1_OFFSET; - break; - case SONYPI_DEVICE_TYPE3: - spic_dev.evport_offset = SONYPI_TYPE3_OFFSET; - break; - case SONYPI_DEVICE_TYPE2: - default: - spic_dev.evport_offset = SONYPI_TYPE2_OFFSET; - break; - } - /* read _PRS resources */ result = sony_pic_possible_resources(device); if (result) { diff --git a/trunk/drivers/misc/thinkpad_acpi.c b/trunk/drivers/misc/thinkpad_acpi.c index f15a58f7403f..95c0b96e83f2 100644 --- a/trunk/drivers/misc/thinkpad_acpi.c +++ b/trunk/drivers/misc/thinkpad_acpi.c @@ -21,8 +21,8 @@ * 02110-1301, USA. */ -#define IBM_VERSION "0.15" -#define TPACPI_SYSFS_VERSION 0x010000 +#define IBM_VERSION "0.14" +#define TPACPI_SYSFS_VERSION 0x000100 /* * Changelog: @@ -92,29 +92,6 @@ MODULE_LICENSE("GPL"); /* Please remove this in year 2009 */ MODULE_ALIAS("ibm_acpi"); -/* - * DMI matching for module autoloading - * - * See http://thinkwiki.org/wiki/List_of_DMI_IDs - * See http://thinkwiki.org/wiki/BIOS_Upgrade_Downloads - * - * Only models listed in thinkwiki will be supported, so add yours - * if it is not there yet. - */ -#define IBM_BIOS_MODULE_ALIAS(__type) \ - MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") - -/* Non-ancient thinkpads */ -MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); -MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); - -/* Ancient thinkpad BIOSes have to be identified by - * BIOS type or model number, and there are far less - * BIOS types than model numbers... */ -IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); -IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); -IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); - #define __unused __attribute__ ((unused)) /**************************************************************************** @@ -129,7 +106,7 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); * ACPI basic handles */ -static acpi_handle root_handle; +static acpi_handle root_handle = NULL; #define IBM_HANDLE(object, parent, paths...) \ static acpi_handle object##_handle; \ @@ -510,36 +487,19 @@ static char *next_cmd(char **cmds) /**************************************************************************** **************************************************************************** * - * Device model: input, hwmon and platform + * Device model: hwmon and platform * **************************************************************************** ****************************************************************************/ -static struct platform_device *tpacpi_pdev; -static struct class_device *tpacpi_hwmon; -static struct input_dev *tpacpi_inputdev; - - -static int tpacpi_resume_handler(struct platform_device *pdev) -{ - struct ibm_struct *ibm, *itmp; - - list_for_each_entry_safe(ibm, itmp, - &tpacpi_all_drivers, - all_drivers) { - if (ibm->resume) - (ibm->resume)(); - } - - return 0; -} +static struct platform_device *tpacpi_pdev = NULL; +static struct class_device *tpacpi_hwmon = NULL; static struct platform_driver tpacpi_pdriver = { .driver = { .name = IBM_DRVR_NAME, .owner = THIS_MODULE, }, - .resume = tpacpi_resume_handler, }; @@ -717,19 +677,9 @@ static int __init thinkpad_acpi_driver_init(struct ibm_init_struct *iibm) printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); printk(IBM_INFO "%s\n", IBM_URL); - printk(IBM_INFO "ThinkPad BIOS %s, EC %s\n", - (thinkpad_id.bios_version_str) ? - thinkpad_id.bios_version_str : "unknown", - (thinkpad_id.ec_version_str) ? - thinkpad_id.ec_version_str : "unknown"); - - if (thinkpad_id.vendor && thinkpad_id.model_str) - printk(IBM_INFO "%s %s\n", - (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ? - "IBM" : ((thinkpad_id.vendor == - PCI_VENDOR_ID_LENOVO) ? - "Lenovo" : "Unknown vendor"), - thinkpad_id.model_str); + if (ibm_thinkpad_ec_found) + printk(IBM_INFO "ThinkPad EC firmware %s\n", + ibm_thinkpad_ec_found); return 0; } @@ -754,28 +704,16 @@ static struct ibm_struct thinkpad_acpi_driver_data = { */ static int hotkey_orig_status; -static u32 hotkey_orig_mask; -static u32 hotkey_all_mask; -static u32 hotkey_reserved_mask; - -static u16 *hotkey_keycode_map; +static int hotkey_orig_mask; -static struct attribute_set *hotkey_dev_attributes; - -static int hotkey_get_wlsw(int *status) -{ - if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) - return -EIO; - return 0; -} +static struct attribute_set *hotkey_dev_attributes = NULL; /* sysfs hotkey enable ------------------------------------------------- */ static ssize_t hotkey_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { - int res, status; - u32 mask; + int res, status, mask; res = hotkey_get(&status, &mask); if (res) @@ -789,8 +727,7 @@ static ssize_t hotkey_enable_store(struct device *dev, const char *buf, size_t count) { unsigned long t; - int res, status; - u32 mask; + int res, status, mask; if (parse_strtoul(buf, 1, &t)) return -EINVAL; @@ -811,14 +748,13 @@ static ssize_t hotkey_mask_show(struct device *dev, struct device_attribute *attr, char *buf) { - int res, status; - u32 mask; + int res, status, mask; res = hotkey_get(&status, &mask); if (res) return res; - return snprintf(buf, PAGE_SIZE, "0x%08x\n", mask); + return snprintf(buf, PAGE_SIZE, "0x%04x\n", mask); } static ssize_t hotkey_mask_store(struct device *dev, @@ -826,10 +762,9 @@ static ssize_t hotkey_mask_store(struct device *dev, const char *buf, size_t count) { unsigned long t; - int res, status; - u32 mask; + int res, status, mask; - if (parse_strtoul(buf, 0xffffffffUL, &t)) + if (parse_strtoul(buf, 0xffff, &t)) return -EINVAL; res = hotkey_get(&status, &mask); @@ -859,123 +794,26 @@ static ssize_t hotkey_bios_mask_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_orig_mask); + return snprintf(buf, PAGE_SIZE, "0x%04x\n", hotkey_orig_mask); } static struct device_attribute dev_attr_hotkey_bios_mask = __ATTR(hotkey_bios_mask, S_IRUGO, hotkey_bios_mask_show, NULL); -/* sysfs hotkey all_mask ----------------------------------------------- */ -static ssize_t hotkey_all_mask_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_all_mask); -} - -static struct device_attribute dev_attr_hotkey_all_mask = - __ATTR(hotkey_all_mask, S_IRUGO, hotkey_all_mask_show, NULL); - -/* sysfs hotkey recommended_mask --------------------------------------- */ -static ssize_t hotkey_recommended_mask_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "0x%08x\n", - hotkey_all_mask & ~hotkey_reserved_mask); -} - -static struct device_attribute dev_attr_hotkey_recommended_mask = - __ATTR(hotkey_recommended_mask, S_IRUGO, - hotkey_recommended_mask_show, NULL); - -/* sysfs hotkey radio_sw ----------------------------------------------- */ -static ssize_t hotkey_radio_sw_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int res, s; - res = hotkey_get_wlsw(&s); - if (res < 0) - return res; - - return snprintf(buf, PAGE_SIZE, "%d\n", !!s); -} - -static struct device_attribute dev_attr_hotkey_radio_sw = - __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); - /* --------------------------------------------------------------------- */ static struct attribute *hotkey_mask_attributes[] = { &dev_attr_hotkey_mask.attr, &dev_attr_hotkey_bios_enabled.attr, &dev_attr_hotkey_bios_mask.attr, - &dev_attr_hotkey_all_mask.attr, - &dev_attr_hotkey_recommended_mask.attr, }; static int __init hotkey_init(struct ibm_init_struct *iibm) { - - static u16 ibm_keycode_map[] __initdata = { - /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ - KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, - KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, - KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, - /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ - KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ - KEY_UNKNOWN, /* 0x0D: FN+INSERT */ - KEY_UNKNOWN, /* 0x0E: FN+DELETE */ - KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ - /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ - KEY_RESERVED, /* 0x10: FN+END (brightness down) */ - KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ - KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ - KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ - KEY_RESERVED, /* 0x14: VOLUME UP */ - KEY_RESERVED, /* 0x15: VOLUME DOWN */ - KEY_RESERVED, /* 0x16: MUTE */ - KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ - /* (assignments unknown, please report if found) */ - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - }; - static u16 lenovo_keycode_map[] __initdata = { - /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ - KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, - KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, - KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, - /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ - KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ - KEY_UNKNOWN, /* 0x0D: FN+INSERT */ - KEY_UNKNOWN, /* 0x0E: FN+DELETE */ - KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ - /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ - KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ - KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ - KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ - KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ - KEY_RESERVED, /* 0x14: VOLUME UP */ - KEY_RESERVED, /* 0x15: VOLUME DOWN */ - KEY_RESERVED, /* 0x16: MUTE */ - KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ - /* (assignments unknown, please report if found) */ - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - }; - -#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) -#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) -#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) - - int res, i; - int status; + int res; vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); - BUG_ON(!tpacpi_inputdev); - IBM_ACPIHANDLE_INIT(hkey); mutex_init(&hotkey_mutex); @@ -986,7 +824,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) str_supported(tp_features.hotkey)); if (tp_features.hotkey) { - hotkey_dev_attributes = create_attr_set(7, NULL); + hotkey_dev_attributes = create_attr_set(4, NULL); if (!hotkey_dev_attributes) return -ENOMEM; res = add_to_attr_set(hotkey_dev_attributes, @@ -1002,92 +840,19 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", str_supported(tp_features.hotkey_mask)); - if (tp_features.hotkey_mask) { - /* MHKA available in A31, R40, R40e, T4x, X31, and later */ - if (!acpi_evalf(hkey_handle, &hotkey_all_mask, - "MHKA", "qd")) - hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */ - } - res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); if (!res && tp_features.hotkey_mask) { res = add_many_to_attr_set(hotkey_dev_attributes, hotkey_mask_attributes, ARRAY_SIZE(hotkey_mask_attributes)); } - - /* Not all thinkpads have a hardware radio switch */ - if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { - tp_features.hotkey_wlsw = 1; - printk(IBM_INFO - "radio switch found; radios are %s\n", - enabled(status, 0)); - res = add_to_attr_set(hotkey_dev_attributes, - &dev_attr_hotkey_radio_sw.attr); - } - if (!res) res = register_attr_set_with_sysfs( hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); - if (res) - return res; - - /* Set up key map */ - - hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, - GFP_KERNEL); - if (!hotkey_keycode_map) { - printk(IBM_ERR "failed to allocate memory for key map\n"); - return -ENOMEM; - } - - if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { - dbg_printk(TPACPI_DBG_INIT, - "using Lenovo default hot key map\n"); - memcpy(hotkey_keycode_map, &lenovo_keycode_map, - TPACPI_HOTKEY_MAP_SIZE); - } else { - dbg_printk(TPACPI_DBG_INIT, - "using IBM default hot key map\n"); - memcpy(hotkey_keycode_map, &ibm_keycode_map, - TPACPI_HOTKEY_MAP_SIZE); - } -#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED - for (i = 0; i < 12; i++) - hotkey_keycode_map[i] = KEY_UNKNOWN; -#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ - - set_bit(EV_KEY, tpacpi_inputdev->evbit); - set_bit(EV_MSC, tpacpi_inputdev->evbit); - set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); - tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; - tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; - tpacpi_inputdev->keycode = hotkey_keycode_map; - for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { - if (hotkey_keycode_map[i] != KEY_RESERVED) { - set_bit(hotkey_keycode_map[i], - tpacpi_inputdev->keybit); - } else { - if (i < sizeof(hotkey_reserved_mask)*8) - hotkey_reserved_mask |= 1 << i; - } - } - - if (tp_features.hotkey_wlsw) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_RADIO, tpacpi_inputdev->swbit); - } - -#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED - dbg_printk(TPACPI_DBG_INIT, - "enabling hot key handling\n"); - res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) - | hotkey_orig_mask); if (res) return res; -#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ } return (tp_features.hotkey)? 0 : 1; @@ -1110,101 +875,22 @@ static void hotkey_exit(void) } } -static void tpacpi_input_send_key(unsigned int scancode, - unsigned int keycode) -{ - if (keycode != KEY_RESERVED) { - input_report_key(tpacpi_inputdev, keycode, 1); - if (keycode == KEY_UNKNOWN) - input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, - scancode); - input_sync(tpacpi_inputdev); - - input_report_key(tpacpi_inputdev, keycode, 0); - if (keycode == KEY_UNKNOWN) - input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, - scancode); - input_sync(tpacpi_inputdev); - } -} - -static void tpacpi_input_send_radiosw(void) -{ - int wlsw; - - if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) - input_report_switch(tpacpi_inputdev, - SW_RADIO, !!wlsw); -} - static void hotkey_notify(struct ibm_struct *ibm, u32 event) { - u32 hkey; - unsigned int keycode, scancode; - int sendacpi = 1; - - if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { - if (tpacpi_inputdev->users > 0) { - switch (hkey >> 12) { - case 1: - /* 0x1000-0x1FFF: key presses */ - scancode = hkey & 0xfff; - if (scancode > 0 && scancode < 0x21) { - scancode--; - keycode = hotkey_keycode_map[scancode]; - tpacpi_input_send_key(scancode, keycode); - sendacpi = (keycode == KEY_RESERVED - || keycode == KEY_UNKNOWN); - } else { - printk(IBM_ERR - "hotkey 0x%04x out of range for keyboard map\n", - hkey); - } - break; - case 5: - /* 0x5000-0x5FFF: LID */ - /* we don't handle it through this path, just - * eat up known LID events */ - if (hkey != 0x5001 && hkey != 0x5002) { - printk(IBM_ERR - "unknown LID-related hotkey event: 0x%04x\n", - hkey); - } - break; - case 7: - /* 0x7000-0x7FFF: misc */ - if (tp_features.hotkey_wlsw && hkey == 0x7000) { - tpacpi_input_send_radiosw(); - sendacpi = 0; - break; - } - /* fallthrough to default */ - default: - /* case 2: dock-related */ - /* 0x2305 - T43 waking up due to bay lever eject while aslept */ - /* case 3: ultra-bay related. maybe bay in dock? */ - /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ - printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey); - } - } + int hkey; - if (sendacpi) - acpi_bus_generate_event(ibm->acpi->device, event, hkey); - } else { - printk(IBM_ERR "unknown hotkey notification event %d\n", event); + if (acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) + acpi_bus_generate_event(ibm->acpi->device, event, hkey); + else { + printk(IBM_ERR "unknown hotkey event %d\n", event); acpi_bus_generate_event(ibm->acpi->device, event, 0); } } -static void hotkey_resume(void) -{ - tpacpi_input_send_radiosw(); -} - /* * Call with hotkey_mutex held */ -static int hotkey_get(int *status, u32 *mask) +static int hotkey_get(int *status, int *mask) { if (!acpi_evalf(hkey_handle, status, "DHKC", "d")) return -EIO; @@ -1219,7 +905,7 @@ static int hotkey_get(int *status, u32 *mask) /* * Call with hotkey_mutex held */ -static int hotkey_set(int status, u32 mask) +static int hotkey_set(int status, int mask) { int i; @@ -1240,8 +926,7 @@ static int hotkey_set(int status, u32 mask) /* procfs -------------------------------------------------------------- */ static int hotkey_read(char *p) { - int res, status; - u32 mask; + int res, status, mask; int len = 0; if (!tp_features.hotkey) { @@ -1259,7 +944,7 @@ static int hotkey_read(char *p) len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); if (tp_features.hotkey_mask) { - len += sprintf(p + len, "mask:\t\t0x%08x\n", mask); + len += sprintf(p + len, "mask:\t\t0x%04x\n", mask); len += sprintf(p + len, "commands:\tenable, disable, reset, \n"); } else { @@ -1272,8 +957,7 @@ static int hotkey_read(char *p) static int hotkey_write(char *buf) { - int res, status; - u32 mask; + int res, status, mask; char *cmd; int do_cmd = 0; @@ -1328,7 +1012,6 @@ static struct ibm_struct hotkey_driver_data = { .read = hotkey_read, .write = hotkey_write, .exit = hotkey_exit, - .resume = hotkey_resume, .acpi = &ibm_hotkey_acpidriver, }; @@ -2087,10 +1770,7 @@ static struct tp_acpi_drv_struct ibm_dock_acpidriver[2] = { .type = ACPI_SYSTEM_NOTIFY, }, { - /* THIS ONE MUST NEVER BE USED FOR DRIVER AUTOLOADING. - * We just use it to get notifications of dock hotplug - * in very old thinkpads */ - .hid = PCI_ROOT_HID_STRING, + .hid = IBM_PCI_HID, .notify = dock_notify, .handle = &pci_handle, .type = ACPI_SYSTEM_NOTIFY, @@ -2149,7 +1829,7 @@ static int __init dock_init2(struct ibm_init_struct *iibm) static void dock_notify(struct ibm_struct *ibm, u32 event) { int docked = dock_docked(); - int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, PCI_ROOT_HID_STRING); + int pci = ibm->acpi->hid && strstr(ibm->acpi->hid, IBM_PCI_HID); if (event == 1 && !pci) /* 570 */ acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ @@ -2709,7 +2389,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) acpi_tmp7 = acpi_evalf(ec_handle, NULL, "TMP7", "qv"); - if (thinkpad_id.ec_model) { + if (ibm_thinkpad_ec_found && experimental) { /* * Direct EC access mode: sensors at registers * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for @@ -2853,8 +2533,6 @@ static int thermal_get_sensor(int idx, s32 *value) snprintf(tmpi, sizeof(tmpi), "TMP%c", '0' + idx); if (!acpi_evalf(ec_handle, &t, tmpi, "d")) return -EIO; - if (t > 127 || t < -127) - t = TP_EC_THERMAL_TMP_NA; *value = t * 1000; return 0; } @@ -2993,39 +2671,22 @@ static struct ibm_struct ecdump_driver_data = { * Backlight/brightness subdriver */ -static struct backlight_device *ibm_backlight_device; +static struct backlight_device *ibm_backlight_device = NULL; static struct backlight_ops ibm_backlight_data = { .get_brightness = brightness_get, .update_status = brightness_update_status, }; -static struct mutex brightness_mutex; - static int __init brightness_init(struct ibm_init_struct *iibm) { int b; vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n"); - mutex_init(&brightness_mutex); - - if (!brightness_mode) { - if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) - brightness_mode = 2; - else - brightness_mode = 3; - - dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n", - brightness_mode); - } - - if (brightness_mode > 3) - return -EINVAL; - b = brightness_get(NULL); if (b < 0) - return 1; + return b; ibm_backlight_device = backlight_device_register( TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, @@ -3061,79 +2722,34 @@ static int brightness_update_status(struct backlight_device *bd) bd->props.brightness : 0); } -/* - * ThinkPads can read brightness from two places: EC 0x31, or - * CMOS NVRAM byte 0x5E, bits 0-3. - */ static int brightness_get(struct backlight_device *bd) { - u8 lec = 0, lcmos = 0, level = 0; - - if (brightness_mode & 1) { - if (!acpi_ec_read(brightness_offset, &lec)) - return -EIO; - lec &= 7; - level = lec; - }; - if (brightness_mode & 2) { - lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS) - & TP_NVRAM_MASK_LEVEL_BRIGHTNESS) - >> TP_NVRAM_POS_LEVEL_BRIGHTNESS; - level = lcmos; - } - - if (brightness_mode == 3 && lec != lcmos) { - printk(IBM_ERR - "CMOS NVRAM (%u) and EC (%u) do not agree " - "on display brightness level\n", - (unsigned int) lcmos, - (unsigned int) lec); + u8 level; + if (!acpi_ec_read(brightness_offset, &level)) return -EIO; - } + + level &= 0x7; return level; } static int brightness_set(int value) { - int cmos_cmd, inc, i, res; - int current_value; - - if (value > 7) - return -EINVAL; - - res = mutex_lock_interruptible(&brightness_mutex); - if (res < 0) - return res; + int cmos_cmd, inc, i; + int current_value = brightness_get(NULL); - current_value = brightness_get(NULL); - if (current_value < 0) { - res = current_value; - goto errout; - } + value &= 7; - cmos_cmd = value > current_value ? - TP_CMOS_BRIGHTNESS_UP : - TP_CMOS_BRIGHTNESS_DOWN; + cmos_cmd = value > current_value ? TP_CMOS_BRIGHTNESS_UP : TP_CMOS_BRIGHTNESS_DOWN; inc = value > current_value ? 1 : -1; - - res = 0; for (i = current_value; i != value; i += inc) { - if ((brightness_mode & 2) && - issue_thinkpad_cmos_command(cmos_cmd)) { - res = -EIO; - goto errout; - } - if ((brightness_mode & 1) && - !acpi_ec_write(brightness_offset, i + inc)) { - res = -EIO; - goto errout;; - } + if (issue_thinkpad_cmos_command(cmos_cmd)) + return -EIO; + if (!acpi_ec_write(brightness_offset, i + inc)) + return -EIO; } -errout: - mutex_unlock(&brightness_mutex); - return res; + return 0; } static int brightness_read(char *p) @@ -3657,19 +3273,20 @@ static int __init fan_init(struct ibm_init_struct *iibm) * Enable for TP-1Y (T43), TP-78 (R51e), * TP-76 (R52), TP-70 (T43, R52), which are known * to be buggy. */ - if (fan_control_initial_status == 0x07) { - switch (thinkpad_id.ec_model) { - case 0x5931: /* TP-1Y */ - case 0x3837: /* TP-78 */ - case 0x3637: /* TP-76 */ - case 0x3037: /* TP-70 */ - printk(IBM_NOTICE - "fan_init: initial fan status is " - "unknown, assuming it is in auto " - "mode\n"); - tp_features.fan_ctrl_status_undef = 1; - ;; - } + if (fan_control_initial_status == 0x07 && + ibm_thinkpad_ec_found && + ((ibm_thinkpad_ec_found[0] == '1' && + ibm_thinkpad_ec_found[1] == 'Y') || + (ibm_thinkpad_ec_found[0] == '7' && + (ibm_thinkpad_ec_found[1] == '6' || + ibm_thinkpad_ec_found[1] == '8' || + ibm_thinkpad_ec_found[1] == '0')) + )) { + printk(IBM_NOTICE + "fan_init: initial fan status is " + "unknown, assuming it is in auto " + "mode\n"); + tp_features.fan_ctrl_status_undef = 1; } } else { printk(IBM_ERR @@ -3857,7 +3474,7 @@ static void fan_watchdog_fire(struct work_struct *ignored) static void fan_watchdog_reset(void) { - static int fan_watchdog_active; + static int fan_watchdog_active = 0; if (fan_control_access_mode == TPACPI_FAN_WR_NONE) return; @@ -4260,7 +3877,7 @@ static struct ibm_struct fan_driver_data = { ****************************************************************************/ /* /proc support */ -static struct proc_dir_entry *proc_dir; +static struct proc_dir_entry *proc_dir = NULL; /* Subdriver registry */ static LIST_HEAD(tpacpi_all_drivers); @@ -4403,30 +4020,13 @@ static void ibm_exit(struct ibm_struct *ibm) /* Probing */ -static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) +static char *ibm_thinkpad_ec_found = NULL; + +static char* __init check_dmi_for_ec(void) { struct dmi_device *dev = NULL; char ec_fw_string[18]; - if (!tp) - return; - - memset(tp, 0, sizeof(*tp)); - - if (dmi_name_in_vendors("IBM")) - tp->vendor = PCI_VENDOR_ID_IBM; - else if (dmi_name_in_vendors("LENOVO")) - tp->vendor = PCI_VENDOR_ID_LENOVO; - else - return; - - tp->bios_version_str = kstrdup(dmi_get_system_info(DMI_BIOS_VERSION), - GFP_KERNEL); - if (!tp->bios_version_str) - return; - tp->bios_model = tp->bios_version_str[0] - | (tp->bios_version_str[1] << 8); - /* * ThinkPad T23 or newer, A31 or newer, R50e or newer, * X32 or newer, all Z series; Some models must have an @@ -4440,20 +4040,10 @@ static void __init get_thinkpad_model_data(struct thinkpad_id_data *tp) ec_fw_string) == 1) { ec_fw_string[sizeof(ec_fw_string) - 1] = 0; ec_fw_string[strcspn(ec_fw_string, " ]")] = 0; - - tp->ec_version_str = kstrdup(ec_fw_string, GFP_KERNEL); - tp->ec_model = ec_fw_string[0] - | (ec_fw_string[1] << 8); - break; + return kstrdup(ec_fw_string, GFP_KERNEL); } } - - tp->model_str = kstrdup(dmi_get_system_info(DMI_PRODUCT_VERSION), - GFP_KERNEL); - if (strnicmp(tp->model_str, "ThinkPad", 8) != 0) { - kfree(tp->model_str); - tp->model_str = NULL; - } + return NULL; } static int __init probe_for_thinkpad(void) @@ -4467,7 +4057,7 @@ static int __init probe_for_thinkpad(void) * Non-ancient models have better DMI tagging, but very old models * don't. */ - is_thinkpad = (thinkpad_id.model_str != NULL); + is_thinkpad = dmi_name_in_vendors("ThinkPad"); /* ec is required because many other handles are relative to it */ IBM_ACPIHANDLE_INIT(ec); @@ -4483,7 +4073,7 @@ static int __init probe_for_thinkpad(void) * false positives a damn great deal */ if (!is_thinkpad) - is_thinkpad = (thinkpad_id.vendor == PCI_VENDOR_ID_IBM); + is_thinkpad = dmi_name_in_vendors("IBM"); if (!is_thinkpad && !force_load) return -ENODEV; @@ -4595,13 +4185,10 @@ static u32 dbg_level; module_param_named(debug, dbg_level, uint, 0); static int force_load; -module_param(force_load, bool, 0); +module_param(force_load, int, 0); static int fan_control_allowed; -module_param_named(fan_control, fan_control_allowed, bool, 0); - -static int brightness_mode; -module_param_named(brightness_mode, brightness_mode, int, 0); +module_param_named(fan_control, fan_control_allowed, int, 0); #define IBM_PARAM(feature) \ module_param_call(feature, set_ibm_param, NULL, NULL, 0) @@ -4629,16 +4216,12 @@ static int __init thinkpad_acpi_module_init(void) int ret, i; /* Driver-level probe */ - - get_thinkpad_model_data(&thinkpad_id); ret = probe_for_thinkpad(); - if (ret) { - thinkpad_acpi_module_exit(); + if (ret) return ret; - } /* Driver initialization */ - + ibm_thinkpad_ec_found = check_dmi_for_ec(); IBM_ACPIHANDLE_INIT(ecrd); IBM_ACPIHANDLE_INIT(ecwr); @@ -4682,22 +4265,6 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } - tpacpi_inputdev = input_allocate_device(); - if (!tpacpi_inputdev) { - printk(IBM_ERR "unable to allocate input device\n"); - thinkpad_acpi_module_exit(); - return -ENOMEM; - } else { - /* Prepare input device, but don't register */ - tpacpi_inputdev->name = "ThinkPad Extra Buttons"; - tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0"; - tpacpi_inputdev->id.bustype = BUS_HOST; - tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? - thinkpad_id.vendor : - PCI_VENDOR_ID_IBM; - tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; - tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; - } for (i = 0; i < ARRAY_SIZE(ibms_init); i++) { ret = ibm_init(&ibms_init[i]); if (ret >= 0 && *ibms_init[i].param) @@ -4707,14 +4274,6 @@ static int __init thinkpad_acpi_module_init(void) return ret; } } - ret = input_register_device(tpacpi_inputdev); - if (ret < 0) { - printk(IBM_ERR "unable to register input device\n"); - thinkpad_acpi_module_exit(); - return ret; - } else { - tp_features.input_device_registered = 1; - } return 0; } @@ -4731,13 +4290,6 @@ static void thinkpad_acpi_module_exit(void) dbg_printk(TPACPI_DBG_INIT, "finished subdriver exit path...\n"); - if (tpacpi_inputdev) { - if (tp_features.input_device_registered) - input_unregister_device(tpacpi_inputdev); - else - input_free_device(tpacpi_inputdev); - } - if (tpacpi_hwmon) hwmon_device_unregister(tpacpi_hwmon); @@ -4750,9 +4302,7 @@ static void thinkpad_acpi_module_exit(void) if (proc_dir) remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); - kfree(thinkpad_id.bios_version_str); - kfree(thinkpad_id.ec_version_str); - kfree(thinkpad_id.model_str); + kfree(ibm_thinkpad_ec_found); } module_init(thinkpad_acpi_module_init); diff --git a/trunk/drivers/misc/thinkpad_acpi.h b/trunk/drivers/misc/thinkpad_acpi.h index b7a4a888cc8b..72d62f2dabb9 100644 --- a/trunk/drivers/misc/thinkpad_acpi.h +++ b/trunk/drivers/misc/thinkpad_acpi.h @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -40,7 +39,6 @@ #include #include #include -#include #include #include @@ -50,7 +48,6 @@ #include #include -#include /**************************************************************************** * Main driver @@ -81,11 +78,6 @@ #define TP_CMOS_BRIGHTNESS_UP 4 #define TP_CMOS_BRIGHTNESS_DOWN 5 -/* ThinkPad CMOS NVRAM constants */ -#define TP_NVRAM_ADDR_BRIGHTNESS 0x5e -#define TP_NVRAM_MASK_LEVEL_BRIGHTNESS 0x07 -#define TP_NVRAM_POS_LEVEL_BRIGHTNESS 0 - #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) @@ -106,13 +98,9 @@ static const char *str_supported(int is_supported); #define vdbg_printk(a_dbg_level, format, arg...) #endif -/* Input IDs */ -#define TPACPI_HKEY_INPUT_VENDOR PCI_VENDOR_ID_IBM -#define TPACPI_HKEY_INPUT_PRODUCT 0x5054 /* "TP" */ -#define TPACPI_HKEY_INPUT_VERSION 0x4101 - /* ACPI HIDs */ #define IBM_HKEY_HID "IBM0068" +#define IBM_PCI_HID "PNP0A03" /* ACPI helpers */ static int __must_check acpi_evalf(acpi_handle handle, @@ -173,7 +161,6 @@ static int parse_strtoul(const char *buf, unsigned long max, static struct platform_device *tpacpi_pdev; static struct class_device *tpacpi_hwmon; static struct platform_driver tpacpi_pdriver; -static struct input_dev *tpacpi_inputdev; static int tpacpi_create_driver_attributes(struct device_driver *drv); static void tpacpi_remove_driver_attributes(struct device_driver *drv); @@ -181,7 +168,9 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv); static int experimental; static u32 dbg_level; static int force_load; +static char *ibm_thinkpad_ec_found; +static char* check_dmi_for_ec(void); static int thinkpad_acpi_module_init(void); static void thinkpad_acpi_module_exit(void); @@ -208,7 +197,6 @@ struct ibm_struct { int (*read) (char *); int (*write) (char *); void (*exit) (void); - void (*resume) (void); struct list_head all_drivers; @@ -240,29 +228,12 @@ static struct { u16 bluetooth:1; u16 hotkey:1; u16 hotkey_mask:1; - u16 hotkey_wlsw:1; u16 light:1; u16 light_status:1; u16 wan:1; u16 fan_ctrl_status_undef:1; - u16 input_device_registered:1; } tp_features; -struct thinkpad_id_data { - unsigned int vendor; /* ThinkPad vendor: - * PCI_VENDOR_ID_IBM/PCI_VENDOR_ID_LENOVO */ - - char *bios_version_str; /* Something like 1ZET51WW (1.03z) */ - char *ec_version_str; /* Something like 1ZHT51WW-1.04a */ - - u16 bios_model; /* Big Endian, TP-1Y = 0x5931, 0 = unknown */ - u16 ec_model; - - char *model_str; -}; - -static struct thinkpad_id_data thinkpad_id; - static struct list_head tpacpi_all_drivers; static struct ibm_init_struct ibms_init[]; @@ -329,7 +300,6 @@ static int bluetooth_write(char *buf); static struct backlight_device *ibm_backlight_device; static int brightness_offset = 0x31; -static int brightness_mode; static int brightness_init(struct ibm_init_struct *iibm); static void brightness_exit(void); @@ -445,14 +415,14 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc); */ static int hotkey_orig_status; -static u32 hotkey_orig_mask; +static int hotkey_orig_mask; static struct mutex hotkey_mutex; static int hotkey_init(struct ibm_init_struct *iibm); static void hotkey_exit(void); -static int hotkey_get(int *status, u32 *mask); -static int hotkey_set(int status, u32 mask); +static int hotkey_get(int *status, int *mask); +static int hotkey_set(int status, int mask); static void hotkey_notify(struct ibm_struct *ibm, u32 event); static int hotkey_read(char *p); static int hotkey_write(char *buf); diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 564cc9b51822..2a237f09ee5d 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -12,13 +12,6 @@ config VGASTATE tristate default n -config VIDEO_OUTPUT_CONTROL - tristate "Lowlevel video output switch controls" - default m - help - This framework adds support for low-level control of the video - output switch. - config FB tristate "Support for frame buffer devices" ---help--- diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 518933d4905f..a562f9d69d2c 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -123,6 +123,3 @@ obj-$(CONFIG_FB_OF) += offb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o - -#video output switch sysfs driver -obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o diff --git a/trunk/include/acpi/acmacros.h b/trunk/include/acpi/acmacros.h index 45662f6dbdb6..8948a6461834 100644 --- a/trunk/include/acpi/acmacros.h +++ b/trunk/include/acpi/acmacros.h @@ -486,8 +486,6 @@ #define ACPI_FUNCTION_NAME(name) #endif -#ifdef DEBUG_FUNC_TRACE - #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ acpi_ut_trace(ACPI_DEBUG_PARAMETERS) #define ACPI_FUNCTION_TRACE_PTR(a,b) ACPI_FUNCTION_NAME(a) \ @@ -565,27 +563,6 @@ #endif /* ACPI_SIMPLE_RETURN_MACROS */ -#else /* !DEBUG_FUNC_TRACE */ - -#define ACPI_FUNCTION_TRACE(a) -#define ACPI_FUNCTION_TRACE_PTR(a,b) -#define ACPI_FUNCTION_TRACE_U32(a,b) -#define ACPI_FUNCTION_TRACE_STR(a,b) -#define ACPI_FUNCTION_EXIT -#define ACPI_FUNCTION_STATUS_EXIT(s) -#define ACPI_FUNCTION_VALUE_EXIT(s) -#define ACPI_FUNCTION_TRACE(a) -#define ACPI_FUNCTION_ENTRY() - -#define return_VOID return -#define return_ACPI_STATUS(s) return(s) -#define return_VALUE(s) return(s) -#define return_UINT8(s) return(s) -#define return_UINT32(s) return(s) -#define return_PTR(s) return(s) - -#endif /* DEBUG_FUNC_TRACE */ - /* Conditional execution */ #define ACPI_DEBUG_EXEC(a) a @@ -622,26 +599,26 @@ #define ACPI_DEBUG_EXEC(a) #define ACPI_NORMAL_EXEC(a) a; -#define ACPI_DEBUG_DEFINE(a) do { } while(0) -#define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0) -#define ACPI_FUNCTION_NAME(a) do { } while(0) -#define ACPI_FUNCTION_TRACE(a) do { } while(0) -#define ACPI_FUNCTION_TRACE_PTR(a,b) do { } while(0) -#define ACPI_FUNCTION_TRACE_U32(a,b) do { } while(0) -#define ACPI_FUNCTION_TRACE_STR(a,b) do { } while(0) -#define ACPI_FUNCTION_EXIT do { } while(0) -#define ACPI_FUNCTION_STATUS_EXIT(s) do { } while(0) -#define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0) -#define ACPI_FUNCTION_ENTRY() do { } while(0) -#define ACPI_DUMP_STACK_ENTRY(a) do { } while(0) -#define ACPI_DUMP_OPERANDS(a,b,c,d,e) do { } while(0) -#define ACPI_DUMP_ENTRY(a,b) do { } while(0) -#define ACPI_DUMP_TABLES(a,b) do { } while(0) -#define ACPI_DUMP_PATHNAME(a,b,c,d) do { } while(0) -#define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0) -#define ACPI_DUMP_BUFFER(a,b) do { } while(0) -#define ACPI_DEBUG_PRINT(pl) do { } while(0) -#define ACPI_DEBUG_PRINT_RAW(pl) do { } while(0) +#define ACPI_DEBUG_DEFINE(a) +#define ACPI_DEBUG_ONLY_MEMBERS(a) +#define ACPI_FUNCTION_NAME(a) +#define ACPI_FUNCTION_TRACE(a) +#define ACPI_FUNCTION_TRACE_PTR(a,b) +#define ACPI_FUNCTION_TRACE_U32(a,b) +#define ACPI_FUNCTION_TRACE_STR(a,b) +#define ACPI_FUNCTION_EXIT +#define ACPI_FUNCTION_STATUS_EXIT(s) +#define ACPI_FUNCTION_VALUE_EXIT(s) +#define ACPI_FUNCTION_ENTRY() +#define ACPI_DUMP_STACK_ENTRY(a) +#define ACPI_DUMP_OPERANDS(a,b,c,d,e) +#define ACPI_DUMP_ENTRY(a,b) +#define ACPI_DUMP_TABLES(a,b) +#define ACPI_DUMP_PATHNAME(a,b,c,d) +#define ACPI_DUMP_RESOURCE_LIST(a) +#define ACPI_DUMP_BUFFER(a,b) +#define ACPI_DEBUG_PRINT(pl) +#define ACPI_DEBUG_PRINT_RAW(pl) #define return_VOID return #define return_ACPI_STATUS(s) return(s) diff --git a/trunk/include/acpi/acoutput.h b/trunk/include/acpi/acoutput.h index c090a8b0bc99..7812267b577f 100644 --- a/trunk/include/acpi/acoutput.h +++ b/trunk/include/acpi/acoutput.h @@ -178,8 +178,8 @@ /* Defaults for debug_level, debug and normal */ -#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR) -#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR) +#define ACPI_DEBUG_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) +#define ACPI_NORMAL_DEFAULT (ACPI_LV_INIT | ACPI_LV_WARN | ACPI_LV_ERROR | ACPI_LV_DEBUG_OBJECT) #define ACPI_DEBUG_ALL (ACPI_LV_AML_DISASSEMBLE | ACPI_LV_ALL_EXCEPTIONS | ACPI_LV_ALL) #endif /* __ACOUTPUT_H__ */ diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index 5e3dcf3299bf..c6fa5e023bc7 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -321,8 +321,7 @@ struct acpi_bus_event { }; extern struct kset acpi_subsys; -extern int acpi_bus_generate_genetlink_event(struct acpi_device *device, - u8 type, int data); + /* * External Functions */ diff --git a/trunk/include/acpi/platform/acenv.h b/trunk/include/acpi/platform/acenv.h index c785485e62a6..dab2ec59a3b0 100644 --- a/trunk/include/acpi/platform/acenv.h +++ b/trunk/include/acpi/platform/acenv.h @@ -136,7 +136,7 @@ /*! [Begin] no source code translation */ -#if defined(_LINUX) || defined(__linux__) +#if defined(__linux__) #include "aclinux.h" #elif defined(_AED_EFI) diff --git a/trunk/include/acpi/platform/aclinux.h b/trunk/include/acpi/platform/aclinux.h index 6ed15a0978eb..a568717f98c6 100644 --- a/trunk/include/acpi/platform/aclinux.h +++ b/trunk/include/acpi/platform/aclinux.h @@ -91,10 +91,7 @@ #define ACPI_USE_NATIVE_DIVIDE #endif -#ifndef __cdecl #define __cdecl -#endif - #define ACPI_FLUSH_CPU_CACHE() #endif /* __KERNEL__ */ diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index f9f987f8e661..b4b0ffdab098 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -21,8 +21,6 @@ #define ACPI_PSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */ #define ACPI_PSD_REV0_ENTRIES 5 -#define ACPI_TSD_REV0_REVISION 0 /* Support for _PSD as in ACPI 3.0 */ -#define ACPI_TSD_REV0_ENTRIES 5 /* * Types of coordination defined in ACPI 3.0. Same macros can be used across * P, C and T states @@ -127,53 +125,17 @@ struct acpi_processor_performance { /* Throttling Control */ -struct acpi_tsd_package { - acpi_integer num_entries; - acpi_integer revision; - acpi_integer domain; - acpi_integer coord_type; - acpi_integer num_processors; -} __attribute__ ((packed)); - -struct acpi_ptc_register { - u8 descriptor; - u16 length; - u8 space_id; - u8 bit_width; - u8 bit_offset; - u8 reserved; - u64 address; -} __attribute__ ((packed)); - -struct acpi_processor_tx_tss { - acpi_integer freqpercentage; /* */ - acpi_integer power; /* milliWatts */ - acpi_integer transition_latency; /* microseconds */ - acpi_integer control; /* control value */ - acpi_integer status; /* success indicator */ -}; struct acpi_processor_tx { u16 power; u16 performance; }; -struct acpi_processor; struct acpi_processor_throttling { - unsigned int state; - unsigned int platform_limit; - struct acpi_pct_register control_register; - struct acpi_pct_register status_register; - unsigned int state_count; - struct acpi_processor_tx_tss *states_tss; - struct acpi_tsd_package domain_info; - cpumask_t shared_cpu_map; - int (*acpi_processor_get_throttling) (struct acpi_processor * pr); - int (*acpi_processor_set_throttling) (struct acpi_processor * pr, - int state); - + int state; u32 address; u8 duty_offset; u8 duty_width; + int state_count; struct acpi_processor_tx states[ACPI_PROCESSOR_MAX_THROTTLING]; }; @@ -207,9 +169,6 @@ struct acpi_processor { u32 id; u32 pblk; int performance_platform_limit; - int throttling_platform_limit; - /* 0 - states 0..n-th state available */ - struct acpi_processor_flags flags; struct acpi_processor_power power; struct acpi_processor_performance *performance; @@ -311,7 +270,7 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) /* in processor_throttling.c */ int acpi_processor_get_throttling_info(struct acpi_processor *pr); -extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state); +int acpi_processor_set_throttling(struct acpi_processor *pr, int state); extern struct file_operations acpi_processor_throttling_fops; /* in processor_idle.c */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index ced4d3f76104..b15c6498fe67 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2040,8 +2040,6 @@ #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb -#define PCI_VENDOR_ID_LENOVO 0x17aa - #define PCI_VENDOR_ID_ARECA 0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120