summaryrefslogtreecommitdiff
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig14
-rw-r--r--drivers/acpi/ac.c5
-rw-r--r--drivers/acpi/asus_acpi.c2
-rw-r--r--drivers/acpi/battery.c52
-rw-r--r--drivers/acpi/bus.c10
-rw-r--r--drivers/acpi/button.c2
-rw-r--r--drivers/acpi/ec.c47
-rw-r--r--drivers/acpi/event.c22
-rw-r--r--drivers/acpi/hardware/hwsleep.c19
-rw-r--r--drivers/acpi/namespace/nsxfeval.c2
-rw-r--r--drivers/acpi/processor_core.c13
-rw-r--r--drivers/acpi/sbs.c3
-rw-r--r--drivers/acpi/scan.c5
-rw-r--r--drivers/acpi/sleep/main.c2
-rw-r--r--drivers/acpi/tables/tbutils.c71
-rw-r--r--drivers/acpi/thermal.c67
-rw-r--r--drivers/acpi/utilities/utglobal.c1
-rw-r--r--drivers/acpi/video.c109
18 files changed, 362 insertions, 84 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f1372de4ce79..574259476fbf 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -68,6 +68,20 @@ config ACPI_PROCFS
Say N to delete /proc/acpi/ files that have moved to /sys/
+config ACPI_PROC_EVENT
+ bool "Deprecated /proc/acpi/event support"
+ depends on PROC_FS
+ ---help---
+ A user-space daemon, acpi, typically read /proc/acpi/event
+ and handled all ACPI sub-system generated events.
+
+ These events are now delivered to user-space via
+ either the input layer, or as netlink events.
+
+ This build option enables the old code for for legacy
+ user-space implementation. After some time, this will
+ be moved under CONFIG_ACPI_PROCFS, and then deleted.
+
config ACPI_AC
tristate "AC Adapter"
depends on X86
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index d8b35093527a..26d70702b313 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -204,7 +204,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
case ACPI_NOTIFY_BUS_CHECK:
case ACPI_NOTIFY_DEVICE_CHECK:
acpi_ac_get_state(ac);
- acpi_bus_generate_event(device, event, (u32) ac->state);
+ acpi_bus_generate_proc_event(device, event, (u32) ac->state);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ (u32) ac->state);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 86fd142f4bf3..d915fec9bf63 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1069,7 +1069,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
hotk->brightness = (event & ~((u32) BR_DOWN));
}
- acpi_bus_generate_event(hotk->device, event,
+ acpi_bus_generate_proc_event(hotk->device, event,
hotk->event_count[event % 128]++);
return;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index d7b499fe0cd9..9b2c0f74f869 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,14 +129,13 @@ 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)
@@ -236,10 +235,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
return 0;
/* Evaluate _BIF */
- mutex_lock(&battery->lock);
- status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
- NULL, &buffer);
- mutex_unlock(&battery->lock);
+
+ status =
+ acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
+ &buffer);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
return -ENODEV;
@@ -286,10 +285,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
return 0;
/* Evaluate _BST */
- mutex_lock(&battery->lock);
- status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
- NULL, &buffer);
- mutex_unlock(&battery->lock);
+
+ status =
+ acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
+ &buffer);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
return -ENODEV;
@@ -337,10 +336,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
arg0.integer.value = alarm;
- mutex_lock(&battery->lock);
- status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+ status =
+ acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
&arg_list, NULL);
- mutex_unlock(&battery->lock);
if (ACPI_FAILURE(status))
return -ENODEV;
@@ -660,6 +658,8 @@ 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,7 +688,9 @@ acpi_battery_write_alarm(struct file *file,
acpi_battery_check_result(battery, result);
if (!result)
- return count;
+ result = count;
+
+ mutex_unlock(&battery->mutex);
return result;
}
@@ -712,6 +714,8 @@ 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]);
@@ -729,6 +733,7 @@ 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;
}
@@ -867,8 +872,11 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
case ACPI_NOTIFY_DEVICE_CHECK:
device = battery->device;
acpi_battery_notify_update(battery);
- acpi_bus_generate_event(device, event,
+ acpi_bus_generate_proc_event(device, event,
acpi_battery_present(battery));
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ acpi_battery_present(battery));
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -892,7 +900,10 @@ static int acpi_battery_add(struct acpi_device *device)
if (!battery)
return -ENOMEM;
- mutex_init(&battery->lock);
+ mutex_init(&battery->mutex);
+
+ mutex_lock(&battery->mutex);
+
battery->device = device;
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
@@ -928,6 +939,7 @@ static int acpi_battery_add(struct acpi_device *device)
kfree(battery);
}
+ mutex_unlock(&battery->mutex);
return result;
}
@@ -942,6 +954,8 @@ 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);
@@ -952,7 +966,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
kfree(battery->bst_data.pointer);
- mutex_destroy(&battery->lock);
+ mutex_unlock(&battery->mutex);
+
+ mutex_destroy(&battery->mutex);
kfree(battery);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6b2658c96242..9ba778a2b484 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -276,6 +276,7 @@ EXPORT_SYMBOL(acpi_bus_set_power);
Event Management
-------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_PROC_EVENT
static DEFINE_SPINLOCK(acpi_bus_event_lock);
LIST_HEAD(acpi_bus_event_list);
@@ -283,7 +284,7 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
extern int event_is_open;
-int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
{
struct acpi_bus_event *event = NULL;
unsigned long flags = 0;
@@ -292,10 +293,6 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
if (!device)
return -EINVAL;
- if (acpi_bus_generate_genetlink_event(device, type, data))
- printk(KERN_WARNING PREFIX
- "Failed to generate an ACPI event via genetlink!\n");
-
/* drop event on the floor if no one's listening */
if (!event_is_open)
return 0;
@@ -318,7 +315,7 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
return 0;
}
-EXPORT_SYMBOL(acpi_bus_generate_event);
+EXPORT_SYMBOL(acpi_bus_generate_proc_event);
int acpi_bus_receive_event(struct acpi_bus_event *event)
{
@@ -364,6 +361,7 @@ int acpi_bus_receive_event(struct acpi_bus_event *event)
}
EXPORT_SYMBOL(acpi_bus_receive_event);
+#endif /* CONFIG_ACPI_PROC_EVENT */
/* --------------------------------------------------------------------------
Notification Handling
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 540581338ef5..2e79a3395ecf 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -284,7 +284,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
}
input_sync(input);
- acpi_bus_generate_event(button->device, event,
+ acpi_bus_generate_proc_event(button->device, event,
++button->pushed);
break;
default:
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 56bee9e065cf..43749c86861f 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -696,14 +696,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
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)
{
struct acpi_ec *ec = NULL;
@@ -727,13 +719,16 @@ 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) {
- ec_remove_handlers(boot_ec);
- mutex_destroy(&boot_ec->lock);
- kfree(boot_ec);
- first_ec = boot_ec = NULL;
+ /* 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;
}
- }
- if (!first_ec)
+ } else
first_ec = ec;
ec->handle = device->handle;
acpi_driver_data(device) = ec;
@@ -762,6 +757,9 @@ 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;
}
@@ -825,7 +823,9 @@ static int acpi_ec_start(struct acpi_device *device)
if (!ec)
return -EINVAL;
- ret = ec_install_handlers(ec);
+ /* Boot EC is already working */
+ if (ec != boot_ec)
+ ret = ec_install_handlers(ec);
/* EC is fully operational, allow queries */
atomic_set(&ec->query_pending, 0);
@@ -835,6 +835,7 @@ 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)
@@ -843,7 +844,21 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
ec = acpi_driver_data(device);
if (!ec)
return -EINVAL;
- ec_remove_handlers(ec);
+
+ /* 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;
+
return 0;
}
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 95637a4ff782..a2b9304596ce 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -17,6 +17,7 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("event");
+#ifdef CONFIG_ACPI_PROC_EVENT
/* Global vars for handling event proc entry */
static DEFINE_SPINLOCK(acpi_system_event_lock);
int event_is_open = 0;
@@ -106,6 +107,7 @@ static const struct file_operations acpi_system_event_ops = {
.release = acpi_system_close_event,
.poll = acpi_system_poll_event,
};
+#endif /* CONFIG_ACPI_PROC_EVENT */
#ifdef CONFIG_NET
static unsigned int acpi_event_seqnum;
@@ -147,7 +149,8 @@ static struct genl_multicast_group acpi_event_mcgrp = {
.name = ACPI_GENL_MCAST_GROUP_NAME,
};
-int acpi_bus_generate_genetlink_event(struct acpi_device *device,
+int acpi_bus_generate_netlink_event(const char *device_class,
+ const char *bus_id,
u8 type, int data)
{
struct sk_buff *skb;
@@ -191,8 +194,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device,
memset(event, 0, sizeof(struct acpi_genl_event));
- strcpy(event->device_class, device->pnp.device_class);
- strcpy(event->bus_id, device->dev.bus_id);
+ strcpy(event->device_class, device_class);
+ strcpy(event->bus_id, bus_id);
event->type = type;
event->data = data;
@@ -211,6 +214,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device,
return 0;
}
+EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
+
static int acpi_event_genetlink_init(void)
{
int result;
@@ -228,12 +233,15 @@ static int acpi_event_genetlink_init(void)
}
#else
-int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type,
- int data)
+int acpi_bus_generate_netlink_event(const char *device_class,
+ const char *bus_id,
+ u8 type, int data)
{
return 0;
}
+EXPORT_SYMBOL(acpi_generate_netlink_event);
+
static int acpi_event_genetlink_init(void)
{
return -ENODEV;
@@ -242,7 +250,9 @@ static int acpi_event_genetlink_init(void)
static int __init acpi_event_init(void)
{
+#ifdef CONFIG_ACPI_PROC_EVENT
struct proc_dir_entry *entry;
+#endif
int error = 0;
if (acpi_disabled)
@@ -254,12 +264,14 @@ static int __init acpi_event_init(void)
printk(KERN_WARNING PREFIX
"Failed to create genetlink family for ACPI event\n");
+#ifdef CONFIG_ACPI_PROC_EVENT
/* 'event' [R] */
entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
if (entry)
entry->proc_fops = &acpi_system_event_ops;
else
return -ENODEV;
+#endif
return 0;
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 76c525dc590b..cf69c0040a39 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -576,13 +576,10 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
}
- status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
- ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
- }
- /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
-
/*
+ * GPEs must be enabled before _WAK is called as GPEs
+ * might get fired there
+ *
* Restore the GPEs:
* 1) Disable/Clear all GPEs
* 2) Enable all runtime GPEs
@@ -591,13 +588,19 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- acpi_gbl_system_awake_and_running = TRUE;
-
status = acpi_hw_enable_all_runtime_gpes();
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
+ status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
+ }
+ /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
+
+ acpi_gbl_system_awake_and_running = TRUE;
+
/* Enable power button */
(void)
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index ab65b2c2560e..f39fbc6b9237 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -540,7 +540,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
******************************************************************************/
acpi_status
-acpi_get_devices(char *HID,
+acpi_get_devices(const char *HID,
acpi_walk_callback user_function,
void *context, void **return_value)
{
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 498422343f38..e944aaee4e06 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -698,16 +698,23 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
acpi_processor_ppc_has_changed(pr);
- acpi_bus_generate_event(device, event,
+ acpi_bus_generate_proc_event(device, event,
pr->performance_platform_limit);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
+ pr->performance_platform_limit);
break;
case ACPI_PROCESSOR_NOTIFY_POWER:
acpi_processor_cst_has_changed(pr);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
break;
case ACPI_PROCESSOR_NOTIFY_THROTTLING:
acpi_processor_tstate_has_changed(pr);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 82c3a550016d..a578986e3214 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -440,11 +440,12 @@ static int acpi_sbs_generate_event(struct acpi_device *device,
strcpy(acpi_device_bid(device), bid);
strcpy(acpi_device_class(device), class);
- result = acpi_bus_generate_event(device, event, state);
+ result = acpi_bus_generate_proc_event(device, event, state);
strcpy(acpi_device_bid(device), bid_saved);
strcpy(acpi_device_class(device), class_saved);
+ acpi_bus_generate_netlink_event(class, bid, event, state);
return result;
}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index be74347d1354..64620d668742 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -35,8 +35,9 @@ struct acpi_device_bus_id{
* e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
* char *modalias: "acpi:IBM0001:ACPI0001"
*/
-int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){
-
+static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
+ int size)
+{
int len;
if (!acpi_dev->flags.hardware_id)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index e8cff5dd4cbc..c52ade816fb4 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -305,7 +305,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
unsigned long d_min, d_max;
if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
- printk(KERN_ERR "ACPI handle has no context!\n");
+ printk(KERN_DEBUG "ACPI handle has no context!\n");
return -ENODEV;
}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 1da64b4518c0..8cc9492ffbf2 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils")
static acpi_physical_address
acpi_tb_get_root_table_entry(u8 * table_entry,
acpi_native_uint table_entry_size);
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_check_xsdt
+ *
+ * PARAMETERS: address - Pointer to the XSDT
+ *
+ * RETURN: status
+ * AE_OK - XSDT is okay
+ * AE_NO_MEMORY - can't map XSDT
+ * AE_INVALID_TABLE_LENGTH - invalid table length
+ * AE_NULL_ENTRY - XSDT has NULL entry
+ *
+ * DESCRIPTION: validate XSDT
+******************************************************************************/
+
+static acpi_status
+acpi_tb_check_xsdt(acpi_physical_address address)
+{
+ struct acpi_table_header *table;
+ u32 length;
+ u64 xsdt_entry_address;
+ u8 *table_entry;
+ u32 table_count;
+ int i;
+
+ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+ if (!table)
+ return AE_NO_MEMORY;
+
+ length = table->length;
+ acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+ if (length < sizeof(struct acpi_table_header))
+ return AE_INVALID_TABLE_LENGTH;
+
+ table = acpi_os_map_memory(address, length);
+ if (!table)
+ return AE_NO_MEMORY;
+
+ /* Calculate the number of tables described in XSDT */
+ table_count =
+ (u32) ((table->length -
+ sizeof(struct acpi_table_header)) / sizeof(u64));
+ table_entry =
+ ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
+ for (i = 0; i < table_count; i++) {
+ ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry);
+ if (!xsdt_entry_address) {
+ /* XSDT has NULL entry */
+ break;
+ }
+ table_entry += sizeof(u64);
+ }
+ acpi_os_unmap_memory(table, length);
+
+ if (i < table_count)
+ return AE_NULL_ENTRY;
+ else
+ return AE_OK;
+}
/*******************************************************************************
*
@@ -341,6 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;
+ acpi_physical_address rsdt_address;
u32 length;
u8 *table_entry;
acpi_status status;
@@ -369,6 +429,8 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
*/
address = (acpi_physical_address) rsdp->xsdt_physical_address;
table_entry_size = sizeof(u64);
+ rsdt_address = (acpi_physical_address)
+ rsdp->rsdt_physical_address;
} else {
/* Root table is an RSDT (32-bit physical addresses) */
@@ -382,6 +444,15 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
*/
acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
+ if (table_entry_size == sizeof(u64)) {
+ if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) {
+ /* XSDT has NULL entry, RSDT is used */
+ address = rsdt_address;
+ table_entry_size = sizeof(u32);
+ ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry,"
+ "using RSDT"));
+ }
+ }
/* Map the RSDT/XSDT table header to get the full table length */
table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 1e06159fd9c4..bc6d5866ef98 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -77,23 +77,27 @@ MODULE_LICENSE("GPL");
static int act;
module_param(act, int, 0644);
-MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n");
+MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
+
+static int crt;
+module_param(crt, int, 0644);
+MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
static int tzp;
module_param(tzp, int, 0444);
-MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
+MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
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");
+MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
static int off;
module_param(off, int, 0);
-MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n");
+MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
static int psv;
module_param(psv, int, 0644);
-MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n");
+MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
static int acpi_thermal_add(struct acpi_device *device);
static int acpi_thermal_remove(struct acpi_device *device, int type);
@@ -340,6 +344,20 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
tz->trips.critical.temperature));
}
+ if (tz->trips.critical.flags.valid == 1) {
+ if (crt == -1) {
+ tz->trips.critical.flags.valid = 0;
+ } else if (crt > 0) {
+ unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
+
+ /*
+ * Allow override to lower critical threshold
+ */
+ if (crt_k < tz->trips.critical.temperature)
+ tz->trips.critical.temperature = crt_k;
+ }
+ }
+
/* Critical Sleep (optional) */
status =
@@ -485,8 +503,12 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
printk(KERN_EMERG
"Critical temperature reached (%ld C), shutting down.\n",
KELVIN_TO_CELSIUS(tz->temperature));
- acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
+ acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
tz->trips.critical.flags.enabled);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ tz->device->dev.bus_id,
+ ACPI_THERMAL_NOTIFY_CRITICAL,
+ tz->trips.critical.flags.enabled);
orderly_poweroff(true);
@@ -504,8 +526,12 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
} else if (tz->trips.hot.flags.enabled)
tz->trips.hot.flags.enabled = 0;
- acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
+ acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
tz->trips.hot.flags.enabled);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ tz->device->dev.bus_id,
+ ACPI_THERMAL_NOTIFY_HOT,
+ tz->trips.hot.flags.enabled);
/* TBD: Call user-mode "sleep(S4)" function */
@@ -1067,9 +1093,9 @@ static int acpi_thermal_add_fs(struct acpi_device *device)
entry->owner = THIS_MODULE;
}
- /* 'trip_points' [R/W] */
+ /* 'trip_points' [R] */
entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
- S_IFREG | S_IRUGO | S_IWUSR,
+ S_IRUGO,
acpi_device_dir(device));
if (!entry)
return -ENODEV;
@@ -1149,12 +1175,16 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
case ACPI_THERMAL_NOTIFY_THRESHOLDS:
acpi_thermal_get_trip_points(tz);
acpi_thermal_check(tz);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
break;
case ACPI_THERMAL_NOTIFY_DEVICES:
if (tz->flags.devices)
acpi_thermal_get_devices(tz);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event, 0);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -1339,6 +1369,13 @@ static int thermal_act(struct dmi_system_id *d) {
}
return 0;
}
+static int thermal_nocrt(struct dmi_system_id *d) {
+
+ printk(KERN_NOTICE "ACPI: %s detected: "
+ "disabling all critical thermal trip point actions.\n", d->ident);
+ nocrt = 1;
+ return 0;
+}
static int thermal_tzp(struct dmi_system_id *d) {
if (tzp == 0) {
@@ -1387,6 +1424,14 @@ static struct dmi_system_id thermal_dmi_table[] __initdata = {
DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
},
},
+ {
+ .callback = thermal_nocrt,
+ .ident = "Gigabyte GA-7ZX",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
+ },
+ },
{}
};
#endif /* CONFIG_DMI */
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 1621655d6e2b..93ea8290b4f7 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -126,6 +126,7 @@ const char *acpi_format_exception(acpi_status status)
"Unknown exception code: 0x%8.8X", status));
exception = "UNKNOWN_STATUS_CODE";
+ dump_stack();
}
return (ACPI_CAST_PTR(const char, exception));
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d98701941981..3c9bb85a6a93 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -31,7 +31,7 @@
#include <linux/list.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-
+#include <linux/input.h>
#include <linux/backlight.h>
#include <linux/video_output.h>
#include <asm/uaccess.h>
@@ -138,6 +138,8 @@ struct acpi_video_bus {
struct semaphore sem;
struct list_head video_device_list;
struct proc_dir_entry *dir;
+ struct input_dev *input;
+ char phys[32]; /* for input device */
};
struct acpi_video_device_flags {
@@ -1764,6 +1766,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_video_bus *video = data;
struct acpi_device *device = NULL;
+ struct input_dev *input;
+ int keycode;
+
printk("video bus notify\n");
@@ -1771,11 +1776,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
return;
device = video->device;
+ input = video->input;
switch (event) {
case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
* most likely via hotkey. */
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1783,22 +1790,38 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
acpi_video_device_enumerate(video);
acpi_video_device_rebind(video);
acpi_video_switch_output(video, event);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_SWITCHVIDEOMODE;
break;
case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
+ acpi_video_switch_output(video, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_SWITCHVIDEOMODE;
+ break;
case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
+ acpi_video_switch_output(video, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_VIDEO_NEXT;
+ break;
case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
acpi_video_switch_output(video, event);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_VIDEO_PREV;
break;
default:
+ keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+
return;
}
@@ -1806,38 +1829,65 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_video_device *video_device = data;
struct acpi_device *device = NULL;
+ struct acpi_video_bus *bus;
+ struct input_dev *input;
+ int keycode;
if (!video_device)
return;
device = video_device->dev;
+ bus = video_device->video;
+ input = bus->input;
switch (event) {
- case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
- case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
- acpi_bus_generate_event(device, event, 0);
- break;
case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESS_CYCLE;
+ break;
case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESSUP;
+ break;
case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESSDOWN;
+ break;
case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
+ acpi_video_switch_brightness(video_device, event);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_BRIGHTNESS_ZERO;
+ break;
case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
acpi_video_switch_brightness(video_device, event);
- acpi_bus_generate_event(device, event, 0);
+ acpi_bus_generate_proc_event(device, event, 0);
+ keycode = KEY_DISPLAY_OFF;
break;
default:
+ keycode = KEY_UNKNOWN;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
+
+ input_report_key(input, keycode, 1);
+ input_sync(input);
+ input_report_key(input, keycode, 0);
+ input_sync(input);
+
return;
}
+static int instance;
static int acpi_video_bus_add(struct acpi_device *device)
{
int result = 0;
acpi_status status = 0;
struct acpi_video_bus *video = NULL;
+ struct input_dev *input;
if (!device)
@@ -1847,6 +1897,13 @@ static int acpi_video_bus_add(struct acpi_device *device)
if (!video)
return -ENOMEM;
+ /* a hack to fix the duplicate name "VID" problem on T61 */
+ if (!strcmp(device->pnp.bus_id, "VID")) {
+ if (instance)
+ device->pnp.bus_id[3] = '0' + instance;
+ instance ++;
+ }
+
video->device = device;
strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
@@ -1881,6 +1938,39 @@ static int acpi_video_bus_add(struct acpi_device *device)
goto end;
}
+
+ video->input = input = input_allocate_device();
+
+ snprintf(video->phys, sizeof(video->phys),
+ "%s/video/input0", acpi_device_hid(video->device));
+
+ input->name = acpi_device_name(video->device);
+ input->phys = video->phys;
+ input->id.bustype = BUS_HOST;
+ input->id.product = 0x06;
+ input->evbit[0] = BIT(EV_KEY);
+ set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
+ set_bit(KEY_VIDEO_NEXT, input->keybit);
+ set_bit(KEY_VIDEO_PREV, input->keybit);
+ set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
+ set_bit(KEY_BRIGHTNESSUP, input->keybit);
+ set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
+ set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
+ set_bit(KEY_DISPLAY_OFF, input->keybit);
+ set_bit(KEY_UNKNOWN, input->keybit);
+ result = input_register_device(input);
+ if (result) {
+ acpi_remove_notify_handler(video->device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_video_bus_notify);
+ acpi_video_bus_stop_devices(video);
+ acpi_video_bus_put_devices(video);
+ kfree(video->attached_array);
+ acpi_video_bus_remove_fs(device);
+ goto end;
+ }
+
+
printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
video->flags.multihead ? "yes" : "no",
@@ -1914,6 +2004,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
acpi_video_bus_put_devices(video);
acpi_video_bus_remove_fs(device);
+ input_unregister_device(video->input);
kfree(video->attached_array);
kfree(video);