diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 22 | ||||
-rw-r--r-- | Documentation/thinkpad-acpi.txt | 4 | ||||
-rw-r--r-- | drivers/acpi/asus_acpi.c | 1 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 47 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxface.c | 23 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 143 | ||||
-rw-r--r-- | drivers/char/sonypi.c | 7 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 22 | ||||
-rw-r--r-- | drivers/misc/sony-laptop.c | 7 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 10 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 2 |
11 files changed, 231 insertions, 57 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a326487a3ab..975f029be25 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -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'] diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index 6711fbcf408..eb2f5986e1e 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt @@ -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 -------------- diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 9c4bd220c44..86fd142f4bf 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1192,6 +1192,7 @@ static int asus_hotk_get_info(void) break; default: kfree(model); + model = NULL; break; } } diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 81651032791..d7b499fe0cd 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -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); diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 5b302c4e293..a9e3331fee5 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -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); diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5a62de1b7f2..1e06159fd9c 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -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; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 73037a4d3c5..aeec67e2726 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -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, diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index aaaa61ea421..518d5d33546 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -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 diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 14ee06c8f12..91da6880ae9 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -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); diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index fa80f355e52..f6cd34a3dba 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -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); diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index 88af089d649..eee8809a50d 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h @@ -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 { |