提交 963c6527 编写于 作者: L 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: (28 commits)
  ACPI: thermal: add DMI hooks to handle AOpen's broken Award BIOS
  ACPI: thermal: create "thermal.act=" to disable or override active trip point
  ACPI: thermal: create "thermal.nocrt" to disable critical actions
  ACPI: thermal: create "thermal.psv=" to override passive trip points
  ACPI: thermal: expose "thermal.tzp=" to set global polling frequency
  ACPI: thermal: create "thermal.off=1" to disable ACPI thermal support
  ACPI: thinkpad-acpi: fix sysfs paths in documentation
  ACPI: static
  ACPI EC: remove potential deadlock from EC
  ACPI: dock: Send key=value pair instead of plain value
  ACPI: bay: send envp with uevent - fix
  acpi-cpufreq: Fix some x86/x86-64 acpi-cpufreq driver issues
  ACPI: fix "Time Problems with 2.6.23-rc1-gf695baf2"
  ACPI: thinkpad-acpi: change thinkpad-acpi input default and kconfig help
  ACPI: EC: fix run-together printk lines
  ACPI: sbs: remove dead code
  ACPI: EC: acpi_ec_remove(): fix use-after-free
  ACPI: EC: Switch from boot_ec as soon as we find its desc in DSDT.
  ACPI: EC: fix build warning
  ACPI: EC: If ECDT is not found, look up EC in DSDT.
  ...
