diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 14 | ||||
-rw-r--r-- | drivers/acpi/ac.c | 5 | ||||
-rw-r--r-- | drivers/acpi/asus_acpi.c | 2 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 52 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 10 | ||||
-rw-r--r-- | drivers/acpi/button.c | 2 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 47 | ||||
-rw-r--r-- | drivers/acpi/event.c | 22 | ||||
-rw-r--r-- | drivers/acpi/hardware/hwsleep.c | 19 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfeval.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 13 | ||||
-rw-r--r-- | drivers/acpi/sbs.c | 3 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 5 | ||||
-rw-r--r-- | drivers/acpi/sleep/main.c | 2 | ||||
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 71 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 67 | ||||
-rw-r--r-- | drivers/acpi/utilities/utglobal.c | 1 | ||||
-rw-r--r-- | drivers/acpi/video.c | 109 |
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); |