diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 17e50824a6f1..72ac28da14e3 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -5,40 +5,43 @@ ccflags-y := -Os ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT -obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ +# use acpi.o to put all files here into acpi.o modparam namespace +obj-y += acpi.o + +acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \ dsinit.o -obj-y += evevent.o evregion.o evsci.o evxfevnt.o \ +acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ evmisc.o evrgnini.o evxface.o evxfregn.o \ evgpe.o evgpeblk.o -obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ +acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \ exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o -obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o +acpi-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o -obj-$(ACPI_FUTURE_USAGE) += hwtimer.o +acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o -obj-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ +acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ nsparse.o nspredef.o -obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o +acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o -obj-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ +acpi-y += psargs.o psparse.o psloop.o pstree.o pswalk.o \ psopcode.o psscope.o psutils.o psxface.o -obj-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ +acpi-y += rsaddr.o rscreate.o rsinfo.o rsio.o rslist.o rsmisc.o rsxface.o \ rscalc.o rsirq.o rsmemory.o rsutils.o -obj-$(ACPI_FUTURE_USAGE) += rsdump.o +acpi-$(ACPI_FUTURE_USAGE) += rsdump.o -obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o +acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o -obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ +acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ utstate.o utmutex.o utobject.o utresrc.o utlock.o diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 772ee5c4ccca..2ec394a328e9 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -787,7 +787,12 @@ struct acpi_bit_register_info { /* For control registers, both ignored and reserved bits must be preserved */ -#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */ +/* + * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) + * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly + * as a BIOS workaround on some machines. + */ +#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ #define ACPI_PM1_CONTROL_PRESERVED_BITS \ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e8f7b64e92da..ae862f1798dc 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -312,7 +312,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) end: if (result) printk(KERN_WARNING PREFIX - "Transitioning device [%s] to D%d\n", + "Device [%s] failed to transition to D%d\n", device->pnp.bus_id, state); else { device->power.state = state; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f7ca8c55956b..72069ba5f1ed 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -202,21 +202,44 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, * Suspend / resume control */ static int acpi_idle_suspend; +static u32 saved_bm_rld; + +static void acpi_idle_bm_rld_save(void) +{ + acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); +} +static void acpi_idle_bm_rld_restore(void) +{ + u32 resumed_bm_rld; + + acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); + + if (resumed_bm_rld != saved_bm_rld) + acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); +} int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { + if (acpi_idle_suspend == 1) + return 0; + + acpi_idle_bm_rld_save(); acpi_idle_suspend = 1; return 0; } int acpi_processor_resume(struct acpi_device * device) { + if (acpi_idle_suspend == 0) + return 0; + + acpi_idle_bm_rld_restore(); acpi_idle_suspend = 0; return 0; } #if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) -static int tsc_halts_in_c(int state) +static void tsc_check_state(int state) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: @@ -226,13 +249,17 @@ static int tsc_halts_in_c(int state) * C/P/S0/S1 states when this bit is set. */ if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) - return 0; + return; /*FALL THROUGH*/ default: - return state > ACPI_STATE_C1; + /* TSC could halt in idle, so notify users */ + if (state > ACPI_STATE_C1) + mark_tsc_unstable("TSC halts in idle"); } } +#else +static void tsc_check_state(int state) { return; } #endif static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) @@ -578,14 +605,9 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) pr->power.timer_broadcast_on_state = INT_MAX; - for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) { + for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { struct acpi_processor_cx *cx = &pr->power.states[i]; -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86) - /* TSC could halt in idle, so notify users */ - if (tsc_halts_in_c(cx->type)) - mark_tsc_unstable("TSC halts in idle");; -#endif switch (cx->type) { case ACPI_STATE_C1: cx->valid = 1; @@ -603,6 +625,8 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) acpi_timer_check_state(i, pr, cx); break; } + if (cx->valid) + tsc_check_state(cx->type); if (cx->valid) working++; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index d0d1f4d50434..7f16f5f8e7d3 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -45,6 +45,14 @@ #define _COMPONENT ACPI_PROCESSOR_COMPONENT ACPI_MODULE_NAME("processor_throttling"); +/* ignore_tpc: + * 0 -> acpi processor driver doesn't ignore _TPC values + * 1 -> acpi processor driver ignores _TPC values + */ +static int ignore_tpc; +module_param(ignore_tpc, int, 0644); +MODULE_PARM_DESC(ignore_tpc, "Disable broken BIOS _TPC throttling support"); + struct throttling_tstate { unsigned int cpu; /* cpu nr */ int target_state; /* target T-state */ @@ -283,6 +291,10 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) if (!pr) return -EINVAL; + + if (ignore_tpc) + goto end; + status = acpi_evaluate_integer(pr->handle, "_TPC", NULL, &tpc); if (ACPI_FAILURE(status)) { if (status != AE_NOT_FOUND) { @@ -290,6 +302,8 @@ static int acpi_processor_get_platform_limit(struct acpi_processor *pr) } return -ENODEV; } + +end: pr->throttling_platform_limit = (int)tpc; return 0; } @@ -302,6 +316,9 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) struct acpi_processor_limit *limit; int target_state; + if (ignore_tpc) + return 0; + result = acpi_processor_get_platform_limit(pr); if (result) { /* Throttling Limit is unsupported */ @@ -821,6 +838,14 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) ret = acpi_read_throttling_status(pr, &value); if (ret >= 0) { state = acpi_get_throttling_state(pr, value); + if (state == -1) { + ACPI_WARNING((AE_INFO, + "Invalid throttling state, reset\n")); + state = 0; + ret = acpi_processor_set_throttling(pr, state); + if (ret) + return ret; + } pr->throttling.state = state; } diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d7ff61c0d571..810cca90ca7f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -538,6 +538,41 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) return -EINVAL; } +/* + * For some buggy _BQC methods, we need to add a constant value to + * the _BQC return value to get the actual current brightness level + */ + +static int bqc_offset_aml_bug_workaround; +static int __init video_set_bqc_offset(const struct dmi_system_id *d) +{ + bqc_offset_aml_bug_workaround = 9; + return 0; +} + +static struct dmi_system_id video_dmi_table[] __initdata = { + /* + * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121 + */ + { + .callback = video_set_bqc_offset, + .ident = "Acer Aspire 5720", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), + }, + }, + { + .callback = video_set_bqc_offset, + .ident = "Acer Aspire 5710Z", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), + }, + }, + {} +}; + static int acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, unsigned long long *level) @@ -557,6 +592,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, *level = device->brightness->levels[*level + 2]; } + *level += bqc_offset_aml_bug_workaround; device->brightness->curr = *level; return 0; } else { @@ -2290,6 +2326,8 @@ EXPORT_SYMBOL(acpi_video_register); static int __init acpi_video_init(void) { + dmi_check_system(video_dmi_table); + if (intel_opregion_present()) return 0; diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 17b24c580c09..4cd35d8fd799 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -84,6 +84,12 @@ config DRM_I915 config DRM_I915_KMS bool "Enable modesetting on intel by default" depends on DRM_I915 + # i915 KMS depends on ACPI_VIDEO when ACPI is enabled + # but for select to work, need to select ACPI_VIDEO's dependencies, ick + select VIDEO_OUTPUT_CONTROL if ACPI + select BACKLIGHT_CLASS_DEVICE if ACPI + select INPUT if ACPI + select ACPI_VIDEO if ACPI help Choose this option if you want kernel modesetting enabled by default, and you have a new enough userspace to support this. Running old diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index eeafc6c0160d..bfc1a8892a32 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -269,16 +269,16 @@ static struct key_entry asus_keymap[] = { {KE_KEY, 0x34, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x40, KEY_PREVIOUSSONG}, {KE_KEY, 0x41, KEY_NEXTSONG}, - {KE_KEY, 0x43, KEY_STOP}, + {KE_KEY, 0x43, KEY_STOPCD}, {KE_KEY, 0x45, KEY_PLAYPAUSE}, {KE_KEY, 0x50, KEY_EMAIL}, {KE_KEY, 0x51, KEY_WWW}, - {KE_KEY, 0x5C, BTN_EXTRA}, /* Performance */ + {KE_KEY, 0x5C, KEY_SCREENLOCK}, /* Screenlock */ {KE_KEY, 0x5D, KEY_WLAN}, {KE_KEY, 0x61, KEY_SWITCHVIDEOMODE}, {KE_KEY, 0x6B, BTN_TOUCH}, /* Lock Mouse */ {KE_KEY, 0x82, KEY_CAMERA}, - {KE_KEY, 0x8A, KEY_TV}, + {KE_KEY, 0x8A, KEY_PROG1}, {KE_KEY, 0x95, KEY_MEDIA}, {KE_KEY, 0x99, KEY_PHONE}, {KE_END, 0}, diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 6f54fd1757cd..353a898c3693 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -158,6 +158,7 @@ enum { KE_KEY, KE_END }; static struct key_entry eeepc_keymap[] = { /* Sleep already handled via generic ACPI code */ {KE_KEY, 0x10, KEY_WLAN }, + {KE_KEY, 0x11, KEY_WLAN }, {KE_KEY, 0x12, KEY_PROG1 }, {KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x14, KEY_VOLUMEDOWN }, @@ -166,6 +167,8 @@ static struct key_entry eeepc_keymap[] = { {KE_KEY, 0x1b, KEY_ZOOM }, {KE_KEY, 0x1c, KEY_PROG2 }, {KE_KEY, 0x1d, KEY_PROG3 }, + {KE_KEY, NOTIFY_BRN_MIN, KEY_BRIGHTNESSDOWN }, + {KE_KEY, NOTIFY_BRN_MIN + 2, KEY_BRIGHTNESSUP }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, @@ -381,11 +384,13 @@ static ssize_t show_sys_acpi(int cm, char *buf) EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA); EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER); EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH); +EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV); static struct attribute *platform_attributes[] = { &dev_attr_camera.attr, &dev_attr_cardr.attr, &dev_attr_disp.attr, + &dev_attr_cpufv.attr, NULL }; @@ -512,15 +517,21 @@ static int eeepc_hotk_check(void) return 0; } -static void notify_brn(void) +static int notify_brn(void) { + /* returns the *previous* brightness, or -1 */ struct backlight_device *bd = eeepc_backlight_device; - if (bd) + if (bd) { + int old = bd->props.brightness; bd->props.brightness = read_brightness(bd); + return old; + } + return -1; } static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) { + enum rfkill_state state; struct pci_dev *dev; struct pci_bus *bus = pci_find_bus(0, 1); @@ -532,7 +543,9 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) return; } - if (get_acpi(CM_ASL_WLAN) == 1) { + eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); + + if (state == RFKILL_STATE_UNBLOCKED) { dev = pci_get_slot(bus, 0); if (dev) { /* Device already present */ @@ -552,23 +565,41 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) pci_dev_put(dev); } } + + rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); } static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) { static struct key_entry *key; u16 count; + int brn = -ENODEV; if (!ehotk) return; if (event >= NOTIFY_BRN_MIN && event <= NOTIFY_BRN_MAX) - notify_brn(); + brn = notify_brn(); count = ehotk->event_count[event % 128]++; acpi_bus_generate_proc_event(ehotk->device, event, count); acpi_bus_generate_netlink_event(ehotk->device->pnp.device_class, dev_name(&ehotk->device->dev), event, count); if (ehotk->inputdev) { + if (brn != -ENODEV) { + /* brightness-change events need special + * handling for conversion to key events + */ + if (brn < 0) + brn = event; + else + brn += NOTIFY_BRN_MIN; + if (event < brn) + event = NOTIFY_BRN_MIN; /* brightness down */ + else if (event > brn) + event = NOTIFY_BRN_MIN + 2; /* ... up */ + else + event = NOTIFY_BRN_MIN + 1; /* ... unchanged */ + } key = eepc_get_entry_by_scancode(event); if (key) { switch (key->type) { @@ -649,6 +680,9 @@ static int eeepc_hotk_add(struct acpi_device *device) if (ACPI_FAILURE(status)) printk(EEEPC_ERR "Error installing notify handler\n"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); + if (get_acpi(CM_ASL_WLAN) != -1) { ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); @@ -704,9 +738,6 @@ static int eeepc_hotk_add(struct acpi_device *device) goto bluetooth_fail; } - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); - eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); - return 0; bluetooth_fail: @@ -717,6 +748,8 @@ static int eeepc_hotk_add(struct acpi_device *device) wlan_fail: if (ehotk->eeepc_wlan_rfkill) rfkill_free(ehotk->eeepc_wlan_rfkill); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); + eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); ehotk_fail: kfree(ehotk); ehotk = NULL; diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9a3a682c6981..9496494f340e 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -110,11 +110,9 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ ret = 0; - if (acpi_bus_power_manageable(handle)) { - ret = acpi_bus_set_power(handle, ACPI_STATE_D3); - if (ret) - return ret; - } + if (acpi_bus_power_manageable(handle)) + acpi_bus_set_power(handle, ACPI_STATE_D3); + /* continue even if acpi_bus_set_power() fails */ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) ret = -ENODEV; return ret; diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index d0b093b66adc..5e38ba10a3a9 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -961,7 +961,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) switch (trip_type) { case THERMAL_TRIP_CRITICAL: - if (temp > trip_temp) { + if (temp >= trip_temp) { if (tz->ops->notify) ret = tz->ops->notify(tz, count, trip_type); @@ -974,7 +974,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) } break; case THERMAL_TRIP_HOT: - if (temp > trip_temp) + if (temp >= trip_temp) if (tz->ops->notify) tz->ops->notify(tz, count, trip_type); break; @@ -986,14 +986,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) cdev = instance->cdev; - if (temp > trip_temp) + if (temp >= trip_temp) cdev->ops->set_cur_state(cdev, 1); else cdev->ops->set_cur_state(cdev, 0); } break; case THERMAL_TRIP_PASSIVE: - if (temp > trip_temp || tz->passive) + if (temp >= trip_temp || tz->passive) thermal_zone_device_passive(tz, temp, trip_temp, count); break;