Commit ef54b1bb authored by Linus Torvalds's avatar Linus Torvalds

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: (34 commits)
  ACPI, i915: Register ACPI video even when not modesetting
  Revert "ACPICA: delete check for AML access to port 0x81-83"
  I/O port protection: update for windows compatibility.
  sony-laptop: always try to unblock rfkill on load
  sony-laptop: fix bogus error message display on resume
  ACPI: EC: Fix ACPI EC resume non-query interrupt message
  sony-laptop: SNC input event 38 fix
  sony-laptop: SNC 127 Initialization Fix
  sony-laptop: Duplicate SNC 127 Event Fix
  ACPI: prevent processor.max_cstate=0 boot crash
  ACPI/hpet: prevent boot hang when hpet=force used on ICH-4M
  ACPI: delete obsolete "bus master activity" proc field
  ACPI: idle: mark_tsc_unstable() at init-time, not run-time
  ACPI: add /sys/firmware/acpi/interrupts/sci_not counter
  ACPI video: fix an error when the brightness levels on AC and on Battery are same
  acpi-cpufreq: Do not let get_measured perf depend on internal variable
  acpi-cpufreq: style-only: add parens to math expression
  acpi-cpufreq: Cleanup: Use printk_once
  x86, acpi_cpufreq: Fix the NULL pointer dereference in get_measured_perf
  thinkpad-acpi: bump up version to 0.23
  ...
