From ed025e168cd87922a7c659f00633e3d2ec61f459 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 16 Apr 2009 15:18:16 +0800 Subject: [PATCH] --- yaml --- r: 144122 b: refs/heads/master c: a65131e942e25c707a652fa4ec2cfcd8b63fec11 h: refs/heads/master v: v3 --- [refs] | 2 +- .../ABI/testing/sysfs-firmware-acpi | 8 +- trunk/Documentation/laptops/thinkpad-acpi.txt | 4 +- .../x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 30 +++---- trunk/drivers/acpi/acpica/hwsleep.c | 43 ++++------ trunk/drivers/acpi/acpica/hwvalid.c | 85 ++++++++++++++++--- trunk/drivers/acpi/acpica/rscreate.c | 27 +++++- trunk/drivers/acpi/ec.c | 1 - trunk/drivers/acpi/osl.c | 4 +- trunk/drivers/acpi/processor_idle.c | 28 +++--- trunk/drivers/acpi/sleep.c | 27 ------ trunk/drivers/acpi/system.c | 11 +-- trunk/drivers/acpi/thermal.c | 2 +- trunk/drivers/acpi/video.c | 51 ++++++----- trunk/drivers/gpu/drm/i915/i915_opregion.c | 9 +- trunk/drivers/platform/x86/sony-laptop.c | 27 ++---- trunk/drivers/platform/x86/thinkpad_acpi.c | 81 ++++++++---------- trunk/include/acpi/processor.h | 1 + trunk/include/linux/acpi.h | 1 - 19 files changed, 225 insertions(+), 217 deletions(-) diff --git a/[refs] b/[refs] index f42722b5a50a..c47daf31b31d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1fe94d37f9296e8884c2f4ca4e22ca3d1398f15c +refs/heads/master: a65131e942e25c707a652fa4ec2cfcd8b63fec11 diff --git a/trunk/Documentation/ABI/testing/sysfs-firmware-acpi b/trunk/Documentation/ABI/testing/sysfs-firmware-acpi index 4f9ba3c2fca7..e8ffc70ffe12 100644 --- a/trunk/Documentation/ABI/testing/sysfs-firmware-acpi +++ b/trunk/Documentation/ABI/testing/sysfs-firmware-acpi @@ -69,13 +69,9 @@ Description: gpe1F: 0 invalid gpe_all: 1192 sci: 1194 - sci_not: 0 - sci - The number of times the ACPI SCI - has been called and claimed an interrupt. - - sci_not - The number of times the ACPI SCI - has been called and NOT claimed an interrupt. + sci - The total number of times the ACPI SCI + has claimed an interrupt. gpe_all - count of SCI caused by GPEs. diff --git a/trunk/Documentation/laptops/thinkpad-acpi.txt b/trunk/Documentation/laptops/thinkpad-acpi.txt index e7e9a69069e1..3d7650768bb5 100644 --- a/trunk/Documentation/laptops/thinkpad-acpi.txt +++ b/trunk/Documentation/laptops/thinkpad-acpi.txt @@ -1,7 +1,7 @@ ThinkPad ACPI Extras Driver - Version 0.23 - April 10th, 2009 + Version 0.22 + November 23rd, 2008 Borislav Deianov Henrique de Moraes Holschuh diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 208ecf6643df..ecdb682ab516 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -65,17 +65,13 @@ enum { struct acpi_cpufreq_data { struct acpi_processor_performance *acpi_data; struct cpufreq_frequency_table *freq_table; + unsigned int max_freq; unsigned int resume; unsigned int cpu_feature; -}; - -static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); - -struct acpi_msr_data { u64 saved_aperf, saved_mperf; }; -static DEFINE_PER_CPU(struct acpi_msr_data, msr_data); +static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); DEFINE_TRACE(power_mark); @@ -291,11 +287,11 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy, return 0; cur.aperf.whole = readin.aperf.whole - - per_cpu(msr_data, cpu).saved_aperf; + per_cpu(drv_data, cpu)->saved_aperf; cur.mperf.whole = readin.mperf.whole - - per_cpu(msr_data, cpu).saved_mperf; - per_cpu(msr_data, cpu).saved_aperf = readin.aperf.whole; - per_cpu(msr_data, cpu).saved_mperf = 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__ /* @@ -339,7 +335,7 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy, #endif - retval = (policy->cpuinfo.max_freq * perf_percent) / 100; + retval = per_cpu(drv_data, policy->cpu)->max_freq * perf_percent / 100; return retval; } @@ -692,11 +688,16 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */ if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && policy->cpuinfo.transition_latency > 20 * 1000) { + static int print_once; policy->cpuinfo.transition_latency = 20 * 1000; - printk_once(KERN_INFO "Capping off P-state tranision" - " latency at 20 uS\n"); + if (!print_once) { + print_once = 1; + printk(KERN_INFO "Capping off P-state tranision latency" + " at 20 uS\n"); + } } + data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ for (i = 0; i < perf->state_count; i++) { if (i > 0 && perf->states[i].core_frequency >= @@ -715,9 +716,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) if (result) goto err_freqfree; - if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq) - printk(KERN_WARNING FW_WARN "P-state 0 is not max freq\n"); - switch (perf->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: /* Current speed is unknown and not detectable by IO port */ diff --git a/trunk/drivers/acpi/acpica/hwsleep.c b/trunk/drivers/acpi/acpica/hwsleep.c index db307a356f08..baa5fc05e124 100644 --- a/trunk/drivers/acpi/acpica/hwsleep.c +++ b/trunk/drivers/acpi/acpica/hwsleep.c @@ -211,12 +211,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) -static unsigned int gts, bfs; -module_param(gts, uint, 0644); -module_param(bfs, uint, 0644); -MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); -MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); - /******************************************************************************* * * FUNCTION: acpi_enter_sleep_state @@ -284,18 +278,16 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) return_ACPI_STATUS(status); } - if (gts) { - /* Execute the _GTS method */ + /* Execute the _GTS method */ - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = sleep_state; + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = sleep_state; - status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - return_ACPI_STATUS(status); - } + status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + return_ACPI_STATUS(status); } /* Get current value of PM1A control */ @@ -521,19 +513,18 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) } } - if (bfs) { - /* Execute the _BFS method */ + /* Execute the _BFS method */ - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = sleep_state; + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = sleep_state; - status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); - } + status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); } + return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/acpica/hwvalid.c b/trunk/drivers/acpi/acpica/hwvalid.c index 7737afb157c3..9c8345754f6a 100644 --- a/trunk/drivers/acpi/acpica/hwvalid.c +++ b/trunk/drivers/acpi/acpica/hwvalid.c @@ -151,7 +151,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) ACPI_ERROR((AE_INFO, "Illegal I/O port address/length above 64K: 0x%p/%X", ACPI_CAST_PTR(void, address), byte_width)); - return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); + return_ACPI_STATUS(AE_LIMIT); } /* Exit if requested address is not within the protected port table */ @@ -178,11 +178,12 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) /* Port illegality may depend on the _OSI calls made by the BIOS */ if (acpi_gbl_osi_data >= port_info->osi_dependency) { - ACPI_ERROR((AE_INFO, - "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", - ACPI_CAST_PTR(void, address), - byte_width, port_info->name, - port_info->start, port_info->end)); + ACPI_DEBUG_PRINT((ACPI_DB_IO, + "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", + ACPI_CAST_PTR(void, address), + byte_width, port_info->name, + port_info->start, + port_info->end)); return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); } @@ -206,7 +207,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) * Value Where value is placed * Width Number of bits * - * RETURN: Value read from port + * RETURN: Status and value read from port * * DESCRIPTION: Read data from an I/O port or register. This is a front-end * to acpi_os_read_port that performs validation on both the port @@ -217,14 +218,43 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) { acpi_status status; + u32 one_byte; + u32 i; + + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); - if (ACPI_FAILURE(status)) { + if (ACPI_SUCCESS(status)) { + status = acpi_os_read_port(address, value, width); return status; } - status = acpi_os_read_port(address, value, width); - return status; + if (status != AE_AML_ILLEGAL_ADDRESS) { + return status; + } + + /* + * There has been a protection violation within the request. Fall + * back to byte granularity port I/O and ignore the failing bytes. + * This provides Windows compatibility. + */ + for (i = 0, *value = 0; i < width; i += 8) { + + /* Validate and read one byte */ + + if (acpi_hw_validate_io_request(address, 8) == AE_OK) { + status = acpi_os_read_port(address, &one_byte, 8); + if (ACPI_FAILURE(status)) { + return status; + } + + *value |= (one_byte << i); + } + + address++; + } + + return AE_OK; } /****************************************************************************** @@ -235,7 +265,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) * Value Value to write * Width Number of bits * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Write data to an I/O port or register. This is a front-end * to acpi_os_write_port that performs validation on both the port @@ -246,12 +276,39 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) { acpi_status status; + u32 i; + + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); - if (ACPI_FAILURE(status)) { + if (ACPI_SUCCESS(status)) { + status = acpi_os_write_port(address, value, width); return status; } - status = acpi_os_write_port(address, value, width); - return status; + if (status != AE_AML_ILLEGAL_ADDRESS) { + return status; + } + + /* + * There has been a protection violation within the request. Fall + * back to byte granularity port I/O and ignore the failing bytes. + * This provides Windows compatibility. + */ + for (i = 0; i < width; i += 8) { + + /* Validate and write one byte */ + + if (acpi_hw_validate_io_request(address, 8) == AE_OK) { + status = + acpi_os_write_port(address, (value >> i) & 0xFF, 8); + if (ACPI_FAILURE(status)) { + return status; + } + } + + address++; + } + + return AE_OK; } diff --git a/trunk/drivers/acpi/acpica/rscreate.c b/trunk/drivers/acpi/acpica/rscreate.c index a3c23d686d5f..663f692fffcf 100644 --- a/trunk/drivers/acpi/acpica/rscreate.c +++ b/trunk/drivers/acpi/acpica/rscreate.c @@ -191,6 +191,8 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); for (index = 0; index < number_of_elements; index++) { + int source_name_index = 2; + int source_index_index = 3; /* * Point user_prt past this current structure @@ -259,6 +261,27 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, return_ACPI_STATUS(AE_BAD_DATA); } + /* + * If BIOS erroneously reversed the _PRT source_name and source_index, + * then reverse them back. + */ + if ((sub_object_list[3])->common.type != + ACPI_TYPE_INTEGER) { + if (acpi_gbl_enable_interpreter_slack) { + source_name_index = 3; + source_index_index = 2; + printk(KERN_WARNING + "ACPI: Handling Garbled _PRT entry\n"); + } else { + ACPI_ERROR((AE_INFO, + "(PRT[%X].source_index) Need Integer, found %s", + index, + acpi_ut_get_object_type_name + (sub_object_list[3]))); + return_ACPI_STATUS(AE_BAD_DATA); + } + } + user_prt->pin = (u32) obj_desc->integer.value; /* @@ -281,7 +304,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, * 3) Third subobject: Dereference the PRT.source_name * The name may be unresolved (slack mode), so allow a null object */ - obj_desc = sub_object_list[2]; + obj_desc = sub_object_list[source_name_index]; if (obj_desc) { switch (obj_desc->common.type) { case ACPI_TYPE_LOCAL_REFERENCE: @@ -355,7 +378,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, /* 4) Fourth subobject: Dereference the PRT.source_index */ - obj_desc = sub_object_list[3]; + obj_desc = sub_object_list[source_index_index]; if (obj_desc->common.type != ACPI_TYPE_INTEGER) { ACPI_ERROR((AE_INFO, "(PRT[%X].SourceIndex) Need Integer, found %s", diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 391f331674c7..04e90443eff7 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -1065,7 +1065,6 @@ 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); - set_bit(EC_FLAGS_GPE_MODE, &ec->flags); acpi_enable_gpe(NULL, ec->gpe); return 0; } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index d916bea729f1..d59f08ecaf16 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -353,10 +353,8 @@ static irqreturn_t acpi_irq(int irq, void *dev_id) if (handled) { acpi_irq_handled++; return IRQ_HANDLED; - } else { - acpi_irq_not_handled++; + } else return IRQ_NONE; - } } acpi_status diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index f7ca8c55956b..6fe121434ffb 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -581,11 +581,6 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { struct acpi_processor_cx *cx = &pr->power.states[i]; -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) - /* TSC could halt in idle, so notify users */ - if (tsc_halts_in_c(cx->type)) - mark_tsc_unstable("TSC halts in idle");; -#endif switch (cx->type) { case ACPI_STATE_C1: cx->valid = 1; @@ -662,9 +657,11 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "active state: C%zd\n" "max_cstate: C%d\n" + "bus master activity: %08x\n" "maximum allowed latency: %d usec\n", pr->power.state ? pr->power.state - pr->power.states : 0, - max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)); + max_cstate, (unsigned)pr->power.bm_activity, + pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)); seq_puts(seq, "states:\n"); @@ -874,6 +871,11 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, kt2 = ktime_get_real(); idle_time = ktime_to_us(ktime_sub(kt2, kt1)); +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) + /* TSC could halt in idle, so notify users */ + if (tsc_halts_in_c(cx->type)) + mark_tsc_unstable("TSC halts in idle");; +#endif sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ @@ -953,7 +955,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, */ acpi_state_timer_broadcast(pr, cx, 1); - kt1 = ktime_get_real(); /* * disable bus master * bm_check implies we need ARB_DIS @@ -975,7 +976,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ACPI_FLUSH_CPU_CACHE(); } + kt1 = ktime_get_real(); acpi_idle_do_entry(cx); + kt2 = ktime_get_real(); + idle_time = ktime_to_us(ktime_sub(kt2, kt1)); /* Re-enable bus master arbitration */ if (pr->flags.bm_check && pr->flags.bm_control) { @@ -984,9 +988,12 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, c3_cpu_count--; spin_unlock(&c3_lock); } - kt2 = ktime_get_real(); - idle_time = ktime_to_us(ktime_sub(kt2, kt1)); +#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) + /* TSC could halt in idle, so notify users */ + if (tsc_halts_in_c(ACPI_STATE_C3)) + mark_tsc_unstable("TSC halts in idle"); +#endif sleep_ticks = us_to_pm_timer_ticks(idle_time); /* Tell the scheduler how much we idled: */ sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); @@ -1030,9 +1037,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) dev->states[i].desc[0] = '\0'; } - if (max_cstate == 0) - max_cstate = 1; - for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { cx = &pr->power.states[i]; state = &dev->states[count]; diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 01574a066534..d060e6fd7fd5 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -713,32 +713,6 @@ static void acpi_power_off(void) acpi_enter_sleep_state(ACPI_STATE_S5); } -/* - * ACPI 2.0 created the optional _GTS and _BFS, - * but industry adoption has been neither rapid nor broad. - * - * Linux gets into trouble when it executes poorly validated - * paths through the BIOS, so disable _GTS and _BFS by default, - * but do speak up and offer the option to enable them. - */ -void __init acpi_gts_bfs_check(void) -{ - acpi_handle dummy; - - if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__GTS, &dummy))) - { - printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); - printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " - "please notify linux-acpi@vger.kernel.org\n"); - } - if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_NAME__BFS, &dummy))) - { - printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); - printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " - "please notify linux-acpi@vger.kernel.org\n"); - } -} - int __init acpi_sleep_init(void) { acpi_status status; @@ -797,6 +771,5 @@ int __init acpi_sleep_init(void) * object can also be evaluated when the system enters S5. */ register_reboot_notifier(&tts_notifier); - acpi_gts_bfs_check(); return 0; } diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index 0944daec064f..da51f05ef8d8 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -38,7 +38,6 @@ ACPI_MODULE_NAME("system"); #define ACPI_SYSTEM_DEVICE_NAME "System" u32 acpi_irq_handled; -u32 acpi_irq_not_handled; /* * Make ACPICA version work as module param @@ -215,9 +214,8 @@ static int acpi_system_sysfs_init(void) #define COUNT_GPE 0 #define COUNT_SCI 1 /* acpi_irq_handled */ -#define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */ -#define COUNT_ERROR 3 /* other */ -#define NUM_COUNTERS_EXTRA 4 +#define COUNT_ERROR 2 /* other */ +#define NUM_COUNTERS_EXTRA 3 struct event_counter { u32 count; @@ -319,8 +317,6 @@ static ssize_t counter_show(struct kobject *kobj, all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = acpi_irq_handled; - all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count = - acpi_irq_not_handled; all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count = acpi_gpe_count; @@ -367,7 +363,6 @@ static ssize_t counter_set(struct kobject *kobj, all_counters[i].count = 0; acpi_gpe_count = 0; acpi_irq_handled = 0; - acpi_irq_not_handled = 0; goto end; } @@ -461,8 +456,6 @@ void acpi_irq_stats_init(void) sprintf(buffer, "gpe_all"); else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) sprintf(buffer, "sci"); - else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT) - sprintf(buffer, "sci_not"); else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR) sprintf(buffer, "error"); else diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 564ea1424288..9cd15e8c8932 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -909,7 +909,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) thermal_zone_device_register("acpitz", trips, tz, &acpi_thermal_zone_ops, 0, 0, 0, - tz->polling_frequency*100); + tz->polling_frequency); if (IS_ERR(tz->thermal_zone)) return -ENODEV; diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 1705d947ea09..cd4fb7543a90 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -770,12 +770,10 @@ acpi_video_init_brightness(struct acpi_video_device *device) * In this case, the first two elements in _BCL packages * are also supported brightness levels that OS should take care of. */ - for (i = 2; i < count; i++) { - if (br->levels[i] == br->levels[0]) + for (i = 2; i < count; i++) + if (br->levels[i] == br->levels[0] || + br->levels[i] == br->levels[1]) level_ac_battery++; - if (br->levels[i] == br->levels[1]) - level_ac_battery++; - } if (level_ac_battery < 2) { level_ac_battery = 2 - level_ac_battery; @@ -809,19 +807,12 @@ acpi_video_init_brightness(struct acpi_video_device *device) br->flags._BCM_use_index = br->flags._BCL_use_index; /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ - br->curr = level_old = max_level; - - if (!device->cap._BQC) - goto set_level; - + br->curr = max_level; result = acpi_video_device_lcd_get_level_current(device, &level_old); if (result) goto out_free_levels; - /* - * Set the level to maximum and check if _BQC uses indexed value - */ - result = acpi_video_device_lcd_set_level(device, max_level); + result = acpi_video_device_lcd_set_level(device, br->curr); if (result) goto out_free_levels; @@ -829,19 +820,25 @@ acpi_video_init_brightness(struct acpi_video_device *device) if (result) goto out_free_levels; - br->flags._BQC_use_index = (level == max_level ? 0 : 1); - - if (!br->flags._BQC_use_index) - goto set_level; - - if (br->flags._BCL_reversed) - level_old = (br->count - 1) - level_old; - level_old = br->levels[level_old]; - -set_level: - result = acpi_video_device_lcd_set_level(device, level_old); - if (result) - goto out_free_levels; + if ((level != level_old) && !br->flags._BCM_use_index) { + /* Note: + * This piece of code does not work correctly if the current + * brightness levels is 0. + * But I guess boxes that boot with such a dark screen are rare + * and no more code is needed to cover this specifial case. + */ + + if (level_ac_battery != 2) { + /* + * For now, we don't support the _BCL like this: + * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16 + * because we may mess up the index returned by _BQC. + * Plus: we have not got a box like this. + */ + ACPI_ERROR((AE_INFO, "_BCL not supported\n")); + } + br->flags._BQC_use_index = 1; + } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count - 2)); diff --git a/trunk/drivers/gpu/drm/i915/i915_opregion.c b/trunk/drivers/gpu/drm/i915/i915_opregion.c index 8dc1fd3115c2..69427722d20e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_opregion.c +++ b/trunk/drivers/gpu/drm/i915/i915_opregion.c @@ -370,8 +370,11 @@ int intel_opregion_init(struct drm_device *dev, int resume) if (mboxes & MBOX_ACPI) { DRM_DEBUG("Public ACPI methods supported\n"); opregion->acpi = base + OPREGION_ACPI_OFFSET; - if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_didl_outputs(dev); + if (!resume) + acpi_video_register(); + } } else { DRM_DEBUG("Public ACPI methods not supported\n"); err = -ENOTSUPP; @@ -388,10 +391,6 @@ int intel_opregion_init(struct drm_device *dev, int resume) opregion->asle = base + OPREGION_ASLE_OFFSET; } - if (!resume) - acpi_video_register(); - - /* Notify BIOS we are ready to handle ACPI video ext notifs. * Right now, all the events are handled by the ACPI video module. * We don't actually need to do anything with them. */ diff --git a/trunk/drivers/platform/x86/sony-laptop.c b/trunk/drivers/platform/x86/sony-laptop.c index 552958545f94..d3c92d777bde 100644 --- a/trunk/drivers/platform/x86/sony-laptop.c +++ b/trunk/drivers/platform/x86/sony-laptop.c @@ -317,8 +317,7 @@ static void sony_laptop_report_input_event(u8 event) struct input_dev *key_dev = sony_laptop_input.key_dev; struct sony_laptop_keypress kp = { NULL }; - if (event == SONYPI_EVENT_FNKEY_RELEASED || - event == SONYPI_EVENT_ANYBUTTON_RELEASED) { + if (event == SONYPI_EVENT_FNKEY_RELEASED) { /* Nothing, not all VAIOs generate this event */ return; } @@ -906,6 +905,7 @@ static struct sony_nc_event sony_127_events[] = { { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0x86, SONYPI_EVENT_PKEY_P5 }, { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, + { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED }, { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0, 0 }, @@ -1004,7 +1004,6 @@ static int sony_nc_function_setup(struct acpi_device *device) sony_call_snc_handle(0x0100, 0, &result); sony_call_snc_handle(0x0101, 0, &result); sony_call_snc_handle(0x0102, 0x100, &result); - sony_call_snc_handle(0x0127, 0, &result); return 0; } @@ -1041,7 +1040,7 @@ static int sony_nc_resume(struct acpi_device *device) /* set the last requested brightness level */ if (sony_backlight_device && - sony_backlight_update_status(sony_backlight_device) < 0) + !sony_backlight_update_status(sony_backlight_device)) printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); return 0; @@ -1103,11 +1102,8 @@ static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) err = rfkill_register(sony_wifi_rfkill); if (err) rfkill_free(sony_wifi_rfkill); - else { + else sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill; - sony_nc_rfkill_set(sony_wifi_rfkill->data, - RFKILL_STATE_UNBLOCKED); - } return err; } @@ -1128,11 +1124,8 @@ static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) err = rfkill_register(sony_bluetooth_rfkill); if (err) rfkill_free(sony_bluetooth_rfkill); - else { + else sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; - sony_nc_rfkill_set(sony_bluetooth_rfkill->data, - RFKILL_STATE_UNBLOCKED); - } return err; } @@ -1152,11 +1145,8 @@ static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) err = rfkill_register(sony_wwan_rfkill); if (err) rfkill_free(sony_wwan_rfkill); - else { + else sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill; - sony_nc_rfkill_set(sony_wwan_rfkill->data, - RFKILL_STATE_UNBLOCKED); - } return err; } @@ -1176,11 +1166,8 @@ static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) err = rfkill_register(sony_wimax_rfkill); if (err) rfkill_free(sony_wimax_rfkill); - else { + else sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill; - sony_nc_rfkill_set(sony_wimax_rfkill->data, - RFKILL_STATE_UNBLOCKED); - } return err; } diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index 912be65b6261..a40b075743d9 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -21,7 +21,7 @@ * 02110-1301, USA. */ -#define TPACPI_VERSION "0.23" +#define TPACPI_VERSION "0.22" #define TPACPI_SYSFS_VERSION 0x020300 /* @@ -303,17 +303,11 @@ static u32 dbg_level; static struct workqueue_struct *tpacpi_wq; -enum led_status_t { - TPACPI_LED_OFF = 0, - TPACPI_LED_ON, - TPACPI_LED_BLINK, -}; - /* Special LED class that can defer work */ struct tpacpi_led_classdev { struct led_classdev led_classdev; struct work_struct work; - enum led_status_t new_state; + enum led_brightness new_brightness; unsigned int led; }; @@ -2952,18 +2946,12 @@ static int hotkey_read(char *p) return len; } -static void hotkey_enabledisable_warn(bool enable) +static void hotkey_enabledisable_warn(void) { tpacpi_log_usertask("procfs hotkey enable/disable"); - if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable), - TPACPI_WARN - "hotkey enable/disable functionality has been " - "removed from the driver. Hotkeys are always " - "enabled\n")) - printk(TPACPI_ERR - "Please remove the hotkey=enable module " - "parameter, it is deprecated. Hotkeys are always " - "enabled\n"); + WARN(1, TPACPI_WARN + "hotkey enable/disable functionality has been " + "removed from the driver. Hotkeys are always enabled.\n"); } static int hotkey_write(char *buf) @@ -2983,9 +2971,9 @@ static int hotkey_write(char *buf) res = 0; while ((cmd = next_cmd(&buf))) { if (strlencmp(cmd, "enable") == 0) { - hotkey_enabledisable_warn(1); + hotkey_enabledisable_warn(); } else if (strlencmp(cmd, "disable") == 0) { - hotkey_enabledisable_warn(0); + hotkey_enabledisable_warn(); res = -EPERM; } else if (strlencmp(cmd, "reset") == 0) { mask = hotkey_orig_mask; @@ -4219,7 +4207,7 @@ static void light_set_status_worker(struct work_struct *work) container_of(work, struct tpacpi_led_classdev, work); if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) - light_set_status((data->new_state != TPACPI_LED_OFF)); + light_set_status((data->new_brightness != LED_OFF)); } static void light_sysfs_set(struct led_classdev *led_cdev, @@ -4229,8 +4217,7 @@ static void light_sysfs_set(struct led_classdev *led_cdev, container_of(led_cdev, struct tpacpi_led_classdev, led_classdev); - data->new_state = (brightness != LED_OFF) ? - TPACPI_LED_ON : TPACPI_LED_OFF; + data->new_brightness = brightness; queue_work(tpacpi_wq, &data->work); } @@ -4737,6 +4724,12 @@ enum { /* For TPACPI_LED_OLD */ TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ }; +enum led_status_t { + TPACPI_LED_OFF = 0, + TPACPI_LED_ON, + TPACPI_LED_BLINK, +}; + static enum led_access_mode led_supported; TPACPI_HANDLE(led, ec, "SLED", /* 570 */ @@ -4848,13 +4841,23 @@ static int led_set_status(const unsigned int led, return rc; } +static void led_sysfs_set_status(unsigned int led, + enum led_brightness brightness) +{ + led_set_status(led, + (brightness == LED_OFF) ? + TPACPI_LED_OFF : + (tpacpi_led_state_cache[led] == TPACPI_LED_BLINK) ? + TPACPI_LED_BLINK : TPACPI_LED_ON); +} + static void led_set_status_worker(struct work_struct *work) { struct tpacpi_led_classdev *data = container_of(work, struct tpacpi_led_classdev, work); if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) - led_set_status(data->led, data->new_state); + led_sysfs_set_status(data->led, data->new_brightness); } static void led_sysfs_set(struct led_classdev *led_cdev, @@ -4863,13 +4866,7 @@ static void led_sysfs_set(struct led_classdev *led_cdev, struct tpacpi_led_classdev *data = container_of(led_cdev, struct tpacpi_led_classdev, led_classdev); - if (brightness == LED_OFF) - data->new_state = TPACPI_LED_OFF; - else if (tpacpi_led_state_cache[data->led] != TPACPI_LED_BLINK) - data->new_state = TPACPI_LED_ON; - else - data->new_state = TPACPI_LED_BLINK; - + data->new_brightness = brightness; queue_work(tpacpi_wq, &data->work); } @@ -4887,7 +4884,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev, } else if ((*delay_on != 500) || (*delay_off != 500)) return -EINVAL; - data->new_state = TPACPI_LED_BLINK; + data->new_brightness = TPACPI_LED_BLINK; queue_work(tpacpi_wq, &data->work); return 0; @@ -7860,15 +7857,6 @@ static int __init thinkpad_acpi_module_init(void) MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); -/* - * This will autoload the driver in almost every ThinkPad - * in widespread use. - * - * Only _VERY_ old models, like the 240, 240x and 570 lack - * the HKEY event interface. - */ -MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids); - /* * DMI matching for module autoloading * @@ -7881,13 +7869,18 @@ MODULE_DEVICE_TABLE(acpi, ibm_htk_device_ids); #define IBM_BIOS_MODULE_ALIAS(__type) \ MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") +/* Non-ancient thinkpads */ +MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); +MODULE_ALIAS("dmi:bvnLENOVO:*:svnLENOVO:*:pvrThinkPad*:rvnLENOVO:*"); + /* Ancient thinkpad BIOSes have to be identified by * BIOS type or model number, and there are far less * BIOS types than model numbers... */ -IBM_BIOS_MODULE_ALIAS("I[MU]"); /* 570, 570e */ +IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); +IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]"); +IBM_BIOS_MODULE_ALIAS("K[UX-Z]"); -MODULE_AUTHOR("Borislav Deianov "); -MODULE_AUTHOR("Henrique de Moraes Holschuh "); +MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); MODULE_DESCRIPTION(TPACPI_DESC); MODULE_VERSION(TPACPI_VERSION); MODULE_LICENSE("GPL"); diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 4927c063347c..b09c4fde9725 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -84,6 +84,7 @@ struct acpi_processor_power { struct acpi_processor_cx *state; unsigned long bm_check_timestamp; u32 default_state; + u32 bm_activity; int count; struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; int timer_broadcast_on_state; diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 88be890ee3c7..6586cbd0d4af 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -111,7 +111,6 @@ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); void acpi_irq_stats_init(void); extern u32 acpi_irq_handled; -extern u32 acpi_irq_not_handled; extern struct acpi_mcfg_allocation *pci_mmcfg_config; extern int pci_mmcfg_config_num;