diff options
-rw-r--r-- | arch/x86/include/asm/cpufeature.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/addon_cpuid_features.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 55 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/longhaul.c | 1 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwvalid.c | 1 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 2 | ||||
-rw-r--r-- | drivers/acpi/proc.c | 13 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 3 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 31 | ||||
-rw-r--r-- | drivers/acpi/sleep.h | 3 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 68 | ||||
-rw-r--r-- | drivers/acpi/video.c | 30 | ||||
-rw-r--r-- | drivers/acpi/wakeup.c | 30 | ||||
-rw-r--r-- | drivers/platform/x86/fujitsu-laptop.c | 60 | ||||
-rw-r--r-- | drivers/platform/x86/panasonic-laptop.c | 28 | ||||
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 30 | ||||
-rw-r--r-- | drivers/platform/x86/wmi.c | 15 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 1 |
19 files changed, 131 insertions, 248 deletions
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 @@ static void __cpuinit setup_APIC_timer(void) { 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 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) 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 @@ struct acpi_cpufreq_data { 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 @@ static u32 get_cur_val(const struct cpumask *mask) 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 long read_measured_perf_ctrs(void *_cur) 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 @@ static const struct acpi_port_info acpi_protected_ports[] = { {"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 struct acpi_driver acpi_battery_driver = { }, }; -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 @@ acpi_system_write_alarm(struct file *file, } #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 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) 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 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) 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 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) 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 @@ acpi_system_write_wakeup_device(struct file *file, 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 @@ acpi_system_write_wakeup_device(struct file *file, } } } - 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 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, 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 @@ extern struct acpi_device *acpi_root; 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 @@ static int acpi_device_register(struct acpi_device *device, */ 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 @@ static int acpi_device_register(struct acpi_device *device, 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 @@ static int acpi_device_register(struct acpi_device *device, } 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 @@ static int acpi_device_register(struct acpi_device *device, 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 int acpi_suspend (u32 state); 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 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); 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 @@ static struct acpi_driver acpi_thermal_driver = { .add = acpi_thermal_add, .remove = acpi_thermal_remove, .resume = acpi_thermal_resume, + .notify = acpi_thermal_notify, }, }; @@ -192,6 +194,7 @@ struct acpi_thermal { struct acpi_handle_list devices; struct thermal_zone_device *thermal_zone; int tz_enabled; + int kelvin_offset; struct mutex lock; }; @@ -581,7 +584,7 @@ static void acpi_thermal_check(void *data) } /* 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 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, 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 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 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 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 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 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 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 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 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 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal, 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 @@ static int acpi_thermal_remove_fs(struct acpi_device *device) 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 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) "Unsupported event [0x%x]\n", event)); break; } - - return; } static int acpi_thermal_get_info(struct acpi_thermal *tz) @@ -1334,10 +1337,28 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) 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 @@ static int acpi_thermal_add(struct acpi_device *device) 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 @@ static int acpi_thermal_add(struct acpi_device *device) 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 @@ end: 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 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) 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 @@ module_param(brightness_switch_enabled, bool, 0644); 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 @@ static struct acpi_driver acpi_video_bus = { .add = acpi_video_bus_add, .remove = acpi_video_bus_remove, .resume = acpi_video_resume, + .notify = acpi_video_bus_notify, }, }; @@ -1986,17 +1988,15 @@ static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 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_resume(struct acpi_device *device) 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 @@ static int acpi_video_bus_add(struct acpi_device *device) 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 @@ static int acpi_video_bus_add(struct acpi_device *device) 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_add(struct acpi_device *device) 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 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) 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 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) { 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 @@ void acpi_enable_wakeup_device_prep(u8 sleep_state) (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 @@ void acpi_enable_wakeup_device(u8 sleep_state) * 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 @@ void acpi_enable_wakeup_device(u8 sleep_state) 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 @@ void acpi_disable_wakeup_device(u8 sleep_state) { 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 @@ void acpi_disable_wakeup_device(u8 sleep_state) 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 @@ void acpi_disable_wakeup_device(u8 sleep_state) 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 @@ int __init acpi_wakeup_device_init(void) /* 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 @@ struct fujitsu_hotkey_t { 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 @@ struct led_classdev kblamps_led = { 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 struct dmi_system_id fujitsu_dmi_table[] = { 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 @@ static int acpi_fujitsu_add(struct acpi_device *device) 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 @@ static int acpi_fujitsu_add(struct acpi_device *device) 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 @@ err_stop: 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 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type) 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 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type) /* 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 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data) 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 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) 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 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) 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 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) 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 @@ err_stop: 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 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) 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 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) 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 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event, input_sync(input); break; } - - return; } /* Initialization */ @@ -1107,6 +1063,7 @@ static struct acpi_driver acpi_fujitsu_driver = { .ops = { .add = acpi_fujitsu_add, .remove = acpi_fujitsu_remove, + .notify = acpi_fujitsu_notify, }, }; @@ -1122,6 +1079,7 @@ static struct acpi_driver acpi_fujitsu_hotkey_driver = { .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 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, 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 @@ static struct acpi_driver acpi_pcc_driver = { .add = acpi_pcc_hotkey_add, .remove = acpi_pcc_hotkey_remove, .resume = acpi_pcc_hotkey_resume, + .notify = acpi_pcc_hotkey_notify, }, }; @@ -271,7 +273,7 @@ static int acpi_pcc_retrieve_biosdata(struct pcc_acpi *pcc, u32 *sinf) 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 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) 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_resume(struct acpi_device *device) 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 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) 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 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) 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 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) 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 @@ static struct sony_nc_event sony_127_events[] = { /* * 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 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) 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 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) } 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 @@ static int sony_nc_add(struct acpi_device *device) 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 @@ static int sony_nc_add(struct acpi_device *device) 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_add(struct acpi_device *device) 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 @@ static int sony_nc_remove(struct acpi_device *device, int type) 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 @@ static struct acpi_driver sony_nc_driver = { .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 struct wmi_block wmi_blocks; 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 @@ static struct acpi_driver acpi_wmi_driver = { .ops = { .add = acpi_wmi_add, .remove = acpi_wmi_remove, + .notify = acpi_wmi_notify, }, }; @@ -643,12 +645,11 @@ acpi_wmi_ec_space_handler(u32 function, acpi_physical_address address, } } -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 void acpi_wmi_notify(acpi_handle handle, u32 event, void *data) 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 @@ static int __init acpi_wmi_add(struct acpi_device *device) 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 acpi_device { 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; |