diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/asus_acpi.c | 55 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 5 | ||||
-rw-r--r-- | drivers/acpi/bay.c | 6 | ||||
-rw-r--r-- | drivers/acpi/debug.c | 57 | ||||
-rw-r--r-- | drivers/acpi/dock.c | 6 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 19 | ||||
-rw-r--r-- | drivers/acpi/events/evgpe.c | 8 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 8 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 17 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 65 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 102 | ||||
-rw-r--r-- | drivers/acpi/sleep/main.c | 15 | ||||
-rw-r--r-- | drivers/acpi/sleep/proc.c | 46 | ||||
-rw-r--r-- | drivers/acpi/tables/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxfroot.c | 4 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 17 | ||||
-rw-r--r-- | drivers/acpi/utilities/utresrc.c | 2 | ||||
-rw-r--r-- | drivers/acpi/video.c | 49 |
18 files changed, 371 insertions, 112 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index d915fec..d25ef96 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -142,6 +142,7 @@ struct asus_hotk { xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N A4S, //Z81sp //(Centrino) + F3Sa, END_MODEL } model; //Models currently supported u16 event_count[128]; //count for each event TODO make this better @@ -405,7 +406,20 @@ static struct model_data model_conf[END_MODEL] = { .brightness_get = "GPLV", .mt_bt_switch = "BLED", .mt_wled = "WLED" - } + }, + + { + .name = "F3Sa", + .mt_bt_switch = "BLED", + .mt_wled = "WLED", + .mt_mled = "MLED", + .brightness_get = "GPLV", + .brightness_set = "SPLV", + .mt_lcd_switch = "\\_SB.PCI0.SBRG.EC0._Q10", + .lcd_status = "\\_SB.PCI0.SBRG.EC0.RPIN", + .display_get = "\\ADVG", + .display_set = "SDSP", + }, }; @@ -710,15 +724,8 @@ static int get_lcd_state(void) { int lcd = 0; - if (hotk->model != L3H) { - /* We don't have to check anything if we are here */ - if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) - printk(KERN_WARNING - "Asus ACPI: Error reading LCD status\n"); - - if (hotk->model == L2D) - lcd = ~lcd; - } else { /* L3H and the like have to be handled differently */ + if (hotk->model == L3H) { + /* L3H and the like have to be handled differently */ acpi_status status = 0; struct acpi_object_list input; union acpi_object mt_params[2]; @@ -745,6 +752,32 @@ static int get_lcd_state(void) if (out_obj.type == ACPI_TYPE_INTEGER) /* That's what the AML code does */ lcd = out_obj.integer.value >> 8; + } else if (hotk->model == F3Sa) { + unsigned long tmp; + union acpi_object param; + struct acpi_object_list input; + acpi_status status; + + /* Read pin 11 */ + param.type = ACPI_TYPE_INTEGER; + param.integer.value = 0x11; + input.count = 1; + input.pointer = ¶m; + + status = acpi_evaluate_integer(NULL, hotk->methods->lcd_status, + &input, &tmp); + if (status != AE_OK) + return -1; + + lcd = tmp; + } else { + /* We don't have to check anything if we are here */ + if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd)) + printk(KERN_WARNING + "Asus ACPI: Error reading LCD status\n"); + + if (hotk->model == L2D) + lcd = ~lcd; } return (lcd & 1); @@ -1134,6 +1167,8 @@ static int asus_model_match(char *model) return W5A; else if (strncmp(model, "A4S", 3) == 0) return A4S; + else if (strncmp(model, "F3Sa", 4) == 0) + return F3Sa; else return END_MODEL; } diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index c4a769d..f6215e8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -194,6 +194,9 @@ static int acpi_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_MANUFACTURER: val->strval = battery->oem_info; break; + case POWER_SUPPLY_PROP_SERIAL_NUMBER: + val->strval = battery->serial_number; + break; default: return -EINVAL; } @@ -212,6 +215,7 @@ static enum power_supply_property charge_battery_props[] = { POWER_SUPPLY_PROP_CHARGE_NOW, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, }; static enum power_supply_property energy_battery_props[] = { @@ -226,6 +230,7 @@ static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_ENERGY_NOW, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, }; #endif diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c index 6daf6088..4777114 100644 --- a/drivers/acpi/bay.c +++ b/drivers/acpi/bay.c @@ -46,6 +46,12 @@ MODULE_LICENSE("GPL"); printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } static void bay_notify(acpi_handle handle, u32 event, void *data); +static const struct acpi_device_id bay_device_ids[] = { + {"LNXIOBAY", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, bay_device_ids); + struct bay { acpi_handle handle; char *name; diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index bf513e0..6df564f 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -130,6 +130,63 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) { module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); +static char trace_method_name[6]; +module_param_string(trace_method_name, trace_method_name, 6, 0644); +static unsigned int trace_debug_layer; +module_param(trace_debug_layer, uint, 0644); +static unsigned int trace_debug_level; +module_param(trace_debug_level, uint, 0644); + +static int param_set_trace_state(const char *val, struct kernel_param *kp) +{ + int result = 0; + + if (!strncmp(val, "enable", strlen("enable") - 1)) { + result = acpi_debug_trace(trace_method_name, trace_debug_level, + trace_debug_layer, 0); + if (result) + result = -EBUSY; + goto exit; + } + + if (!strncmp(val, "disable", strlen("disable") - 1)) { + int name = 0; + result = acpi_debug_trace((char *)&name, trace_debug_level, + trace_debug_layer, 0); + if (result) + result = -EBUSY; + goto exit; + } + + if (!strncmp(val, "1", 1)) { + result = acpi_debug_trace(trace_method_name, trace_debug_level, + trace_debug_layer, 1); + if (result) + result = -EBUSY; + goto exit; + } + + result = -EINVAL; +exit: + return result; +} + +static int param_get_trace_state(char *buffer, struct kernel_param *kp) +{ + if (!acpi_gbl_trace_method_name) + return sprintf(buffer, "disable"); + else { + if (acpi_gbl_trace_flags & 1) + return sprintf(buffer, "1"); + else + return sprintf(buffer, "enable"); + } + return 0; +} + +module_param_call(trace_state, param_set_trace_state, param_get_trace_state, + NULL, 0644); + /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 1dabdf4..b3dec21 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -51,6 +51,12 @@ static struct atomic_notifier_head dock_notifier_list; static struct platform_device *dock_device; static char dock_device_name[] = "dock"; +static const struct acpi_device_id dock_device_ids[] = { + {"LNXDOCK", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, dock_device_ids); + struct dock_station { acpi_handle handle; unsigned long last_dock_time; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 987b967..7222a18 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -573,7 +573,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, void *handler_context, void *region_context) { struct acpi_ec *ec = handler_context; - int result = 0, i = 0; + int result = 0, i; u8 temp = 0; if ((address > 0xFF) || !value || !handler_context) @@ -585,7 +585,18 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, if (bits != 8 && acpi_strict) return AE_BAD_PARAMETER; - while (bits - i > 0) { + acpi_ec_burst_enable(ec); + + if (function == ACPI_READ) { + result = acpi_ec_read(ec, address, &temp); + *value = temp; + } else { + temp = 0xff & (*value); + result = acpi_ec_write(ec, address, temp); + } + + for (i = 8; unlikely(bits - i > 0); i += 8) { + ++address; if (function == ACPI_READ) { result = acpi_ec_read(ec, address, &temp); (*value) |= ((acpi_integer)temp) << i; @@ -593,10 +604,10 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, temp = 0xff & ((*value) >> i); result = acpi_ec_write(ec, address, temp); } - i += 8; - ++address; } + acpi_ec_burst_disable(ec); + switch (result) { case -EINVAL: return AE_BAD_PARAMETER; diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index e22f4a9..056b788 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -270,18 +270,18 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) case ACPI_GPE_TYPE_WAKE_RUN: ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); - /*lint -fallthrough */ + /* fallthrough */ case ACPI_GPE_TYPE_RUNTIME: /* Disable the requested runtime GPE */ ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); - status = acpi_hw_write_gpe_enable_reg(gpe_event_info); - break; + + /* fallthrough */ default: - return_ACPI_STATUS(AE_BAD_PARAMETER); + acpi_hw_write_gpe_enable_reg(gpe_event_info); } return_ACPI_STATUS(AE_OK); diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index fde7ac8..9772a48 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -250,8 +250,12 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) "System description tables not found\n"); return 0; } - } else - return acpi_find_rsdp(); + } else { + acpi_physical_address pa = 0; + + acpi_find_root_pointer(&pa); + return pa; + } } void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e48ee4f..c53113e 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -812,11 +812,18 @@ static int is_processor_present(acpi_handle handle) status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) { - ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present")); - return 0; - } - return 1; + /* + * if a processor object does not have an _STA object, + * OSPM assumes that the processor is present. + */ + if (status == AE_NOT_FOUND) + return 1; + + if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) + return 1; + + ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present")); + return 0; } static diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index eb1f82f..32003fd 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -38,7 +38,7 @@ #include <linux/dmi.h> #include <linux/moduleparam.h> #include <linux/sched.h> /* need_resched() */ -#include <linux/latency.h> +#include <linux/pm_qos_params.h> #include <linux/clockchips.h> #include <linux/cpuidle.h> @@ -98,6 +98,9 @@ module_param(bm_history, uint, 0644); static int acpi_processor_set_power_policy(struct acpi_processor *pr); +#else /* CONFIG_CPU_IDLE */ +static unsigned int latency_factor __read_mostly = 2; +module_param(latency_factor, uint, 0644); #endif /* @@ -201,6 +204,10 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); } +/* + * Callers should disable interrupts before the call and enable + * interrupts after return. + */ static void acpi_safe_halt(void) { current_thread_info()->status &= ~TS_POLLING; @@ -261,7 +268,7 @@ static atomic_t c3_cpu_count; /* Common C-state entry for C2, C3, .. */ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) { - if (cstate->space_id == ACPI_CSTATE_FFH) { + if (cstate->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cstate); } else { @@ -413,6 +420,8 @@ static void acpi_processor_idle(void) pm_idle_save(); else acpi_safe_halt(); + + local_irq_enable(); return; } @@ -521,6 +530,7 @@ static void acpi_processor_idle(void) * skew otherwise. */ sleep_ticks = 0xFFFFFFFF; + local_irq_enable(); break; case ACPI_STATE_C2: @@ -648,7 +658,8 @@ static void acpi_processor_idle(void) if (cx->promotion.state && ((cx->promotion.state - pr->power.states) <= max_cstate)) { if (sleep_ticks > cx->promotion.threshold.ticks && - cx->promotion.state->latency <= system_latency_constraint()) { + cx->promotion.state->latency <= + pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { cx->promotion.count++; cx->demotion.count = 0; if (cx->promotion.count >= @@ -692,7 +703,8 @@ static void acpi_processor_idle(void) * or if the latency of the current state is unacceptable */ if ((pr->power.state - pr->power.states) > max_cstate || - pr->power.state->latency > system_latency_constraint()) { + pr->power.state->latency > + pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) { if (cx->demotion.state) next_state = cx->demotion.state; } @@ -920,20 +932,20 @@ static int acpi_processor_get_power_info_cst(struct acpi_processor *pr) cx.address = reg->address; cx.index = current_count + 1; - cx.space_id = ACPI_CSTATE_SYSTEMIO; + cx.entry_method = ACPI_CSTATE_SYSTEMIO; if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) { if (acpi_processor_ffh_cstate_probe (pr->id, &cx, reg) == 0) { - cx.space_id = ACPI_CSTATE_FFH; - } else if (cx.type != ACPI_STATE_C1) { + cx.entry_method = ACPI_CSTATE_FFH; + } else if (cx.type == ACPI_STATE_C1) { /* * C1 is a special case where FIXED_HARDWARE * can be handled in non-MWAIT way as well. * In that case, save this _CST entry info. - * That is, we retain space_id of SYSTEM_IO for - * halt based C1. * Otherwise, ignore this info and continue. */ + cx.entry_method = ACPI_CSTATE_HALT; + } else { continue; } } @@ -1200,7 +1212,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) "maximum allowed latency: %d usec\n", pr->power.state ? pr->power.state - pr->power.states : 0, max_cstate, (unsigned)pr->power.bm_activity, - system_latency_constraint()); + pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)); seq_puts(seq, "states:\n"); @@ -1367,12 +1379,16 @@ static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, /** * acpi_idle_do_entry - a helper function that does C2 and C3 type entry * @cx: cstate data + * + * Caller disables interrupt before call and enables interrupt after return. */ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) { - if (cx->space_id == ACPI_CSTATE_FFH) { + if (cx->entry_method == ACPI_CSTATE_FFH) { /* Call into architectural FFH based C-state */ acpi_processor_ffh_cstate_enter(cx); + } else if (cx->entry_method == ACPI_CSTATE_HALT) { + acpi_safe_halt(); } else { int unused; /* IO port based C-state */ @@ -1394,21 +1410,27 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) static int acpi_idle_enter_c1(struct cpuidle_device *dev, struct cpuidle_state *state) { + u32 t1, t2; struct acpi_processor *pr; struct acpi_processor_cx *cx = cpuidle_get_statedata(state); + pr = processors[smp_processor_id()]; if (unlikely(!pr)) return 0; + local_irq_disable(); if (pr->flags.bm_check) acpi_idle_update_bm_rld(pr, cx); - acpi_safe_halt(); + t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + acpi_idle_do_entry(cx); + t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); + local_irq_enable(); cx->usage++; - return 0; + return ticks_elapsed_in_us(t1, t2); } /** @@ -1515,7 +1537,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, if (dev->safe_state) { return dev->safe_state->enter(dev, dev->safe_state); } else { + local_irq_disable(); acpi_safe_halt(); + local_irq_enable(); return 0; } } @@ -1607,7 +1631,7 @@ struct cpuidle_driver acpi_idle_driver = { */ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) { - int i, count = 0; + int i, count = CPUIDLE_DRIVER_STATE_START; struct acpi_processor_cx *cx; struct cpuidle_state *state; struct cpuidle_device *dev = &pr->power.dev; @@ -1636,13 +1660,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); state->exit_latency = cx->latency; - state->target_residency = cx->latency * 6; + state->target_residency = cx->latency * latency_factor; state->power_usage = cx->power; state->flags = 0; switch (cx->type) { case ACPI_STATE_C1: state->flags |= CPUIDLE_FLAG_SHALLOW; + state->flags |= CPUIDLE_FLAG_TIME_VALID; state->enter = acpi_idle_enter_c1; dev->safe_state = state; break; @@ -1665,6 +1690,8 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) } count++; + if (count == CPUIDLE_STATE_MAX) + break; } dev->state_count = count; @@ -1718,8 +1745,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, "ACPI: processor limited to max C-state %d\n", max_cstate); first_run++; -#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP) - register_latency_notifier(&acpi_processor_latency_notifier); +#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP) + pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY, + &acpi_processor_latency_notifier); #endif } @@ -1806,7 +1834,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr, */ cpu_idle_wait(); #ifdef CONFIG_SMP - unregister_latency_notifier(&acpi_processor_latency_notifier); + pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY, + &acpi_processor_latency_notifier); #endif } #endif diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index cbfe9ae..c7b0aa5 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -830,7 +830,7 @@ static int acpi_bus_get_flags(struct acpi_device *device) if (ACPI_SUCCESS(status)) device->flags.wake_capable = 1; - /* TBD: Peformance management */ + /* TBD: Performance management */ return 0; } @@ -941,6 +941,15 @@ static int acpi_bay_match(struct acpi_device *device){ return -ENODEV; } +/* + * acpi_dock_match - see if a device has a _DCK method + */ +static int acpi_dock_match(struct acpi_device *device) +{ + acpi_handle tmp; + return acpi_get_handle(device->handle, "_DCK", &tmp); +} + static void acpi_device_set_id(struct acpi_device *device, struct acpi_device *parent, acpi_handle handle, int type) @@ -950,6 +959,7 @@ static void acpi_device_set_id(struct acpi_device *device, char *hid = NULL; char *uid = NULL; struct acpi_compatible_id_list *cid_list = NULL; + const char *cid_add = NULL; acpi_status status; switch (type) { @@ -972,15 +982,18 @@ static void acpi_device_set_id(struct acpi_device *device, device->flags.bus_address = 1; } - if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){ - status = acpi_video_bus_match(device); - if(ACPI_SUCCESS(status)) - hid = ACPI_VIDEO_HID; + /* If we have a video/bay/dock device, add our selfdefined + HID to the CID list. Like that the video/bay/dock drivers + will get autoloaded and the device might still match + against another driver. + */ + if (ACPI_SUCCESS(acpi_video_bus_match(device))) + cid_add = ACPI_VIDEO_HID; + else if (ACPI_SUCCESS(acpi_bay_match(device))) + cid_add = ACPI_BAY_HID; + else if (ACPI_SUCCESS(acpi_dock_match(device))) + cid_add = ACPI_DOCK_HID; - status = acpi_bay_match(device); - if (ACPI_SUCCESS(status)) - hid = ACPI_BAY_HID; - } break; case ACPI_BUS_TYPE_POWER: hid = ACPI_POWER_HID; @@ -1021,11 +1034,44 @@ static void acpi_device_set_id(struct acpi_device *device, strcpy(device->pnp.unique_id, uid); device->flags.unique_id = 1; } - if (cid_list) { - device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL); - if (device->pnp.cid_list) - memcpy(device->pnp.cid_list, cid_list, cid_list->size); - else + if (cid_list || cid_add) { + struct acpi_compatible_id_list *list; + int size = 0; + int count = 0; + + if (cid_list) { + size = cid_list->size; + } else if (cid_add) { + size = sizeof(struct acpi_compatible_id_list); + cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); + if (!cid_list) { + printk(KERN_ERR "Memory allocation error\n"); + kfree(buffer.pointer); + return; + } else { + cid_list->count = 0; + cid_list->size = size; + } + } + if (cid_add) + size += sizeof(struct acpi_compatible_id); + list = kmalloc(size, GFP_KERNEL); + + if (list) { + if (cid_list) { + memcpy(list, cid_list, cid_list->size); + count = cid_list->count; + } + if (cid_add) { + strncpy(list->id[count].value, cid_add, + ACPI_MAX_CID_LENGTH); + count++; + device->flags.compatible_ids = 1; + } + list->size = size; + list->count = count; + device->pnp.cid_list = list; + } else printk(KERN_ERR "Memory allocation error\n"); } @@ -1081,6 +1127,20 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) } static int +acpi_is_child_device(struct acpi_device *device, + int (*matcher)(struct acpi_device *)) +{ + int result = -ENODEV; + + do { + if (ACPI_SUCCESS(matcher(device))) + return AE_OK; + } while ((device = device->parent)); + + return result; +} + +static int acpi_add_single_object(struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, int type, struct acpi_bus_ops *ops) @@ -1131,10 +1191,20 @@ acpi_add_single_object(struct acpi_device **child, case ACPI_BUS_TYPE_PROCESSOR: case ACPI_BUS_TYPE_DEVICE: result = acpi_bus_get_status(device); - if (ACPI_FAILURE(result) || !device->status.present) { - result = -ENOENT; + if (ACPI_FAILURE(result)) { + result = -ENODEV; goto end; } + if (!device->status.present) { + /* Bay and dock should be handled even if absent */ + if (!ACPI_SUCCESS( + acpi_is_child_device(device, acpi_bay_match)) && + !ACPI_SUCCESS( + acpi_is_child_device(device, acpi_dock_match))) { + result = -ENODEV; + goto end; + } + } break; default: STRUCT_TO_INT(device->status) = diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 485de13..7f97e32 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -472,11 +472,20 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) if (acpi_target_sleep_state == ACPI_STATE_S0 || (wake && adev->wakeup.state.enabled && adev->wakeup.sleep_state <= acpi_target_sleep_state)) { + acpi_status status; + acpi_method[3] = 'W'; - acpi_evaluate_integer(handle, acpi_method, NULL, &d_max); - /* Sanity check */ - if (d_max < d_min) + status = acpi_evaluate_integer(handle, acpi_method, NULL, + &d_max); + if (ACPI_FAILURE(status)) { + d_max = d_min; + } else if (d_max < d_min) { + /* Warn the user of the broken DSDT */ + printk(KERN_WARNING "ACPI: Wrong value from %s\n", + acpi_method); + /* Sanitize it */ d_min = d_max; + } } if (d_min_p) diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 1538355..f8df521 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c @@ -178,6 +178,9 @@ static int get_date_field(char **p, u32 * value) * Try to find delimeter, only to insert null. The end of the * string won't have one, but is still valid. */ + if (*p == NULL) + return result; + next = strpbrk(*p, "- :"); if (next) *next++ = '\0'; @@ -190,6 +193,8 @@ static int get_date_field(char **p, u32 * value) if (next) *p = next; + else + *p = NULL; return result; } @@ -251,27 +256,6 @@ acpi_system_write_alarm(struct file *file, if ((result = get_date_field(&p, &sec))) goto end; - if (sec > 59) { - min += 1; - sec -= 60; - } - if (min > 59) { - hr += 1; - min -= 60; - } - if (hr > 23) { - day += 1; - hr -= 24; - } - if (day > 31) { - mo += 1; - day -= 31; - } - if (mo > 12) { - yr += 1; - mo -= 12; - } - spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); @@ -288,24 +272,24 @@ acpi_system_write_alarm(struct file *file, spin_unlock_irq(&rtc_lock); if (sec > 59) { - min++; - sec -= 60; + min += sec/60; + sec = sec%60; } if (min > 59) { - hr++; - min -= 60; + hr += min/60; + min = min%60; } if (hr > 23) { - day++; - hr -= 24; + day += hr/24; + hr = hr%24; } if (day > 31) { - mo++; - day -= 31; + mo += day/32; + day = day%32; } if (mo > 12) { - yr++; - mo -= 12; + yr += mo/13; + mo = mo%13; } spin_lock_irq(&rtc_lock); diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile index 0a7d7af..7385efa 100644 --- a/drivers/acpi/tables/Makefile +++ b/drivers/acpi/tables/Makefile @@ -2,6 +2,6 @@ # Makefile for all Linux ACPI interpreter subdirectories # -obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o +obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o EXTRA_CFLAGS += $(ACPI_CFLAGS) diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index cf8fa51..9ecb4b6 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -100,7 +100,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) /******************************************************************************* * - * FUNCTION: acpi_tb_find_rsdp + * FUNCTION: acpi_find_root_pointer * * PARAMETERS: table_address - Where the table pointer is returned * @@ -219,8 +219,6 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address) return_ACPI_STATUS(AE_NOT_FOUND); } -ACPI_EXPORT_SYMBOL(acpi_find_root_pointer) - /******************************************************************************* * * FUNCTION: acpi_tb_scan_memory_for_rsdp diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5f79b44..3a0af9a 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -492,7 +492,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 || nocrt) + if (!tz || !tz->trips.critical.flags.valid) return -EINVAL; if (tz->temperature >= tz->trips.critical.temperature) { @@ -501,9 +501,6 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) } else if (tz->trips.critical.flags.enabled) tz->trips.critical.flags.enabled = 0; - printk(KERN_EMERG - "Critical temperature reached (%ld C), shutting down.\n", - KELVIN_TO_CELSIUS(tz->temperature)); 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, @@ -511,14 +508,20 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); - orderly_poweroff(true); + /* take no action if nocrt is set */ + if(!nocrt) { + printk(KERN_EMERG + "Critical temperature reached (%ld C), shutting down.\n", + KELVIN_TO_CELSIUS(tz->temperature)); + orderly_poweroff(true); + } return 0; } static int acpi_thermal_hot(struct acpi_thermal *tz) { - if (!tz || !tz->trips.hot.flags.valid || nocrt) + if (!tz || !tz->trips.hot.flags.valid) return -EINVAL; if (tz->temperature >= tz->trips.hot.temperature) { @@ -534,7 +537,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); - /* TBD: Call user-mode "sleep(S4)" function */ + /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */ return 0; } diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c index cbbd331..b630ee1 100644 --- a/drivers/acpi/utilities/utresrc.c +++ b/drivers/acpi/utilities/utresrc.c @@ -1,6 +1,6 @@ /******************************************************************************* * - * Module Name: utresrc - Resource managment utilities + * Module Name: utresrc - Resource management utilities * ******************************************************************************/ diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index bd77e81..a54ff6b 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -292,18 +292,26 @@ static int acpi_video_device_set_state(struct acpi_video_device *device, int sta static int acpi_video_get_brightness(struct backlight_device *bd) { unsigned long cur_level; + int i; struct acpi_video_device *vd = (struct acpi_video_device *)bl_get_data(bd); acpi_video_device_lcd_get_level_current(vd, &cur_level); - return (int) cur_level; + for (i = 2; i < vd->brightness->count; i++) { + if (vd->brightness->levels[i] == cur_level) + /* The first two entries are special - see page 575 + of the ACPI spec 3.0 */ + return i-2; + } + return 0; } static int acpi_video_set_brightness(struct backlight_device *bd) { - int request_level = bd->props.brightness; + int request_level = bd->props.brightness+2; struct acpi_video_device *vd = (struct acpi_video_device *)bl_get_data(bd); - acpi_video_device_lcd_set_level(vd, request_level); + acpi_video_device_lcd_set_level(vd, + vd->brightness->levels[request_level]); return 0; } @@ -652,7 +660,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) kfree(obj); if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ - unsigned long tmp; static int count = 0; char *name; name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); @@ -660,11 +667,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) return; sprintf(name, "acpi_video%d", count++); - acpi_video_device_lcd_get_level_current(device, &tmp); device->backlight = backlight_device_register(name, NULL, device, &acpi_backlight_ops); - device->backlight->props.max_brightness = max_level; - device->backlight->props.brightness = (int)tmp; + device->backlight->props.max_brightness = device->brightness->count-3; + device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); backlight_update_status(device->backlight); kfree(name); @@ -1256,8 +1262,37 @@ acpi_video_bus_write_DOS(struct file *file, static int acpi_video_bus_add_fs(struct acpi_device *device) { + long device_id; + int status; struct proc_dir_entry *entry = NULL; struct acpi_video_bus *video; + struct device *dev; + + status = + acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); + + if (!ACPI_SUCCESS(status)) + return -ENODEV; + + /* We need to attempt to determine whether the _ADR refers to a + PCI device or not. There's no terribly good way to do this, + so the best we can hope for is to assume that there'll never + be a video device in the host bridge */ + if (device_id >= 0x10000) { + /* It looks like a PCI device. Does it exist? */ + dev = acpi_get_physical_device(device->handle); + } else { + /* It doesn't look like a PCI device. Does its parent + exist? */ + acpi_handle phandle; + if (acpi_get_parent(device->handle, &phandle)) + return -ENODEV; + dev = acpi_get_physical_device(phandle); + } + if (!dev) + return -ENODEV; + put_device(dev); + video = acpi_driver_data(device); |