......@@ -163,6 +163,8 @@ and is between 256 and 4096 characters. It is defined in the file
acpi_irq_isa= [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
Format: <irq>,<irq>...
acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
Format: To spoof as Windows 98: ="Microsoft Windows"
......@@ -1820,6 +1822,26 @@ and is between 256 and 4096 characters. It is defined in the file
thash_entries= [KNL,NET]
Set number of hash buckets for TCP connection
thermal.act= [HW,ACPI]
-1: disable all active trip points in all thermal zones
<degrees C>: override all lowest active trip points
thermal.nocrt= [HW,ACPI]
Set to disable actions on ACPI thermal zone
critical and hot trip points.
thermal.off= [HW,ACPI]
1: disable ACPI thermal control
thermal.psv= [HW,ACPI]
-1: disable all passive trip points
<degrees C>: override all passive trip points to this value
thermal.tzp= [HW,ACPI]
Specify global default ACPI thermal zone polling rate
<deci-seconds>: poll all this frequency
0: no polling (default)
time Show timing data prefixed to each printk message line
[deprecated, see 'printk.time']
......
......@@ -105,10 +105,10 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
as a driver attribute (see below).
Sysfs driver attributes are on the driver's sysfs attribute space,
for 2.6.20 this is /sys/bus/platform/drivers/thinkpad-acpi/.
for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
Sysfs device attributes are on the driver's sysfs attribute space,
for 2.6.20 this is /sys/devices/platform/thinkpad-acpi/.
for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
Driver version
--------------
......
......@@ -68,7 +68,8 @@ struct acpi_cpufreq_data {
};
static struct acpi_cpufreq_data *drv_data[NR_CPUS];
static struct acpi_processor_performance *acpi_perf_data[NR_CPUS];
/* acpi_perf_data is a pointer to percpu data. */
static struct acpi_processor_performance *acpi_perf_data;
static struct cpufreq_driver acpi_cpufreq_driver;
......@@ -508,24 +509,14 @@ acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
* do _PDC and _PSD and find out the processor dependency for the
* actual init that will happen later...
*/
static int acpi_cpufreq_early_init(void)
static int __init acpi_cpufreq_early_init(void)
{
struct acpi_processor_performance *data;
unsigned int i, j;
dprintk("acpi_cpufreq_early_init\n");
for_each_possible_cpu(i) {
data = kzalloc(sizeof(struct acpi_processor_performance),
GFP_KERNEL);
if (!data) {
for_each_possible_cpu(j) {
kfree(acpi_perf_data[j]);
acpi_perf_data[j] = NULL;
}
return -ENOMEM;
}
acpi_perf_data[i] = data;
acpi_perf_data = alloc_percpu(struct acpi_processor_performance);
if (!acpi_perf_data) {
dprintk("Memory allocation error for acpi_perf_data.\n");
return -ENOMEM;
}
/* Do initialization in ACPI core */
......@@ -574,14 +565,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
dprintk("acpi_cpufreq_cpu_init\n");
if (!acpi_perf_data[cpu])
return -ENODEV;
data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
if (!data)
return -ENOMEM;
data->acpi_data = acpi_perf_data[cpu];
data->acpi_data = percpu_ptr(acpi_perf_data, cpu);
drv_data[cpu] = data;
if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
......@@ -778,24 +766,25 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
static int __init acpi_cpufreq_init(void)
{
int ret;
dprintk("acpi_cpufreq_init\n");
acpi_cpufreq_early_init();
ret = acpi_cpufreq_early_init();
if (ret)
return ret;
return cpufreq_register_driver(&acpi_cpufreq_driver);
}
static void __exit acpi_cpufreq_exit(void)
{
unsigned int i;
dprintk("acpi_cpufreq_exit\n");
cpufreq_unregister_driver(&acpi_cpufreq_driver);
for_each_possible_cpu(i) {
kfree(acpi_perf_data[i]);
acpi_perf_data[i] = NULL;
}
free_percpu(acpi_perf_data);
return;
}
......
......@@ -1192,6 +1192,7 @@ static int asus_hotk_get_info(void)
break;
default:
kfree(model);
model = NULL;
break;
}
}
......
......@@ -113,7 +113,7 @@ struct acpi_battery_info {
acpi_string oem_info;
};
enum acpi_battery_files{
enum acpi_battery_files {
ACPI_BATTERY_INFO = 0,
ACPI_BATTERY_STATE,
ACPI_BATTERY_ALARM,
......@@ -129,13 +129,14 @@ struct acpi_battery_flags {
};
struct acpi_battery {
struct mutex mutex;
struct acpi_device *device;
struct acpi_battery_flags flags;
struct acpi_buffer bif_data;
struct acpi_buffer bst_data;
struct mutex lock;
unsigned long alarm;
unsigned long update_time[ACPI_BATTERY_NUMFILES];
};
inline int acpi_battery_present(struct acpi_battery *battery)
......@@ -235,10 +236,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
return 0;
/* Evaluate _BIF */
status =
acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
&buffer);
mutex_lock(&battery->lock);
status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
NULL, &buffer);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
return -ENODEV;
......@@ -285,10 +286,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
return 0;
/* Evaluate _BST */
status =
acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
&buffer);
mutex_lock(&battery->lock);
status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
NULL, &buffer);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
return -ENODEV;
......@@ -336,9 +337,10 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
arg0.integer.value = alarm;
status =
acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
mutex_lock(&battery->lock);
status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
&arg_list, NULL);
mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status))
return -ENODEV;
......@@ -658,8 +660,6 @@ acpi_battery_write_alarm(struct file *file,
if (!battery || (count > sizeof(alarm_string) - 1))
return -EINVAL;
mutex_lock(&battery->mutex);
result = acpi_battery_update(battery, 1, &update_result);
if (result) {
result = -ENODEV;
......@@ -688,9 +688,7 @@ acpi_battery_write_alarm(struct file *file,
acpi_battery_check_result(battery, result);
if (!result)
result = count;
mutex_unlock(&battery->mutex);
return count;
return result;
}
......@@ -714,8 +712,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
int update_result = ACPI_BATTERY_NONE_UPDATE;
int update = 0;
mutex_lock(&battery->mutex);
update = (get_seconds() - battery->update_time[fid] >= update_time);
update = (update | battery->flags.update[fid]);
......@@ -733,7 +729,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
result = acpi_read_funcs[fid].print(seq, result);
acpi_battery_check_result(battery, result);
battery->flags.update[fid] = result;
mutex_unlock(&battery->mutex);
return result;
}
......@@ -897,10 +892,7 @@ static int acpi_battery_add(struct acpi_device *device)
if (!battery)
return -ENOMEM;
mutex_init(&battery->mutex);
mutex_lock(&battery->mutex);
mutex_init(&battery->lock);
battery->device = device;
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
......@@ -936,7 +928,6 @@ static int acpi_battery_add(struct acpi_device *device)
kfree(battery);
}
mutex_unlock(&battery->mutex);
return result;
}
......@@ -951,8 +942,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
battery = acpi_driver_data(device);
mutex_lock(&battery->mutex);
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify);
......@@ -963,9 +952,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
kfree(battery->bst_data.pointer);
mutex_unlock(&battery->mutex);
mutex_destroy(&battery->mutex);
mutex_destroy(&battery->lock);
kfree(battery);
......
......@@ -337,7 +337,7 @@ static void bay_notify(acpi_handle handle, u32 event, void *data)
char *envp[] = { event_string, NULL };
bay_dprintk(handle, "Bay event");
sprintf(event_string, "BAY_EVENT=%d\n", event);
sprintf(event_string, "BAY_EVENT=%d", event);
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
}
......
......@@ -336,13 +336,13 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
static void dock_event(struct dock_station *ds, u32 event, int num)
{
struct device *dev = &dock_device->dev;
char event_string[7];
char event_string[13];
char *envp[] = { event_string, NULL };
if (num == UNDOCK_EVENT)
sprintf(event_string, "UNDOCK");
sprintf(event_string, "EVENT=undock");
else
sprintf(event_string, "DOCK");
sprintf(event_string, "EVENT=dock");
/*
* Indicate that the status of the dock station has
......
......@@ -471,7 +471,6 @@ static void acpi_ec_gpe_query(void *ec_cxt)
}
}
mutex_unlock(&ec->lock);
printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
}
static u32 acpi_ec_gpe_handler(void *data)
......@@ -653,42 +652,39 @@ static struct acpi_ec *make_acpi_ec(void)
}
static acpi_status
acpi_ec_register_query_methods(acpi_handle handle, u32 level,
void *context, void **return_value)
ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
{
struct acpi_namespace_node *node = handle;
struct acpi_ec *ec = context;
int value = 0;
if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
}
return AE_OK;
}
acpi_status status;
static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle)
{
if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS,
ec_parse_io_ports, ec)))
return -EINVAL;
struct acpi_ec *ec = context;
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
ec_parse_io_ports, ec);
if (ACPI_FAILURE(status))
return status;
/* Get GPE bit assignment (EC events). */
/* TODO: Add support for _GPE returning a package */
if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe)))
return -EINVAL;
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
if (ACPI_FAILURE(status))
return status;
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
/* Find and register all query methods */
acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
acpi_ec_register_query_methods, ec, NULL);
ec->handle = handle;
printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx",
printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
ec->gpe, ec->command_addr, ec->data_addr);
return 0;
return AE_CTRL_TERMINATE;
}
static void ec_remove_handlers(struct acpi_ec *ec)
{
acpi_remove_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler);
acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
}
static int acpi_ec_add(struct acpi_device *device)
......@@ -705,7 +701,8 @@ static int acpi_ec_add(struct acpi_device *device)
if (!ec)
return -ENOMEM;
if (ec_parse_device(ec, device->handle)) {
if (ec_parse_device(device->handle, 0, ec, NULL) !=
AE_CTRL_TERMINATE) {
kfree(ec);
return -EINVAL;
}
......@@ -713,16 +710,13 @@ static int acpi_ec_add(struct acpi_device *device)
/* Check if we found the boot EC */
if (boot_ec) {
if (boot_ec->gpe == ec->gpe) {
/* We might have incorrect info for GL at boot time */
mutex_lock(&boot_ec->lock);
boot_ec->global_lock = ec->global_lock;
/* Copy handlers from new ec into boot ec */
list_splice(&ec->list, &boot_ec->list);
mutex_unlock(&boot_ec->lock);
kfree(ec);
ec = boot_ec;
ec_remove_handlers(boot_ec);
mutex_destroy(&boot_ec->lock);
kfree(boot_ec);
first_ec = boot_ec = NULL;
}
} else
}
if (!first_ec)
first_ec = ec;
ec->handle = device->handle;
acpi_driver_data(device) = ec;
......@@ -734,14 +728,14 @@ static int acpi_ec_add(struct acpi_device *device)
static int acpi_ec_remove(struct acpi_device *device, int type)
{
struct acpi_ec *ec;
struct acpi_ec_query_handler *handler;
struct acpi_ec_query_handler *handler, *tmp;
if (!device)
return -EINVAL;
ec = acpi_driver_data(device);
mutex_lock(&ec->lock);
list_for_each_entry(handler, &ec->list, node) {
list_for_each_entry_safe(handler, tmp, &ec->list, node) {
list_del(&handler->node);
kfree(handler);
}
......@@ -751,9 +745,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
if (ec == first_ec)
first_ec = NULL;
/* Don't touch boot EC */
if (boot_ec != ec)
kfree(ec);
return 0;
}
......@@ -817,9 +808,7 @@ static int acpi_ec_start(struct acpi_device *device)
if (!ec)
return -EINVAL;
/* Boot EC is already working */
if (ec != boot_ec)
ret = ec_install_handlers(ec);
ret = ec_install_handlers(ec);
/* EC is fully operational, allow queries */
atomic_set(&ec->query_pending, 0);
......@@ -829,7 +818,6 @@ static int acpi_ec_start(struct acpi_device *device)
static int acpi_ec_stop(struct acpi_device *device, int type)
{
acpi_status status;
struct acpi_ec *ec;
if (!device)
......@@ -838,21 +826,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
ec = acpi_driver_data(device);
if (!ec)
return -EINVAL;
/* Don't touch boot EC */
if (ec == boot_ec)
return 0;
status = acpi_remove_address_space_handler(ec->handle,
ACPI_ADR_SPACE_EC,
&acpi_ec_space_handler);
if (ACPI_FAILURE(status))
return -ENODEV;
status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
if (ACPI_FAILURE(status))
return -ENODEV;
ec_remove_handlers(ec);
return 0;
}
......@@ -868,18 +842,21 @@ int __init acpi_ec_ecdt_probe(void)
/*
* Generate a boot ec context
*/
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_FAILURE(status))
goto error;
printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
boot_ec->handle = ACPI_ROOT_OBJECT;
if (ACPI_SUCCESS(status)) {
printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
boot_ec->handle = ACPI_ROOT_OBJECT;
} else {
printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
boot_ec, NULL);
if (ACPI_FAILURE(status))
goto error;
}
ret = ec_install_handlers(boot_ec);
if (!ret) {
......
......@@ -108,7 +108,7 @@ static const struct file_operations acpi_system_event_ops = {
};
#ifdef CONFIG_NET
unsigned int acpi_event_seqnum;
static unsigned int acpi_event_seqnum;
struct acpi_genl_event {
acpi_device_class device_class;
char bus_id[15];
......
......@@ -969,11 +969,17 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
}
if (pr->flags.bm_check) {
/* bus mastering control is necessary */
if (!pr->flags.bm_control) {
/* In this case we enter C3 without bus mastering */
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"C3 support without bus mastering control\n"));
if (pr->flags.has_cst != 1) {
/* bus mastering control is necessary */
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"C3 support requires BM control\n"));
return;
} else {
/* Here we enter C3 without bus mastering */
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"C3 support without BM control\n"));
}
}
} else {
/*
......
......@@ -539,7 +539,7 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
}
int acpi_processor_preregister_performance(
struct acpi_processor_performance **performance)
struct acpi_processor_performance *performance)
{
int count, count_target;
int retval = 0;
......@@ -567,12 +567,12 @@ int acpi_processor_preregister_performance(
continue;
}
if (!performance || !performance[i]) {
if (!performance || !percpu_ptr(performance, i)) {
retval = -EINVAL;
continue;
}
pr->performance = performance[i];
pr->performance = percpu_ptr(performance, i);
cpu_set(i, pr->performance->shared_cpu_map);
if (acpi_processor_get_psd(pr)) {
retval = -EINVAL;
......
......@@ -1415,7 +1415,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
char dir_name[32];
int do_battery_init = 0, do_ac_init = 0;
int old_remaining_capacity = 0;
int update_ac = 1, update_battery = 1;
int update_battery = 1;
int up_tm = update_time;
if (sbs_zombie(sbs)) {
......@@ -1435,10 +1435,6 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
sbs->run_cnt++;
if (!update_ac && !update_battery) {
goto end;
}
old_ac_present = sbs->ac.ac_present;
result = acpi_ac_get_present(sbs);
......
......@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("tbxface")
/* Local prototypes */
static acpi_status acpi_tb_load_namespace(void);
static int no_auto_ssdt;
/*******************************************************************************
*
* FUNCTION: acpi_allocate_root_table
......@@ -536,6 +538,10 @@ static acpi_status acpi_tb_load_namespace(void)
ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
acpi_tb_print_table_header(0, table);
if (no_auto_ssdt == 0) {
printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
}
}
status =
......@@ -577,6 +583,11 @@ static acpi_status acpi_tb_load_namespace(void)
continue;
}
if (no_auto_ssdt) {
printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
continue;
}
/* Ignore errors while loading tables, get as many as possible */
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
......@@ -622,3 +633,15 @@ acpi_status acpi_load_tables(void)
}
ACPI_EXPORT_SYMBOL(acpi_load_tables)
static int __init acpi_no_auto_ssdt_setup(char *s) {
printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
no_auto_ssdt = 1;
return 1;
}
__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
......@@ -33,6 +33,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
......@@ -74,10 +75,26 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
MODULE_LICENSE("GPL");
static int act;
module_param(act, int, 0644);
MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n");
static int tzp;
module_param(tzp, int, 0);
module_param(tzp, int, 0444);
MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
static int nocrt;
module_param(nocrt, int, 0);
MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n");
static int off;
module_param(off, int, 0);
MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n");
static int psv;
module_param(psv, int, 0644);
MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n");
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
static int acpi_thermal_resume(struct acpi_device *device);
......@@ -339,9 +356,16 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
/* Passive: Processors (optional) */
status =
acpi_evaluate_integer(tz->device->handle, "_PSV", NULL,
&tz->trips.passive.temperature);
if (psv == -1) {
status = AE_SUPPORT;
} else if (psv > 0) {
tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv);
status = AE_OK;
} else {
status = acpi_evaluate_integer(tz->device->handle,
"_PSV", NULL, &tz->trips.passive.temperature);
}
if (ACPI_FAILURE(status)) {
tz->trips.passive.flags.valid = 0;
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
......@@ -386,11 +410,33 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
status =
acpi_evaluate_integer(tz->device->handle, name, NULL,
&tz->trips.active[i].temperature);
if (ACPI_FAILURE(status))
if (act == -1)
break; /* disable all active trip points */
status = acpi_evaluate_integer(tz->device->handle,
name, NULL, &tz->trips.active[i].temperature);
if (ACPI_FAILURE(status)) {
if (i == 0) /* no active trip points */
break;
if (act <= 0) /* no override requested */
break;
if (i == 1) { /* 1 trip point */
tz->trips.active[0].temperature =
CELSIUS_TO_KELVIN(act);
} else { /* multiple trips */
/*
* Don't allow override higher than
* the next higher trip point
*/
tz->trips.active[i - 1].temperature =
(tz->trips.active[i - 2].temperature <
CELSIUS_TO_KELVIN(act) ?
tz->trips.active[i - 2].temperature :
CELSIUS_TO_KELVIN(act));
}
break;
}
name[2] = 'L';
status =
......@@ -427,7 +473,7 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz)
static int acpi_thermal_critical(struct acpi_thermal *tz)
{
if (!tz || !tz->trips.critical.flags.valid)
if (!tz || !tz->trips.critical.flags.valid || nocrt)
return -EINVAL;
if (tz->temperature >= tz->trips.critical.temperature) {
......@@ -449,7 +495,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
static int acpi_thermal_hot(struct acpi_thermal *tz)
{
if (!tz || !tz->trips.hot.flags.valid)
if (!tz || !tz->trips.hot.flags.valid || nocrt)
return -EINVAL;
if (tz->temperature >= tz->trips.hot.temperature) {
......@@ -824,12 +870,14 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
goto end;
if (tz->trips.critical.flags.valid)
seq_printf(seq, "critical (S5): %ld C\n",
KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
seq_printf(seq, "critical (S5): %ld C%s",
KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
nocrt ? " <disabled>\n" : "\n");
if (tz->trips.hot.flags.valid)
seq_printf(seq, "hot (S4): %ld C\n",
KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
seq_printf(seq, "hot (S4): %ld C%s",
KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
nocrt ? " <disabled>\n" : "\n");
if (tz->trips.passive.flags.valid) {
seq_printf(seq,
......@@ -1281,11 +1329,78 @@ static int acpi_thermal_resume(struct acpi_device *device)
return AE_OK;
}
#ifdef CONFIG_DMI
static int thermal_act(struct dmi_system_id *d) {
if (act == 0) {
printk(KERN_NOTICE "ACPI: %s detected: "
"disabling all active thermal trip points\n", d->ident);
act = -1;
}
return 0;
}
static int thermal_tzp(struct dmi_system_id *d) {
if (tzp == 0) {
printk(KERN_NOTICE "ACPI: %s detected: "
"enabling thermal zone polling\n", d->ident);
tzp = 300; /* 300 dS = 30 Seconds */
}
return 0;
}
static int thermal_psv(struct dmi_system_id *d) {
if (psv == 0) {
printk(KERN_NOTICE "ACPI: %s detected: "
"disabling all passive thermal trip points\n", d->ident);
psv = -1;
}
return 0;
}
static struct dmi_system_id thermal_dmi_table[] __initdata = {
/*
* Award BIOS on this AOpen makes thermal control almost worthless.
* http://bugzilla.kernel.org/show_bug.cgi?id=8842
*/
{
.callback = thermal_act,
.ident = "AOpen i915GMm-HFS",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
},
},
{
.callback = thermal_psv,
.ident = "AOpen i915GMm-HFS",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
},
},
{
.callback = thermal_tzp,
.ident = "AOpen i915GMm-HFS",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
},
},
{}
};
#endif /* CONFIG_DMI */
static int __init acpi_thermal_init(void)
{
int result = 0;
dmi_check_system(thermal_dmi_table);
if (off) {
printk(KERN_NOTICE "ACPI: thermal control disabled\n");
return -ENODEV;
}
acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
if (!acpi_thermal_dir)
return -ENODEV;
......
......@@ -1147,10 +1147,15 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type)
return 0;
}
const static struct acpi_device_id sonypi_device_ids[] = {
{"SNY6001", 0},
{"", 0},
};
static struct acpi_driver sonypi_acpi_driver = {
.name = "sonypi",
.class = "hkey",
.ids = "SNY6001",
.ids = sonypi_device_ids,
.ops = {
.add = sonypi_acpi_add,
.remove = sonypi_acpi_remove,
......
......@@ -200,14 +200,22 @@ config THINKPAD_ACPI_BAY
config THINKPAD_ACPI_INPUT_ENABLED
bool "Enable input layer support by default"
depends on THINKPAD_ACPI
default y
default n
---help---
Enables hot key handling over the input layer by default. If unset,
the driver does not enable any hot key handling by default, and also
starts up with a mostly empty keymap.
If you are not sure, say Y here. Say N to retain the deprecated
behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21.
This option enables thinkpad-acpi hot key handling over the input
layer at driver load time. When it is unset, the driver does not
enable hot key handling by default, and also starts up with a mostly
empty keymap.
This option should be enabled if you have a new enough HAL or other
userspace support that properly handles the thinkpad-acpi event
device. It auto-tunes the hot key support to those reported by the
firmware and enables it automatically.
If unsure, say N here to retain the old behaviour of ibm-acpi, and
thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and
set up the thinkpad-acpi hot key handling using the sysfs interace
after loading the driver.
endif # MISC_DEVICES
......@@ -845,7 +845,7 @@ static struct sony_nc_event sony_C_events[] = {
};
/* SNC-only model map */
struct dmi_system_id sony_nc_ids[] = {
static struct dmi_system_id sony_nc_ids[] = {
{
.ident = "Sony Vaio FE Series",
.callback = sony_nc_C_enable,
......@@ -942,6 +942,11 @@ 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))
printk(KERN_WARNING DRV_PFX "unable to restore brightness level");
/* re-initialize models with specific requirements */
dmi_check_system(sony_nc_ids);
......
......@@ -4668,12 +4668,15 @@ static int __init thinkpad_acpi_module_init(void)
thinkpad_acpi_module_exit();
return ret;
}
tp_features.platform_drv_registered = 1;
ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
if (ret) {
printk(IBM_ERR "unable to create sysfs driver attributes\n");
thinkpad_acpi_module_exit();
return ret;
}
tp_features.platform_drv_attrs_registered = 1;
/* Device initialization */
......@@ -4756,8 +4759,11 @@ static void thinkpad_acpi_module_exit(void)
if (tpacpi_pdev)
platform_device_unregister(tpacpi_pdev);
tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
platform_driver_unregister(&tpacpi_pdriver);
if (tp_features.platform_drv_attrs_registered)
tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
if (tp_features.platform_drv_registered)
platform_driver_unregister(&tpacpi_pdriver);
if (proc_dir)
remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
......
......@@ -246,6 +246,8 @@ static struct {
u16 wan:1;
u16 fan_ctrl_status_undef:1;
u16 input_device_registered:1;
u16 platform_drv_registered:1;
u16 platform_drv_attrs_registered:1;
} tp_features;
struct thinkpad_id_data {
......
......@@ -232,7 +232,7 @@ struct acpi_processor_errata {
extern int acpi_processor_preregister_performance(struct
acpi_processor_performance
**performance);
*performance);
extern int acpi_processor_register_performance(struct acpi_processor_performance
*performance, unsigned int cpu);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册