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 ...
This commit is contained in:
Коммит
ef54b1bb2e
|
@ -69,9 +69,13 @@ Description:
|
|||
gpe1F: 0 invalid
|
||||
gpe_all: 1192
|
||||
sci: 1194
|
||||
sci_not: 0
|
||||
|
||||
sci - The total number of times the ACPI SCI
|
||||
has claimed an interrupt.
|
||||
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.
|
||||
|
||||
gpe_all - count of SCI caused by GPEs.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
ThinkPad ACPI Extras Driver
|
||||
|
||||
Version 0.22
|
||||
November 23rd, 2008
|
||||
Version 0.23
|
||||
April 10th, 2009
|
||||
|
||||
Borislav Deianov <borislav@users.sf.net>
|
||||
Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
||||
|
|
|
@ -65,14 +65,18 @@ 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;
|
||||
u64 saved_aperf, saved_mperf;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
/* acpi_perf_data is a pointer to percpu data. */
|
||||
|
@ -287,11 +291,11 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy,
|
|||
return 0;
|
||||
|
||||
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 -
|
||||
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;
|
||||
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;
|
||||
|
||||
#ifdef __i386__
|
||||
/*
|
||||
|
@ -335,7 +339,7 @@ static unsigned int get_measured_perf(struct cpufreq_policy *policy,
|
|||
|
||||
#endif
|
||||
|
||||
retval = per_cpu(drv_data, policy->cpu)->max_freq * perf_percent / 100;
|
||||
retval = (policy->cpuinfo.max_freq * perf_percent) / 100;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -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 */
|
||||
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;
|
||||
if (!print_once) {
|
||||
print_once = 1;
|
||||
printk(KERN_INFO "Capping off P-state tranision latency"
|
||||
" at 20 uS\n");
|
||||
}
|
||||
printk_once(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 >=
|
||||
|
@ -716,6 +715,9 @@ 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 */
|
||||
|
|
|
@ -211,6 +211,12 @@ 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
|
||||
|
@ -278,16 +284,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
|
|||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Execute the _GTS method */
|
||||
if (gts) {
|
||||
/* 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 */
|
||||
|
@ -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.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);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ 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},
|
||||
|
@ -151,7 +152,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 +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 */
|
||||
|
||||
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 +208,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 +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 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 +266,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 +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 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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
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
|
||||
|
@ -261,27 +259,6 @@ 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;
|
||||
|
||||
/*
|
||||
|
@ -304,7 +281,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[source_name_index];
|
||||
obj_desc = sub_object_list[2];
|
||||
if (obj_desc) {
|
||||
switch (obj_desc->common.type) {
|
||||
case ACPI_TYPE_LOCAL_REFERENCE:
|
||||
|
@ -378,7 +355,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[source_index_index];
|
||||
obj_desc = sub_object_list[3];
|
||||
if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"(PRT[%X].SourceIndex) Need Integer, found %s",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* acpi_button.c - ACPI Button Driver ($Revision: 30 $)
|
||||
* button.c - ACPI Button Driver
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
|
||||
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
|
||||
|
@ -41,17 +41,13 @@
|
|||
|
||||
#define ACPI_BUTTON_SUBCLASS_POWER "power"
|
||||
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button (CM)"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_POWERF "Power Button (FF)"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
|
||||
#define ACPI_BUTTON_TYPE_POWER 0x01
|
||||
#define ACPI_BUTTON_TYPE_POWERF 0x02
|
||||
|
||||
#define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
|
||||
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button (CM)"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_SLEEPF "Sleep Button (FF)"
|
||||
#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
|
||||
#define ACPI_BUTTON_TYPE_SLEEP 0x03
|
||||
#define ACPI_BUTTON_TYPE_SLEEPF 0x04
|
||||
|
||||
#define ACPI_BUTTON_SUBCLASS_LID "lid"
|
||||
#define ACPI_BUTTON_HID_LID "PNP0C0D"
|
||||
|
@ -95,7 +91,6 @@ static struct acpi_driver acpi_button_driver = {
|
|||
};
|
||||
|
||||
struct acpi_button {
|
||||
struct acpi_device *device; /* Fixed button kludge */
|
||||
unsigned int type;
|
||||
struct input_dev *input;
|
||||
char phys[32]; /* for input device */
|
||||
|
@ -126,14 +121,10 @@ static struct proc_dir_entry *acpi_button_dir;
|
|||
|
||||
static int acpi_button_info_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_button *button = seq->private;
|
||||
|
||||
if (!button || !button->device)
|
||||
return 0;
|
||||
struct acpi_device *device = seq->private;
|
||||
|
||||
seq_printf(seq, "type: %s\n",
|
||||
acpi_device_name(button->device));
|
||||
|
||||
acpi_device_name(device));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -144,14 +135,11 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file)
|
|||
|
||||
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
|
||||
{
|
||||
struct acpi_button *button = seq->private;
|
||||
struct acpi_device *device = seq->private;
|
||||
acpi_status status;
|
||||
unsigned long long state;
|
||||
|
||||
if (!button || !button->device)
|
||||
return 0;
|
||||
|
||||
status = acpi_evaluate_integer(button->device->handle, "_LID", NULL, &state);
|
||||
status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
|
||||
seq_printf(seq, "state: %s\n",
|
||||
ACPI_FAILURE(status) ? "unsupported" :
|
||||
(state ? "open" : "closed"));
|
||||
|
@ -169,24 +157,17 @@ static struct proc_dir_entry *acpi_lid_dir;
|
|||
|
||||
static int acpi_button_add_fs(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
struct proc_dir_entry *entry = NULL;
|
||||
struct acpi_button *button;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
||||
button = acpi_driver_data(device);
|
||||
|
||||
switch (button->type) {
|
||||
case ACPI_BUTTON_TYPE_POWER:
|
||||
case ACPI_BUTTON_TYPE_POWERF:
|
||||
if (!acpi_power_dir)
|
||||
acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER,
|
||||
acpi_button_dir);
|
||||
entry = acpi_power_dir;
|
||||
break;
|
||||
case ACPI_BUTTON_TYPE_SLEEP:
|
||||
case ACPI_BUTTON_TYPE_SLEEPF:
|
||||
if (!acpi_sleep_dir)
|
||||
acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP,
|
||||
acpi_button_dir);
|
||||
|
@ -210,8 +191,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
|
|||
/* 'info' [R] */
|
||||
entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
|
||||
S_IRUGO, acpi_device_dir(device),
|
||||
&acpi_button_info_fops,
|
||||
acpi_driver_data(device));
|
||||
&acpi_button_info_fops, device);
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -219,8 +199,7 @@ static int acpi_button_add_fs(struct acpi_device *device)
|
|||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
|
||||
S_IRUGO, acpi_device_dir(device),
|
||||
&acpi_button_state_fops,
|
||||
acpi_driver_data(device));
|
||||
&acpi_button_state_fops, device);
|
||||
if (!entry)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -250,15 +229,16 @@ static int acpi_button_remove_fs(struct acpi_device *device)
|
|||
/* --------------------------------------------------------------------------
|
||||
Driver Interface
|
||||
-------------------------------------------------------------------------- */
|
||||
static int acpi_lid_send_state(struct acpi_button *button)
|
||||
static int acpi_lid_send_state(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
unsigned long long state;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
|
||||
&state);
|
||||
status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
/* input layer checks if event is redundant */
|
||||
input_report_switch(button->input, SW_LID, !state);
|
||||
input_sync(button->input);
|
||||
|
@ -270,9 +250,6 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
|
|||
struct acpi_button *button = acpi_driver_data(device);
|
||||
struct input_dev *input;
|
||||
|
||||
if (!button || !button->device)
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case ACPI_FIXED_HARDWARE_EVENT:
|
||||
event = ACPI_BUTTON_NOTIFY_STATUS;
|
||||
|
@ -280,7 +257,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
|
|||
case ACPI_BUTTON_NOTIFY_STATUS:
|
||||
input = button->input;
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID) {
|
||||
acpi_lid_send_state(button);
|
||||
acpi_lid_send_state(device);
|
||||
} else {
|
||||
int keycode = test_bit(KEY_SLEEP, input->keybit) ?
|
||||
KEY_SLEEP : KEY_POWER;
|
||||
|
@ -291,43 +268,35 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
|
|||
input_sync(input);
|
||||
}
|
||||
|
||||
acpi_bus_generate_proc_event(button->device, event,
|
||||
++button->pushed);
|
||||
acpi_bus_generate_proc_event(device, event, ++button->pushed);
|
||||
break;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Unsupported event [0x%x]\n", event));
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int acpi_button_resume(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_button *button;
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
button = acpi_driver_data(device);
|
||||
if (button && button->type == ACPI_BUTTON_TYPE_LID)
|
||||
return acpi_lid_send_state(button);
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID)
|
||||
return acpi_lid_send_state(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_button_add(struct acpi_device *device)
|
||||
{
|
||||
int error;
|
||||
struct acpi_button *button;
|
||||
struct input_dev *input;
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
char *hid, *name, *class;
|
||||
int error;
|
||||
|
||||
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
|
||||
if (!button)
|
||||
return -ENOMEM;
|
||||
|
||||
button->device = device;
|
||||
device->driver_data = button;
|
||||
|
||||
button->input = input = input_allocate_device();
|
||||
|
@ -336,40 +305,29 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
goto err_free_button;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the button type (via hid), as fixed-feature buttons
|
||||
* need to be handled a bit differently than generic-space.
|
||||
*/
|
||||
if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) {
|
||||
hid = acpi_device_hid(device);
|
||||
name = acpi_device_name(device);
|
||||
class = acpi_device_class(device);
|
||||
|
||||
if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
|
||||
!strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
|
||||
button->type = ACPI_BUTTON_TYPE_POWER;
|
||||
strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_POWER);
|
||||
sprintf(acpi_device_class(device), "%s/%s",
|
||||
strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
|
||||
sprintf(class, "%s/%s",
|
||||
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
|
||||
} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) {
|
||||
button->type = ACPI_BUTTON_TYPE_POWERF;
|
||||
strcpy(acpi_device_name(device),
|
||||
ACPI_BUTTON_DEVICE_NAME_POWERF);
|
||||
sprintf(acpi_device_class(device), "%s/%s",
|
||||
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
|
||||
} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) {
|
||||
} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
|
||||
!strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
|
||||
button->type = ACPI_BUTTON_TYPE_SLEEP;
|
||||
strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_SLEEP);
|
||||
sprintf(acpi_device_class(device), "%s/%s",
|
||||
strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
|
||||
sprintf(class, "%s/%s",
|
||||
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
|
||||
} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) {
|
||||
button->type = ACPI_BUTTON_TYPE_SLEEPF;
|
||||
strcpy(acpi_device_name(device),
|
||||
ACPI_BUTTON_DEVICE_NAME_SLEEPF);
|
||||
sprintf(acpi_device_class(device), "%s/%s",
|
||||
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
|
||||
} else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) {
|
||||
} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
|
||||
button->type = ACPI_BUTTON_TYPE_LID;
|
||||
strcpy(acpi_device_name(device), ACPI_BUTTON_DEVICE_NAME_LID);
|
||||
sprintf(acpi_device_class(device), "%s/%s",
|
||||
strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
|
||||
sprintf(class, "%s/%s",
|
||||
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
|
||||
} else {
|
||||
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n",
|
||||
acpi_device_hid(device));
|
||||
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
|
||||
error = -ENODEV;
|
||||
goto err_free_input;
|
||||
}
|
||||
|
@ -378,10 +336,9 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
if (error)
|
||||
goto err_free_input;
|
||||
|
||||
snprintf(button->phys, sizeof(button->phys),
|
||||
"%s/button/input0", acpi_device_hid(device));
|
||||
snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
|
||||
|
||||
input->name = acpi_device_name(device);
|
||||
input->name = name;
|
||||
input->phys = button->phys;
|
||||
input->id.bustype = BUS_HOST;
|
||||
input->id.product = button->type;
|
||||
|
@ -389,13 +346,11 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
|
||||
switch (button->type) {
|
||||
case ACPI_BUTTON_TYPE_POWER:
|
||||
case ACPI_BUTTON_TYPE_POWERF:
|
||||
input->evbit[0] = BIT_MASK(EV_KEY);
|
||||
set_bit(KEY_POWER, input->keybit);
|
||||
break;
|
||||
|
||||
case ACPI_BUTTON_TYPE_SLEEP:
|
||||
case ACPI_BUTTON_TYPE_SLEEPF:
|
||||
input->evbit[0] = BIT_MASK(EV_KEY);
|
||||
set_bit(KEY_SLEEP, input->keybit);
|
||||
break;
|
||||
|
@ -410,7 +365,7 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
if (error)
|
||||
goto err_remove_fs;
|
||||
if (button->type == ACPI_BUTTON_TYPE_LID)
|
||||
acpi_lid_send_state(button);
|
||||
acpi_lid_send_state(device);
|
||||
|
||||
if (device->wakeup.flags.valid) {
|
||||
/* Button's GPE is run-wake GPE */
|
||||
|
@ -422,9 +377,7 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
device->wakeup.state.enabled = 1;
|
||||
}
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s]\n",
|
||||
acpi_device_name(device), acpi_device_bid(device));
|
||||
|
||||
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
|
||||
return 0;
|
||||
|
||||
err_remove_fs:
|
||||
|
@ -438,17 +391,11 @@ static int acpi_button_add(struct acpi_device *device)
|
|||
|
||||
static int acpi_button_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
struct acpi_button *button;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return -EINVAL;
|
||||
|
||||
button = acpi_driver_data(device);
|
||||
struct acpi_button *button = acpi_driver_data(device);
|
||||
|
||||
acpi_button_remove_fs(device);
|
||||
input_unregister_device(button->input);
|
||||
kfree(button);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -459,6 +406,7 @@ static int __init acpi_button_init(void)
|
|||
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
if (!acpi_button_dir)
|
||||
return -ENODEV;
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_button_driver);
|
||||
if (result < 0) {
|
||||
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
|
||||
|
|
|
@ -1065,6 +1065,7 @@ static int acpi_ec_resume(struct acpi_device *device)
|
|||
struct acpi_ec *ec = acpi_driver_data(device);
|
||||
/* Enable use of GPE back */
|
||||
clear_bit(EC_FLAGS_NO_GPE, &ec->flags);
|
||||
set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
|
||||
acpi_enable_gpe(NULL, ec->gpe);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -353,8 +353,10 @@ static irqreturn_t acpi_irq(int irq, void *dev_id)
|
|||
if (handled) {
|
||||
acpi_irq_handled++;
|
||||
return IRQ_HANDLED;
|
||||
} else
|
||||
} else {
|
||||
acpi_irq_not_handled++;
|
||||
return IRQ_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
acpi_status
|
||||
|
|
|
@ -581,6 +581,11 @@ 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;
|
||||
|
@ -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"
|
||||
"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, (unsigned)pr->power.bm_activity,
|
||||
pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
|
||||
max_cstate, pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
|
||||
|
||||
seq_puts(seq, "states:\n");
|
||||
|
||||
|
@ -871,11 +874,6 @@ 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: */
|
||||
|
@ -955,6 +953,7 @@ 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
|
||||
|
@ -976,10 +975,7 @@ 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) {
|
||||
|
@ -988,12 +984,9 @@ 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);
|
||||
|
@ -1037,6 +1030,9 @@ 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];
|
||||
|
|
|
@ -713,6 +713,32 @@ 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;
|
||||
|
@ -771,5 +797,6 @@ 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;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ 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
|
||||
|
@ -214,8 +215,9 @@ err:
|
|||
|
||||
#define COUNT_GPE 0
|
||||
#define COUNT_SCI 1 /* acpi_irq_handled */
|
||||
#define COUNT_ERROR 2 /* other */
|
||||
#define NUM_COUNTERS_EXTRA 3
|
||||
#define COUNT_SCI_NOT 2 /* acpi_irq_not_handled */
|
||||
#define COUNT_ERROR 3 /* other */
|
||||
#define NUM_COUNTERS_EXTRA 4
|
||||
|
||||
struct event_counter {
|
||||
u32 count;
|
||||
|
@ -317,6 +319,8 @@ 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;
|
||||
|
||||
|
@ -363,6 +367,7 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -456,6 +461,8 @@ 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
|
||||
|
|
|
@ -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);
|
||||
tz->polling_frequency*100);
|
||||
if (IS_ERR(tz->thermal_zone))
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
@ -770,10 +770,12 @@ 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] ||
|
||||
br->levels[i] == br->levels[1])
|
||||
for (i = 2; i < count; i++) {
|
||||
if (br->levels[i] == br->levels[0])
|
||||
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;
|
||||
|
@ -807,12 +809,19 @@ 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 = 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);
|
||||
if (result)
|
||||
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)
|
||||
goto out_free_levels;
|
||||
|
||||
|
@ -820,25 +829,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
|
|||
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.
|
||||
*/
|
||||
br->flags._BQC_use_index = (level == max_level ? 0 : 1);
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"found %d brightness levels\n", count - 2));
|
||||
|
|
|
@ -370,11 +370,8 @@ 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;
|
||||
|
@ -391,6 +388,10 @@ 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. */
|
||||
|
|
|
@ -317,7 +317,8 @@ 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) {
|
||||
if (event == SONYPI_EVENT_FNKEY_RELEASED ||
|
||||
event == SONYPI_EVENT_ANYBUTTON_RELEASED) {
|
||||
/* Nothing, not all VAIOs generate this event */
|
||||
return;
|
||||
}
|
||||
|
@ -905,7 +906,6 @@ 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,6 +1004,7 @@ 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;
|
||||
}
|
||||
|
@ -1040,7 +1041,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))
|
||||
sony_backlight_update_status(sony_backlight_device) < 0)
|
||||
printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
|
||||
|
||||
return 0;
|
||||
|
@ -1102,8 +1103,11 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -1124,8 +1128,11 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -1145,8 +1152,11 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -1166,8 +1176,11 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define TPACPI_VERSION "0.22"
|
||||
#define TPACPI_VERSION "0.23"
|
||||
#define TPACPI_SYSFS_VERSION 0x020300
|
||||
|
||||
/*
|
||||
|
@ -303,11 +303,17 @@ 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_brightness new_brightness;
|
||||
enum led_status_t new_state;
|
||||
unsigned int led;
|
||||
};
|
||||
|
||||
|
@ -2946,12 +2952,18 @@ static int hotkey_read(char *p)
|
|||
return len;
|
||||
}
|
||||
|
||||
static void hotkey_enabledisable_warn(void)
|
||||
static void hotkey_enabledisable_warn(bool enable)
|
||||
{
|
||||
tpacpi_log_usertask("procfs hotkey enable/disable");
|
||||
WARN(1, TPACPI_WARN
|
||||
"hotkey enable/disable functionality has been "
|
||||
"removed from the driver. Hotkeys are always enabled.\n");
|
||||
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");
|
||||
}
|
||||
|
||||
static int hotkey_write(char *buf)
|
||||
|
@ -2971,9 +2983,9 @@ static int hotkey_write(char *buf)
|
|||
res = 0;
|
||||
while ((cmd = next_cmd(&buf))) {
|
||||
if (strlencmp(cmd, "enable") == 0) {
|
||||
hotkey_enabledisable_warn();
|
||||
hotkey_enabledisable_warn(1);
|
||||
} else if (strlencmp(cmd, "disable") == 0) {
|
||||
hotkey_enabledisable_warn();
|
||||
hotkey_enabledisable_warn(0);
|
||||
res = -EPERM;
|
||||
} else if (strlencmp(cmd, "reset") == 0) {
|
||||
mask = hotkey_orig_mask;
|
||||
|
@ -4207,7 +4219,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_brightness != LED_OFF));
|
||||
light_set_status((data->new_state != TPACPI_LED_OFF));
|
||||
}
|
||||
|
||||
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,
|
||||
struct tpacpi_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);
|
||||
}
|
||||
|
||||
|
@ -4724,12 +4737,6 @@ 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 */
|
||||
|
@ -4841,23 +4848,13 @@ 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_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,
|
||||
|
@ -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, 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);
|
||||
}
|
||||
|
||||
|
@ -4884,7 +4887,7 @@ static int led_sysfs_blink_set(struct led_classdev *led_cdev,
|
|||
} else if ((*delay_on != 500) || (*delay_off != 500))
|
||||
return -EINVAL;
|
||||
|
||||
data->new_brightness = TPACPI_LED_BLINK;
|
||||
data->new_state = TPACPI_LED_BLINK;
|
||||
queue_work(tpacpi_wq, &data->work);
|
||||
|
||||
return 0;
|
||||
|
@ -7857,6 +7860,15 @@ 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
|
||||
*
|
||||
|
@ -7869,18 +7881,13 @@ MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
|
|||
#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[BDHIMNOTWVYZ]");
|
||||
IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]");
|
||||
IBM_BIOS_MODULE_ALIAS("K[UX-Z]");
|
||||
IBM_BIOS_MODULE_ALIAS("I[MU]"); /* 570, 570e */
|
||||
|
||||
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_VERSION(TPACPI_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -84,7 +84,6 @@ 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;
|
||||
|
|
|
@ -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);
|
||||
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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче