Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6:
x86 ACPI: Add support for Always Running APIC timer
ACPI x86: Make aperf/mperf MSR access in acpi_cpufreq read_only
ACPI x86: Cleanup acpi_cpufreq structures related to aperf/mperf
ACPICA: delete check for AML access to port 0x81-83
ACPI: WMI: use .notify method instead of installing handler directly
sony-laptop: use .notify method instead of installing handler directly
panasonic-laptop: use .notify method instead of installing handler directly
fujitsu-laptop: use .notify method instead of installing hotkey handler directly
fujitsu-laptop: use .notify method instead of installing handler directly
ACPI: video: use .notify method instead of installing handler directly
ACPI: thermal: use .notify method instead of installing handler directly
ACPI battery: fix async boot oops
ACPI: delete acpi_device.g_list
NULL noise: drivers/platform/x86/panasonic-laptop.c
ACPI: cpufreq: remove dupilcated #include
ACPI: Adjust Kelvin offset to match local implementation
ACPI: convert acpi_device_lock spinlock to mutex
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 0beba0d..bb83b1c 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -154,6 +154,7 @@
* CPUID levels like 0x6, 0xA etc
*/
#define X86_FEATURE_IDA (7*32+ 0) /* Intel Dynamic Acceleration */
+#define X86_FEATURE_ARAT (7*32+ 1) /* Always Running APIC Timer */
/* Virtualization flags: Linux defined */
#define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 098ec84..f287092 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -431,6 +431,12 @@
{
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
+ if (cpu_has(¤t_cpu_data, X86_FEATURE_ARAT)) {
+ lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
+ /* Make LAPIC timer preferrable over percpu HPET */
+ lapic_clockevent.rating = 150;
+ }
+
memcpy(levt, &lapic_clockevent, sizeof(*levt));
levt->cpumask = cpumask_of(smp_processor_id());
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
index 8220ae6..c965e52 100644
--- a/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -31,6 +31,7 @@
static const struct cpuid_bit __cpuinitconst cpuid_bits[] = {
{ X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
+ { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006 },
{ 0, 0, 0, 0 }
};
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 19f6b9d..9d3af38 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -68,6 +68,7 @@
unsigned int max_freq;
unsigned int resume;
unsigned int cpu_feature;
+ u64 saved_aperf, saved_mperf;
};
static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
@@ -241,26 +242,23 @@
return cmd.val;
}
-struct perf_cur {
+struct perf_pair {
union {
struct {
u32 lo;
u32 hi;
} split;
u64 whole;
- } aperf_cur, mperf_cur;
+ } aperf, mperf;
};
static long read_measured_perf_ctrs(void *_cur)
{
- struct perf_cur *cur = _cur;
+ struct perf_pair *cur = _cur;
- rdmsr(MSR_IA32_APERF, cur->aperf_cur.split.lo, cur->aperf_cur.split.hi);
- rdmsr(MSR_IA32_MPERF, cur->mperf_cur.split.lo, cur->mperf_cur.split.hi);
-
- wrmsr(MSR_IA32_APERF, 0, 0);
- wrmsr(MSR_IA32_MPERF, 0, 0);
+ rdmsr(MSR_IA32_APERF, cur->aperf.split.lo, cur->aperf.split.hi);
+ rdmsr(MSR_IA32_MPERF, cur->mperf.split.lo, cur->mperf.split.hi);
return 0;
}
@@ -281,52 +279,57 @@
static unsigned int get_measured_perf(struct cpufreq_policy *policy,
unsigned int cpu)
{
- struct perf_cur cur;
+ struct perf_pair readin, cur;
unsigned int perf_percent;
unsigned int retval;
- if (!work_on_cpu(cpu, read_measured_perf_ctrs, &cur))
+ if (!work_on_cpu(cpu, read_measured_perf_ctrs, &readin))
return 0;
+ cur.aperf.whole = readin.aperf.whole -
+ per_cpu(drv_data, cpu)->saved_aperf;
+ cur.mperf.whole = readin.mperf.whole -
+ per_cpu(drv_data, cpu)->saved_mperf;
+ per_cpu(drv_data, cpu)->saved_aperf = readin.aperf.whole;
+ per_cpu(drv_data, cpu)->saved_mperf = readin.mperf.whole;
+
#ifdef __i386__
/*
* We dont want to do 64 bit divide with 32 bit kernel
* Get an approximate value. Return failure in case we cannot get
* an approximate value.
*/
- if (unlikely(cur.aperf_cur.split.hi || cur.mperf_cur.split.hi)) {
+ if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) {
int shift_count;
u32 h;
- h = max_t(u32, cur.aperf_cur.split.hi, cur.mperf_cur.split.hi);
+ h = max_t(u32, cur.aperf.split.hi, cur.mperf.split.hi);
shift_count = fls(h);
- cur.aperf_cur.whole >>= shift_count;
- cur.mperf_cur.whole >>= shift_count;
+ cur.aperf.whole >>= shift_count;
+ cur.mperf.whole >>= shift_count;
}
- if (((unsigned long)(-1) / 100) < cur.aperf_cur.split.lo) {
+ if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) {
int shift_count = 7;
- cur.aperf_cur.split.lo >>= shift_count;
- cur.mperf_cur.split.lo >>= shift_count;
+ cur.aperf.split.lo >>= shift_count;
+ cur.mperf.split.lo >>= shift_count;
}
- if (cur.aperf_cur.split.lo && cur.mperf_cur.split.lo)
- perf_percent = (cur.aperf_cur.split.lo * 100) /
- cur.mperf_cur.split.lo;
+ if (cur.aperf.split.lo && cur.mperf.split.lo)
+ perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo;
else
perf_percent = 0;
#else
- if (unlikely(((unsigned long)(-1) / 100) < cur.aperf_cur.whole)) {
+ if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) {
int shift_count = 7;
- cur.aperf_cur.whole >>= shift_count;
- cur.mperf_cur.whole >>= shift_count;
+ cur.aperf.whole >>= shift_count;
+ cur.mperf.whole >>= shift_count;
}
- if (cur.aperf_cur.whole && cur.mperf_cur.whole)
- perf_percent = (cur.aperf_cur.whole * 100) /
- cur.mperf_cur.whole;
+ if (cur.aperf.whole && cur.mperf.whole)
+ perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole;
else
perf_percent = 0;
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index 0bd48e6..ce2ed3e 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -33,7 +33,6 @@
#include <linux/timex.h>
#include <linux/io.h>
#include <linux/acpi.h>
-#include <linux/kernel.h>
#include <asm/msr.h>
#include <acpi/processor.h>
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index bd3c937..7737afb 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -90,7 +90,6 @@
{"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
{"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
{"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
- {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
{"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
{"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
{"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index b0de631..3c7d894 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -903,7 +903,7 @@
},
};
-static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
+static void acpi_battery_init_async(void *unused, async_cookie_t cookie)
{
if (acpi_disabled)
return;
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 05dfdc9..d0d550d 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -343,9 +343,6 @@
}
#endif /* HAVE_ACPI_LEGACY_ALARM */
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
static int
acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
{
@@ -353,7 +350,7 @@
seq_printf(seq, "Device\tS-state\t Status Sysfs node\n");
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -361,7 +358,6 @@
if (!dev->wakeup.flags.valid)
continue;
- spin_unlock(&acpi_device_lock);
ldev = acpi_get_physical_device(dev->handle);
seq_printf(seq, "%s\t S%d\t%c%-8s ",
@@ -376,9 +372,8 @@
seq_printf(seq, "\n");
put_device(ldev);
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return 0;
}
@@ -409,7 +404,7 @@
strbuf[len] = '\0';
sscanf(strbuf, "%s", str);
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -446,7 +441,7 @@
}
}
}
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return count;
}
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 4e6e758..6fe1214 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -145,6 +145,9 @@
struct acpi_processor_power *pwr = &pr->power;
u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
+ if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
+ return;
+
/*
* Check, if one of the previous states already marked the lapic
* unstable
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 20c23c0..8ff510b 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -24,7 +24,7 @@
static LIST_HEAD(acpi_device_list);
static LIST_HEAD(acpi_bus_id_list);
-DEFINE_SPINLOCK(acpi_device_lock);
+DEFINE_MUTEX(acpi_device_lock);
LIST_HEAD(acpi_wakeup_device_list);
struct acpi_device_bus_id{
@@ -491,7 +491,6 @@
*/
INIT_LIST_HEAD(&device->children);
INIT_LIST_HEAD(&device->node);
- INIT_LIST_HEAD(&device->g_list);
INIT_LIST_HEAD(&device->wakeup_list);
new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
@@ -500,7 +499,7 @@
return -ENOMEM;
}
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
/*
* Find suitable bus_id and instance number in acpi_bus_id_list
* If failed, create one and link it into acpi_bus_id_list
@@ -521,14 +520,12 @@
}
dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
- if (device->parent) {
+ if (device->parent)
list_add_tail(&device->node, &device->parent->children);
- list_add_tail(&device->g_list, &device->parent->g_list);
- } else
- list_add_tail(&device->g_list, &acpi_device_list);
+
if (device->wakeup.flags.valid)
list_add_tail(&device->wakeup_list, &acpi_wakeup_device_list);
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
if (device->parent)
device->dev.parent = &parent->dev;
@@ -549,28 +546,22 @@
device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
return 0;
end:
- spin_lock(&acpi_device_lock);
- if (device->parent) {
+ mutex_lock(&acpi_device_lock);
+ if (device->parent)
list_del(&device->node);
- list_del(&device->g_list);
- } else
- list_del(&device->g_list);
list_del(&device->wakeup_list);
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return result;
}
static void acpi_device_unregister(struct acpi_device *device, int type)
{
- spin_lock(&acpi_device_lock);
- if (device->parent) {
+ mutex_lock(&acpi_device_lock);
+ if (device->parent)
list_del(&device->node);
- list_del(&device->g_list);
- } else
- list_del(&device->g_list);
list_del(&device->wakeup_list);
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
acpi_detach_data(device->handle, acpi_bus_data_handler);
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
index cfaf8f5..8a8f3b3 100644
--- a/drivers/acpi/sleep.h
+++ b/drivers/acpi/sleep.h
@@ -5,3 +5,6 @@
extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state);
+
+extern struct list_head acpi_wakeup_device_list;
+extern struct mutex acpi_device_lock;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index e8c143c..9cd15e8 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -98,6 +98,7 @@
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
static int acpi_thermal_resume(struct acpi_device *device);
+static void acpi_thermal_notify(struct acpi_device *device, u32 event);
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
@@ -123,6 +124,7 @@
.add = acpi_thermal_add,
.remove = acpi_thermal_remove,
.resume = acpi_thermal_resume,
+ .notify = acpi_thermal_notify,
},
};
@@ -192,6 +194,7 @@
struct acpi_handle_list devices;
struct thermal_zone_device *thermal_zone;
int tz_enabled;
+ int kelvin_offset;
struct mutex lock;
};
@@ -581,7 +584,7 @@
}
/* sys I/F for generic thermal sysfs support */
-#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
+#define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
static int thermal_get_temp(struct thermal_zone_device *thermal,
unsigned long *temp)
@@ -596,7 +599,7 @@
if (result)
return result;
- *temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
+ *temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
return 0;
}
@@ -702,7 +705,8 @@
if (tz->trips.critical.flags.valid) {
if (!trip) {
*temp = KELVIN_TO_MILLICELSIUS(
- tz->trips.critical.temperature);
+ tz->trips.critical.temperature,
+ tz->kelvin_offset);
return 0;
}
trip--;
@@ -711,7 +715,8 @@
if (tz->trips.hot.flags.valid) {
if (!trip) {
*temp = KELVIN_TO_MILLICELSIUS(
- tz->trips.hot.temperature);
+ tz->trips.hot.temperature,
+ tz->kelvin_offset);
return 0;
}
trip--;
@@ -720,7 +725,8 @@
if (tz->trips.passive.flags.valid) {
if (!trip) {
*temp = KELVIN_TO_MILLICELSIUS(
- tz->trips.passive.temperature);
+ tz->trips.passive.temperature,
+ tz->kelvin_offset);
return 0;
}
trip--;
@@ -730,7 +736,8 @@
tz->trips.active[i].flags.valid; i++) {
if (!trip) {
*temp = KELVIN_TO_MILLICELSIUS(
- tz->trips.active[i].temperature);
+ tz->trips.active[i].temperature,
+ tz->kelvin_offset);
return 0;
}
trip--;
@@ -745,7 +752,8 @@
if (tz->trips.critical.flags.valid) {
*temperature = KELVIN_TO_MILLICELSIUS(
- tz->trips.critical.temperature);
+ tz->trips.critical.temperature,
+ tz->kelvin_offset);
return 0;
} else
return -EINVAL;
@@ -1264,17 +1272,14 @@
Driver Interface
-------------------------------------------------------------------------- */
-static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_thermal_notify(struct acpi_device *device, u32 event)
{
- struct acpi_thermal *tz = data;
- struct acpi_device *device = NULL;
+ struct acpi_thermal *tz = acpi_driver_data(device);
if (!tz)
return;
- device = tz->device;
-
switch (event) {
case ACPI_THERMAL_NOTIFY_TEMPERATURE:
acpi_thermal_check(tz);
@@ -1298,8 +1303,6 @@
"Unsupported event [0x%x]\n", event));
break;
}
-
- return;
}
static int acpi_thermal_get_info(struct acpi_thermal *tz)
@@ -1334,10 +1337,28 @@
return 0;
}
+/*
+ * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
+ * handles temperature values with a single decimal place. As a consequence,
+ * some implementations use an offset of 273.1 and others use an offset of
+ * 273.2. Try to find out which one is being used, to present the most
+ * accurate and visually appealing number.
+ *
+ * The heuristic below should work for all ACPI thermal zones which have a
+ * critical trip point with a value being a multiple of 0.5 degree Celsius.
+ */
+static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
+{
+ if (tz->trips.critical.flags.valid &&
+ (tz->trips.critical.temperature % 5) == 1)
+ tz->kelvin_offset = 2731;
+ else
+ tz->kelvin_offset = 2732;
+}
+
static int acpi_thermal_add(struct acpi_device *device)
{
int result = 0;
- acpi_status status = AE_OK;
struct acpi_thermal *tz = NULL;
@@ -1360,6 +1381,8 @@
if (result)
goto free_memory;
+ acpi_thermal_guess_offset(tz);
+
result = acpi_thermal_register_thermal_zone(tz);
if (result)
goto free_memory;
@@ -1368,21 +1391,11 @@
if (result)
goto unregister_thermal_zone;
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_thermal_notify, tz);
- if (ACPI_FAILURE(status)) {
- result = -ENODEV;
- goto remove_fs;
- }
-
printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
acpi_device_name(device), acpi_device_bid(device),
KELVIN_TO_CELSIUS(tz->temperature));
goto end;
-remove_fs:
- acpi_thermal_remove_fs(device);
unregister_thermal_zone:
thermal_zone_device_unregister(tz->thermal_zone);
free_memory:
@@ -1393,7 +1406,6 @@
static int acpi_thermal_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
struct acpi_thermal *tz = NULL;
if (!device || !acpi_driver_data(device))
@@ -1401,10 +1413,6 @@
tz = acpi_driver_data(device);
- status = acpi_remove_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_thermal_notify);
-
acpi_thermal_remove_fs(device);
acpi_thermal_unregister_thermal_zone(tz);
mutex_destroy(&tz->lock);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index ab06143..cd4fb75 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -79,6 +79,7 @@
static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
static int acpi_video_resume(struct acpi_device *device);
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id video_device_ids[] = {
{ACPI_VIDEO_HID, 0},
@@ -94,6 +95,7 @@
.add = acpi_video_bus_add,
.remove = acpi_video_bus_remove,
.resume = acpi_video_resume,
+ .notify = acpi_video_bus_notify,
},
};
@@ -1986,17 +1988,15 @@
return acpi_video_bus_DOS(video, 0, 1);
}
-static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
{
- struct acpi_video_bus *video = data;
- struct acpi_device *device = NULL;
+ struct acpi_video_bus *video = acpi_driver_data(device);
struct input_dev *input;
int keycode;
if (!video)
return;
- device = video->device;
input = video->input;
switch (event) {
@@ -2127,7 +2127,6 @@
static int acpi_video_bus_add(struct acpi_device *device)
{
- acpi_status status;
struct acpi_video_bus *video;
struct input_dev *input;
int error;
@@ -2169,20 +2168,10 @@
acpi_video_bus_get_devices(video, device);
acpi_video_bus_start_devices(video);
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify, video);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX
- "Error installing notify handler\n");
- error = -ENODEV;
- goto err_stop_video;
- }
-
video->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
- goto err_uninstall_notify;
+ goto err_stop_video;
}
snprintf(video->phys, sizeof(video->phys),
@@ -2218,9 +2207,6 @@
err_free_input_dev:
input_free_device(input);
- err_uninstall_notify:
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify);
err_stop_video:
acpi_video_bus_stop_devices(video);
acpi_video_bus_put_devices(video);
@@ -2235,7 +2221,6 @@
static int acpi_video_bus_remove(struct acpi_device *device, int type)
{
- acpi_status status = 0;
struct acpi_video_bus *video = NULL;
@@ -2245,11 +2230,6 @@
video = acpi_driver_data(device);
acpi_video_bus_stop_devices(video);
-
- status = acpi_remove_notify_handler(video->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_video_bus_notify);
-
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 5aee8c2..88725dc 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -12,12 +12,14 @@
#include "internal.h"
#include "sleep.h"
+/*
+ * We didn't lock acpi_device_lock in the file, because it invokes oops in
+ * suspend/resume and isn't really required as this is called in S-state. At
+ * that time, there is no device hotplug
+ **/
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("wakeup_devices")
-extern struct list_head acpi_wakeup_device_list;
-extern spinlock_t acpi_device_lock;
-
/**
* acpi_enable_wakeup_device_prep - prepare wakeup devices
* @sleep_state: ACPI state
@@ -29,7 +31,6 @@
{
struct list_head *node, *next;
- spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct acpi_device,
@@ -40,11 +41,8 @@
(sleep_state > (u32) dev->wakeup.sleep_state))
continue;
- spin_unlock(&acpi_device_lock);
acpi_enable_wakeup_device_power(dev, sleep_state);
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
}
/**
@@ -60,7 +58,6 @@
* Caution: this routine must be invoked when interrupt is disabled
* Refer ACPI2.0: P212
*/
- spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -74,22 +71,17 @@
if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
|| sleep_state > (u32) dev->wakeup.sleep_state) {
if (dev->wakeup.flags.run_wake) {
- spin_unlock(&acpi_device_lock);
/* set_gpe_type will disable GPE, leave it like that */
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number,
ACPI_GPE_TYPE_RUNTIME);
- spin_lock(&acpi_device_lock);
}
continue;
}
- spin_unlock(&acpi_device_lock);
if (!dev->wakeup.flags.run_wake)
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number);
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
}
/**
@@ -101,7 +93,6 @@
{
struct list_head *node, *next;
- spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev =
container_of(node, struct acpi_device, wakeup_list);
@@ -112,19 +103,16 @@
if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared)
|| sleep_state > (u32) dev->wakeup.sleep_state) {
if (dev->wakeup.flags.run_wake) {
- spin_unlock(&acpi_device_lock);
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number,
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);
- spin_lock(&acpi_device_lock);
}
continue;
}
- spin_unlock(&acpi_device_lock);
acpi_disable_wakeup_device_power(dev);
/* Never disable run-wake GPE */
if (!dev->wakeup.flags.run_wake) {
@@ -133,16 +121,14 @@
acpi_clear_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
}
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
}
int __init acpi_wakeup_device_init(void)
{
struct list_head *node, *next;
- spin_lock(&acpi_device_lock);
+ mutex_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct acpi_device,
@@ -150,15 +136,13 @@
/* In case user doesn't load button driver */
if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
continue;
- spin_unlock(&acpi_device_lock);
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number,
ACPI_GPE_TYPE_WAKE_RUN);
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number);
dev->wakeup.state.enabled = 1;
- spin_lock(&acpi_device_lock);
}
- spin_unlock(&acpi_device_lock);
+ mutex_unlock(&acpi_device_lock);
return 0;
}
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index 45940f3..218b9a1 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -174,8 +174,7 @@
static struct fujitsu_hotkey_t *fujitsu_hotkey;
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
- void *data);
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_LEDS_CLASS
static enum led_brightness logolamp_get(struct led_classdev *cdev);
@@ -203,7 +202,7 @@
static u32 dbg_level = 0x03;
#endif
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event);
/* Fujitsu ACPI interface function */
@@ -658,7 +657,6 @@
static int acpi_fujitsu_add(struct acpi_device *device)
{
- acpi_status status;
acpi_handle handle;
int result = 0;
int state = 0;
@@ -673,20 +671,10 @@
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = fujitsu;
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_notify, fujitsu);
-
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR "Error installing notify handler\n");
- error = -ENODEV;
- goto err_stop;
- }
-
fujitsu->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
- goto err_uninstall_notify;
+ goto err_stop;
}
snprintf(fujitsu->phys, sizeof(fujitsu->phys),
@@ -743,9 +731,6 @@
end:
err_free_input_dev:
input_free_device(input);
-err_uninstall_notify:
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_notify);
err_stop:
return result;
@@ -753,7 +738,6 @@
static int acpi_fujitsu_remove(struct acpi_device *device, int type)
{
- acpi_status status;
struct fujitsu_t *fujitsu = NULL;
if (!device || !acpi_driver_data(device))
@@ -761,10 +745,6 @@
fujitsu = acpi_driver_data(device);
- status = acpi_remove_notify_handler(fujitsu->acpi_handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_notify);
-
if (!device || !acpi_driver_data(device))
return -EINVAL;
@@ -775,7 +755,7 @@
/* Brightness notify */
-static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_fujitsu_notify(struct acpi_device *device, u32 event)
{
struct input_dev *input;
int keycode;
@@ -829,15 +809,12 @@
input_report_key(input, keycode, 0);
input_sync(input);
}
-
- return;
}
/* ACPI device for hotkey handling */
static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
{
- acpi_status status;
acpi_handle handle;
int result = 0;
int state = 0;
@@ -854,17 +831,6 @@
sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
device->driver_data = fujitsu_hotkey;
- status = acpi_install_notify_handler(device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_hotkey_notify,
- fujitsu_hotkey);
-
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR "Error installing notify handler\n");
- error = -ENODEV;
- goto err_stop;
- }
-
/* kfifo */
spin_lock_init(&fujitsu_hotkey->fifo_lock);
fujitsu_hotkey->fifo =
@@ -879,7 +845,7 @@
fujitsu_hotkey->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
- goto err_uninstall_notify;
+ goto err_free_fifo;
}
snprintf(fujitsu_hotkey->phys, sizeof(fujitsu_hotkey->phys),
@@ -975,9 +941,7 @@
end:
err_free_input_dev:
input_free_device(input);
-err_uninstall_notify:
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_hotkey_notify);
+err_free_fifo:
kfifo_free(fujitsu_hotkey->fifo);
err_stop:
@@ -986,7 +950,6 @@
static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
{
- acpi_status status;
struct fujitsu_hotkey_t *fujitsu_hotkey = NULL;
if (!device || !acpi_driver_data(device))
@@ -994,10 +957,6 @@
fujitsu_hotkey = acpi_driver_data(device);
- status = acpi_remove_notify_handler(fujitsu_hotkey->acpi_handle,
- ACPI_DEVICE_NOTIFY,
- acpi_fujitsu_hotkey_notify);
-
fujitsu_hotkey->acpi_handle = NULL;
kfifo_free(fujitsu_hotkey->fifo);
@@ -1005,8 +964,7 @@
return 0;
}
-static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
- void *data)
+static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event)
{
struct input_dev *input;
int keycode, keycode_r;
@@ -1089,8 +1047,6 @@
input_sync(input);
break;
}
-
- return;
}
/* Initialization */
@@ -1107,6 +1063,7 @@
.ops = {
.add = acpi_fujitsu_add,
.remove = acpi_fujitsu_remove,
+ .notify = acpi_fujitsu_notify,
},
};
@@ -1122,6 +1079,7 @@
.ops = {
.add = acpi_fujitsu_hotkey_add,
.remove = acpi_fujitsu_hotkey_remove,
+ .notify = acpi_fujitsu_hotkey_notify,
},
};
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index a5ce4bc..fe7cf01 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -176,6 +176,7 @@
static int acpi_pcc_hotkey_add(struct acpi_device *device);
static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type);
static int acpi_pcc_hotkey_resume(struct acpi_device *device);
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id pcc_device_ids[] = {
{ "MAT0012", 0},
@@ -194,6 +195,7 @@
.add = acpi_pcc_hotkey_add,
.remove = acpi_pcc_hotkey_remove,
.resume = acpi_pcc_hotkey_resume,
+ .notify = acpi_pcc_hotkey_notify,
},
};
@@ -271,7 +273,7 @@
union acpi_object *hkey = NULL;
int i;
- status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, 0,
+ status = acpi_evaluate_object(pcc->handle, METHOD_HKEY_SINF, NULL,
&buffer);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -527,9 +529,9 @@
return;
}
-static void acpi_pcc_hotkey_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event)
{
- struct pcc_acpi *pcc = (struct pcc_acpi *) data;
+ struct pcc_acpi *pcc = acpi_driver_data(device);
switch (event) {
case HKEY_NOTIFY:
@@ -599,7 +601,6 @@
static int acpi_pcc_hotkey_add(struct acpi_device *device)
{
- acpi_status status;
struct pcc_acpi *pcc;
int num_sifr, result;
@@ -640,22 +641,11 @@
goto out_sinf;
}
- /* initialize hotkey input device */
- status = acpi_install_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
- acpi_pcc_hotkey_notify, pcc);
-
- if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
- "Error installing notify handler\n"));
- result = -ENODEV;
- goto out_input;
- }
-
/* initialize backlight */
pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
&pcc_backlight_ops);
if (IS_ERR(pcc->backlight))
- goto out_notify;
+ goto out_input;
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
@@ -680,9 +670,6 @@
out_backlight:
backlight_device_unregister(pcc->backlight);
-out_notify:
- acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
- acpi_pcc_hotkey_notify);
out_input:
input_unregister_device(pcc->input_dev);
/* no need to input_free_device() since core input API refcount and
@@ -723,9 +710,6 @@
backlight_device_unregister(pcc->backlight);
- acpi_remove_notify_handler(pcc->handle, ACPI_DEVICE_NOTIFY,
- acpi_pcc_hotkey_notify);
-
input_unregister_device(pcc->input_dev);
/* no need to input_free_device() since core input API refcount and
* free()s the device */
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index a90ec5c..d3c92d7 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -914,7 +914,7 @@
/*
* ACPI callbacks
*/
-static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
+static void sony_nc_notify(struct acpi_device *device, u32 event)
{
u32 ev = event;
@@ -933,7 +933,7 @@
struct sony_nc_event *key_event;
if (sony_call_snc_handle(key_handle, 0x200, &result)) {
- dprintk("sony_acpi_notify, unable to decode"
+ dprintk("sony_nc_notify, unable to decode"
" event 0x%.2x 0x%.2x\n", key_handle,
ev);
/* restore the original event */
@@ -968,7 +968,7 @@
} else
sony_laptop_report_input_event(ev);
- dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
+ dprintk("sony_nc_notify, event: 0x%.2x\n", ev);
acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
}
@@ -1276,15 +1276,6 @@
goto outwalk;
}
- status = acpi_install_notify_handler(sony_nc_acpi_handle,
- ACPI_DEVICE_NOTIFY,
- sony_acpi_notify, NULL);
- if (ACPI_FAILURE(status)) {
- printk(KERN_WARNING DRV_PFX "unable to install notify handler (%u)\n", status);
- result = -ENODEV;
- goto outinput;
- }
-
if (acpi_video_backlight_support()) {
printk(KERN_INFO DRV_PFX "brightness ignored, must be "
"controlled by ACPI video driver\n");
@@ -1362,13 +1353,6 @@
if (sony_backlight_device)
backlight_device_unregister(sony_backlight_device);
- status = acpi_remove_notify_handler(sony_nc_acpi_handle,
- ACPI_DEVICE_NOTIFY,
- sony_acpi_notify);
- if (ACPI_FAILURE(status))
- printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
- outinput:
sony_laptop_remove_input();
outwalk:
@@ -1378,7 +1362,6 @@
static int sony_nc_remove(struct acpi_device *device, int type)
{
- acpi_status status;
struct sony_nc_value *item;
if (sony_backlight_device)
@@ -1386,12 +1369,6 @@
sony_nc_acpi_device = NULL;
- status = acpi_remove_notify_handler(sony_nc_acpi_handle,
- ACPI_DEVICE_NOTIFY,
- sony_acpi_notify);
- if (ACPI_FAILURE(status))
- printk(KERN_WARNING DRV_PFX "unable to remove notify handler\n");
-
for (item = sony_nc_values; item->name; ++item) {
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
@@ -1425,6 +1402,7 @@
.add = sony_nc_add,
.remove = sony_nc_remove,
.resume = sony_nc_resume,
+ .notify = sony_nc_notify,
},
};
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 2f269e11..043b208 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -81,6 +81,7 @@
static int acpi_wmi_remove(struct acpi_device *device, int type);
static int acpi_wmi_add(struct acpi_device *device);
+static void acpi_wmi_notify(struct acpi_device *device, u32 event);
static const struct acpi_device_id wmi_device_ids[] = {
{"PNP0C14", 0},
@@ -96,6 +97,7 @@
.ops = {
.add = acpi_wmi_add,
.remove = acpi_wmi_remove,
+ .notify = acpi_wmi_notify,
},
};
@@ -643,12 +645,11 @@
}
}
-static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_wmi_notify(struct acpi_device *device, u32 event)
{
struct guid_block *block;
struct wmi_block *wblock;
struct list_head *p;
- struct acpi_device *device = data;
list_for_each(p, &wmi_blocks.list) {
wblock = list_entry(p, struct wmi_block, list);
@@ -669,9 +670,6 @@
static int acpi_wmi_remove(struct acpi_device *device, int type)
{
- acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_wmi_notify);
-
acpi_remove_address_space_handler(device->handle,
ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler);
@@ -683,13 +681,6 @@
acpi_status status;
int result = 0;
- status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
- acpi_wmi_notify, device);
- if (ACPI_FAILURE(status)) {
- printk(KERN_ERR PREFIX "Error installing notify handler\n");
- return -ENODEV;
- }
-
status = acpi_install_address_space_handler(device->handle,
ACPI_ADR_SPACE_EC,
&acpi_wmi_ec_space_handler,
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a222851..c34b110 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -270,7 +270,6 @@
struct list_head children;
struct list_head node;
struct list_head wakeup_list;
- struct list_head g_list;
struct acpi_device_status status;
struct acpi_device_flags flags;
struct acpi_device_pnp pnp;