parents 9fe9293d 1162cf6b
...@@ -69,9 +69,13 @@ Description: ...@@ -69,9 +69,13 @@ Description:
gpe1F: 0 invalid gpe1F: 0 invalid
gpe_all: 1192 gpe_all: 1192
sci: 1194 sci: 1194
sci_not: 0
sci - The total number of times the ACPI SCI sci - The number of times the ACPI SCI
has claimed an interrupt. has been called and claimed an interrupt.
sci_not - The number of times the ACPI SCI
has been called and NOT claimed an interrupt.
gpe_all - count of SCI caused by GPEs. gpe_all - count of SCI caused by GPEs.
......
ThinkPad ACPI Extras Driver ThinkPad ACPI Extras Driver
Version 0.22 Version 0.23
November 23rd, 2008 April 10th, 2009
Borislav Deianov <borislav@users.sf.net> Borislav Deianov <borislav@users.sf.net>
Henrique de Moraes Holschuh <hmh@hmh.eng.br> Henrique de Moraes Holschuh <hmh@hmh.eng.br>
......
...@@ -65,14 +65,18 @@ enum { ...@@ -65,14 +65,18 @@ enum {
struct acpi_cpufreq_data { struct acpi_cpufreq_data {
struct acpi_processor_performance *acpi_data; struct acpi_processor_performance *acpi_data;
struct cpufreq_frequency_table *freq_table; struct cpufreq_frequency_table *freq_table;
unsigned int max_freq;
unsigned int resume; unsigned int resume;
unsigned int cpu_feature; unsigned int cpu_feature;
u64 saved_aperf, saved_mperf;
}; };
static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); 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);
DEFINE_TRACE(power_mark); DEFINE_TRACE(power_mark);
/* acpi_perf_data is a pointer to percpu data. */ /* acpi_perf_data is a pointer to percpu data. */
...@@ -287,11 +291,11 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy, ...@@ -287,11 +291,11 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy,
return 0; return 0;
cur.aperf.whole = readin.aperf.whole - cur.aperf.whole = readin.aperf.whole -
per_cpu(drv_data, cpu)->saved_aperf; per_cpu(msr_data, cpu).saved_aperf;
cur.mperf.whole = readin.mperf.whole - cur.mperf.whole = readin.mperf.whole -
per_cpu(drv_data, cpu)->saved_mperf; per_cpu(msr_data, cpu).saved_mperf;
per_cpu(drv_data, cpu)->saved_aperf = readin.aperf.whole; per_cpu(msr_data, cpu).saved_aperf = readin.aperf.whole;
per_cpu(drv_data, cpu)->saved_mperf = readin.mperf.whole; per_cpu(msr_data, cpu).saved_mperf = readin.mperf.whole;
#ifdef __i386__ #ifdef __i386__
/* /*
...@@ -335,7 +339,7 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy, ...@@ -335,7 +339,7 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy,
#endif #endif
retval = per_cpu(drv_data, policy->cpu)->max_freq * perf_percent / 100; retval = (policy->cpuinfo.max_freq * perf_percent) / 100;
return retval; return retval;
} }
...@@ -688,16 +692,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -688,16 +692,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
/* Check for high latency (>20uS) from buggy BIOSes, like on T42 */ /* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
policy->cpuinfo.transition_latency > 20 * 1000) { policy->cpuinfo.transition_latency > 20 * 1000) {
static int print_once;
policy->cpuinfo.transition_latency = 20 * 1000; policy->cpuinfo.transition_latency = 20 * 1000;
if (!print_once) { printk_once(KERN_INFO "Capping off P-state tranision"
print_once = 1; " latency at 20 uS\n");
printk(KERN_INFO "Capping off P-state tranision latency"
" at 20 uS\n");
}
} }
data->max_freq = perf->states[0].core_frequency * 1000;
/* table init */ /* table init */
for (i = 0; i < perf->state_count; i++) { for (i = 0; i < perf->state_count; i++) {
if (i > 0 && perf->states[i].core_frequency >= if (i > 0 && perf->states[i].core_frequency >=
...@@ -716,6 +715,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -716,6 +715,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (result) if (result)
goto err_freqfree; 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) { switch (perf->control_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO: case ACPI_ADR_SPACE_SYSTEM_IO:
/* Current speed is unknown and not detectable by IO port */ /* Current speed is unknown and not detectable by IO port */
......
...@@ -211,6 +211,12 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) ...@@ -211,6 +211,12 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) 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 * FUNCTION: acpi_enter_sleep_state
...@@ -278,16 +284,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ...@@ -278,16 +284,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
/* Execute the _GTS method */ if (gts) {
/* Execute the _GTS method */
arg_list.count = 1; arg_list.count = 1;
arg_list.pointer = &arg; arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER; arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = sleep_state; arg.integer.value = sleep_state;
status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
}
} }
/* Get current value of PM1A control */ /* Get current value of PM1A control */
...@@ -513,18 +521,19 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) ...@@ -513,18 +521,19 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
} }
} }
/* Execute the _BFS method */ if (bfs) {
/* Execute the _BFS method */
arg_list.count = 1; arg_list.count = 1;
arg_list.pointer = &arg; arg_list.pointer = &arg;
arg.type = ACPI_TYPE_INTEGER; arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = sleep_state; arg.integer.value = sleep_state;
status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
}
} }
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -90,6 +90,7 @@ static const struct acpi_port_info acpi_protected_ports[] = { ...@@ -90,6 +90,7 @@ static const struct acpi_port_info acpi_protected_ports[] = {
{"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
{"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
{"CMOS", 0x0074, 0x0076, 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}, {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
{"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
{"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP}, {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
...@@ -151,7 +152,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) ...@@ -151,7 +152,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"Illegal I/O port address/length above 64K: 0x%p/%X", "Illegal I/O port address/length above 64K: 0x%p/%X",
ACPI_CAST_PTR(void, address), byte_width)); 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 */ /* Exit if requested address is not within the protected port table */
...@@ -178,11 +179,12 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) ...@@ -178,11 +179,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 */ /* Port illegality may depend on the _OSI calls made by the BIOS */
if (acpi_gbl_osi_data >= port_info->osi_dependency) { if (acpi_gbl_osi_data >= port_info->osi_dependency) {
ACPI_ERROR((AE_INFO, ACPI_DEBUG_PRINT((ACPI_DB_IO,
"Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void, address),
byte_width, port_info->name, byte_width, port_info->name,
port_info->start, port_info->end)); port_info->start,
port_info->end));
return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
} }
...@@ -206,7 +208,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) ...@@ -206,7 +208,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
* Value Where value is placed * Value Where value is placed
* Width Number of bits * 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 * 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 * to acpi_os_read_port that performs validation on both the port
...@@ -217,14 +219,43 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) ...@@ -217,14 +219,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 acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
{ {
acpi_status status; 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); 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; return status;
} }
status = acpi_os_read_port(address, value, width); if (status != AE_AML_ILLEGAL_ADDRESS) {
return status; 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 +266,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) ...@@ -235,7 +266,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
* Value Value to write * Value Value to write
* Width Number of bits * Width Number of bits
* *
* RETURN: None * RETURN: Status
* *
* DESCRIPTION: Write data to an I/O port or register. This is a front-end * 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 * to acpi_os_write_port that performs validation on both the port
...@@ -246,12 +277,39 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) ...@@ -246,12 +277,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 acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
{ {
acpi_status status; acpi_status status;
u32 i;
/* Validate the entire request and perform the I/O */
status = acpi_hw_validate_io_request(address, width); 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; return status;
} }
status = acpi_os_write_port(address, value, width); if (status != AE_AML_ILLEGAL_ADDRESS) {
return status; 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;
} }
...@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer);
for (index = 0; index < number_of_elements; index++) { 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 * Point user_prt past this current structure
...@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
return_ACPI_STATUS(AE_BAD_DATA); 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; user_prt->pin = (u32) obj_desc->integer.value;
/* /*
...@@ -304,7 +281,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -304,7 +281,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* 3) Third subobject: Dereference the PRT.source_name * 3) Third subobject: Dereference the PRT.source_name
* The name may be unresolved (slack mode), so allow a null object * The name may be unresolved (slack mode), so allow a null object
*/ */
obj_desc = sub_object_list[source_name_index]; obj_desc = sub_object_list[2];
if (obj_desc) { if (obj_desc) {
switch (obj_desc->common.type) { switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE: case ACPI_TYPE_LOCAL_REFERENCE:
...@@ -378,7 +355,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, ...@@ -378,7 +355,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */ /* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index]; obj_desc = sub_object_list[3];
if (obj_desc->common.type != ACPI_TYPE_INTEGER) { if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO, ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s", "(PRT[%X].SourceIndex) Need Integer, found %s",
......
This diff is collapsed.
...@@ -1065,6 +1065,7 @@ static int acpi_ec_resume(struct acpi_device *device) ...@@ -1065,6 +1065,7 @@ static int acpi_ec_resume(struct acpi_device *device)
struct acpi_ec *ec = acpi_driver_data(device); struct acpi_ec *ec = acpi_driver_data(device);
/* Enable use of GPE back */ /* Enable use of GPE back */
clear_bit(EC_FLAGS_NO_GPE, &ec->flags); clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
acpi_enable_gpe(NULL, ec->gpe); acpi_enable_gpe(NULL, ec->gpe);
return 0; return 0;
} }
......
...@@ -353,8 +353,10 @@ static irqreturn_t acpi_irq(int irq, void *dev_id) ...@@ -353,8 +353,10 @@ static irqreturn_t acpi_irq(int irq, void *dev_id)
if (handled) { if (handled) {
acpi_irq_handled++; acpi_irq_handled++;
return IRQ_HANDLED; return IRQ_HANDLED;
} else } else {
acpi_irq_not_handled++;
return IRQ_NONE; return IRQ_NONE;
}
} }
acpi_status acpi_status
......
...@@ -581,6 +581,11 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) ...@@ -581,6 +581,11 @@ static int acpi_processor_power_verify(struct acpi_processor *pr)
for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
struct acpi_processor_cx *cx = &pr->power.states[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) { switch (cx->type) {
case ACPI_STATE_C1: case ACPI_STATE_C1:
cx->valid = 1; cx->valid = 1;
...@@ -657,11 +662,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) ...@@ -657,11 +662,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
seq_printf(seq, "active state: C%zd\n" seq_printf(seq, "active state: C%zd\n"
"max_cstate: C%d\n" "max_cstate: C%d\n"
"bus master activity: %08x\n"
"maximum allowed latency: %d usec\n", "maximum allowed latency: %d usec\n",
pr->power.state ? pr->power.state - pr->power.states : 0, pr->power.state ? pr->power.state - pr->power.states : 0,
max_cstate, (unsigned)pr->power.bm_activity, max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
seq_puts(seq, "states:\n"); seq_puts(seq, "states:\n");
...@@ -871,11 +874,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, ...@@ -871,11 +874,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
kt2 = ktime_get_real(); kt2 = ktime_get_real();
idle_time = ktime_to_us(ktime_sub(kt2, kt1)); 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); sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */ /* Tell the scheduler how much we idled: */
...@@ -955,6 +953,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ...@@ -955,6 +953,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
*/ */
acpi_state_timer_broadcast(pr, cx, 1); acpi_state_timer_broadcast(pr, cx, 1);
kt1 = ktime_get_real();
/* /*
* disable bus master * disable bus master
* bm_check implies we need ARB_DIS * bm_check implies we need ARB_DIS
...@@ -976,10 +975,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ...@@ -976,10 +975,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
ACPI_FLUSH_CPU_CACHE(); ACPI_FLUSH_CPU_CACHE();
} }
kt1 = ktime_get_real();
acpi_idle_do_entry(cx); acpi_idle_do_entry(cx);
kt2 = ktime_get_real();
idle_time = ktime_to_us(ktime_sub(kt2, kt1));
/* Re-enable bus master arbitration */ /* Re-enable bus master arbitration */
if (pr->flags.bm_check && pr->flags.bm_control) { if (pr->flags.bm_check && pr->flags.bm_control) {
...@@ -988,12 +984,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, ...@@ -988,12 +984,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count--; c3_cpu_count--;
spin_unlock(&c3_lock); 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); sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */ /* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
...@@ -1037,6 +1030,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) ...@@ -1037,6 +1030,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
dev->states[i].desc[0] = '\0'; 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++) { for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
cx = &pr->power.states[i]; cx = &pr->power.states[i];
state = &dev->states[count]; state = &dev->states[count];
......
...@@ -713,6 +713,32 @@ static void acpi_power_off(void) ...@@ -713,6 +713,32 @@ static void acpi_power_off(void)
acpi_enter_sleep_state(ACPI_STATE_S5); 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) int __init acpi_sleep_init(void)
{ {
acpi_status status; acpi_status status;
...@@ -771,5 +797,6 @@ int __init acpi_sleep_init(void) ...@@ -771,5 +797,6 @@ int __init acpi_sleep_init(void)
* object can also be evaluated when the system enters S5. * object can also be evaluated when the system enters S5.
*/ */
register_reboot_notifier(&tts_notifier); register_reboot_notifier(&tts_notifier);
acpi_gts_bfs_check();
return 0; return 0;
} }
...@@ -38,6 +38,7 @@ ACPI_MODULE_NAME("system"); ...@@ -38,6 +38,7 @@ ACPI_MODULE_NAME("system");
#define ACPI_SYSTEM_DEVICE_NAME "System" #define ACPI_SYSTEM_DEVICE_NAME "System"
u32 acpi_irq_handled; u32 acpi_irq_handled;
u32 acpi_irq_not_handled;
/* /*
* Make ACPICA version work as module param * Make ACPICA version work as module param
...@@ -214,8 +215,9 @@ static int acpi_system_sysfs_init(void) ...@@ -214,8 +215,9 @@ static int acpi_system_sysfs_init(void)
#define COUNT_GPE 0 #define COUNT_GPE 0
#define COUNT_SCI 1 /* acpi_irq_handled */ #define COUNT_SCI 1 /* acpi_irq_handled */
#define COUNT_ERROR 2 /* other */ #define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */
#define NUM_COUNTERS_EXTRA 3 #define COUNT_ERROR 3 /* other */
#define NUM_COUNTERS_EXTRA 4
struct event_counter { struct event_counter {
u32 count; u32 count;
...@@ -317,6 +319,8 @@ static ssize_t counter_show(struct kobject *kobj, ...@@ -317,6 +319,8 @@ static ssize_t counter_show(struct kobject *kobj,
all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count = all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
acpi_irq_handled; 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 = all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
acpi_gpe_count; acpi_gpe_count;
...@@ -363,6 +367,7 @@ static ssize_t counter_set(struct kobject *kobj, ...@@ -363,6 +367,7 @@ static ssize_t counter_set(struct kobject *kobj,
all_counters[i].count = 0; all_counters[i].count = 0;
acpi_gpe_count = 0; acpi_gpe_count = 0;
acpi_irq_handled = 0; acpi_irq_handled = 0;
acpi_irq_not_handled = 0;
goto end; goto end;
} }
...@@ -456,6 +461,8 @@ void acpi_irq_stats_init(void) ...@@ -456,6 +461,8 @@ void acpi_irq_stats_init(void)
sprintf(buffer, "gpe_all"); sprintf(buffer, "gpe_all");
else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
sprintf(buffer, "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) else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
sprintf(buffer, "error"); sprintf(buffer, "error");
else else
......
...@@ -909,7 +909,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) ...@@ -909,7 +909,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
thermal_zone_device_register("acpitz", trips, tz, thermal_zone_device_register("acpitz", trips, tz,
&acpi_thermal_zone_ops, &acpi_thermal_zone_ops,
0, 0, 0, 0, 0, 0,
tz->polling_frequency); tz->polling_frequency*100);
if (IS_ERR(tz->thermal_zone)) if (IS_ERR(tz->thermal_zone))
return -ENODEV; return -ENODEV;
......
...@@ -770,10 +770,12 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -770,10 +770,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
* In this case, the first two elements in _BCL packages * In this case, the first two elements in _BCL packages
* are also supported brightness levels that OS should take care of. * are also supported brightness levels that OS should take care of.
*/ */
for (i = 2; i < count; i++) for (i = 2; i < count; i++) {
if (br->levels[i] == br->levels[0] || if (br->levels[i] == br->levels[0])
br->levels[i] == br->levels[1])
level_ac_battery++; level_ac_battery++;
if (br->levels[i] == br->levels[1])
level_ac_battery++;
}
if (level_ac_battery < 2) { if (level_ac_battery < 2) {
level_ac_battery = 2 - level_ac_battery; level_ac_battery = 2 - level_ac_battery;
...@@ -807,12 +809,19 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -807,12 +809,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br->flags._BCM_use_index = br->flags._BCL_use_index; br->flags._BCM_use_index = br->flags._BCL_use_index;
/* _BQC uses INDEX while _BCL uses VALUE in some laptops */ /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
br->curr = max_level; br->curr = level_old = max_level;
if (!device->cap._BQC)
goto set_level;
result = acpi_video_device_lcd_get_level_current(device, &level_old); result = acpi_video_device_lcd_get_level_current(device, &level_old);
if (result) if (result)
goto out_free_levels; goto out_free_levels;
result = acpi_video_device_lcd_set_level(device, br->curr); /*
* Set the level to maximum and check if _BQC uses indexed value
*/
result = acpi_video_device_lcd_set_level(device, max_level);
if (result) if (result)
goto out_free_levels; goto out_free_levels;
...@@ -820,25 +829,19 @@ acpi_video_init_brightness(struct acpi_video_device *device) ...@@ -820,25 +829,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
if (result) if (result)
goto out_free_levels; goto out_free_levels;
if ((level != level_old) && !br->flags._BCM_use_index) { br->flags._BQC_use_index = (level == max_level ? 0 : 1);
/* Note:
* This piece of code does not work correctly if the current if (!br->flags._BQC_use_index)
* brightness levels is 0. goto set_level;
* 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 (br->flags._BCL_reversed)
*/ level_old = (br->count - 1) - level_old;
level_old = br->levels[level_old];
if (level_ac_battery != 2) {
/* set_level:
* For now, we don't support the _BCL like this: result = acpi_video_device_lcd_set_level(device, level_old);
* 16, 15, 0, 1, 2, 3, ..., 14, 15, 16 if (result)
* because we may mess up the index returned by _BQC. goto out_free_levels;
* 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, ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"found %d brightness levels\n", count - 2)); "found %d brightness levels\n", count - 2));
......
...@@ -370,11 +370,8 @@ int intel_opregion_init(struct drm_device *dev, int resume) ...@@ -370,11 +370,8 @@ int intel_opregion_init(struct drm_device *dev, int resume)
if (mboxes & MBOX_ACPI) { if (mboxes & MBOX_ACPI) {
DRM_DEBUG("Public ACPI methods supported\n"); DRM_DEBUG("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET; 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); intel_didl_outputs(dev);
if (!resume)
acpi_video_register();
}
} else { } else {
DRM_DEBUG("Public ACPI methods not supported\n"); DRM_DEBUG("Public ACPI methods not supported\n");
err = -ENOTSUPP; err = -ENOTSUPP;
...@@ -391,6 +388,10 @@ int intel_opregion_init(struct drm_device *dev, int resume) ...@@ -391,6 +388,10 @@ int intel_opregion_init(struct drm_device *dev, int resume)
opregion->asle = base + OPREGION_ASLE_OFFSET; opregion->asle = base + OPREGION_ASLE_OFFSET;
} }
if (!resume)
acpi_video_register();
/* Notify BIOS we are ready to handle ACPI video ext notifs. /* Notify BIOS we are ready to handle ACPI video ext notifs.
* Right now, all the events are handled by the ACPI video module. * Right now, all the events are handled by the ACPI video module.
* We don't actually need to do anything with them. */ * We don't actually need to do anything with them. */
......
...@@ -317,7 +317,8 @@ static void sony_laptop_report_input_event(u8 event) ...@@ -317,7 +317,8 @@ static void sony_laptop_report_input_event(u8 event)
struct input_dev *key_dev = sony_laptop_input.key_dev; struct input_dev *key_dev = sony_laptop_input.key_dev;
struct sony_laptop_keypress kp = { NULL }; struct sony_laptop_keypress kp = { NULL };
if (event == SONYPI_EVENT_FNKEY_RELEASED) { if (event == SONYPI_EVENT_FNKEY_RELEASED ||
event == SONYPI_EVENT_ANYBUTTON_RELEASED) {
/* Nothing, not all VAIOs generate this event */ /* Nothing, not all VAIOs generate this event */
return; return;
} }
...@@ -905,7 +906,6 @@ static struct sony_nc_event sony_127_events[] = { ...@@ -905,7 +906,6 @@ static struct sony_nc_event sony_127_events[] = {
{ 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x86, SONYPI_EVENT_PKEY_P5 }, { 0x86, SONYPI_EVENT_PKEY_P5 },
{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED }, { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
{ 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED }, { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0, 0 }, { 0, 0 },
...@@ -1004,6 +1004,7 @@ static int sony_nc_function_setup(struct acpi_device *device) ...@@ -1004,6 +1004,7 @@ static int sony_nc_function_setup(struct acpi_device *device)
sony_call_snc_handle(0x0100, 0, &result); sony_call_snc_handle(0x0100, 0, &result);
sony_call_snc_handle(0x0101, 0, &result); sony_call_snc_handle(0x0101, 0, &result);
sony_call_snc_handle(0x0102, 0x100, &result); sony_call_snc_handle(0x0102, 0x100, &result);
sony_call_snc_handle(0x0127, 0, &result);
return 0; return 0;
} }
...@@ -1040,7 +1041,7 @@ static int sony_nc_resume(struct acpi_device *device) ...@@ -1040,7 +1041,7 @@ static int sony_nc_resume(struct acpi_device *device)
/* set the last requested brightness level */ /* set the last requested brightness level */
if (sony_backlight_device && if (sony_backlight_device &&
!sony_backlight_update_status(sony_backlight_device)) sony_backlight_update_status(sony_backlight_device) < 0)
printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n"); printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
return 0; return 0;
...@@ -1102,8 +1103,11 @@ static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) ...@@ -1102,8 +1103,11 @@ static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
err = rfkill_register(sony_wifi_rfkill); err = rfkill_register(sony_wifi_rfkill);
if (err) if (err)
rfkill_free(sony_wifi_rfkill); rfkill_free(sony_wifi_rfkill);
else else {
sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill; sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
sony_nc_rfkill_set(sony_wifi_rfkill->data,
RFKILL_STATE_UNBLOCKED);
}
return err; return err;
} }
...@@ -1124,8 +1128,11 @@ static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) ...@@ -1124,8 +1128,11 @@ static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
err = rfkill_register(sony_bluetooth_rfkill); err = rfkill_register(sony_bluetooth_rfkill);
if (err) if (err)
rfkill_free(sony_bluetooth_rfkill); rfkill_free(sony_bluetooth_rfkill);
else else {
sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
sony_nc_rfkill_set(sony_bluetooth_rfkill->data,
RFKILL_STATE_UNBLOCKED);
}
return err; return err;
} }
...@@ -1145,8 +1152,11 @@ static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) ...@@ -1145,8 +1152,11 @@ static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
err = rfkill_register(sony_wwan_rfkill); err = rfkill_register(sony_wwan_rfkill);
if (err) if (err)
rfkill_free(sony_wwan_rfkill); rfkill_free(sony_wwan_rfkill);
else else {
sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill; sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
sony_nc_rfkill_set(sony_wwan_rfkill->data,
RFKILL_STATE_UNBLOCKED);
}
return err; return err;
} }
...@@ -1166,8 +1176,11 @@ static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) ...@@ -1166,8 +1176,11 @@ static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
err = rfkill_register(sony_wimax_rfkill); err = rfkill_register(sony_wimax_rfkill);
if (err) if (err)
rfkill_free(sony_wimax_rfkill); rfkill_free(sony_wimax_rfkill);
else else {
sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill; sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
sony_nc_rfkill_set(sony_wimax_rfkill->data,
RFKILL_STATE_UNBLOCKED);
}
return err; return err;
} }
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#define TPACPI_VERSION "0.22" #define TPACPI_VERSION "0.23"
#define TPACPI_SYSFS_VERSION 0x020300 #define TPACPI_SYSFS_VERSION 0x020300
/* /*
...@@ -303,11 +303,17 @@ static u32 dbg_level; ...@@ -303,11 +303,17 @@ static u32 dbg_level;
static struct workqueue_struct *tpacpi_wq; 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 */ /* Special LED class that can defer work */
struct tpacpi_led_classdev { struct tpacpi_led_classdev {
struct led_classdev led_classdev; struct led_classdev led_classdev;
struct work_struct work; struct work_struct work;
enum led_brightness new_brightness; enum led_status_t new_state;
unsigned int led; unsigned int led;
}; };
...@@ -2946,12 +2952,18 @@ static int hotkey_read(char *p) ...@@ -2946,12 +2952,18 @@ static int hotkey_read(char *p)
return len; return len;
} }
static void hotkey_enabledisable_warn(void) static void hotkey_enabledisable_warn(bool enable)
{ {
tpacpi_log_usertask("procfs hotkey enable/disable"); tpacpi_log_usertask("procfs hotkey enable/disable");
WARN(1, TPACPI_WARN if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
"hotkey enable/disable functionality has been " TPACPI_WARN
"removed from the driver. Hotkeys are always enabled.\n"); "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");
} }
static int hotkey_write(char *buf) static int hotkey_write(char *buf)
...@@ -2971,9 +2983,9 @@ static int hotkey_write(char *buf) ...@@ -2971,9 +2983,9 @@ static int hotkey_write(char *buf)
res = 0; res = 0;
while ((cmd = next_cmd(&buf))) { while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) { if (strlencmp(cmd, "enable") == 0) {
hotkey_enabledisable_warn(); hotkey_enabledisable_warn(1);
} else if (strlencmp(cmd, "disable") == 0) { } else if (strlencmp(cmd, "disable") == 0) {
hotkey_enabledisable_warn(); hotkey_enabledisable_warn(0);
res = -EPERM; res = -EPERM;
} else if (strlencmp(cmd, "reset") == 0) { } else if (strlencmp(cmd, "reset") == 0) {
mask = hotkey_orig_mask; mask = hotkey_orig_mask;
...@@ -4207,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work) ...@@ -4207,7 +4219,7 @@ static void light_set_status_worker(struct work_struct *work)
container_of(work, struct tpacpi_led_classdev, work); container_of(work, struct tpacpi_led_classdev, work);
if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
light_set_status((data->new_brightness != LED_OFF)); light_set_status((data->new_state != TPACPI_LED_OFF));
} }
static void light_sysfs_set(struct led_classdev *led_cdev, static void light_sysfs_set(struct led_classdev *led_cdev,
...@@ -4217,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev, ...@@ -4217,7 +4229,8 @@ static void light_sysfs_set(struct led_classdev *led_cdev,
container_of(led_cdev, container_of(led_cdev,
struct tpacpi_led_classdev, struct tpacpi_led_classdev,
led_classdev); led_classdev);
data->new_brightness = brightness; data->new_state = (brightness != LED_OFF) ?
TPACPI_LED_ON : TPACPI_LED_OFF;
queue_work(tpacpi_wq, &data->work); queue_work(tpacpi_wq, &data->work);
} }
...@@ -4724,12 +4737,6 @@ enum { /* For TPACPI_LED_OLD */ ...@@ -4724,12 +4737,6 @@ enum { /* For TPACPI_LED_OLD */
TPACPI_LED_EC_HLMS = 0x0e, /* EC reg to select led to command */ 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; static enum led_access_mode led_supported;
TPACPI_HANDLE(led, ec, "SLED", /* 570 */ TPACPI_HANDLE(led, ec, "SLED", /* 570 */
...@@ -4841,23 +4848,13 @@ static int led_set_status(const unsigned int led, ...@@ -4841,23 +4848,13 @@ static int led_set_status(const unsigned int led,
return rc; 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) static void led_set_status_worker(struct work_struct *work)
{ {
struct tpacpi_led_classdev *data = struct tpacpi_led_classdev *data =
container_of(work, struct tpacpi_led_classdev, work); container_of(work, struct tpacpi_led_classdev, work);
if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING)) if (likely(tpacpi_lifecycle == TPACPI_LIFE_RUNNING))
led_sysfs_set_status(data->led, data->new_brightness); led_set_status(data->led, data->new_state);
} }
static void led_sysfs_set(struct led_classdev *led_cdev, static void led_sysfs_set(struct led_classdev *led_cdev,
...@@ -4866,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev, ...@@ -4866,7 +4863,13 @@ static void led_sysfs_set(struct led_classdev *led_cdev,
struct tpacpi_led_classdev *data = container_of(led_cdev, struct tpacpi_led_classdev *data = container_of(led_cdev,
struct tpacpi_led_classdev, led_classdev); struct tpacpi_led_classdev, led_classdev);
data->new_brightness = brightness; 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;
queue_work(tpacpi_wq, &data->work); queue_work(tpacpi_wq, &data->work);
} }
...@@ -4884,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev, ...@@ -4884,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
} else if ((*delay_on != 500) || (*delay_off != 500)) } else if ((*delay_on != 500) || (*delay_off != 500))
return -EINVAL; return -EINVAL;
data->new_brightness = TPACPI_LED_BLINK; data->new_state = TPACPI_LED_BLINK;
queue_work(tpacpi_wq, &data->work); queue_work(tpacpi_wq, &data->work);
return 0; return 0;
...@@ -7857,6 +7860,15 @@ static int __init thinkpad_acpi_module_init(void) ...@@ -7857,6 +7860,15 @@ static int __init thinkpad_acpi_module_init(void)
MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); 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 * DMI matching for module autoloading
* *
...@@ -7869,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME); ...@@ -7869,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
#define IBM_BIOS_MODULE_ALIAS(__type) \ #define IBM_BIOS_MODULE_ALIAS(__type) \
MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") 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 /* Ancient thinkpad BIOSes have to be identified by
* BIOS type or model number, and there are far less * BIOS type or model number, and there are far less
* BIOS types than model numbers... */ * BIOS types than model numbers... */
IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); IBM_BIOS_MODULE_ALIAS("I[MU]"); /* 570, 570e */
IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]");
IBM_BIOS_MODULE_ALIAS("K[UX-Z]");
MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); MODULE_AUTHOR("Borislav Deianov <borislav@users.sf.net>");
MODULE_AUTHOR("Henrique de Moraes Holschuh <hmh@hmh.eng.br>");
MODULE_DESCRIPTION(TPACPI_DESC); MODULE_DESCRIPTION(TPACPI_DESC);
MODULE_VERSION(TPACPI_VERSION); MODULE_VERSION(TPACPI_VERSION);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -84,7 +84,6 @@ struct acpi_processor_power { ...@@ -84,7 +84,6 @@ struct acpi_processor_power {
struct acpi_processor_cx *state; struct acpi_processor_cx *state;
unsigned long bm_check_timestamp; unsigned long bm_check_timestamp;
u32 default_state; u32 default_state;
u32 bm_activity;
int count; int count;
struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER]; struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
int timer_broadcast_on_state; int timer_broadcast_on_state;
......
...@@ -111,6 +111,7 @@ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); ...@@ -111,6 +111,7 @@ int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
void acpi_irq_stats_init(void); void acpi_irq_stats_init(void);
extern u32 acpi_irq_handled; extern u32 acpi_irq_handled;
extern u32 acpi_irq_not_handled;
extern struct acpi_mcfg_allocation *pci_mmcfg_config; extern struct acpi_mcfg_allocation *pci_mmcfg_config;
extern int pci_mmcfg_config_num; extern int pci_mmcfg_config_num;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment