diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-05-14 09:12:10 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-05-14 09:12:10 -0400 |
| commit | c01782d8190cf89c0642b2246caa17c27be0c54a (patch) | |
| tree | 7b2bca5ea7d96b8b7af58458af0727b92f1efa89 | |
| parent | d5a2fa27ecd772b51d93a91209205ec4d6ea2da1 (diff) | |
| parent | 0ab5bb64937d76c660c29813d8de0f4b47bf7550 (diff) | |
Merge branch 'acpi-fixes'
* acpi-fixes:
ACPI / AC: Add sleep quirk for Thinkpad e530
ACPI / EC: Restart transaction even when the IBF flag set
ACPI video: ignore BIOS initial backlight value for HP 1000
ACPI: Fix section to __init. Align with usage in acpixf.h
ACPI / PM: Move processor suspend/resume to syscore_ops
| -rw-r--r-- | drivers/acpi/ac.c | 33 | ||||
| -rw-r--r-- | drivers/acpi/ec.c | 4 | ||||
| -rw-r--r-- | drivers/acpi/processor_driver.c | 8 | ||||
| -rw-r--r-- | drivers/acpi/processor_idle.c | 29 | ||||
| -rw-r--r-- | drivers/acpi/video.c | 8 | ||||
| -rw-r--r-- | include/acpi/acpiosxf.h | 2 | ||||
| -rw-r--r-- | include/acpi/processor.h | 10 |
7 files changed, 74 insertions, 20 deletions
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 00d2efd674df..4f4e741d34b2 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
| 31 | #include <linux/dmi.h> | ||
| 32 | #include <linux/delay.h> | ||
| 31 | #ifdef CONFIG_ACPI_PROCFS_POWER | 33 | #ifdef CONFIG_ACPI_PROCFS_POWER |
| 32 | #include <linux/proc_fs.h> | 34 | #include <linux/proc_fs.h> |
| 33 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
| @@ -74,6 +76,8 @@ static int acpi_ac_resume(struct device *dev); | |||
| 74 | #endif | 76 | #endif |
| 75 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | 77 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); |
| 76 | 78 | ||
| 79 | static int ac_sleep_before_get_state_ms; | ||
| 80 | |||
| 77 | static struct acpi_driver acpi_ac_driver = { | 81 | static struct acpi_driver acpi_ac_driver = { |
| 78 | .name = "ac", | 82 | .name = "ac", |
| 79 | .class = ACPI_AC_CLASS, | 83 | .class = ACPI_AC_CLASS, |
| @@ -252,6 +256,16 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
| 252 | case ACPI_AC_NOTIFY_STATUS: | 256 | case ACPI_AC_NOTIFY_STATUS: |
| 253 | case ACPI_NOTIFY_BUS_CHECK: | 257 | case ACPI_NOTIFY_BUS_CHECK: |
| 254 | case ACPI_NOTIFY_DEVICE_CHECK: | 258 | case ACPI_NOTIFY_DEVICE_CHECK: |
| 259 | /* | ||
| 260 | * A buggy BIOS may notify AC first and then sleep for | ||
| 261 | * a specific time before doing actual operations in the | ||
| 262 | * EC event handler (_Qxx). This will cause the AC state | ||
| 263 | * reported by the ACPI event to be incorrect, so wait for a | ||
| 264 | * specific time for the EC event handler to make progress. | ||
| 265 | */ | ||
| 266 | if (ac_sleep_before_get_state_ms > 0) | ||
| 267 | msleep(ac_sleep_before_get_state_ms); | ||
| 268 | |||
| 255 | acpi_ac_get_state(ac); | 269 | acpi_ac_get_state(ac); |
| 256 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); | 270 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); |
| 257 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 271 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| @@ -264,6 +278,24 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
| 264 | return; | 278 | return; |
| 265 | } | 279 | } |
| 266 | 280 | ||
| 281 | static int thinkpad_e530_quirk(const struct dmi_system_id *d) | ||
| 282 | { | ||
| 283 | ac_sleep_before_get_state_ms = 1000; | ||
| 284 | return 0; | ||
| 285 | } | ||
| 286 | |||
| 287 | static struct dmi_system_id ac_dmi_table[] = { | ||
| 288 | { | ||
| 289 | .callback = thinkpad_e530_quirk, | ||
| 290 | .ident = "thinkpad e530", | ||
| 291 | .matches = { | ||
| 292 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 293 | DMI_MATCH(DMI_PRODUCT_NAME, "32597CG"), | ||
| 294 | }, | ||
| 295 | }, | ||
| 296 | {}, | ||
| 297 | }; | ||
| 298 | |||
| 267 | static int acpi_ac_add(struct acpi_device *device) | 299 | static int acpi_ac_add(struct acpi_device *device) |
| 268 | { | 300 | { |
| 269 | int result = 0; | 301 | int result = 0; |
| @@ -312,6 +344,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
| 312 | kfree(ac); | 344 | kfree(ac); |
| 313 | } | 345 | } |
| 314 | 346 | ||
| 347 | dmi_check_system(ac_dmi_table); | ||
| 315 | return result; | 348 | return result; |
| 316 | } | 349 | } |
| 317 | 350 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d45b2871d33b..edc00818c803 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -223,7 +223,7 @@ static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) | |||
| 223 | static int ec_poll(struct acpi_ec *ec) | 223 | static int ec_poll(struct acpi_ec *ec) |
| 224 | { | 224 | { |
| 225 | unsigned long flags; | 225 | unsigned long flags; |
| 226 | int repeat = 2; /* number of command restarts */ | 226 | int repeat = 5; /* number of command restarts */ |
| 227 | while (repeat--) { | 227 | while (repeat--) { |
| 228 | unsigned long delay = jiffies + | 228 | unsigned long delay = jiffies + |
| 229 | msecs_to_jiffies(ec_delay); | 229 | msecs_to_jiffies(ec_delay); |
| @@ -241,8 +241,6 @@ static int ec_poll(struct acpi_ec *ec) | |||
| 241 | } | 241 | } |
| 242 | advance_transaction(ec, acpi_ec_read_status(ec)); | 242 | advance_transaction(ec, acpi_ec_read_status(ec)); |
| 243 | } while (time_before(jiffies, delay)); | 243 | } while (time_before(jiffies, delay)); |
| 244 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) | ||
| 245 | break; | ||
| 246 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 244 | pr_debug(PREFIX "controller reset, restart transaction\n"); |
| 247 | spin_lock_irqsave(&ec->lock, flags); | 245 | spin_lock_irqsave(&ec->lock, flags); |
| 248 | start_transaction(ec); | 246 | start_transaction(ec); |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index bec717ffd25f..c266cdc11784 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
| @@ -95,9 +95,6 @@ static const struct acpi_device_id processor_device_ids[] = { | |||
| 95 | }; | 95 | }; |
| 96 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | 96 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); |
| 97 | 97 | ||
| 98 | static SIMPLE_DEV_PM_OPS(acpi_processor_pm, | ||
| 99 | acpi_processor_suspend, acpi_processor_resume); | ||
| 100 | |||
| 101 | static struct acpi_driver acpi_processor_driver = { | 98 | static struct acpi_driver acpi_processor_driver = { |
| 102 | .name = "processor", | 99 | .name = "processor", |
| 103 | .class = ACPI_PROCESSOR_CLASS, | 100 | .class = ACPI_PROCESSOR_CLASS, |
| @@ -107,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
| 107 | .remove = acpi_processor_remove, | 104 | .remove = acpi_processor_remove, |
| 108 | .notify = acpi_processor_notify, | 105 | .notify = acpi_processor_notify, |
| 109 | }, | 106 | }, |
| 110 | .drv.pm = &acpi_processor_pm, | ||
| 111 | }; | 107 | }; |
| 112 | 108 | ||
| 113 | #define INSTALL_NOTIFY_HANDLER 1 | 109 | #define INSTALL_NOTIFY_HANDLER 1 |
| @@ -934,6 +930,8 @@ static int __init acpi_processor_init(void) | |||
| 934 | if (result < 0) | 930 | if (result < 0) |
| 935 | return result; | 931 | return result; |
| 936 | 932 | ||
| 933 | acpi_processor_syscore_init(); | ||
| 934 | |||
| 937 | acpi_processor_install_hotplug_notify(); | 935 | acpi_processor_install_hotplug_notify(); |
| 938 | 936 | ||
| 939 | acpi_thermal_cpufreq_init(); | 937 | acpi_thermal_cpufreq_init(); |
| @@ -956,6 +954,8 @@ static void __exit acpi_processor_exit(void) | |||
| 956 | 954 | ||
| 957 | acpi_processor_uninstall_hotplug_notify(); | 955 | acpi_processor_uninstall_hotplug_notify(); |
| 958 | 956 | ||
| 957 | acpi_processor_syscore_exit(); | ||
| 958 | |||
| 959 | acpi_bus_unregister_driver(&acpi_processor_driver); | 959 | acpi_bus_unregister_driver(&acpi_processor_driver); |
| 960 | 960 | ||
| 961 | return; | 961 | return; |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f0df2c9434d2..eb133c77aadb 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/sched.h> /* need_resched() */ | 34 | #include <linux/sched.h> /* need_resched() */ |
| 35 | #include <linux/clockchips.h> | 35 | #include <linux/clockchips.h> |
| 36 | #include <linux/cpuidle.h> | 36 | #include <linux/cpuidle.h> |
| 37 | #include <linux/syscore_ops.h> | ||
| 37 | 38 | ||
| 38 | /* | 39 | /* |
| 39 | * Include the apic definitions for x86 to have the APIC timer related defines | 40 | * Include the apic definitions for x86 to have the APIC timer related defines |
| @@ -210,33 +211,41 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, | |||
| 210 | 211 | ||
| 211 | #endif | 212 | #endif |
| 212 | 213 | ||
| 214 | #ifdef CONFIG_PM_SLEEP | ||
| 213 | static u32 saved_bm_rld; | 215 | static u32 saved_bm_rld; |
| 214 | 216 | ||
| 215 | static void acpi_idle_bm_rld_save(void) | 217 | int acpi_processor_suspend(void) |
| 216 | { | 218 | { |
| 217 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); | 219 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); |
| 220 | return 0; | ||
| 218 | } | 221 | } |
| 219 | static void acpi_idle_bm_rld_restore(void) | 222 | |
| 223 | void acpi_processor_resume(void) | ||
| 220 | { | 224 | { |
| 221 | u32 resumed_bm_rld; | 225 | u32 resumed_bm_rld; |
| 222 | 226 | ||
| 223 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); | 227 | acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld); |
| 228 | if (resumed_bm_rld == saved_bm_rld) | ||
| 229 | return; | ||
| 224 | 230 | ||
| 225 | if (resumed_bm_rld != saved_bm_rld) | 231 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); |
| 226 | acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); | ||
| 227 | } | 232 | } |
| 228 | 233 | ||
| 229 | int acpi_processor_suspend(struct device *dev) | 234 | static struct syscore_ops acpi_processor_syscore_ops = { |
| 235 | .suspend = acpi_processor_suspend, | ||
| 236 | .resume = acpi_processor_resume, | ||
| 237 | }; | ||
| 238 | |||
| 239 | void acpi_processor_syscore_init(void) | ||
| 230 | { | 240 | { |
| 231 | acpi_idle_bm_rld_save(); | 241 | register_syscore_ops(&acpi_processor_syscore_ops); |
| 232 | return 0; | ||
| 233 | } | 242 | } |
| 234 | 243 | ||
| 235 | int acpi_processor_resume(struct device *dev) | 244 | void acpi_processor_syscore_exit(void) |
| 236 | { | 245 | { |
| 237 | acpi_idle_bm_rld_restore(); | 246 | unregister_syscore_ops(&acpi_processor_syscore_ops); |
| 238 | return 0; | ||
| 239 | } | 247 | } |
| 248 | #endif /* CONFIG_PM_SLEEP */ | ||
| 240 | 249 | ||
| 241 | #if defined(CONFIG_X86) | 250 | #if defined(CONFIG_X86) |
| 242 | static void tsc_check_state(int state) | 251 | static void tsc_check_state(int state) |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index c3932d0876e0..5b32e15a65ce 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
| @@ -456,6 +456,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
| 456 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"), | 456 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"), |
| 457 | }, | 457 | }, |
| 458 | }, | 458 | }, |
| 459 | { | ||
| 460 | .callback = video_ignore_initial_backlight, | ||
| 461 | .ident = "HP 1000 Notebook PC", | ||
| 462 | .matches = { | ||
| 463 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), | ||
| 464 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 1000 Notebook PC"), | ||
| 465 | }, | ||
| 466 | }, | ||
| 459 | {} | 467 | {} |
| 460 | }; | 468 | }; |
| 461 | 469 | ||
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 5b3d2bd4813a..64b8c7639520 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
| @@ -77,7 +77,7 @@ struct acpi_signal_fatal_info { | |||
| 77 | /* | 77 | /* |
| 78 | * OSL Initialization and shutdown primitives | 78 | * OSL Initialization and shutdown primitives |
| 79 | */ | 79 | */ |
| 80 | acpi_status __initdata acpi_os_initialize(void); | 80 | acpi_status __init acpi_os_initialize(void); |
| 81 | 81 | ||
| 82 | acpi_status acpi_os_terminate(void); | 82 | acpi_status acpi_os_terminate(void); |
| 83 | 83 | ||
diff --git a/include/acpi/processor.h b/include/acpi/processor.h index b327b5a9296d..ea69367fdd3b 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h | |||
| @@ -329,10 +329,16 @@ int acpi_processor_power_init(struct acpi_processor *pr); | |||
| 329 | int acpi_processor_power_exit(struct acpi_processor *pr); | 329 | int acpi_processor_power_exit(struct acpi_processor *pr); |
| 330 | int acpi_processor_cst_has_changed(struct acpi_processor *pr); | 330 | int acpi_processor_cst_has_changed(struct acpi_processor *pr); |
| 331 | int acpi_processor_hotplug(struct acpi_processor *pr); | 331 | int acpi_processor_hotplug(struct acpi_processor *pr); |
| 332 | int acpi_processor_suspend(struct device *dev); | ||
| 333 | int acpi_processor_resume(struct device *dev); | ||
| 334 | extern struct cpuidle_driver acpi_idle_driver; | 332 | extern struct cpuidle_driver acpi_idle_driver; |
| 335 | 333 | ||
| 334 | #ifdef CONFIG_PM_SLEEP | ||
| 335 | void acpi_processor_syscore_init(void); | ||
| 336 | void acpi_processor_syscore_exit(void); | ||
| 337 | #else | ||
| 338 | static inline void acpi_processor_syscore_init(void) {} | ||
| 339 | static inline void acpi_processor_syscore_exit(void) {} | ||
| 340 | #endif | ||
| 341 | |||
| 336 | /* in processor_thermal.c */ | 342 | /* in processor_thermal.c */ |
| 337 | int acpi_processor_get_limit_info(struct acpi_processor *pr); | 343 | int acpi_processor_get_limit_info(struct acpi_processor *pr); |
| 338 | extern const struct thermal_cooling_device_ops processor_cooling_ops; | 344 | extern const struct thermal_cooling_device_ops processor_cooling_ops; |
