summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-firmware-acpi16
-rw-r--r--Documentation/acpi/debug.txt148
-rw-r--r--Documentation/kernel-parameters.txt87
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/ia64/kvm/Kconfig2
-rw-r--r--arch/ia64/kvm/kvm-ia64.c12
-rw-r--r--arch/ia64/kvm/vcpu.h5
-rw-r--r--arch/mn10300/Kconfig.debug9
-rw-r--r--arch/mn10300/mm/misalignment.c538
-rw-r--r--arch/x86/include/asm/acpi.h1
-rw-r--r--arch/x86/kernel/acpi/boot.c1
-rw-r--r--arch/x86/kernel/kvmclock.c2
-rw-r--r--arch/x86/kvm/Kconfig2
-rw-r--r--arch/x86/kvm/i8254.c4
-rw-r--r--arch/x86/kvm/mmu.c2
-rw-r--r--arch/x86/kvm/vmx.c3
-rw-r--r--arch/x86/kvm/vmx.h1
-rw-r--r--drivers/acpi/Kconfig22
-rw-r--r--drivers/acpi/Makefile8
-rw-r--r--drivers/acpi/ac.c3
-rw-r--r--drivers/acpi/acpi_memhotplug.c1
-rw-r--r--drivers/acpi/battery.c3
-rw-r--r--drivers/acpi/bus.c11
-rw-r--r--drivers/acpi/button.c3
-rw-r--r--drivers/acpi/cm_sbs.c7
-rw-r--r--drivers/acpi/container.c1
-rw-r--r--drivers/acpi/debug.c15
-rw-r--r--drivers/acpi/ec.c97
-rw-r--r--drivers/acpi/events/evgpe.c2
-rw-r--r--drivers/acpi/events/evxfevnt.c41
-rw-r--r--drivers/acpi/fan.c1
-rw-r--r--drivers/acpi/glue.c40
-rw-r--r--drivers/acpi/pci_link.c11
-rw-r--r--drivers/acpi/pci_root.c6
-rw-r--r--drivers/acpi/power.c11
-rw-r--r--drivers/acpi/processor_core.c93
-rw-r--r--drivers/acpi/processor_idle.c1
-rw-r--r--drivers/acpi/processor_perflib.c2
-rw-r--r--drivers/acpi/processor_thermal.c1
-rw-r--r--drivers/acpi/processor_throttling.c2
-rw-r--r--drivers/acpi/reboot.c25
-rw-r--r--drivers/acpi/scan.c42
-rw-r--r--drivers/acpi/sleep/proc.c4
-rw-r--r--drivers/acpi/sleep/wakeup.c8
-rw-r--r--drivers/acpi/system.c48
-rw-r--r--drivers/acpi/tables/tbfadt.c2
-rw-r--r--drivers/acpi/thermal.c9
-rw-r--r--drivers/acpi/video.c42
-rw-r--r--drivers/acpi/video_detect.c267
-rw-r--r--drivers/acpi/wmi.c2
-rw-r--r--drivers/char/sonypi.c4
-rw-r--r--drivers/idle/Kconfig3
-rw-r--r--drivers/misc/Kconfig4
-rw-r--r--drivers/misc/acer-wmi.c6
-rw-r--r--drivers/misc/asus-laptop.c10
-rw-r--r--drivers/misc/compal-laptop.c12
-rw-r--r--drivers/misc/eeepc-laptop.c12
-rw-r--r--drivers/misc/fujitsu-laptop.c43
-rw-r--r--drivers/misc/intel_menlow.c10
-rw-r--r--drivers/misc/msi-laptop.c16
-rw-r--r--drivers/misc/sony-laptop.c6
-rw-r--r--drivers/misc/thinkpad_acpi.c29
-rw-r--r--include/acpi/acpi_bus.h2
-rw-r--r--include/acpi/acpi_drivers.h22
-rw-r--r--include/acpi/acpixf.h4
-rw-r--r--include/acpi/actypes.h1
-rw-r--r--include/linux/acpi.h48
-rw-r--r--mm/mmap.c2
68 files changed, 1393 insertions, 516 deletions
diff --git a/Documentation/ABI/testing/sysfs-firmware-acpi b/Documentation/ABI/testing/sysfs-firmware-acpi
index f27be7d1a49f..e8ffc70ffe12 100644
--- a/Documentation/ABI/testing/sysfs-firmware-acpi
+++ b/Documentation/ABI/testing/sysfs-firmware-acpi
@@ -89,7 +89,7 @@ Description:
error - an interrupt that can't be accounted for above.
- invalid: it's either a wakeup GPE or a GPE/Fixed Event that
+ invalid: it's either a GPE or a Fixed Event that
doesn't have an event handler.
disable: the GPE/Fixed Event is valid but disabled.
@@ -117,30 +117,30 @@ Description:
and other user space applications so that the machine won't shutdown
when pressing the power button.
# cat ff_pwr_btn
- 0
+ 0 enabled
# press the power button for 3 times;
# cat ff_pwr_btn
- 3
+ 3 enabled
# echo disable > ff_pwr_btn
# cat ff_pwr_btn
- disable
+ 3 disabled
# press the power button for 3 times;
# cat ff_pwr_btn
- disable
+ 3 disabled
# echo enable > ff_pwr_btn
# cat ff_pwr_btn
- 4
+ 4 enabled
/*
* this is because the status bit is set even if the enable bit is cleared,
* and it triggers an ACPI fixed event when the enable bit is set again
*/
# press the power button for 3 times;
# cat ff_pwr_btn
- 7
+ 7 enabled
# echo disable > ff_pwr_btn
# press the power button for 3 times;
# echo clear > ff_pwr_btn /* clear the status bit */
# echo disable > ff_pwr_btn
# cat ff_pwr_btn
- 7
+ 7 enabled
diff --git a/Documentation/acpi/debug.txt b/Documentation/acpi/debug.txt
new file mode 100644
index 000000000000..65bf47c46b6d
--- /dev/null
+++ b/Documentation/acpi/debug.txt
@@ -0,0 +1,148 @@
+ ACPI Debug Output
+
+
+The ACPI CA, the Linux ACPI core, and some ACPI drivers can generate debug
+output. This document describes how to use this facility.
+
+Compile-time configuration
+--------------------------
+
+ACPI debug output is globally enabled by CONFIG_ACPI_DEBUG. If this config
+option is turned off, the debug messages are not even built into the
+kernel.
+
+Boot- and run-time configuration
+--------------------------------
+
+When CONFIG_ACPI_DEBUG=y, you can select the component and level of messages
+you're interested in. At boot-time, use the acpi.debug_layer and
+acpi.debug_level kernel command line options. After boot, you can use the
+debug_layer and debug_level files in /sys/module/acpi/parameters/ to control
+the debug messages.
+
+debug_layer (component)
+-----------------------
+
+The "debug_layer" is a mask that selects components of interest, e.g., a
+specific driver or part of the ACPI interpreter. To build the debug_layer
+bitmask, look for the "#define _COMPONENT" in an ACPI source file.
+
+You can set the debug_layer mask at boot-time using the acpi.debug_layer
+command line argument, and you can change it after boot by writing values
+to /sys/module/acpi/parameters/debug_layer.
+
+The possible components are defined in include/acpi/acoutput.h and
+include/acpi/acpi_drivers.h. Reading /sys/module/acpi/parameters/debug_layer
+shows the supported mask values, currently these:
+
+ ACPI_UTILITIES 0x00000001
+ ACPI_HARDWARE 0x00000002
+ ACPI_EVENTS 0x00000004
+ ACPI_TABLES 0x00000008
+ ACPI_NAMESPACE 0x00000010
+ ACPI_PARSER 0x00000020
+ ACPI_DISPATCHER 0x00000040
+ ACPI_EXECUTER 0x00000080
+ ACPI_RESOURCES 0x00000100
+ ACPI_CA_DEBUGGER 0x00000200
+ ACPI_OS_SERVICES 0x00000400
+ ACPI_CA_DISASSEMBLER 0x00000800
+ ACPI_COMPILER 0x00001000
+ ACPI_TOOLS 0x00002000
+ ACPI_BUS_COMPONENT 0x00010000
+ ACPI_AC_COMPONENT 0x00020000
+ ACPI_BATTERY_COMPONENT 0x00040000
+ ACPI_BUTTON_COMPONENT 0x00080000
+ ACPI_SBS_COMPONENT 0x00100000
+ ACPI_FAN_COMPONENT 0x00200000
+ ACPI_PCI_COMPONENT 0x00400000
+ ACPI_POWER_COMPONENT 0x00800000
+ ACPI_CONTAINER_COMPONENT 0x01000000
+ ACPI_SYSTEM_COMPONENT 0x02000000
+ ACPI_THERMAL_COMPONENT 0x04000000
+ ACPI_MEMORY_DEVICE_COMPONENT 0x08000000
+ ACPI_VIDEO_COMPONENT 0x10000000
+ ACPI_PROCESSOR_COMPONENT 0x20000000
+
+debug_level
+-----------
+
+The "debug_level" is a mask that selects different types of messages, e.g.,
+those related to initialization, method execution, informational messages, etc.
+To build debug_level, look at the level specified in an ACPI_DEBUG_PRINT()
+statement.
+
+The ACPI interpreter uses several different levels, but the Linux
+ACPI core and ACPI drivers generally only use ACPI_LV_INFO.
+
+You can set the debug_level mask at boot-time using the acpi.debug_level
+command line argument, and you can change it after boot by writing values
+to /sys/module/acpi/parameters/debug_level.
+
+The possible levels are defined in include/acpi/acoutput.h. Reading
+/sys/module/acpi/parameters/debug_level shows the supported mask values,
+currently these:
+
+ ACPI_LV_INIT 0x00000001
+ ACPI_LV_DEBUG_OBJECT 0x00000002
+ ACPI_LV_INFO 0x00000004
+ ACPI_LV_INIT_NAMES 0x00000020
+ ACPI_LV_PARSE 0x00000040
+ ACPI_LV_LOAD 0x00000080
+ ACPI_LV_DISPATCH 0x00000100
+ ACPI_LV_EXEC 0x00000200
+ ACPI_LV_NAMES 0x00000400
+ ACPI_LV_OPREGION 0x00000800
+ ACPI_LV_BFIELD 0x00001000
+ ACPI_LV_TABLES 0x00002000
+ ACPI_LV_VALUES 0x00004000
+ ACPI_LV_OBJECTS 0x00008000
+ ACPI_LV_RESOURCES 0x00010000
+ ACPI_LV_USER_REQUESTS 0x00020000
+ ACPI_LV_PACKAGE 0x00040000
+ ACPI_LV_ALLOCATIONS 0x00100000
+ ACPI_LV_FUNCTIONS 0x00200000
+ ACPI_LV_OPTIMIZATIONS 0x00400000
+ ACPI_LV_MUTEX 0x01000000
+ ACPI_LV_THREADS 0x02000000
+ ACPI_LV_IO 0x04000000
+ ACPI_LV_INTERRUPTS 0x08000000
+ ACPI_LV_AML_DISASSEMBLE 0x10000000
+ ACPI_LV_VERBOSE_INFO 0x20000000
+ ACPI_LV_FULL_TABLES 0x40000000
+ ACPI_LV_EVENTS 0x80000000
+
+Examples
+--------
+
+For example, drivers/acpi/bus.c contains this:
+
+ #define _COMPONENT ACPI_BUS_COMPONENT
+ ...
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device insertion detected\n"));
+
+To turn on this message, set the ACPI_BUS_COMPONENT bit in acpi.debug_layer
+and the ACPI_LV_INFO bit in acpi.debug_level. (The ACPI_DEBUG_PRINT
+statement uses ACPI_DB_INFO, which is macro based on the ACPI_LV_INFO
+definition.)
+
+Enable all AML "Debug" output (stores to the Debug object while interpreting
+AML) during boot:
+
+ acpi.debug_layer=0xffffffff acpi.debug_level=0x2
+
+Enable PCI and PCI interrupt routing debug messages:
+
+ acpi.debug_layer=0x400000 acpi.debug_level=0x4
+
+Enable all ACPI hardware-related messages:
+
+ acpi.debug_layer=0x2 acpi.debug_level=0xffffffff
+
+Enable all ACPI_DB_INFO messages after boot:
+
+ # echo 0x4 > /sys/module/acpi/parameters/debug_level
+
+Show all valid component values:
+
+ # cat /sys/module/acpi/parameters/debug_layer
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index c86c07459712..c600c4ffc657 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -198,59 +198,42 @@ and is between 256 and 4096 characters. It is defined in the file
that require a timer override, but don't have
HPET
- acpi.debug_layer= [HW,ACPI]
+ acpi_backlight= [HW,ACPI]
+ acpi_backlight=vendor
+ acpi_backlight=video
+ If set to vendor, prefer vendor specific driver
+ (e.g. thinkpad_acpi, sony_acpi, etc.) instead
+ of the ACPI video.ko driver.
+
+ acpi_display_output= [HW,ACPI]
+ acpi_display_output=vendor
+ acpi_display_output=video
+ See above.
+
+ acpi.debug_layer= [HW,ACPI,ACPI_DEBUG]
+ acpi.debug_level= [HW,ACPI,ACPI_DEBUG]
Format: <int>
- Each bit of the <int> indicates an ACPI debug layer,
- 1: enable, 0: disable. It is useful for boot time
- debugging. After system has booted up, it can be set
- via /sys/module/acpi/parameters/debug_layer.
- CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
- Available bits (add the numbers together) to enable debug output
- for specific parts of the ACPI subsystem:
- 0x01 utilities 0x02 hardware 0x04 events 0x08 tables
- 0x10 namespace 0x20 parser 0x40 dispatcher
- 0x80 executer 0x100 resources 0x200 acpica debugger
- 0x400 os services 0x800 acpica disassembler.
- The number can be in decimal or prefixed with 0x in hex.
- Warning: Many of these options can produce a lot of
- output and make your system unusable. Be very careful.
-
- acpi.debug_level= [HW,ACPI]
- Format: <int>
- Each bit of the <int> indicates an ACPI debug level,
- which corresponds to the level in an ACPI_DEBUG_PRINT
- statement. After system has booted up, this mask
- can be set via /sys/module/acpi/parameters/debug_level.
-
- CONFIG_ACPI_DEBUG must be enabled for this to produce
- any output. The number can be in decimal or prefixed
- with 0x in hex. Some of these options produce so much
- output that the system is unusable.
-
- The following global components are defined by the
- ACPI CA:
- 0x01 error
- 0x02 warn
- 0x04 init
- 0x08 debug object
- 0x10 info
- 0x20 init names
- 0x40 parse
- 0x80 load
- 0x100 dispatch
- 0x200 execute
- 0x400 names
- 0x800 operation region
- 0x1000 bfield
- 0x2000 tables
- 0x4000 values
- 0x8000 objects
- 0x10000 resources
- 0x20000 user requests
- 0x40000 package
- The number can be in decimal or prefixed with 0x in hex.
- Warning: Many of these options can produce a lot of
- output and make your system unusable. Be very careful.
+ CONFIG_ACPI_DEBUG must be enabled to produce any ACPI
+ debug output. Bits in debug_layer correspond to a
+ _COMPONENT in an ACPI source file, e.g.,
+ #define _COMPONENT ACPI_PCI_COMPONENT
+ Bits in debug_level correspond to a level in
+ ACPI_DEBUG_PRINT statements, e.g.,
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, ...
+ See Documentation/acpi/debug.txt for more information
+ about debug layers and levels.
+
+ Enable AML "Debug" output, i.e., stores to the Debug
+ object while interpreting AML:
+ acpi.debug_layer=0xffffffff acpi.debug_level=0x2
+ Enable PCI/PCI interrupt routing info messages:
+ acpi.debug_layer=0x400000 acpi.debug_level=0x4
+ Enable all messages related to ACPI hardware:
+ acpi.debug_layer=0x2 acpi.debug_level=0xffffffff
+
+ Some values produce so much output that the system is
+ unusable. The "log_buf_len" parameter may be useful
+ if you need to capture more output.
acpi.power_nocheck= [HW,ACPI]
Format: 1/0 enable/disable the check of power state.
diff --git a/MAINTAINERS b/MAINTAINERS
index 53e78c83cc7a..272d04e95faa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2216,6 +2216,13 @@ M: adaplas@gmail.com
L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
+INTEL MENLOW THERMAL DRIVER
+P: Sujith Thomas
+M: sujith.thomas@intel.com
+L: linux-acpi@vger.kernel.org
+W: http://www.lesswatts.org/projects/acpi/
+S: Supported
+
INTEL IA32 MICROCODE UPDATE SUPPORT
P: Tigran Aivazian
M: tigran@aivazian.fsnet.co.uk
@@ -3377,7 +3384,9 @@ S: Maintained
PNP SUPPORT
P: Adam Belay
-M: ambx1@neo.rr.com
+M: abelay@mit.edu
+P: Bjorn Helgaas
+M: bjorn.helgaas@hp.com
S: Maintained
PNXxxxx I2C DRIVER
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 8e99fed6b3fd..f833a0b4188d 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -20,6 +20,8 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
depends on HAVE_KVM && EXPERIMENTAL
+ # for device assignment:
+ depends on PCI
select PREEMPT_NOTIFIERS
select ANON_INODES
---help---
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index 3caac477de9e..af1464f7a6ad 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -673,16 +673,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
vcpu_load(vcpu);
+ if (vcpu->sigset_active)
+ sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
+
if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
kvm_vcpu_block(vcpu);
clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
- vcpu_put(vcpu);
- return -EAGAIN;
+ r = -EAGAIN;
+ goto out;
}
- if (vcpu->sigset_active)
- sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
-
if (vcpu->mmio_needed) {
memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
kvm_set_mmio_data(vcpu);
@@ -690,7 +690,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
vcpu->mmio_needed = 0;
}
r = __vcpu_run(vcpu, kvm_run);
-
+out:
if (vcpu->sigset_active)
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h
index 341e3fee280c..e9b2a4e121c0 100644
--- a/arch/ia64/kvm/vcpu.h
+++ b/arch/ia64/kvm/vcpu.h
@@ -384,6 +384,10 @@ static inline u64 __gpfn_is_io(u64 gpfn)
#define MODE_IND(psr) \
(((psr).it << 2) + ((psr).dt << 1) + (psr).rt)
+#ifndef CONFIG_SMP
+#define _vmm_raw_spin_lock(x) do {}while(0)
+#define _vmm_raw_spin_unlock(x) do {}while(0)
+#else
#define _vmm_raw_spin_lock(x) \
do { \
__u32 *ia64_spinlock_ptr = (__u32 *) (x); \
@@ -403,6 +407,7 @@ static inline u64 __gpfn_is_io(u64 gpfn)
do { barrier(); \
((spinlock_t *)x)->raw_lock.lock = 0; } \
while (0)
+#endif
void vmm_spin_lock(spinlock_t *lock);
void vmm_spin_unlock(spinlock_t *lock);
diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug
index 524e33819f32..ff80e86b9bd2 100644
--- a/arch/mn10300/Kconfig.debug
+++ b/arch/mn10300/Kconfig.debug
@@ -15,6 +15,15 @@ config DEBUG_DECOMPRESS_KERNEL
decompressing Linux seeing "Uncompressing Linux... " and
"Ok, booting the kernel.\n" on console.
+config TEST_MISALIGNMENT_HANDLER
+ bool "Run tests on the misalignment handler"
+ depends on DEBUG_KERNEL
+ default n
+ help
+ If you say Y here the kernel will execute a list of misaligned memory
+ accesses to make sure the misalignment handler deals them with
+ correctly. If it does not, the kernel will throw a BUG.
+
config KPROBES
bool "Kprobes"
depends on DEBUG_KERNEL
diff --git a/arch/mn10300/mm/misalignment.c b/arch/mn10300/mm/misalignment.c
index 32aa89dc3848..94c4a4358065 100644
--- a/arch/mn10300/mm/misalignment.c
+++ b/arch/mn10300/mm/misalignment.c
@@ -37,26 +37,22 @@
#include <asm/asm-offsets.h>
#if 0
-#define kdebug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__)
+#define kdebug(FMT, ...) printk(KERN_DEBUG "MISALIGN: "FMT"\n", ##__VA_ARGS__)
#else
#define kdebug(FMT, ...) do {} while (0)
#endif
-static int misalignment_addr(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
- void **_address, unsigned long **_postinc);
+static int misalignment_addr(unsigned long *registers, unsigned long sp,
+ unsigned params, unsigned opcode,
+ unsigned long disp,
+ void **_address, unsigned long **_postinc,
+ unsigned long *_inc);
static int misalignment_reg(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
+ unsigned opcode, unsigned long disp,
unsigned long **_register);
-static inline unsigned int_log2(unsigned x)
-{
- unsigned y;
- asm("bsch %1,%0" : "=r"(y) : "r"(x), "0"(0));
- return y;
-}
-#define log2(x) int_log2(x)
+static void misalignment_MOV_Lcc(struct pt_regs *regs, uint32_t opcode);
static const unsigned Dreg_index[] = {
REG_D0 >> 2, REG_D1 >> 2, REG_D2 >> 2, REG_D3 >> 2
@@ -86,9 +82,10 @@ enum format_id {
FMT_D7,
FMT_D8,
FMT_D9,
+ FMT_D10,
};
-struct {
+static const struct {
u_int8_t opsz, dispsz;
} format_tbl[16] = {
[FMT_S0] = { 8, 0 },
@@ -103,6 +100,7 @@ struct {
[FMT_D7] = { 24, 8 },
[FMT_D8] = { 24, 24 },
[FMT_D9] = { 24, 32 },
+ [FMT_D10] = { 32, 0 },
};
enum value_id {
@@ -128,9 +126,14 @@ enum value_id {
SD24, /* 24-bit signed displacement */
SIMM4_2, /* 4-bit signed displacement in opcode bits 4-7 */
SIMM8, /* 8-bit signed immediate */
+ IMM8, /* 8-bit unsigned immediate */
+ IMM16, /* 16-bit unsigned immediate */
IMM24, /* 24-bit unsigned immediate */
IMM32, /* 32-bit unsigned immediate */
- IMM32_HIGH8, /* 32-bit unsigned immediate, high 8-bits in opcode */
+ IMM32_HIGH8, /* 32-bit unsigned immediate, LSB in opcode */
+
+ IMM32_MEM, /* 32-bit unsigned displacement */
+ IMM32_HIGH8_MEM, /* 32-bit unsigned displacement, LSB in opcode */
DN0 = DM0,
DN1 = DM1,
@@ -149,7 +152,7 @@ enum value_id {
};
struct mn10300_opcode {
- const char *name;
+ const char name[8];
u_int32_t opcode;
u_int32_t opmask;
unsigned exclusion;
@@ -185,6 +188,10 @@ struct mn10300_opcode {
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
static const struct mn10300_opcode mn10300_opcodes[] = {
+{ "mov", 0x4200, 0xf300, 0, FMT_S1, 0, {DM1, MEM2(IMM8, SP)}},
+{ "mov", 0x4300, 0xf300, 0, FMT_S1, 0, {AM1, MEM2(IMM8, SP)}},
+{ "mov", 0x5800, 0xfc00, 0, FMT_S1, 0, {MEM2(IMM8, SP), DN0}},
+{ "mov", 0x5c00, 0xfc00, 0, FMT_S1, 0, {MEM2(IMM8, SP), AN0}},
{ "mov", 0x60, 0xf0, 0, FMT_S0, 0, {DM1, MEM(AN0)}},
{ "mov", 0x70, 0xf0, 0, FMT_S0, 0, {MEM(AM0), DN1}},
{ "mov", 0xf000, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), AN1}},
@@ -197,8 +204,6 @@ static const struct mn10300_opcode mn10300_opcodes[] = {
{ "mov", 0xf81000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}},
{ "mov", 0xf82000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8,AM0), AN1}},
{ "mov", 0xf83000, 0xfff000, 0, FMT_D1, 0, {AM1, MEM2(SD8, AN0)}},
-{ "mov", 0xf8f000, 0xfffc00, 0, FMT_D1, AM33, {MEM2(SD8, AM0), SP}},
-{ "mov", 0xf8f400, 0xfffc00, 0, FMT_D1, AM33, {SP, MEM2(SD8, AN0)}},
{ "mov", 0xf90a00, 0xffff00, 0, FMT_D6, AM33, {MEM(RM0), RN2}},
{ "mov", 0xf91a00, 0xffff00, 0, FMT_D6, AM33, {RM2, MEM(RN0)}},
{ "mov", 0xf96a00, 0xffff00, 0x12, FMT_D6, AM33, {MEMINC(RM0), RN2}},
@@ -207,24 +212,46 @@ static const struct mn10300_opcode mn10300_opcodes[] = {
{ "mov", 0xfa100000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}},
{ "mov", 0xfa200000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), AN1}},
{ "mov", 0xfa300000, 0xfff00000, 0, FMT_D2, 0, {AM1, MEM2(SD16, AN0)}},
+{ "mov", 0xfa900000, 0xfff30000, 0, FMT_D2, 0, {AM1, MEM2(IMM16, SP)}},
+{ "mov", 0xfa910000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}},
+{ "mov", 0xfab00000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), AN0}},
+{ "mov", 0xfab40000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}},
{ "mov", 0xfb0a0000, 0xffff0000, 0, FMT_D7, AM33, {MEM2(SD8, RM0), RN2}},
{ "mov", 0xfb1a0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEM2(SD8, RN0)}},
{ "mov", 0xfb6a0000, 0xffff0000, 0x22, FMT_D7, AM33, {MEMINC2 (RM0, SIMM8), RN2}},
{ "mov", 0xfb7a0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEMINC2 (RN0, SIMM8)}},
+{ "mov", 0xfb8a0000, 0xffff0f00, 0, FMT_D7, AM33, {MEM2(IMM8, SP), RN2}},
{ "mov", 0xfb8e0000, 0xffff000f, 0, FMT_D7, AM33, {MEM2(RI, RM0), RD2}},
+{ "mov", 0xfb9a0000, 0xffff0f00, 0, FMT_D7, AM33, {RM2, MEM2(IMM8, SP)}},
{ "mov", 0xfb9e0000, 0xffff000f, 0, FMT_D7, AM33, {RD2, MEM2(RI, RN0)}},
{ "mov", 0xfc000000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}},
{ "mov", 0xfc100000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}},
{ "mov", 0xfc200000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), AN1}},
{ "mov", 0xfc300000, 0xfff00000, 0, FMT_D4, 0, {AM1, MEM2(IMM32,AN0)}},
+{ "mov", 0xfc800000, 0xfff30000, 0, FMT_D4, 0, {AM1, MEM(IMM32_MEM)}},
+{ "mov", 0xfc810000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}},
+{ "mov", 0xfc900000, 0xfff30000, 0, FMT_D4, 0, {AM1, MEM2(IMM32, SP)}},
+{ "mov", 0xfc910000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}},
+{ "mov", 0xfca00000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), AN0}},
+{ "mov", 0xfca40000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}},
+{ "mov", 0xfcb00000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), AN0}},
+{ "mov", 0xfcb40000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}},
{ "mov", 0xfd0a0000, 0xffff0000, 0, FMT_D8, AM33, {MEM2(SD24, RM0), RN2}},
{ "mov", 0xfd1a0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEM2(SD24, RN0)}},
{ "mov", 0xfd6a0000, 0xffff0000, 0x22, FMT_D8, AM33, {MEMINC2 (RM0, IMM24), RN2}},
{ "mov", 0xfd7a0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEMINC2 (RN0, IMM24)}},
+{ "mov", 0xfd8a0000, 0xffff0f00, 0, FMT_D8, AM33, {MEM2(IMM24, SP), RN2}},
+{ "mov", 0xfd9a0000, 0xffff0f00, 0, FMT_D8, AM33, {RM2, MEM2(IMM24, SP)}},
{ "mov", 0xfe0a0000, 0xffff0000, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8,RM0), RN2}},
+{ "mov", 0xfe0a0000, 0xffff0000, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8,RM0), RN2}},
+{ "mov", 0xfe0e0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM(IMM32_HIGH8_MEM), RN2}},
+{ "mov", 0xfe1a0000, 0xffff0000, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, RN0)}},
{ "mov", 0xfe1a0000, 0xffff0000, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, RN0)}},
+{ "mov", 0xfe1e0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM(IMM32_HIGH8_MEM)}},
{ "mov", 0xfe6a0000, 0xffff0000, 0x22, FMT_D9, AM33, {MEMINC2 (RM0, IMM32_HIGH8), RN2}},
{ "mov", 0xfe7a0000, 0xffff0000, 0, FMT_D9, AM33, {RN2, MEMINC2 (RM0, IMM32_HIGH8)}},
+{ "mov", 0xfe8a0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8, SP), RN2}},
+{ "mov", 0xfe9a0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, SP)}},
{ "movhu", 0xf060, 0xfff0, 0, FMT_D0, 0, {MEM(AM0), DN1}},
{ "movhu", 0xf070, 0xfff0, 0, FMT_D0, 0, {DM1, MEM(AN0)}},
@@ -232,29 +259,58 @@ static const struct mn10300_opcode mn10300_opcodes[] = {
{ "movhu", 0xf4c0, 0xffc0, 0, FMT_D0, 0, {DM2, MEM2(DI, AN0)}},
{ "movhu", 0xf86000, 0xfff000, 0, FMT_D1, 0, {MEM2(SD8, AM0), DN1}},
{ "movhu", 0xf87000, 0xfff000, 0, FMT_D1, 0, {DM1, MEM2(SD8, AN0)}},
+{ "movhu", 0xf89300, 0xfff300, 0, FMT_D1, 0, {DM1, MEM2(IMM8, SP)}},
+{ "movhu", 0xf8bc00, 0xfffc00, 0, FMT_D1, 0, {MEM2(IMM8, SP), DN0}},
{ "movhu", 0xf94a00, 0xffff00, 0, FMT_D6, AM33, {MEM(RM0), RN2}},
{ "movhu", 0xf95a00, 0xffff00, 0, FMT_D6, AM33, {RM2, MEM(RN0)}},
{ "movhu", 0xf9ea00, 0xffff00, 0x12, FMT_D6, AM33, {MEMINC(RM0), RN2}},
{ "movhu", 0xf9fa00, 0xffff00, 0, FMT_D6, AM33, {RM2, MEMINC(RN0)}},
{ "movhu", 0xfa600000, 0xfff00000, 0, FMT_D2, 0, {MEM2(SD16, AM0), DN1}},
{ "movhu", 0xfa700000, 0xfff00000, 0, FMT_D2, 0, {DM1, MEM2(SD16, AN0)}},
+{ "movhu", 0xfa930000, 0xfff30000, 0, FMT_D2, 0, {DM1, MEM2(IMM16, SP)}},
+{ "movhu", 0xfabc0000, 0xfffc0000, 0, FMT_D2, 0, {MEM2(IMM16, SP), DN0}},
{ "movhu", 0xfb4a0000, 0xffff0000, 0, FMT_D7, AM33, {MEM2(SD8, RM0), RN2}},
{ "movhu", 0xfb5a0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEM2(SD8, RN0)}},
+{ "movhu", 0xfbca0000, 0xffff0f00, 0, FMT_D7, AM33, {MEM2(IMM8, SP), RN2}},
{ "movhu", 0xfbce0000, 0xffff000f, 0, FMT_D7, AM33, {MEM2(RI, RM0), RD2}},
+{ "movhu", 0xfbda0000, 0xffff0f00, 0, FMT_D7, AM33, {RM2, MEM2(IMM8, SP)}},
{ "movhu", 0xfbde0000, 0xffff000f, 0, FMT_D7, AM33, {RD2, MEM2(RI, RN0)}},
{ "movhu", 0xfbea0000, 0xffff0000, 0x22, FMT_D7, AM33, {MEMINC2 (RM0, SIMM8), RN2}},
{ "movhu", 0xfbfa0000, 0xffff0000, 0, FMT_D7, AM33, {RM2, MEMINC2 (RN0, SIMM8)}},
{ "movhu", 0xfc600000, 0xfff00000, 0, FMT_D4, 0, {MEM2(IMM32,AM0), DN1}},
{ "movhu", 0xfc700000, 0xfff00000, 0, FMT_D4, 0, {DM1, MEM2(IMM32,AN0)}},
+{ "movhu", 0xfc830000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM(IMM32_MEM)}},
+{ "movhu", 0xfc930000, 0xfff30000, 0, FMT_D4, 0, {DM1, MEM2(IMM32, SP)}},
+{ "movhu", 0xfcac0000, 0xfffc0000, 0, FMT_D4, 0, {MEM(IMM32_MEM), DN0}},
+{ "movhu", 0xfcbc0000, 0xfffc0000, 0, FMT_D4, 0, {MEM2(IMM32, SP), DN0}},
{ "movhu", 0xfd4a0000, 0xffff0000, 0, FMT_D8, AM33, {MEM2(SD24, RM0), RN2}},
{ "movhu", 0xfd5a0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEM2(SD24, RN0)}},
+{ "movhu", 0xfdca0000, 0xffff0f00, 0, FMT_D8, AM33, {MEM2(IMM24, SP), RN2}},
+{ "movhu", 0xfdda0000, 0xffff0f00, 0, FMT_D8, AM33, {RM2, MEM2(IMM24, SP)}},
{ "movhu", 0xfdea0000, 0xffff0000, 0x22, FMT_D8, AM33, {MEMINC2 (RM0, IMM24), RN2}},
{ "movhu", 0xfdfa0000, 0xffff0000, 0, FMT_D8, AM33, {RM2, MEMINC2 (RN0, IMM24)}},
{ "movhu", 0xfe4a0000, 0xffff0000, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8,RM0), RN2}},
+{ "movhu", 0xfe4e0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM(IMM32_HIGH8_MEM), RN2}},
{ "movhu", 0xfe5a0000, 0xffff0000, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, RN0)}},
+{ "movhu", 0xfe5e0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM(IMM32_HIGH8_MEM)}},
+{ "movhu", 0xfeca0000, 0xffff0f00, 0, FMT_D9, AM33, {MEM2(IMM32_HIGH8, SP), RN2}},
+{ "movhu", 0xfeda0000, 0xffff0f00, 0, FMT_D9, AM33, {RM2, MEM2(IMM32_HIGH8, SP)}},
{ "movhu", 0xfeea0000, 0xffff0000, 0x22, FMT_D9, AM33, {MEMINC2 (RM0, IMM32_HIGH8), RN2}},
{ "movhu", 0xfefa0000, 0xffff0000, 0, FMT_D9, AM33, {RN2, MEMINC2 (RM0, IMM32_HIGH8)}},
-{ 0, 0, 0, 0, 0, 0, {0}},
+
+{ "mov_llt", 0xf7e00000, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lgt", 0xf7e00001, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lge", 0xf7e00002, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lle", 0xf7e00003, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lcs", 0xf7e00004, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lhi", 0xf7e00005, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lcc", 0xf7e00006, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lls", 0xf7e00007, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_leq", 0xf7e00008, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lne", 0xf7e00009, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+{ "mov_lra", 0xf7e0000a, 0xffff000f, 0x22, FMT_D10, AM33, {MEMINC2 (RN4,SIMM4_2), RM6}},
+
+{ "", 0, 0, 0, 0, 0, {0}},
};
/*
@@ -265,18 +321,21 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
const struct exception_table_entry *fixup;
const struct mn10300_opcode *pop;
unsigned long *registers = (unsigned long *) regs;
- unsigned long data, *store, *postinc;
+ unsigned long data, *store, *postinc, disp, inc, sp;
mm_segment_t seg;
siginfo_t info;
- uint32_t opcode, disp, noc, xo, xm;
- uint8_t *pc, byte;
+ uint32_t opcode, noc, xo, xm;
+ uint8_t *pc, byte, datasz;
void *address;
- unsigned tmp, npop;
+ unsigned tmp, npop, dispsz, loop;
+
+ /* we don't fix up userspace misalignment faults */
+ if (user_mode(regs))
+ goto bus_error;
- kdebug("MISALIGN at %lx\n", regs->pc);
+ sp = (unsigned long) regs + sizeof(*regs);
- if (in_interrupt())
- die("Misalignment trap in interrupt context", regs, code);
+ kdebug("==>misalignment({pc=%lx,sp=%lx})", regs->pc, sp);
if (regs->epsw & EPSW_IE)
asm volatile("or %0,epsw" : : "i"(EPSW_IE));
@@ -294,8 +353,8 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
opcode = byte;
noc = 8;
- for (pop = mn10300_opcodes; pop->name; pop++) {
- npop = log2(pop->opcode | pop->opmask);
+ for (pop = mn10300_opcodes; pop->name[0]; pop++) {
+ npop = ilog2(pop->opcode | pop->opmask);
if (npop <= 0 || npop > 31)
continue;
npop = (npop + 8) & ~7;
@@ -328,15 +387,15 @@ asmlinkage void misalignment(struct pt_regs *regs, enum exception_code code)
}
/* didn't manage to find a fixup */
- if (!user_mode(regs))
- printk(KERN_CRIT "MISALIGN: %lx: unsupported instruction %x\n",
- regs->pc, opcode);
+ printk(KERN_CRIT "MISALIGN: %lx: unsupported instruction %x\n",
+ regs->pc, opcode);
failed:
set_fs(seg);
if (die_if_no_fixup("misalignment error", regs, code))
return;
+bus_error:
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
@@ -346,31 +405,27 @@ failed:
/* error reading opcodes */
fetch_error:
- if (!user_mode(regs))
- printk(KERN_CRIT
- "MISALIGN: %p: fault whilst reading instruction data\n",
- pc);
+ printk(KERN_CRIT
+ "MISALIGN: %p: fault whilst reading instruction data\n",
+ pc);
goto failed;
bad_addr_mode:
- if (!user_mode(regs))
- printk(KERN_CRIT
- "MISALIGN: %lx: unsupported addressing mode %x\n",
- regs->pc, opcode);
+ printk(KERN_CRIT
+ "MISALIGN: %lx: unsupported addressing mode %x\n",
+ regs->pc, opcode);
goto failed;
bad_reg_mode:
- if (!user_mode(regs))
- printk(KERN_CRIT
- "MISALIGN: %lx: unsupported register mode %x\n",
- regs->pc, opcode);
+ printk(KERN_CRIT
+ "MISALIGN: %lx: unsupported register mode %x\n",
+ regs->pc, opcode);
goto failed;
unsupported_instruction:
- if (!user_mode(regs))
- printk(KERN_CRIT
- "MISALIGN: %lx: unsupported instruction %x (%s)\n",
- regs->pc, opcode, pop->name);
+ printk(KERN_CRIT
+ "MISALIGN: %lx: unsupported instruction %x (%s)\n",
+ regs->pc, opcode, pop->name);
goto failed;
transfer_failed:
@@ -391,7 +446,7 @@ transfer_failed:
/* we matched the opcode */
found_opcode:
- kdebug("MISALIGN: %lx: %x==%x { %x, %x }\n",
+ kdebug("%lx: %x==%x { %x, %x }",
regs->pc, opcode, pop->opcode, pop->params[0], pop->params[1]);
tmp = format_tbl[pop->format].opsz;
@@ -406,106 +461,108 @@ found_opcode:
/* grab the extra displacement (note it's LSB first) */
disp = 0;
- tmp = format_tbl[pop->format].dispsz >> 3;
- while (tmp > 0) {
- tmp--;
- disp <<= 8;
-
+ dispsz = format_tbl[pop->format].dispsz;
+ for (loop = 0; loop < dispsz; loop += 8) {
pc++;
if (__get_user(byte, pc) != 0)
goto fetch_error;
- disp |= byte;
+ disp |= byte << loop;
+ kdebug("{%p} disp[%02x]=%02x", pc, loop, byte);
}
+ kdebug("disp=%lx", disp);
+
set_fs(KERNEL_XDS);
- if (fixup || regs->epsw & EPSW_nSL)
+ if (fixup)
set_fs(seg);
tmp = (pop->params[0] ^ pop->params[1]) & 0x80000000;
if (!tmp) {
- if (!user_mode(regs))
- printk(KERN_CRIT
- "MISALIGN: %lx:"
- " insn not move to/from memory %x\n",
- regs->pc, opcode);
+ printk(KERN_CRIT
+ "MISALIGN: %lx: insn not move to/from memory %x\n",
+ regs->pc, opcode);
goto failed;
}
+ /* determine the data transfer size of the move */
+ if (pop->name[3] == 0 || /* "mov" */
+ pop->name[4] == 'l') /* mov_lcc */
+ inc = datasz = 4;
+ else if (pop->name[3] == 'h') /* movhu */
+ inc = datasz = 2;
+ else
+ goto unsupported_instruction;
+
if (pop->params[0] & 0x80000000) {
/* move memory to register */
- if (!misalignment_addr(registers, pop->params[0], opcode, disp,
- &address, &postinc))
+ if (!misalignment_addr(registers, sp,
+ pop->params[0], opcode, disp,
+ &address, &postinc, &inc))
goto bad_addr_mode;
if (!misalignment_reg(registers, pop->params[1], opcode, disp,
&store))
goto bad_reg_mode;
- if (strcmp(pop->name, "mov") == 0) {
- kdebug("FIXUP: mov (%p),DARn\n", address);
- if (copy_from_user(&data, (void *) address, 4) != 0)
- goto transfer_failed;
- if (pop->params[0] & 0x1000000)
- *postinc += 4;
- } else if (strcmp(pop->name, "movhu") == 0) {
- kdebug("FIXUP: movhu (%p),DARn\n", address);
- data = 0;
- if (copy_from_user(&data, (void *) address, 2) != 0)
- goto transfer_failed;
- if (pop->params[0] & 0x1000000)
- *postinc += 2;
- } else {
- goto unsupported_instruction;
+ kdebug("mov%u (%p),DARn", datasz, address);
+ if (copy_from_user(&data, (void *) address, datasz) != 0)
+ goto transfer_failed;
+ if (pop->params[0] & 0x1000000) {
+ kdebug("inc=%lx", inc);
+ *postinc += inc;
}
*store = data;
+ kdebug("loaded %lx", data);
} else {
/* move register to memory */
if (!misalignment_reg(registers, pop->params[0], opcode, disp,
&store))
goto bad_reg_mode;
- if (!misalignment_addr(registers, pop->params[1], opcode, disp,
- &address, &postinc))
+ if (!misalignment_addr(registers, sp,
+ pop->params[1], opcode, disp,
+ &address, &postinc, &inc))
goto bad_addr_mode;
data = *store;
- if (strcmp(pop->name, "mov") == 0) {
- kdebug("FIXUP: mov %lx,(%p)\n", data, address);
- if (copy_to_user((void *) address, &data, 4) != 0)
- goto transfer_failed;
- if (pop->params[1] & 0x1000000)
- *postinc += 4;
- } else if (strcmp(pop->name, "movhu") == 0) {
- kdebug("FIXUP: movhu %hx,(%p)\n",
- (uint16_t) data, address);
- if (copy_to_user((void *) address, &data, 2) != 0)
- goto transfer_failed;
- if (pop->params[1] & 0x1000000)
- *postinc += 2;
- } else {
- goto unsupported_instruction;
- }
+ kdebug("mov%u %lx,(%p)", datasz, data, address);
+ if (copy_to_user((void *) address, &data, datasz) != 0)
+ goto transfer_failed;
+ if (pop->params[1] & 0x1000000)
+ *postinc += inc;
}
tmp = format_tbl[pop->format].opsz + format_tbl[pop->format].dispsz;
regs->pc += tmp >> 3;
+ /* handle MOV_Lcc, which are currently the only FMT_D10 insns that
+ * access memory */
+ if (pop->format == FMT_D10)
+ misalignment_MOV_Lcc(regs, opcode);
+
set_fs(seg);
- return;
}
/*
* determine the address that was being accessed
*/
-static int misalignment_addr(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
- void **_address, unsigned long **_postinc)
+static int misalignment_addr(unsigned long *registers, unsigned long sp,
+ unsigned params, unsigned opcode,
+ unsigned long disp,
+ void **_address, unsigned long **_postinc,
+ unsigned long *_inc)
{
unsigned long *postinc = NULL, address = 0, tmp;
- params &= 0x7fffffff;
+ if (!(params & 0x1000000)) {
+ kdebug("noinc");
+ *_inc = 0;
+ _inc = NULL;
+ }
+
+ params &= 0x00ffffff;
do {
switch (params & 0xff) {
@@ -514,11 +571,11 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
address += *postinc;
break;
case DM1:
- postinc = &registers[Dreg_index[opcode >> 2 & 0x0c]];
+ postinc = &registers[Dreg_index[opcode >> 2 & 0x03]];
address += *postinc;
break;
case DM2:
- postinc = &registers[Dreg_index[opcode >> 4 & 0x30]];
+ postinc = &registers[Dreg_index[opcode >> 4 & 0x03]];
address += *postinc;
break;
case AM0:
@@ -526,11 +583,11 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
address += *postinc;
break;
case AM1:
- postinc = &registers[Areg_index[opcode >> 2 & 0x0c]];
+ postinc = &registers[Areg_index[opcode >> 2 & 0x03]];
address += *postinc;
break;
case AM2:
- postinc = &registers[Areg_index[opcode >> 4 & 0x30]];
+ postinc = &registers[Areg_index[opcode >> 4 & 0x03]];
address += *postinc;
break;
case RM0:
@@ -561,33 +618,53 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
postinc = &registers[Rreg_index[disp >> 4 & 0x0f]];
address += *postinc;
break;
+ case SP:
+ address += sp;
+ break;
+ /* displacements are either to be added to the address
+ * before use, or, in the case of post-inc addressing,
+ * to be added into the base register after use */
case SD8:
case SIMM8:
- address += (int32_t) (int8_t) (disp & 0xff);
- break;
+ disp = (long) (int8_t) (disp & 0xff);
+ goto displace_or_inc;
case SD16:
- address += (int32_t) (int16_t) (disp & 0xffff);
- break;
+ disp = (long) (int16_t) (disp & 0xffff);
+ goto displace_or_inc;
case SD24:
tmp = disp << 8;
asm("asr 8,%0" : "=r"(tmp) : "0"(tmp));
- address += tmp;
- break;
+ disp = (long) tmp;
+ goto displace_or_inc;
case SIMM4_2:
tmp = opcode >> 4 & 0x0f;
tmp <<= 28;
asm("asr 28,%0" : "=r"(tmp) : "0"(tmp));
- address += tmp;
- break;
+ disp = (long) tmp;
+ goto displace_or_inc;
+ case IMM8:
+ disp &= 0x000000ff;
+ goto displace_or_inc;
+ case IMM16:
+ disp &= 0x0000ffff;
+ goto displace_or_inc;
case IMM24:
- address += disp & 0x00ffffff;
- break;
+ disp &= 0x00ffffff;
+ goto displace_or_inc;
case IMM32:
+ case IMM32_MEM:
case IMM32_HIGH8:
- address += disp;
+ case IMM32_HIGH8_MEM:
+ displace_or_inc:
+ kdebug("%s %lx", _inc ? "incr" : "disp", disp);
+ if (!_inc)
+ address += disp;
+ else
+ *_inc = disp;
break;
default:
+ BUG();
return 0;
}
} while ((params >>= 8));
@@ -601,7 +678,7 @@ static int misalignment_addr(unsigned long *registers, unsigned params,
* determine the register that is acting as source/dest
*/
static int misalignment_reg(unsigned long *registers, unsigned params,
- unsigned opcode, unsigned disp,
+ unsigned opcode, unsigned long disp,
unsigned long **_register)
{
params &= 0x7fffffff;
@@ -654,8 +731,239 @@ static int misalignment_reg(unsigned long *registers, unsigned params,
break;
default:
+ BUG();
return 0;
}
return 1;
}
+
+/*
+ * handle the conditional loop part of the move-and-loop instructions
+ */
+static void misalignment_MOV_Lcc(struct pt_regs *regs, uint32_t opcode)
+{
+ unsigned long epsw = regs->epsw;
+ unsigned long NxorV;
+
+ kdebug("MOV_Lcc %x [flags=%lx]", opcode, epsw & 0xf);
+
+ /* calculate N^V and shift onto the same bit position as Z */
+ NxorV = ((epsw >> 3) ^ epsw >> 1) & 1;
+
+ switch (opcode & 0xf) {
+ case 0x0: /* MOV_LLT: N^V */
+ if (NxorV)
+ goto take_the_loop;
+ return;
+ case 0x1: /* MOV_LGT: ~(Z or (N^V))*/
+ if (!((epsw & EPSW_FLAG_Z) | NxorV))
+ goto take_the_loop;
+ return;
+ case 0x2: /* MOV_LGE: ~(N^V) */
+ if (!NxorV)
+ goto take_the_loop;
+ return;
+ case 0x3: /* MOV_LLE: Z or (N^V) */
+ if ((epsw & EPSW_FLAG_Z) | NxorV)
+ goto take_the_loop;
+ return;
+
+ case 0x4: /* MOV_LCS: C */
+ if (epsw & EPSW_FLAG_C)
+ goto take_the_loop;
+ return;
+ case 0x5: /* MOV_LHI: ~(C or Z) */
+ if (!(epsw & (EPSW_FLAG_C | EPSW_FLAG_Z)))
+ goto take_the_loop;
+ return;
+ case 0x6: /* MOV_LCC: ~C */
+ if (!(epsw & EPSW_FLAG_C))
+ goto take_the_loop;
+ return;
+ case 0x7: /* MOV_LLS: C or Z */
+ if (epsw & (EPSW_FLAG_C | EPSW_FLAG_Z))
+ goto take_the_loop;
+ return;
+
+ case 0x8: /* MOV_LEQ: Z */
+ if (epsw & EPSW_FLAG_Z)
+ goto take_the_loop;
+ return;
+ case 0x9: /* MOV_LNE: ~Z */
+ if (!(epsw & EPSW_FLAG_Z))
+ goto take_the_loop;
+ return;
+ case 0xa: /* MOV_LRA: always */
+ goto take_the_loop;
+
+ default:
+ BUG();
+ }
+
+take_the_loop:
+ /* wind the PC back to just after the SETLB insn */
+ kdebug("loop LAR=%lx", regs->lar);
+ regs->pc = regs->lar - 4;
+}
+
+/*
+ * misalignment handler tests
+ */
+#ifdef CONFIG_TEST_MISALIGNMENT_HANDLER
+static u8 __initdata testbuf[512] __attribute__((aligned(16))) = {
+ [257] = 0x11,
+ [258] = 0x22,
+ [259] = 0x33,
+ [260] = 0x44,
+};
+
+#define ASSERTCMP(X, OP, Y) \
+do { \
+ if (unlikely(!((X) OP (Y)))) { \
+ printk(KERN_ERR "\n"); \
+ printk(KERN_ERR "MISALIGN: Assertion failed at line %u\n", \
+ __LINE__); \
+ printk(KERN_ERR "0x%lx " #OP " 0x%lx is false\n", \
+ (unsigned long)(X), (unsigned long)(Y)); \
+ BUG(); \
+ } \
+} while(0)
+
+static int __init test_misalignment(void)
+{
+ register void *r asm("e0");
+ register u32 y asm("e1");
+ void *p = testbuf, *q;
+ u32 tmp, tmp2, x;
+
+ printk(KERN_NOTICE "==>test_misalignment() [testbuf=%p]\n", p);
+ p++;
+
+ printk(KERN_NOTICE "___ MOV (Am),Dn ___\n");
+ q = p + 256;
+ asm volatile("mov (%0),%1" : "+a"(q), "=d"(x));
+ ASSERTCMP(q, ==, p + 256);
+ ASSERTCMP(x, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV (256,Am),Dn ___\n");
+ q = p;
+ asm volatile("mov (256,%0),%1" : "+a"(q), "=d"(x));
+ ASSERTCMP(q, ==, p);
+ ASSERTCMP(x, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV (Di,Am),Dn ___\n");
+ tmp = 256;
+ q = p;
+ asm volatile("mov (%2,%0),%1" : "+a"(q), "=d"(x), "+d"(tmp));
+ ASSERTCMP(q, ==, p);
+ ASSERTCMP(x, ==, 0x44332211);
+ ASSERTCMP(tmp, ==, 256);
+
+ printk(KERN_NOTICE "___ MOV (256,Rm),Rn ___\n");
+ r = p;
+ asm volatile("mov (256,%0),%1" : "+r"(r), "=r"(y));
+ ASSERTCMP(r, ==, p);
+ ASSERTCMP(y, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV (Rm+),Rn ___\n");
+ r = p + 256;
+ asm volatile("mov (%0+),%1" : "+r"(r), "=r"(y));
+ ASSERTCMP(r, ==, p + 256 + 4);
+ ASSERTCMP(y, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV (Rm+,8),Rn ___\n");
+ r = p + 256;
+ asm volatile("mov (%0+,8),%1" : "+r"(r), "=r"(y));
+ ASSERTCMP(r, ==, p + 256 + 8);
+ ASSERTCMP(y, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV (7,SP),Rn ___\n");
+ asm volatile(
+ "add -16,sp \n"
+ "mov +0x11,%0 \n"
+ "movbu %0,(7,sp) \n"
+ "mov +0x22,%0 \n"
+ "movbu %0,(8,sp) \n"
+ "mov +0x33,%0 \n"
+ "movbu %0,(9,sp) \n"
+ "mov +0x44,%0 \n"
+ "movbu %0,(10,sp) \n"
+ "mov (7,sp),%1 \n"
+ "add +16,sp \n"
+ : "+a"(q), "=d"(x));
+ ASSERTCMP(x, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV (259,SP),Rn ___\n");
+ asm volatile(
+ "add -264,sp \n"
+ "mov +0x11,%0 \n"
+ "movbu %0,(259,sp) \n"
+ "mov +0x22,%0 \n"
+ "movbu %0,(260,sp) \n"
+ "mov +0x33,%0 \n"
+ "movbu %0,(261,sp) \n"
+ "mov +0x55,%0 \n"
+ "movbu %0,(262,sp) \n"
+ "mov (259,sp),%1 \n"
+ "add +264,sp \n"
+ : "+d"(tmp), "=d"(x));
+ ASSERTCMP(x, ==, 0x55332211);
+
+ printk(KERN_NOTICE "___ MOV (260,SP),Rn ___\n");
+ asm volatile(
+ "add -264,sp \n"
+ "mov +0x11,%0 \n"
+ "movbu %0,(260,sp) \n"
+ "mov +0x22,%0 \n"
+ "movbu %0,(261,sp) \n"
+ "mov +0x33,%0 \n"
+ "movbu %0,(262,sp) \n"
+ "mov +0x55,%0 \n"
+ "movbu %0,(263,sp) \n"
+ "mov (260,sp),%1 \n"
+ "add +264,sp \n"
+ : "+d"(tmp), "=d"(x));
+ ASSERTCMP(x, ==, 0x55332211);
+
+
+ printk(KERN_NOTICE "___ MOV_LNE ___\n");
+ tmp = 1;
+ tmp2 = 2;
+ q = p + 256;
+ asm volatile(
+ "setlb \n"
+ "mov %2,%3 \n"
+ "mov %1,%2 \n"
+ "cmp +0,%1 \n"
+ "mov_lne (%0+,4),%1"
+ : "+r"(q), "+d"(tmp), "+d"(tmp2), "=d"(x)
+ :
+ : "cc");
+ ASSERTCMP(q, ==, p + 256 + 12);
+ ASSERTCMP(x, ==, 0x44332211);
+
+ printk(KERN_NOTICE "___ MOV in SETLB ___\n");
+ tmp = 1;
+ tmp2 = 2;
+ q = p + 256;
+ asm volatile(
+ "setlb \n"
+ "mov %1,%3 \n"
+ "mov (%0+),%1 \n"
+ "cmp +0,%1 \n"
+ "lne "
+ : "+a"(q), "+d"(tmp), "+d"(tmp2), "=d"(x)
+ :
+ : "cc");
+
+ ASSERTCMP(q, ==, p + 256 + 8);
+ ASSERTCMP(x, ==, 0x44332211);
+
+ printk(KERN_NOTICE "<==test_misalignment()\n");
+ return 0;
+}
+
+arch_initcall(test_misalignment);
+
+#endif /* CONFIG_TEST_MISALIGNMENT_HANDLER */
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 8d676d8ecde9..9830681446ad 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -113,7 +113,6 @@ static inline void acpi_disable_pci(void)
acpi_pci_disabled = 1;
acpi_noirq_set();
}
-extern int acpi_irq_balance_set(char *str);
/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 8c1f76abae9e..4c51a2f8fd31 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1343,7 +1343,6 @@ static void __init acpi_process_madt(void)
error = acpi_parse_madt_ioapic_entries();
if (!error) {
acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
- acpi_irq_balance_set(NULL);
acpi_ioapic = 1;
smp_found_config = 1;
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index 774ac4991568..1c9cc431ea4f 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -128,7 +128,7 @@ static int kvm_register_clock(char *txt)
}
#ifdef CONFIG_X86_LOCAL_APIC
-static void kvm_setup_secondary_clock(void)
+static void __devinit kvm_setup_secondary_clock(void)
{
/*
* Now that the first cpu already had this clocksource initialized,
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
index ce3251ce5504..b81125f0bdee 100644
--- a/arch/x86/kvm/Kconfig
+++ b/arch/x86/kvm/Kconfig
@@ -20,6 +20,8 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support"
depends on HAVE_KVM
+ # for device assignment:
+ depends on PCI
select PREEMPT_NOTIFIERS
select MMU_NOTIFIER
select ANON_INODES
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 8772dc946823..59ebd37ad79e 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -548,8 +548,10 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
mutex_lock(&kvm->lock);
pit->irq_source_id = kvm_request_irq_source_id(kvm);
mutex_unlock(&kvm->lock);
- if (pit->irq_source_id < 0)
+ if (pit->irq_source_id < 0) {
+ kfree(pit);
return NULL;
+ }
mutex_init(&pit->pit_state.lock);
mutex_lock(&pit->pit_state.lock);
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 2a5e64881d9b..f1983d9477cd 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -314,7 +314,7 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
if (r)
goto out;
r = mmu_topup_memory_cache(&vcpu->arch.mmu_rmap_desc_cache,
- rmap_desc_cache, 1);
+ rmap_desc_cache, 4);
if (r)
goto out;
r = mmu_topup_memory_cache_page(&vcpu->arch.mmu_page_cache, 8);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 2643b430d83a..d06b4dc0e2ea 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3564,7 +3564,8 @@ static int __init vmx_init(void)
bypass_guest_pf = 0;
kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
VMX_EPT_WRITABLE_MASK |
- VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
+ VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT |
+ VMX_EPT_IGMT_BIT);
kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
VMX_EPT_EXECUTABLE_MASK);
kvm_enable_tdp();
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
index 3e010d21fdd7..ec5edc339da6 100644
--- a/arch/x86/kvm/vmx.h
+++ b/arch/x86/kvm/vmx.h
@@ -352,6 +352,7 @@ enum vmcs_field {
#define VMX_EPT_READABLE_MASK 0x1ull
#define VMX_EPT_WRITABLE_MASK 0x2ull
#define VMX_EPT_EXECUTABLE_MASK 0x4ull
+#define VMX_EPT_IGMT_BIT (1ull << 6)
#define VMX_EPT_IDENTITY_PAGETABLE_ADDR 0xfffbc000ul
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f4f632917509..b0243fd55ac0 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -312,9 +312,13 @@ config ACPI_DEBUG
bool "Debug Statements"
default n
help
- The ACPI driver can optionally report errors with a great deal
- of verbosity. Saying Y enables these statements. This will increase
- your kernel size by around 50K.
+ The ACPI subsystem can produce debug output. Saying Y enables this
+ output and increases the kernel size by around 50K.
+
+ Use the acpi.debug_layer and acpi.debug_level kernel command-line
+ parameters documented in Documentation/acpi/debug.txt and
+ Documentation/kernel-parameters.txt to control the type and
+ amount of debug output.
config ACPI_DEBUG_FUNC_TRACE
bool "Additionally enable ACPI function tracing"
@@ -324,14 +328,6 @@ config ACPI_DEBUG_FUNC_TRACE
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
- help
- This driver is required on some systems for the proper operation of
- the battery and thermal drivers. If you are compiling for a
- mobile system, say Y.
-
config ACPI_PCI_SLOT
tristate "PCI slot detection driver"
default n
@@ -341,10 +337,6 @@ config ACPI_PCI_SLOT
help you correlate PCI bus addresses with the physical geography
of your slots. If you are unsure, say N.
-config ACPI_POWER
- bool
- default y
-
config ACPI_SYSTEM
bool
default y
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d91c027ece8f..3c0c93300f12 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -39,19 +39,23 @@ obj-y += sleep/
obj-y += bus.o glue.o
obj-y += scan.o
# Keep EC driver first. Initialization of others depend on it.
-obj-$(CONFIG_ACPI_EC) += ec.o
+obj-y += ec.o
obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
obj-$(CONFIG_ACPI_DOCK) += dock.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
+ifdef CONFIG_ACPI_VIDEO
+obj-y += video_detect.o
+endif
+
obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
-obj-$(CONFIG_ACPI_POWER) += power.o
+obj-y += power.o
obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o
obj-$(CONFIG_ACPI_DEBUG) += debug.o
obj-$(CONFIG_ACPI_NUMA) += numa.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index d72a1b6c8a94..9b917dac7732 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -37,7 +37,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_AC_COMPONENT 0x00020000
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_AC_DEVICE_NAME "AC Adapter"
#define ACPI_AC_FILE_STATE "state"
@@ -242,7 +241,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
acpi_ac_get_state(ac);
acpi_bus_generate_proc_event(device, event, (u32) ac->state);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event,
+ dev_name(&device->dev), event,
(u32) ac->state);
#ifdef CONFIG_ACPI_SYSFS_POWER
kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 71d21c51c45f..63a17b55b39b 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -32,7 +32,6 @@
#include <linux/memory_hotplug.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL
#define ACPI_MEMORY_DEVICE_CLASS "memory"
#define ACPI_MEMORY_DEVICE_HID "PNP0C80"
#define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device"
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index b2133e89ad9a..1423b0c0cd2e 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -46,7 +46,6 @@
#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
-#define ACPI_BATTERY_COMPONENT 0x00040000
#define ACPI_BATTERY_CLASS "battery"
#define ACPI_BATTERY_DEVICE_NAME "Battery"
#define ACPI_BATTERY_NOTIFY_STATUS 0x80
@@ -782,7 +781,7 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery));
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event,
+ dev_name(&device->dev), event,
acpi_battery_present(battery));
#ifdef CONFIG_ACPI_SYSFS_POWER
/* acpi_batter_update could remove power_supply object */
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c797c6473f31..7edf6d913c13 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -688,6 +688,14 @@ void __init acpi_early_init(void)
if (acpi_disabled)
return;
+ /*
+ * ACPI CA initializes acpi_dbg_level to non-zero, which means
+ * we get debug output merely by turning on CONFIG_ACPI_DEBUG.
+ * Turn it off so we don't get output unless the user specifies
+ * acpi.debug_level.
+ */
+ acpi_dbg_level = 0;
+
printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION);
/* enable workarounds, unless strict ACPI spec. compliance */
@@ -774,7 +782,7 @@ static int __init acpi_bus_init(void)
"Unable to initialize ACPI OS objects\n");
goto error1;
}
-#ifdef CONFIG_ACPI_EC
+
/*
* ACPI 2.0 requires the EC driver to be loaded and work before
* the EC device is found in the namespace (i.e. before acpi_initialize_objects()
@@ -785,7 +793,6 @@ static int __init acpi_bus_init(void)
*/
status = acpi_ec_ecdt_probe();
/* Ignore result. Not having an ECDT is not fatal. */
-#endif
status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index cb046c3fc3f2..171fd914f435 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -33,7 +33,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_BUTTON_COMPONENT 0x00080000
#define ACPI_BUTTON_CLASS "button"
#define ACPI_BUTTON_FILE_INFO "info"
#define ACPI_BUTTON_FILE_STATE "state"
@@ -479,7 +478,7 @@ static int acpi_button_add(struct acpi_device *device)
device->wakeup.gpe_number,
ACPI_GPE_TYPE_WAKE_RUN);
acpi_enable_gpe(device->wakeup.gpe_device,
- device->wakeup.gpe_number, ACPI_NOT_ISR);
+ device->wakeup.gpe_number);
device->wakeup.state.enabled = 1;
}
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
index 4441e84b28a9..307963bd1043 100644
--- a/drivers/acpi/cm_sbs.c
+++ b/drivers/acpi/cm_sbs.c
@@ -34,7 +34,6 @@
ACPI_MODULE_NAME("cm_sbs");
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_BATTERY_CLASS "battery"
-#define ACPI_SBS_COMPONENT 0x00080000
#define _COMPONENT ACPI_SBS_COMPONENT
static struct proc_dir_entry *acpi_ac_dir;
static struct proc_dir_entry *acpi_battery_dir;
@@ -105,9 +104,3 @@ void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param)
return;
}
EXPORT_SYMBOL(acpi_unlock_battery_dir);
-
-static int __init acpi_cm_sbs_init(void)
-{
- return 0;
-}
-subsys_initcall(acpi_cm_sbs_init);
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 134818b265a9..17020c12623c 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -41,7 +41,6 @@
#define INSTALL_NOTIFY_HANDLER 1
#define UNINSTALL_NOTIFY_HANDLER 2
-#define ACPI_CONTAINER_COMPONENT 0x01000000
#define _COMPONENT ACPI_CONTAINER_COMPONENT
ACPI_MODULE_NAME("container");
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index abf36b4b1d1d..c48396892008 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -44,6 +44,21 @@ static const struct acpi_dlayer acpi_debug_layers[] = {
ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
ACPI_DEBUG_INIT(ACPI_COMPILER),
ACPI_DEBUG_INIT(ACPI_TOOLS),
+
+ ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_AC_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT),
+ ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT),
};
static const struct acpi_dlevel acpi_debug_levels[] = {
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index ef42316f89f5..cf41f9fc24a7 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -70,7 +70,7 @@ enum ec_command {
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
#define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
-#define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts
+#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
per one transaction */
enum {
@@ -100,8 +100,11 @@ struct transaction {
u8 *rdata;
unsigned short irq_count;
u8 command;
+ u8 wi;
+ u8 ri;
u8 wlen;
u8 rlen;
+ bool done;
};
static struct acpi_ec {
@@ -178,34 +181,45 @@ static int ec_transaction_done(struct acpi_ec *ec)
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&ec->curr_lock, flags);
- if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
+ if (!ec->curr || ec->curr->done)
ret = 1;
spin_unlock_irqrestore(&ec->curr_lock, flags);
return ret;
}
+static void start_transaction(struct acpi_ec *ec)
+{
+ ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
+ ec->curr->done = false;
+ acpi_ec_write_cmd(ec, ec->curr->command);
+}
+
static void gpe_transaction(struct acpi_ec *ec, u8 status)
{
unsigned long flags;
spin_lock_irqsave(&ec->curr_lock, flags);
if (!ec->curr)
goto unlock;
- if (ec->curr->wlen > 0) {
- if ((status & ACPI_EC_FLAG_IBF) == 0) {
- acpi_ec_write_data(ec, *(ec->curr->wdata++));
- --ec->curr->wlen;
- } else
- /* false interrupt, state didn't change */
- ++ec->curr->irq_count;
-
- } else if (ec->curr->rlen > 0) {
+ if (ec->curr->wlen > ec->curr->wi) {
+ if ((status & ACPI_EC_FLAG_IBF) == 0)
+ acpi_ec_write_data(ec,
+ ec->curr->wdata[ec->curr->wi++]);
+ else
+ goto err;
+ } else if (ec->curr->rlen > ec->curr->ri) {
if ((status & ACPI_EC_FLAG_OBF) == 1) {
- *(ec->curr->rdata++) = acpi_ec_read_data(ec);
- --ec->curr->rlen;
+ ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec);
+ if (ec->curr->rlen == ec->curr->ri)
+ ec->curr->done = true;
} else
- /* false interrupt, state didn't change */
- ++ec->curr->irq_count;
- }
+ goto err;
+ } else if (ec->curr->wlen == ec->curr->wi &&
+ (status & ACPI_EC_FLAG_IBF) == 0)
+ ec->curr->done = true;
+ goto unlock;
+err:
+ /* false interrupt, state didn't change */
+ ++ec->curr->irq_count;
unlock:
spin_unlock_irqrestore(&ec->curr_lock, flags);
}
@@ -215,6 +229,15 @@ static int acpi_ec_wait(struct acpi_ec *ec)
if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
msecs_to_jiffies(ACPI_EC_DELAY)))
return 0;
+ /* try restart command if we get any false interrupts */
+ if (ec->curr->irq_count &&
+ (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
+ pr_debug(PREFIX "controller reset, restart transaction\n");
+ start_transaction(ec);
+ if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
+ msecs_to_jiffies(ACPI_EC_DELAY)))
+ return 0;
+ }
/* missing GPEs, switch back to poll mode */
if (printk_ratelimit())
pr_info(PREFIX "missing confirmations, "
@@ -239,10 +262,10 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
static int ec_poll(struct acpi_ec *ec)
{
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
- msleep(1);
+ udelay(ACPI_EC_UDELAY);
while (time_before(jiffies, delay)) {
gpe_transaction(ec, acpi_ec_read_status(ec));
- msleep(1);
+ udelay(ACPI_EC_UDELAY);
if (ec_transaction_done(ec))
return 0;
}
@@ -259,14 +282,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
/* disable GPE during transaction if storm is detected */
if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
- acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ acpi_disable_gpe(NULL, ec->gpe);
}
/* start transaction */
spin_lock_irqsave(&ec->curr_lock, tmp);
/* following two actions should be kept atomic */
- t->irq_count = 0;
ec->curr = t;
- acpi_ec_write_cmd(ec, ec->curr->command);
+ start_transaction(ec);
if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
spin_unlock_irqrestore(&ec->curr_lock, tmp);
@@ -283,10 +305,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
/* check if we received SCI during transaction */
ec_check_sci(ec, acpi_ec_read_status(ec));
/* it is safe to enable GPE outside of transaction */
- acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ acpi_enable_gpe(NULL, ec->gpe);
} else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
t->irq_count > ACPI_EC_STORM_THRESHOLD) {
- pr_debug(PREFIX "GPE storm detected\n");
+ pr_info(PREFIX "GPE storm detected, "
+ "transactions will use polling mode\n");
set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
}
return ret;
@@ -558,17 +581,26 @@ static u32 acpi_ec_gpe_handler(void *data)
pr_debug(PREFIX "~~~> interrupt\n");
status = acpi_ec_read_status(ec);
- gpe_transaction(ec, status);
- if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
- wake_up(&ec->wait);
+ if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) {
+ gpe_transaction(ec, status);
+ if (ec_transaction_done(ec) &&
+ (status & ACPI_EC_FLAG_IBF) == 0)
+ wake_up(&ec->wait);
+ }
ec_check_sci(ec, status);
if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
!test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
/* this is non-query, must be confirmation */
- if (printk_ratelimit())
- pr_info(PREFIX "non-query interrupt received,"
+ if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
+ if (printk_ratelimit())
+ pr_info(PREFIX "non-query interrupt received,"
+ " switching to interrupt mode\n");
+ } else {
+ /* hush, STORM switches the mode every transaction */
+ pr_debug(PREFIX "non-query interrupt received,"
" switching to interrupt mode\n");
+ }
set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
}
return ACPI_INTERRUPT_HANDLED;
@@ -736,7 +768,7 @@ static acpi_status
ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
{
acpi_status status;
- unsigned long long tmp;
+ unsigned long long tmp = 0;
struct acpi_ec *ec = context;
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
@@ -751,6 +783,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
return status;
ec->gpe = tmp;
/* Use the global lock for all EC transactions? */
+ tmp = 0;
acpi_evaluate_integer(handle, "_GLK", NULL, &tmp);
ec->global_lock = tmp;
ec->handle = handle;
@@ -868,7 +901,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
if (ACPI_FAILURE(status))
return -ENODEV;
acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME);
- acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ acpi_enable_gpe(NULL, ec->gpe);
status = acpi_install_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler,
@@ -1007,7 +1040,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state)
/* Stop using GPE */
set_bit(EC_FLAGS_NO_GPE, &ec->flags);
clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
- acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ acpi_disable_gpe(NULL, ec->gpe);
return 0;
}
@@ -1016,7 +1049,7 @@ static int acpi_ec_resume(struct acpi_device *device)
struct acpi_ec *ec = acpi_driver_data(device);
/* Enable use of GPE back */
clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
- acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ acpi_enable_gpe(NULL, ec->gpe);
return 0;
}
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index c5e53aae86f7..f45c74fe745e 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -289,8 +289,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
*/
status = acpi_hw_low_disable_gpe(gpe_event_info);
return_ACPI_STATUS(status);
-
- return_ACPI_STATUS(AE_OK);
}
/*******************************************************************************
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c
index 73bfd6bf962f..41554f736b68 100644
--- a/drivers/acpi/events/evxfevnt.c
+++ b/drivers/acpi/events/evxfevnt.c
@@ -248,21 +248,15 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
* DESCRIPTION: Enable an ACPI event (general purpose)
*
******************************************************************************/
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
{
acpi_status status = AE_OK;
+ acpi_cpu_flags flags;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE(acpi_enable_gpe);
- /* Use semaphore lock if not executing at interrupt level */
-
- if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
@@ -277,9 +271,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
unlock_and_exit:
- if (flags & ACPI_NOT_ISR) {
- (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
- }
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
@@ -299,22 +291,15 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
* DESCRIPTION: Disable an ACPI event (general purpose)
*
******************************************************************************/
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
{
acpi_status status = AE_OK;
+ acpi_cpu_flags flags;
struct acpi_gpe_event_info *gpe_event_info;
ACPI_FUNCTION_TRACE(acpi_disable_gpe);
- /* Use semaphore lock if not executing at interrupt level */
-
- if (flags & ACPI_NOT_ISR) {
- status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- }
-
+ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
@@ -325,10 +310,8 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
status = acpi_ev_disable_gpe(gpe_event_info);
- unlock_and_exit:
- if (flags & ACPI_NOT_ISR) {
- (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
- }
+unlock_and_exit:
+ acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
@@ -521,6 +504,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
if (value)
*event_status |= ACPI_EVENT_FLAG_SET;
+ if (acpi_gbl_fixed_event_handlers[event].handler)
+ *event_status |= ACPI_EVENT_FLAG_HANDLE;
+
return_ACPI_STATUS(status);
}
@@ -571,6 +557,9 @@ acpi_get_gpe_status(acpi_handle gpe_device,
status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
+ if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
+ *event_status |= ACPI_EVENT_FLAG_HANDLE;
+
unlock_and_exit:
if (flags & ACPI_NOT_ISR) {
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index 60d54d1f6b19..eaaee1660bdf 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -34,7 +34,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_FAN_COMPONENT 0x00200000
#define ACPI_FAN_CLASS "fan"
#define ACPI_FAN_FILE_STATE "state"
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 24649ada08df..adec3d15810a 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -140,6 +140,46 @@ struct device *acpi_get_physical_device(acpi_handle handle)
EXPORT_SYMBOL(acpi_get_physical_device);
+/* ToDo: When a PCI bridge is found, return the PCI device behind the bridge
+ * This should work in general, but did not on a Lenovo T61 for the
+ * graphics card. But this must be fixed when the PCI device is
+ * bound and the kernel device struct is attached to the acpi device
+ * Note: A success call will increase reference count by one
+ * Do call put_device(dev) on the returned device then
+ */
+struct device *acpi_get_physical_pci_device(acpi_handle handle)
+{
+ struct device *dev;
+ long long device_id;
+ acpi_status status;
+
+ status =
+ acpi_evaluate_integer(handle, "_ADR", NULL, &device_id);
+
+ if (ACPI_FAILURE(status))
+ return NULL;
+
+ /* We need to attempt to determine whether the _ADR refers to a
+ PCI device or not. There's no terribly good way to do this,
+ so the best we can hope for is to assume that there'll never
+ be a device in the host bridge */
+ if (device_id >= 0x10000) {
+ /* It looks like a PCI device. Does it exist? */
+ dev = acpi_get_physical_device(handle);
+ } else {
+ /* It doesn't look like a PCI device. Does its parent
+ exist? */
+ acpi_handle phandle;
+ if (acpi_get_parent(handle, &phandle))
+ return NULL;
+ dev = acpi_get_physical_device(phandle);
+ }
+ if (!dev)
+ return NULL;
+ return dev;
+}
+EXPORT_SYMBOL(acpi_get_physical_pci_device);
+
static int acpi_bind_one(struct device *dev, acpi_handle handle)
{
struct acpi_device *acpi_dev;
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index fcfdef7b4fdd..e52ad91ce2dc 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -531,7 +531,7 @@ int __init acpi_irq_penalty_init(void)
return 0;
}
-static int acpi_irq_balance; /* 0: static, 1: balance */
+static int acpi_irq_balance = -1; /* 0: static, 1: balance */
static int acpi_pci_link_allocate(struct acpi_pci_link *link)
{
@@ -950,10 +950,17 @@ device_initcall(irqrouter_init_sysfs);
static int __init acpi_pci_link_init(void)
{
-
if (acpi_noirq)
return 0;
+ if (acpi_irq_balance == -1) {
+ /* no command line switch: enable balancing in IOAPIC mode */
+ if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
+ acpi_irq_balance = 1;
+ else
+ acpi_irq_balance = 0;
+ }
+
acpi_link.count = 0;
INIT_LIST_HEAD(&acpi_link.entries);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 1b8f67d21d53..642554b1b60c 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -376,15 +376,9 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
static int __init acpi_pci_root_init(void)
{
-
if (acpi_pci_disabled)
return 0;
- /* DEBUG:
- acpi_dbg_layer = ACPI_PCI_COMPONENT;
- acpi_dbg_level = 0xFFFFFFFF;
- */
-
if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
return -ENODEV;
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index a1718e56103b..bb7d50dd2818 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -44,9 +44,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define _COMPONENT ACPI_POWER_COMPONENT
+#define _COMPONENT ACPI_POWER_COMPONENT
ACPI_MODULE_NAME("power");
-#define ACPI_POWER_COMPONENT 0x00800000
#define ACPI_POWER_CLASS "power_resource"
#define ACPI_POWER_DEVICE_NAME "Power Resource"
#define ACPI_POWER_FILE_INFO "info"
@@ -153,7 +152,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state)
ACPI_POWER_RESOURCE_STATE_OFF;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
- acpi_ut_get_node_name(handle), state ? "on" : "off"));
+ acpi_ut_get_node_name(handle),
+ *state ? "on" : "off"));
return 0;
}
@@ -516,11 +516,6 @@ int acpi_power_transition(struct acpi_device *device, int state)
cl = &device->power.states[device->power.state].resources;
tl = &device->power.states[state].resources;
- if (!cl->count && !tl->count) {
- result = -ENODEV;
- goto end;
- }
-
/* TBD: Resources must be ordered. */
/*
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 24a362f8034c..34948362f41d 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -59,7 +59,6 @@
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
-#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
#define ACPI_PROCESSOR_FILE_INFO "info"
@@ -89,6 +88,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr);
static const struct acpi_device_id processor_device_ids[] = {
+ {ACPI_PROCESSOR_OBJECT_HID, 0},
{ACPI_PROCESSOR_HID, 0},
{"", 0},
};
@@ -409,7 +409,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device)
/* Use the acpiid in MADT to map cpus in case of SMP */
#ifndef CONFIG_SMP
-static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;}
+static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; }
#else
static struct acpi_table_madt *madt;
@@ -428,27 +428,35 @@ static int map_lapic_id(struct acpi_subtable_header *entry,
}
static int map_lsapic_id(struct acpi_subtable_header *entry,
- u32 acpi_id, int *apic_id)
+ int device_declaration, u32 acpi_id, int *apic_id)
{
struct acpi_madt_local_sapic *lsapic =
(struct acpi_madt_local_sapic *)entry;
+ u32 tmp = (lsapic->id << 8) | lsapic->eid;
+
/* Only check enabled APICs*/
- if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
- /* First check against id */
- if (lsapic->processor_id == acpi_id) {
- *apic_id = (lsapic->id << 8) | lsapic->eid;
- return 1;
- /* Check against optional uid */
- } else if (entry->length >= 16 &&
- lsapic->uid == acpi_id) {
- *apic_id = lsapic->uid;
- return 1;
- }
- }
+ if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ /* Device statement declaration type */
+ if (device_declaration) {
+ if (entry->length < 16)
+ printk(KERN_ERR PREFIX
+ "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n",
+ tmp);
+ else if (lsapic->uid == acpi_id)
+ goto found;
+ /* Processor statement declaration type */
+ } else if (lsapic->processor_id == acpi_id)
+ goto found;
+
return 0;
+found:
+ *apic_id = tmp;
+ return 1;
}
-static int map_madt_entry(u32 acpi_id)
+static int map_madt_entry(int type, u32 acpi_id)
{
unsigned long madt_end, entry;
int apic_id = -1;
@@ -469,7 +477,7 @@ static int map_madt_entry(u32 acpi_id)
if (map_lapic_id(header, acpi_id, &apic_id))
break;
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
- if (map_lsapic_id(header, acpi_id, &apic_id))
+ if (map_lsapic_id(header, type, acpi_id, &apic_id))
break;
}
entry += header->length;
@@ -477,7 +485,7 @@ static int map_madt_entry(u32 acpi_id)
return apic_id;
}
-static int map_mat_entry(acpi_handle handle, u32 acpi_id)
+static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
{
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj;
@@ -500,7 +508,7 @@ static int map_mat_entry(acpi_handle handle, u32 acpi_id)
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
map_lapic_id(header, acpi_id, &apic_id);
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
- map_lsapic_id(header, acpi_id, &apic_id);
+ map_lsapic_id(header, type, acpi_id, &apic_id);
}
exit:
@@ -509,14 +517,14 @@ exit:
return apic_id;
}
-static int get_cpu_id(acpi_handle handle, u32 acpi_id)
+static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)
{
int i;
int apic_id = -1;
- apic_id = map_mat_entry(handle, acpi_id);
+ apic_id = map_mat_entry(handle, type, acpi_id);
if (apic_id == -1)
- apic_id = map_madt_entry(acpi_id);
+ apic_id = map_madt_entry(type, acpi_id);
if (apic_id == -1)
return apic_id;
@@ -532,15 +540,16 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id)
Driver Interface
-------------------------------------------------------------------------- */
-static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
+static int acpi_processor_get_info(struct acpi_device *device)
{
acpi_status status = 0;
union acpi_object object = { 0 };
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
- int cpu_index;
+ struct acpi_processor *pr;
+ int cpu_index, device_declaration = 0;
static int cpu0_initialized;
-
+ pr = acpi_driver_data(device);
if (!pr)
return -EINVAL;
@@ -561,22 +570,23 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No bus mastering arbitration control\n"));
- /* Check if it is a Device with HID and UID */
- if (has_uid) {
+ if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) {
+ /*
+ * Declared with "Device" statement; match _UID.
+ * Note that we don't handle string _UIDs yet.
+ */
unsigned long long value;
status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
NULL, &value);
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Evaluating processor _UID\n");
+ printk(KERN_ERR PREFIX
+ "Evaluating processor _UID [%#x]\n", status);
return -ENODEV;
}
+ device_declaration = 1;
pr->acpi_id = value;
} else {
- /*
- * Evalute the processor object. Note that it is common on SMP to
- * have the first (boot) processor with a valid PBLK address while
- * all others have a NULL address.
- */
+ /* Declared with "Processor" statement; match ProcessorID */
status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Evaluating processor object\n");
@@ -584,12 +594,13 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
}
/*
- * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
- * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c
- */
+ * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
+ * >>> 'acpi_get_processor_id(acpi_id, &id)' in
+ * arch/xxx/acpi.c
+ */
pr->acpi_id = object.processor.proc_id;
}
- cpu_index = get_cpu_id(pr->handle, pr->acpi_id);
+ cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);
/* Handle UP system running SMP kernel, with no LAPIC in MADT */
if (!cpu0_initialized && (cpu_index == -1) &&
@@ -661,7 +672,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
pr = acpi_driver_data(device);
- result = acpi_processor_get_info(pr, device->flags.unique_id);
+ result = acpi_processor_get_info(device);
if (result) {
/* Processor is physically not present */
return 0;
@@ -761,20 +772,20 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
acpi_bus_generate_proc_event(device, event,
pr->performance_platform_limit);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event,
+ dev_name(&device->dev), event,
pr->performance_platform_limit);
break;
case ACPI_PROCESSOR_NOTIFY_POWER:
acpi_processor_cst_has_changed(pr);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event, 0);
+ dev_name(&device->dev), event, 0);
break;
case ACPI_PROCESSOR_NOTIFY_THROTTLING:
acpi_processor_tstate_has_changed(pr);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event, 0);
+ dev_name(&device->dev), event, 0);
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 81b40ed5379e..5f8d746a9b81 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -59,7 +59,6 @@
#include <acpi/processor.h>
#include <asm/processor.h>
-#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_idle");
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index dbcf260ea93f..0d7b772bef50 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -44,9 +44,9 @@
#endif
#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
-#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index ef34b18f95ca..b1eb376fae45 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -40,7 +40,6 @@
#include <acpi/processor.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_thermal");
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 3da2df93d924..a0c38c94a8a0 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -38,9 +38,9 @@
#include <asm/uaccess.h>
#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
-#define ACPI_PROCESSOR_COMPONENT 0x01000000
#define ACPI_PROCESSOR_CLASS "processor"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_throttling");
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c
index 755baf2ca70a..a6b662c00b67 100644
--- a/drivers/acpi/reboot.c
+++ b/drivers/acpi/reboot.c
@@ -15,28 +15,9 @@ void acpi_reboot(void)
rr = &acpi_gbl_FADT.reset_register;
- /*
- * Is the ACPI reset register supported?
- *
- * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates
- * whether the ACPI reset mechanism is supported.
- *
- * However, some boxes have this bit clear, yet a valid
- * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only
- * mechanism that works for them after S3.
- *
- * This suggests that other operating systems may not be checking
- * the RESET_REG_SUP bit, and are using other means to decide
- * whether to use the ACPI reboot mechanism or not.
- *
- * So when acpi reboot is requested,
- * only the reset_register is checked. If the following
- * conditions are met, it indicates that the reset register is supported.
- * a. reset_register is not zero
- * b. the access width is eight
- * c. the bit_offset is zero
- */
- if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0)
+ /* Is the reset register supported? */
+ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) ||
+ rr->bit_width != 8 || rr->bit_offset != 0)
return;
reset_value = acpi_gbl_FADT.reset_value;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a9dda8e0f9f9..bd5253ee5c85 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -109,8 +109,7 @@ static int acpi_bus_hot_remove_device(void *context)
return 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Hot-removing device %s...\n", device->dev.bus_id));
-
+ "Hot-removing device %s...\n", dev_name(&device->dev)));
if (acpi_bus_trim(device, 1)) {
printk(KERN_ERR PREFIX
@@ -460,7 +459,7 @@ static int acpi_device_register(struct acpi_device *device,
acpi_device_bus_id->instance_no = 0;
list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list);
}
- sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
+ dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
if (device->parent) {
list_add_tail(&device->node, &device->parent->children);
@@ -484,7 +483,8 @@ static int acpi_device_register(struct acpi_device *device,
result = acpi_device_setup_files(device);
if(result)
- printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id);
+ printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
+ dev_name(&device->dev));
device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
return 0;
@@ -919,36 +919,6 @@ static void acpi_device_get_busid(struct acpi_device *device,
}
}
-static int
-acpi_video_bus_match(struct acpi_device *device)
-{
- acpi_handle h_dummy;
-
- if (!device)
- return -EINVAL;
-
- /* Since there is no HID, CID for ACPI Video drivers, we have
- * to check well known required nodes for each feature we support.
- */
-
- /* Does this device able to support video switching ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
- ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
- return 0;
-
- /* Does this device able to retrieve a video ROM ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
- return 0;
-
- /* Does this device able to configure which video head to be POSTed ? */
- if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
- ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
- ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
- return 0;
-
- return -ENODEV;
-}
-
/*
* acpi_bay_match - see if a device is an ejectable driver bay
*
@@ -1031,7 +1001,7 @@ static void acpi_device_set_id(struct acpi_device *device,
will get autoloaded and the device might still match
against another driver.
*/
- if (ACPI_SUCCESS(acpi_video_bus_match(device)))
+ if (acpi_is_video_device(device))
cid_add = ACPI_VIDEO_HID;
else if (ACPI_SUCCESS(acpi_bay_match(device)))
cid_add = ACPI_BAY_HID;
@@ -1043,7 +1013,7 @@ static void acpi_device_set_id(struct acpi_device *device,
hid = ACPI_POWER_HID;
break;
case ACPI_BUS_TYPE_PROCESSOR:
- hid = ACPI_PROCESSOR_HID;
+ hid = ACPI_PROCESSOR_OBJECT_HID;
break;
case ACPI_BUS_TYPE_SYSTEM:
hid = ACPI_SYSTEM_HID;
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 631ee2ee2ca0..64e591ba86f2 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -366,8 +366,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
dev->wakeup.state.enabled ? "enabled" : "disabled");
if (ldev)
seq_printf(seq, "%s:%s",
- ldev->bus ? ldev->bus->name : "no-bus",
- ldev->bus_id);
+ dev_name(ldev) ? ldev->bus->name : "no-bus",
+ dev_name(ldev));
seq_printf(seq, "\n");
put_device(ldev);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 38655eb132dc..dea4c23df764 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -88,7 +88,7 @@ void acpi_enable_wakeup_device(u8 sleep_state)
spin_unlock(&acpi_device_lock);
if (!dev->wakeup.flags.run_wake)
acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_ISR);
+ dev->wakeup.gpe_number);
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
@@ -122,7 +122,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
ACPI_GPE_TYPE_WAKE_RUN);
/* Re-enable it, since set_gpe_type will disable it */
acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ dev->wakeup.gpe_number);
spin_lock(&acpi_device_lock);
}
continue;
@@ -133,7 +133,7 @@ void acpi_disable_wakeup_device(u8 sleep_state)
/* Never disable run-wake GPE */
if (!dev->wakeup.flags.run_wake) {
acpi_disable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ dev->wakeup.gpe_number);
acpi_clear_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
}
@@ -162,7 +162,7 @@ static int __init acpi_wakeup_device_init(void)
dev->wakeup.gpe_number,
ACPI_GPE_TYPE_WAKE_RUN);
acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ dev->wakeup.gpe_number);
dev->wakeup.state.enabled = 1;
spin_lock(&acpi_device_lock);
}
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 1d74171b7940..6e4107f82403 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct kobject *kobj,
container_of(bin_attr, struct acpi_table_attr, attr);
struct acpi_table_header *table_header = NULL;
acpi_status status;
+ char name[ACPI_NAME_SIZE];
+
+ if (strncmp(table_attr->name, "NULL", 4))
+ memcpy(name, table_attr->name, ACPI_NAME_SIZE);
+ else
+ memcpy(name, "\0\0\0\0", 4);
status =
- acpi_get_table(table_attr->name, table_attr->instance,
+ acpi_get_table(name, table_attr->instance,
&table_header);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
struct acpi_table_header *header = NULL;
struct acpi_table_attr *attr = NULL;
- memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
+ if (table_header->signature[0] != '\0')
+ memcpy(table_attr->name, table_header->signature,
+ ACPI_NAME_SIZE);
+ else
+ memcpy(table_attr->name, "NULL", 4);
list_for_each_entry(attr, &acpi_table_attr_list, node) {
- if (!memcmp(table_header->signature, attr->name,
- ACPI_NAME_SIZE))
+ if (!memcmp(table_attr->name, 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);
+ !acpi_get_table
+ (table_header->signature, 2, &header)))
+ sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
+ table_attr->instance);
table_attr->attr.size = 0;
table_attr->attr.read = acpi_table_show;
@@ -167,7 +176,6 @@ static int acpi_system_sysfs_init(void)
#define COUNT_ERROR 2 /* other */
#define NUM_COUNTERS_EXTRA 3
-#define ACPI_EVENT_VALID 0x01
struct event_counter {
u32 count;
u32 flags;
@@ -312,12 +320,6 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle)
} else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS))
result = acpi_get_event_status(index - num_gpes, status);
- /*
- * sleep/power button GPE/Fixed Event is enabled after acpi_system_init,
- * check the status at runtime and mark it as valid once it's enabled
- */
- if (!result && (*status & ACPI_EVENT_FLAG_ENABLED))
- all_counters[index].flags |= ACPI_EVENT_VALID;
end:
return result;
}
@@ -346,12 +348,14 @@ static ssize_t counter_show(struct kobject *kobj,
if (result)
goto end;
- if (!(all_counters[index].flags & ACPI_EVENT_VALID))
- size += sprintf(buf + size, " invalid");
+ if (!(status & ACPI_EVENT_FLAG_HANDLE))
+ size += sprintf(buf + size, " invalid");
else if (status & ACPI_EVENT_FLAG_ENABLED)
- size += sprintf(buf + size, " enable");
+ size += sprintf(buf + size, " enabled");
+ else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
+ size += sprintf(buf + size, " wake_enabled");
else
- size += sprintf(buf + size, " disable");
+ size += sprintf(buf + size, " disabled");
end:
size += sprintf(buf + size, "\n");
@@ -385,7 +389,7 @@ static ssize_t counter_set(struct kobject *kobj,
if (result)
goto end;
- if (!(all_counters[index].flags & ACPI_EVENT_VALID)) {
+ if (!(status & ACPI_EVENT_FLAG_HANDLE)) {
printk(KERN_WARNING PREFIX
"Can not change Invalid GPE/Fixed Event status\n");
return -EINVAL;
@@ -394,10 +398,10 @@ static ssize_t counter_set(struct kobject *kobj,
if (index < num_gpes) {
if (!strcmp(buf, "disable\n") &&
(status & ACPI_EVENT_FLAG_ENABLED))
- result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR);
+ result = acpi_disable_gpe(handle, index);
else if (!strcmp(buf, "enable\n") &&
!(status & ACPI_EVENT_FLAG_ENABLED))
- result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR);
+ result = acpi_enable_gpe(handle, index);
else if (!strcmp(buf, "clear\n") &&
(status & ACPI_EVENT_FLAG_SET))
result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR);
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
index 2c7885e7ffba..2817158fb6a1 100644
--- a/drivers/acpi/tables/tbfadt.c
+++ b/drivers/acpi/tables/tbfadt.c
@@ -304,7 +304,7 @@ static void acpi_tb_convert_fadt(void)
* 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) {
+ if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) {
acpi_gbl_FADT.preferred_profile = 0;
acpi_gbl_FADT.pstate_control = 0;
acpi_gbl_FADT.cst_control = 0;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index ad6cae938f0b..073ff09218a9 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -47,7 +47,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_THERMAL_COMPONENT 0x04000000
#define ACPI_THERMAL_CLASS "thermal_zone"
#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone"
#define ACPI_THERMAL_FILE_STATE "state"
@@ -576,7 +575,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
tz->trips.critical.flags.enabled);
acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- tz->device->dev.bus_id,
+ dev_name(&tz->device->dev),
ACPI_THERMAL_NOTIFY_CRITICAL,
tz->trips.critical.flags.enabled);
@@ -605,7 +604,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
tz->trips.hot.flags.enabled);
acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- tz->device->dev.bus_id,
+ dev_name(&tz->device->dev),
ACPI_THERMAL_NOTIFY_HOT,
tz->trips.hot.flags.enabled);
@@ -1592,14 +1591,14 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
acpi_thermal_check(tz);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event, 0);
+ dev_name(&device->dev), event, 0);
break;
case ACPI_THERMAL_NOTIFY_DEVICES:
acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
acpi_thermal_check(tz);
acpi_bus_generate_proc_event(device, event, 0);
acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event, 0);
+ dev_name(&device->dev), event, 0);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index a29b0ccac65a..baa441929720 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -41,7 +41,6 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_VIDEO_COMPONENT 0x08000000
#define ACPI_VIDEO_CLASS "video"
#define ACPI_VIDEO_BUS_NAME "Video Bus"
#define ACPI_VIDEO_DEVICE_NAME "Video Device"
@@ -739,7 +738,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cap._DSS = 1;
}
- max_level = acpi_video_init_brightness(device);
+ if (acpi_video_backlight_support())
+ max_level = acpi_video_init_brightness(device);
if (device->cap._BCL && device->cap._BCM && max_level > 0) {
int result;
@@ -785,18 +785,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
printk(KERN_ERR PREFIX "Create sysfs link\n");
}
- 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);
+
+ if (acpi_video_display_switch_support()) {
+
+ if (device->cap._DCS && device->cap._DSS) {
+ static int count;
+ 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;
}
/*
@@ -842,11 +845,16 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video)
static int acpi_video_bus_check(struct acpi_video_bus *video)
{
acpi_status status = -ENOENT;
-
+ struct device *dev;
if (!video)
return -EINVAL;
+ dev = acpi_get_physical_pci_device(video->device->handle);
+ if (!dev)
+ return -ENODEV;
+ put_device(dev);
+
/* Since there is no HID, CID and so on for VGA driver, we have
* to check well known required nodes.
*/
@@ -2094,12 +2102,6 @@ static int __init acpi_video_init(void)
{
int result = 0;
-
- /*
- acpi_dbg_level = 0xFFFFFFFF;
- acpi_dbg_layer = 0x08000000;
- */
-
acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
if (!acpi_video_dir)
return -ENODEV;
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
new file mode 100644
index 000000000000..f022eb6f5637
--- /dev/null
+++ b/drivers/acpi/video_detect.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2008 SuSE Linux Products GmbH
+ * Thomas Renninger <trenn@suse.de>
+ *
+ * May be copied or modified under the terms of the GNU General Public License
+ *
+ * video_detect.c:
+ * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c
+ * There a Linux specific (Spec does not provide a HID for video devices) is
+ * assinged
+ *
+ * After PCI devices are glued with ACPI devices
+ * acpi_get_physical_pci_device() can be called to identify ACPI graphics
+ * devices for which a real graphics card is plugged in
+ *
+ * Now acpi_video_get_capabilities() can be called to check which
+ * capabilities the graphics cards plugged in support. The check for general
+ * video capabilities will be triggered by the first caller of
+ * acpi_video_get_capabilities(NULL); which will happen when the first
+ * backlight (or display output) switching supporting driver calls:
+ * acpi_video_backlight_support();
+ *
+ * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B)
+ * are available, video.ko should be used to handle the device.
+ *
+ * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi,
+ * sony_acpi,... can take care about backlight brightness and display output
+ * switching.
+ *
+ * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
+ * this file will not be compiled, acpi_video_get_capabilities() and
+ * acpi_video_backlight_support() will always return 0 and vendor specific
+ * drivers always can handle backlight.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+
+ACPI_MODULE_NAME("video");
+#define _COMPONENT ACPI_VIDEO_COMPONENT
+
+static long acpi_video_support;
+static bool acpi_video_caps_checked;
+
+static acpi_status
+acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
+ void **retyurn_value)
+{
+ long *cap = context;
+ acpi_handle h_dummy;
+
+ if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) &&
+ ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
+ "support\n"));
+ *cap |= ACPI_VIDEO_BACKLIGHT;
+ /* We have backlight support, no need to scan further */
+ return AE_CTRL_TERMINATE;
+ }
+ return 0;
+}
+
+/* Returns true if the device is a video device which can be handled by
+ * video.ko.
+ * The device will get a Linux specific CID added in scan.c to
+ * identify the device as an ACPI graphics device
+ * Be aware that the graphics device may not be physically present
+ * Use acpi_video_get_capabilities() to detect general ACPI video
+ * capabilities of present cards
+ */
+long acpi_is_video_device(struct acpi_device *device)
+{
+ acpi_handle h_dummy;
+ long video_caps = 0;
+
+ if (!device)
+ return 0;
+
+ /* Does this device able to support video switching ? */
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
+ video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
+
+ /* Does this device able to retrieve a video ROM ? */
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy)))
+ video_caps |= ACPI_VIDEO_ROM_AVAILABLE;
+
+ /* Does this device able to configure which video head to be POSTed ? */
+ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) &&
+ ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy)))
+ video_caps |= ACPI_VIDEO_DEVICE_POSTING;
+
+ /* Only check for backlight functionality if one of the above hit. */
+ if (video_caps)
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle,
+ ACPI_UINT32_MAX, acpi_backlight_cap_match,
+ &video_caps, NULL);
+
+ return video_caps;
+}
+EXPORT_SYMBOL(acpi_is_video_device);
+
+static acpi_status
+find_video(acpi_handle handle, u32 lvl, void *context, void **rv)
+{
+ long *cap = context;
+ struct device *dev;
+ struct acpi_device *acpi_dev;
+
+ const struct acpi_device_id video_ids[] = {
+ {ACPI_VIDEO_HID, 0},
+ {"", 0},
+ };
+ if (acpi_bus_get_device(handle, &acpi_dev))
+ return AE_OK;
+
+ if (!acpi_match_device_ids(acpi_dev, video_ids)) {
+ dev = acpi_get_physical_pci_device(handle);
+ if (!dev)
+ return AE_OK;
+ put_device(dev);
+ *cap |= acpi_is_video_device(acpi_dev);
+ }
+ return AE_OK;
+}
+
+/*
+ * Returns the video capabilities of a specific ACPI graphics device
+ *
+ * if NULL is passed as argument all ACPI devices are enumerated and
+ * all graphics capabilities of physically present devices are
+ * summerized and returned. This is cached and done only once.
+ */
+long acpi_video_get_capabilities(acpi_handle graphics_handle)
+{
+ long caps = 0;
+ struct acpi_device *tmp_dev;
+ acpi_status status;
+
+ if (acpi_video_caps_checked && graphics_handle == NULL)
+ return acpi_video_support;
+
+ if (!graphics_handle) {
+ /* Only do the global walk through all graphics devices once */
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ ACPI_UINT32_MAX, find_video,
+ &caps, NULL);
+ /* There might be boot param flags set already... */
+ acpi_video_support |= caps;
+ acpi_video_caps_checked = 1;
+ /* Add blacklists here. Be careful to use the right *DMI* bits
+ * to still be able to override logic via boot params, e.g.:
+ *
+ * if (dmi_name_in_vendors("XY")) {
+ * acpi_video_support |=
+ * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR;
+ * acpi_video_support |=
+ * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR;
+ *}
+ */
+ } else {
+ status = acpi_bus_get_device(graphics_handle, &tmp_dev);
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status, "Invalid device"));
+ return 0;
+ }
+ acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle,
+ ACPI_UINT32_MAX, find_video,
+ &caps, NULL);
+ }
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n",
+ graphics_handle ? caps : acpi_video_support,
+ graphics_handle ? "on device " : "in general",
+ graphics_handle ? acpi_device_bid(tmp_dev) : ""));
+ return caps;
+}
+EXPORT_SYMBOL(acpi_video_get_capabilities);
+
+/* Returns true if video.ko can do backlight switching */
+int acpi_video_backlight_support(void)
+{
+ /*
+ * We must check whether the ACPI graphics device is physically plugged
+ * in. Therefore this must be called after binding PCI and ACPI devices
+ */
+ if (!acpi_video_caps_checked)
+ acpi_video_get_capabilities(NULL);
+
+ /* First check for boot param -> highest prio */
+ if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR)
+ return 0;
+ else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO)
+ return 1;
+
+ /* Then check for DMI blacklist -> second highest prio */
+ if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR)
+ return 0;
+ else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO)
+ return 1;
+
+ /* Then go the default way */
+ return acpi_video_support & ACPI_VIDEO_BACKLIGHT;
+}
+EXPORT_SYMBOL(acpi_video_backlight_support);
+
+/*
+ * Returns true if video.ko can do display output switching.
+ * This does not work well/at all with binary graphics drivers
+ * which disable system io ranges and do it on their own.
+ */
+int acpi_video_display_switch_support(void)
+{
+ if (!acpi_video_caps_checked)
+ acpi_video_get_capabilities(NULL);
+
+ if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR)
+ return 0;
+ else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO)
+ return 1;
+
+ if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR)
+ return 0;
+ else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO)
+ return 1;
+
+ return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING;
+}
+EXPORT_SYMBOL(acpi_video_display_switch_support);
+
+/*
+ * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video
+ * To force that backlight or display output switching is processed by vendor
+ * specific acpi drivers or video.ko driver.
+ */
+int __init acpi_backlight(char *str)
+{
+ if (str == NULL || *str == '\0')
+ return 1;
+ else {
+ if (!strcmp("vendor", str))
+ acpi_video_support |=
+ ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR;
+ if (!strcmp("video", str))
+ acpi_video_support |=
+ ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
+ }
+ return 1;
+}
+__setup("acpi_backlight=", acpi_backlight);
+
+int __init acpi_display_output(char *str)
+{
+ if (str == NULL || *str == '\0')
+ return 1;
+ else {
+ if (!strcmp("vendor", str))
+ acpi_video_support |=
+ ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR;
+ if (!strcmp("video", str))
+ acpi_video_support |=
+ ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO;
+ }
+ return 1;
+}
+__setup("acpi_display_output=", acpi_display_output);
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
index 47cd7baf9b1b..8a8b377712c9 100644
--- a/drivers/acpi/wmi.c
+++ b/drivers/acpi/wmi.c
@@ -660,7 +660,7 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
wblock->handler(event, wblock->handler_data);
acpi_bus_generate_netlink_event(
- device->pnp.device_class, device->dev.bus_id,
+ device->pnp.device_class, dev_name(&device->dev),
event, 0);
break;
}
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 2457b07dabd6..f4374437a033 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -523,7 +523,7 @@ static int acpi_driver_registered;
static int sonypi_ec_write(u8 addr, u8 value)
{
-#ifdef CONFIG_ACPI_EC
+#ifdef CONFIG_ACPI
if (SONYPI_ACPI_ACTIVE)
return ec_write(addr, value);
#endif
@@ -539,7 +539,7 @@ static int sonypi_ec_write(u8 addr, u8 value)
static int sonypi_ec_read(u8 addr, u8 *value)
{
-#ifdef CONFIG_ACPI_EC
+#ifdef CONFIG_ACPI
if (SONYPI_ACPI_ACTIVE)
return ec_read(addr, value);
#endif
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig
index 108264de0ac9..f15e90a453d1 100644
--- a/drivers/idle/Kconfig
+++ b/drivers/idle/Kconfig
@@ -1,5 +1,6 @@
menu "Memory power savings"
+depends on X86_64
config I7300_IDLE_IOAT_CHANNEL
bool
@@ -7,7 +8,7 @@ config I7300_IDLE_IOAT_CHANNEL
config I7300_IDLE
tristate "Intel chipset idle memory power saving driver"
select I7300_IDLE_IOAT_CHANNEL
- depends on X86_64 && EXPERIMENTAL
+ depends on EXPERIMENTAL
help
Enable memory power savings when idle with certain Intel server
chipsets. The chipset must have I/O AT support, such as the
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 9494400e8fd0..4494ad27cbf1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -230,7 +230,7 @@ config HP_WMI
config MSI_LAPTOP
tristate "MSI Laptop Extras"
depends on X86
- depends on ACPI_EC
+ depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE
---help---
This is a driver for laptops built by MSI (MICRO-STAR
@@ -260,7 +260,7 @@ config PANASONIC_LAPTOP
config COMPAL_LAPTOP
tristate "Compal Laptop Extras"
depends on X86
- depends on ACPI_EC
+ depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE
---help---
This is a driver for laptops built by Compal:
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index 0532a2de2ce4..94c9f911824e 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -1297,6 +1297,12 @@ static int __init acer_wmi_init(void)
set_quirks();
+ if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) {
+ interface->capability &= ~ACER_CAP_BRIGHTNESS;
+ printk(ACER_INFO "Brightness must be controlled by "
+ "generic video driver\n");
+ }
+
if (platform_driver_register(&acer_platform_driver)) {
printk(ACER_ERR "Unable to register platform driver.\n");
goto error_platform_register;
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index a9d5228724a6..8fb8b3591048 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -1208,9 +1208,13 @@ static int __init asus_laptop_init(void)
dev = acpi_get_physical_device(hotk->device->handle);
- result = asus_backlight_init(dev);
- if (result)
- goto fail_backlight;
+ if (!acpi_video_backlight_support()) {
+ result = asus_backlight_init(dev);
+ if (result)
+ goto fail_backlight;
+ } else
+ printk(ASUS_INFO "Brightness ignored, must be controlled by "
+ "ACPI video driver\n");
result = asus_led_init(dev);
if (result)
diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c
index 344b790a6253..11003bba10d3 100644
--- a/drivers/misc/compal-laptop.c
+++ b/drivers/misc/compal-laptop.c
@@ -326,12 +326,14 @@ static int __init compal_init(void)
/* Register backlight stuff */
- compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
- &compalbl_ops);
- if (IS_ERR(compalbl_device))
- return PTR_ERR(compalbl_device);
+ if (!acpi_video_backlight_support()) {
+ compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
+ &compalbl_ops);
+ if (IS_ERR(compalbl_device))
+ return PTR_ERR(compalbl_device);
- compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
+ compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
+ }
ret = platform_driver_register(&compal_driver);
if (ret)
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c
index 9ef98b2d5039..02fe2b8b8939 100644
--- a/drivers/misc/eeepc-laptop.c
+++ b/drivers/misc/eeepc-laptop.c
@@ -825,9 +825,15 @@ static int __init eeepc_laptop_init(void)
return -ENODEV;
}
dev = acpi_get_physical_device(ehotk->device->handle);
- result = eeepc_backlight_init(dev);
- if (result)
- goto fail_backlight;
+
+ if (!acpi_video_backlight_support()) {
+ result = eeepc_backlight_init(dev);
+ if (result)
+ goto fail_backlight;
+ } else
+ printk(EEEPC_INFO "Backlight controlled by ACPI video "
+ "driver\n");
+
result = eeepc_hwmon_init(dev);
if (result)
goto fail_hwmon;
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
index d2cf0bfe3163..a7dd3e9fb79d 100644
--- a/drivers/misc/fujitsu-laptop.c
+++ b/drivers/misc/fujitsu-laptop.c
@@ -464,6 +464,14 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id)
return 0;
}
+static int dmi_check_cb_s6420(const struct dmi_system_id *id)
+{
+ dmi_check_cb_common(id);
+ fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */
+ fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */
+ return 0;
+}
+
static int dmi_check_cb_p8010(const struct dmi_system_id *id)
{
dmi_check_cb_common(id);
@@ -473,7 +481,7 @@ static int dmi_check_cb_p8010(const struct dmi_system_id *id)
return 0;
}
-static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
+static struct dmi_system_id fujitsu_dmi_table[] = {
{
.ident = "Fujitsu Siemens S6410",
.matches = {
@@ -482,6 +490,13 @@ static struct dmi_system_id __initdata fujitsu_dmi_table[] = {
},
.callback = dmi_check_cb_s6410},
{
+ .ident = "Fujitsu Siemens S6420",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"),
+ },
+ .callback = dmi_check_cb_s6420},
+ {
.ident = "Fujitsu LifeBook P8010",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
@@ -990,16 +1005,16 @@ static int __init fujitsu_init(void)
/* Register backlight stuff */
- fujitsu->bl_device =
- backlight_device_register("fujitsu-laptop", NULL, NULL,
- &fujitsubl_ops);
- if (IS_ERR(fujitsu->bl_device))
- return PTR_ERR(fujitsu->bl_device);
-
- max_brightness = fujitsu->max_brightness;
-
- fujitsu->bl_device->props.max_brightness = max_brightness - 1;
- fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
+ if (!acpi_video_backlight_support()) {
+ fujitsu->bl_device =
+ backlight_device_register("fujitsu-laptop", NULL, NULL,
+ &fujitsubl_ops);
+ if (IS_ERR(fujitsu->bl_device))
+ return PTR_ERR(fujitsu->bl_device);
+ max_brightness = fujitsu->max_brightness;
+ fujitsu->bl_device->props.max_brightness = max_brightness - 1;
+ fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
+ }
ret = platform_driver_register(&fujitsupf_driver);
if (ret)
@@ -1035,7 +1050,8 @@ fail_hotkey:
fail_backlight:
- backlight_device_unregister(fujitsu->bl_device);
+ if (fujitsu->bl_device)
+ backlight_device_unregister(fujitsu->bl_device);
fail_platform_device2:
@@ -1062,7 +1078,8 @@ static void __exit fujitsu_cleanup(void)
&fujitsupf_attribute_group);
platform_device_unregister(fujitsu->pf_device);
platform_driver_unregister(&fujitsupf_driver);
- backlight_device_unregister(fujitsu->bl_device);
+ if (fujitsu->bl_device)
+ backlight_device_unregister(fujitsu->bl_device);
acpi_bus_unregister_driver(&acpi_fujitsu_driver);
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c
index e00a2756e97e..27b7662955bb 100644
--- a/drivers/misc/intel_menlow.c
+++ b/drivers/misc/intel_menlow.c
@@ -52,6 +52,11 @@ MODULE_LICENSE("GPL");
#define MEMORY_ARG_CUR_BANDWIDTH 1
#define MEMORY_ARG_MAX_BANDWIDTH 0
+/*
+ * GTHS returning 'n' would mean that [0,n-1] states are supported
+ * In that case max_cstate would be n-1
+ * GTHS returning '0' would mean that no bandwidth control states are supported
+ */
static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
unsigned long *max_state)
{
@@ -71,6 +76,9 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
if (ACPI_FAILURE(status))
return -EFAULT;
+ if (!value)
+ return -EINVAL;
+
*max_state = value - 1;
return 0;
}
@@ -121,7 +129,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
if (memory_get_int_max_bandwidth(cdev, &max_state))
return -EFAULT;
- if (max_state < 0 || state > max_state)
+ if (state > max_state)
return -EINVAL;
arg_list.count = 1;
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index de898c6938f3..759763d18e4c 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -347,12 +347,16 @@ static int __init msi_init(void)
/* Register backlight stuff */
- msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL,
- &msibl_ops);
- if (IS_ERR(msibl_device))
- return PTR_ERR(msibl_device);
-
- msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
+ if (acpi_video_backlight_support()) {
+ printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
+ "by ACPI video driver\n");
+ } else {
+ msibl_device = backlight_device_register("msi-laptop-bl", NULL,
+ NULL, &msibl_ops);
+ if (IS_ERR(msibl_device))
+ return PTR_ERR(msibl_device);
+ msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
+ }
ret = platform_driver_register(&msipf_driver);
if (ret)
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 06f07e19dc70..7bcb81002dcf 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -1038,7 +1038,11 @@ static int sony_nc_add(struct acpi_device *device)
goto outinput;
}
- if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &handle))) {
+ if (!acpi_video_backlight_support()) {
+ printk(KERN_INFO DRV_PFX "Sony: Brightness ignored, must be "
+ "controlled by ACPI video driver\n");
+ } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
+ &handle))) {
sony_backlight_device = backlight_device_register("sony", NULL,
NULL,
&sony_backlight_ops);
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 4db1cf9078d9..7a4a26b0edd2 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -4932,16 +4932,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
*/
b = tpacpi_check_std_acpi_brightness_support();
if (b > 0) {
- if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
- printk(TPACPI_NOTICE
- "Lenovo BIOS switched to ACPI backlight "
- "control mode\n");
- }
- if (brightness_enable > 1) {
- printk(TPACPI_NOTICE
- "standard ACPI backlight interface "
- "available, not loading native one...\n");
- return 1;
+
+ if (acpi_video_backlight_support()) {
+ if (brightness_enable > 1) {
+ printk(TPACPI_NOTICE
+ "Standard ACPI backlight interface "
+ "available, not loading native one.\n");
+ return 1;
+ } else if (brightness_enable == 1) {
+ printk(TPACPI_NOTICE
+ "Backlight control force enabled, even if standard "
+ "ACPI backlight interface is available\n");
+ }
+ } else {
+ if (brightness_enable > 1) {
+ printk(TPACPI_NOTICE
+ "Standard ACPI backlight interface not "
+ "available, thinkpad_acpi native "
+ "brightness control enabled\n");
+ }
}
}
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 54a279e44c9a..e9f6574930ef 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -380,6 +380,8 @@ struct acpi_bus_type {
int register_acpi_bus_type(struct acpi_bus_type *);
int unregister_acpi_bus_type(struct acpi_bus_type *);
struct device *acpi_get_physical_device(acpi_handle);
+struct device *acpi_get_physical_pci_device(acpi_handle);
+
/* helper */
acpi_handle acpi_get_child(acpi_handle, acpi_integer);
acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index cf04c6011c2a..5fc1bb0f4a90 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -31,8 +31,24 @@
#define ACPI_MAX_STRING 80
+/*
+ * Please update drivers/acpi/debug.c and Documentation/acpi/debug.txt
+ * if you add to this list.
+ */
#define ACPI_BUS_COMPONENT 0x00010000
+#define ACPI_AC_COMPONENT 0x00020000
+#define ACPI_BATTERY_COMPONENT 0x00040000
+#define ACPI_BUTTON_COMPONENT 0x00080000
+#define ACPI_SBS_COMPONENT 0x00100000
+#define ACPI_FAN_COMPONENT 0x00200000
+#define ACPI_PCI_COMPONENT 0x00400000
+#define ACPI_POWER_COMPONENT 0x00800000
+#define ACPI_CONTAINER_COMPONENT 0x01000000
#define ACPI_SYSTEM_COMPONENT 0x02000000
+#define ACPI_THERMAL_COMPONENT 0x04000000
+#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000
+#define ACPI_VIDEO_COMPONENT 0x10000000
+#define ACPI_PROCESSOR_COMPONENT 0x20000000
/*
* _HID definitions
@@ -41,6 +57,7 @@
*/
#define ACPI_POWER_HID "LNXPOWER"
+#define ACPI_PROCESSOR_OBJECT_HID "ACPI_CPU"
#define ACPI_PROCESSOR_HID "ACPI0007"
#define ACPI_SYSTEM_HID "LNXSYSTM"
#define ACPI_THERMAL_HID "LNXTHERM"
@@ -54,7 +71,6 @@
PCI
-------------------------------------------------------------------------- */
-#define ACPI_PCI_COMPONENT 0x00400000
/* ACPI PCI Interrupt Link (pci_link.c) */
@@ -86,7 +102,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
Power Resource
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_POWER
int acpi_device_sleep_wake(struct acpi_device *dev,
int enable, int sleep_state, int dev_state);
int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
@@ -94,15 +109,12 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev);
int acpi_power_get_inferred_state(struct acpi_device *device);
int acpi_power_transition(struct acpi_device *device, int state);
extern int acpi_power_nocheck;
-#endif
/* --------------------------------------------------------------------------
Embedded Controller
-------------------------------------------------------------------------- */
-#ifdef CONFIG_ACPI_EC
int acpi_ec_ecdt_probe(void);
int acpi_boot_ec_enable(void);
-#endif
/* --------------------------------------------------------------------------
Processor
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 94d94e126e9f..33bc0e3b1954 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -252,9 +252,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type);
-acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
+acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);
-acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
+acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);
acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags);
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index e8936ab59627..7220361790b3 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -525,6 +525,7 @@ typedef u32 acpi_event_status;
#define ACPI_EVENT_FLAG_ENABLED (acpi_event_status) 0x01
#define ACPI_EVENT_FLAG_WAKE_ENABLED (acpi_event_status) 0x02
#define ACPI_EVENT_FLAG_SET (acpi_event_status) 0x04
+#define ACPI_EVENT_FLAG_HANDLE (acpi_event_status) 0x08
/*
* General Purpose Events (GPE)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index fd6a452b0ceb..fba8051fb297 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -163,8 +163,6 @@ struct acpi_pci_driver {
int acpi_pci_register_driver(struct acpi_pci_driver *driver);
void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
-#ifdef CONFIG_ACPI_EC
-
extern int ec_read(u8 addr, u8 *val);
extern int ec_write(u8 addr, u8 val);
extern int ec_transaction(u8 command,
@@ -172,8 +170,6 @@ extern int ec_transaction(u8 command,
u8 *rdata, unsigned rdata_len,
int force_poll);
-#endif /*CONFIG_ACPI_EC*/
-
#if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE)
typedef void (*wmi_notify_handler) (u32 value, void *context);
@@ -194,6 +190,50 @@ extern bool wmi_has_guid(const char *guid);
#endif /* CONFIG_ACPI_WMI */
+#define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001
+#define ACPI_VIDEO_DEVICE_POSTING 0x0002
+#define ACPI_VIDEO_ROM_AVAILABLE 0x0004
+#define ACPI_VIDEO_BACKLIGHT 0x0008
+#define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR 0x0010
+#define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO 0x0020
+#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR 0x0040
+#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO 0x0080
+#define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR 0x0100
+#define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200
+#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400
+#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800
+
+#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE)
+
+extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle);
+extern long acpi_is_video_device(struct acpi_device *device);
+extern int acpi_video_backlight_support(void);
+extern int acpi_video_display_switch_support(void);
+
+#else
+
+static inline long acpi_video_get_capabilities(acpi_handle graphics_dev_handle)
+{
+ return 0;
+}
+
+static inline long acpi_is_video_device(struct acpi_device *device)
+{
+ return 0;
+}
+
+static inline int acpi_video_backlight_support(void)
+{
+ return 0;
+}
+
+static inline int acpi_video_display_switch_support(void)
+{
+ return 0;
+}
+
+#endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */
+
extern int acpi_blacklisted(void);
#ifdef CONFIG_DMI
extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
diff --git a/mm/mmap.c b/mm/mmap.c
index de14ac21e5b5..d4855a682ab6 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1704,7 +1704,7 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
vma = find_vma_prev(mm, addr, &prev);
if (vma && (vma->vm_start <= addr))
return vma;
- if (expand_stack(prev, addr))
+ if (!prev || expand_stack(prev, addr))
return NULL;
if (prev->vm_flags & VM_LOCKED) {
if (mlock_vma_pages_range(prev, addr, prev->vm_end) < 0)