diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-13 16:45:57 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-13 16:45:57 -0500 |
| commit | 18320f2a6871aaf2522f793fee4a67eccf5e131a (patch) | |
| tree | bb900ce16b590a5e1ae8fcff78e5677e99fcbd35 | |
| parent | db3ecdee1cf0538f11832f7ef66945c4dd903918 (diff) | |
| parent | c7fb90dfbef49b03e6f3fd6a32338e59cbcf34ee (diff) | |
Merge tag 'pm+acpi-3.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI and power management updates from Rafael Wysocki:
"These are two reverts related to system suspend breakage by one of a
recent commits, a fix for a recently introduced bug in devfreq and a
bunch of other things that didn't make it into my previous pull
request, but otherwise are ready to go.
Specifics:
- Revert two ACPI EC driver commits, one that broke system suspend on
Acer Aspire S5 and one that depends on it (Rafael J Wysocki).
- Fix a typo leading to an incorrect check in the exynos-ppmu devfreq
driver (Dan Carpenter).
- Add support for one more Broadwell CPU model to intel_idle (Len Brown).
- Fix an obscure problem with state transitions related to interrupts
in the speedstep-smi cpufreq driver (Mikulas Patocka).
- Remove some unnecessary messages related to the "out of memory"
condition from the core PM code (Quentin Lambert).
- Update turbostat parameters and documentation, add support for one
more Broadwell CPU model to it and modify it to skip printing
disabled package C-states (Len Brown)"
* tag 'pm+acpi-3.20-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM / devfreq: event: testing the wrong variable
cpufreq: speedstep-smi: enable interrupts when waiting
PM / OPP / clk: Remove unnecessary OOM message
Revert "ACPI / EC: Add query flushing support"
Revert "ACPI / EC: Add GPE reference counting debugging messages"
tools/power turbostat: support additional Broadwell model
intel_idle: support additional Broadwell model
tools/power turbostat: update parameters, documentation
tools/power turbostat: Skip printing disabled package C-states
| -rw-r--r-- | drivers/acpi/ec.c | 125 | ||||
| -rw-r--r-- | drivers/base/firmware_class.c | 1 | ||||
| -rw-r--r-- | drivers/base/power/clock_ops.c | 4 | ||||
| -rw-r--r-- | drivers/base/power/opp.c | 8 | ||||
| -rw-r--r-- | drivers/cpufreq/speedstep-lib.c | 3 | ||||
| -rw-r--r-- | drivers/cpufreq/speedstep-smi.c | 12 | ||||
| -rw-r--r-- | drivers/devfreq/event/exynos-ppmu.c | 4 | ||||
| -rw-r--r-- | drivers/idle/intel_idle.c | 1 | ||||
| -rw-r--r-- | tools/power/x86/turbostat/turbostat.8 | 68 | ||||
| -rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 344 |
10 files changed, 293 insertions, 277 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 14d0c89ada2a..982b67faaaf3 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | /* Uncomment next line to get verbose printout */ | 32 | /* Uncomment next line to get verbose printout */ |
| 33 | /* #define DEBUG */ | 33 | /* #define DEBUG */ |
| 34 | #define DEBUG_REF 0 | ||
| 35 | #define pr_fmt(fmt) "ACPI : EC: " fmt | 34 | #define pr_fmt(fmt) "ACPI : EC: " fmt |
| 36 | 35 | ||
| 37 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
| @@ -77,9 +76,7 @@ enum ec_command { | |||
| 77 | * when trying to clear the EC */ | 76 | * when trying to clear the EC */ |
| 78 | 77 | ||
| 79 | enum { | 78 | enum { |
| 80 | EC_FLAGS_EVENT_ENABLED, /* Event is enabled */ | 79 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
| 81 | EC_FLAGS_EVENT_PENDING, /* Event is pending */ | ||
| 82 | EC_FLAGS_EVENT_DETECTED, /* Event is detected */ | ||
| 83 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and | 80 | EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and |
| 84 | * OpReg are installed */ | 81 | * OpReg are installed */ |
| 85 | EC_FLAGS_STARTED, /* Driver is started */ | 82 | EC_FLAGS_STARTED, /* Driver is started */ |
| @@ -91,13 +88,6 @@ enum { | |||
| 91 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ | 88 | #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ |
| 92 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ | 89 | #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ |
| 93 | 90 | ||
| 94 | #define ec_debug_ref(ec, fmt, ...) \ | ||
| 95 | do { \ | ||
| 96 | if (DEBUG_REF) \ | ||
| 97 | pr_debug("%lu: " fmt, ec->reference_count, \ | ||
| 98 | ## __VA_ARGS__); \ | ||
| 99 | } while (0) | ||
| 100 | |||
| 101 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ | 91 | /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ |
| 102 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; | 92 | static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; |
| 103 | module_param(ec_delay, uint, 0644); | 93 | module_param(ec_delay, uint, 0644); |
| @@ -161,12 +151,6 @@ static bool acpi_ec_flushed(struct acpi_ec *ec) | |||
| 161 | return ec->reference_count == 1; | 151 | return ec->reference_count == 1; |
| 162 | } | 152 | } |
| 163 | 153 | ||
| 164 | static bool acpi_ec_has_pending_event(struct acpi_ec *ec) | ||
| 165 | { | ||
| 166 | return test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || | ||
| 167 | test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); | ||
| 168 | } | ||
| 169 | |||
| 170 | /* -------------------------------------------------------------------------- | 154 | /* -------------------------------------------------------------------------- |
| 171 | * EC Registers | 155 | * EC Registers |
| 172 | * -------------------------------------------------------------------------- */ | 156 | * -------------------------------------------------------------------------- */ |
| @@ -334,97 +318,34 @@ static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) | |||
| 334 | * the flush operation is not in | 318 | * the flush operation is not in |
| 335 | * progress | 319 | * progress |
| 336 | * @ec: the EC device | 320 | * @ec: the EC device |
| 337 | * @allow_event: whether event should be handled | ||
| 338 | * | 321 | * |
| 339 | * This function must be used before taking a new action that should hold | 322 | * This function must be used before taking a new action that should hold |
| 340 | * the reference count. If this function returns false, then the action | 323 | * the reference count. If this function returns false, then the action |
| 341 | * must be discarded or it will prevent the flush operation from being | 324 | * must be discarded or it will prevent the flush operation from being |
| 342 | * completed. | 325 | * completed. |
| 343 | * | ||
| 344 | * During flushing, QR_EC command need to pass this check when there is a | ||
| 345 | * pending event, so that the reference count held for the pending event | ||
| 346 | * can be decreased by the completion of the QR_EC command. | ||
| 347 | */ | 326 | */ |
| 348 | static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec, | 327 | static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) |
| 349 | bool allow_event) | ||
| 350 | { | 328 | { |
| 351 | if (!acpi_ec_started(ec)) { | 329 | if (!acpi_ec_started(ec)) |
| 352 | if (!allow_event || !acpi_ec_has_pending_event(ec)) | 330 | return false; |
| 353 | return false; | ||
| 354 | } | ||
| 355 | acpi_ec_submit_request(ec); | 331 | acpi_ec_submit_request(ec); |
| 356 | return true; | 332 | return true; |
| 357 | } | 333 | } |
| 358 | 334 | ||
| 359 | static void acpi_ec_submit_event(struct acpi_ec *ec) | 335 | static void acpi_ec_submit_query(struct acpi_ec *ec) |
| 360 | { | 336 | { |
| 361 | if (!test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || | 337 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { |
| 362 | !test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags)) | 338 | pr_debug("***** Event started *****\n"); |
| 363 | return; | ||
| 364 | /* Hold reference for pending event */ | ||
| 365 | if (!acpi_ec_submit_flushable_request(ec, true)) | ||
| 366 | return; | ||
| 367 | ec_debug_ref(ec, "Increase event\n"); | ||
| 368 | if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { | ||
| 369 | pr_debug("***** Event query started *****\n"); | ||
| 370 | schedule_work(&ec->work); | 339 | schedule_work(&ec->work); |
| 371 | return; | ||
| 372 | } | 340 | } |
| 373 | acpi_ec_complete_request(ec); | ||
| 374 | ec_debug_ref(ec, "Decrease event\n"); | ||
| 375 | } | 341 | } |
| 376 | 342 | ||
| 377 | static void acpi_ec_complete_event(struct acpi_ec *ec) | 343 | static void acpi_ec_complete_query(struct acpi_ec *ec) |
| 378 | { | 344 | { |
| 379 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | 345 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { |
| 380 | clear_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); | 346 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
| 381 | pr_debug("***** Event query stopped *****\n"); | 347 | pr_debug("***** Event stopped *****\n"); |
| 382 | /* Unhold reference for pending event */ | ||
| 383 | acpi_ec_complete_request(ec); | ||
| 384 | ec_debug_ref(ec, "Decrease event\n"); | ||
| 385 | /* Check if there is another SCI_EVT detected */ | ||
| 386 | acpi_ec_submit_event(ec); | ||
| 387 | } | ||
| 388 | } | ||
| 389 | |||
| 390 | static void acpi_ec_submit_detection(struct acpi_ec *ec) | ||
| 391 | { | ||
| 392 | /* Hold reference for query submission */ | ||
| 393 | if (!acpi_ec_submit_flushable_request(ec, false)) | ||
| 394 | return; | ||
| 395 | ec_debug_ref(ec, "Increase query\n"); | ||
| 396 | if (!test_and_set_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags)) { | ||
| 397 | pr_debug("***** Event detection blocked *****\n"); | ||
| 398 | acpi_ec_submit_event(ec); | ||
| 399 | return; | ||
| 400 | } | 348 | } |
| 401 | acpi_ec_complete_request(ec); | ||
| 402 | ec_debug_ref(ec, "Decrease query\n"); | ||
| 403 | } | ||
| 404 | |||
| 405 | static void acpi_ec_complete_detection(struct acpi_ec *ec) | ||
| 406 | { | ||
| 407 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { | ||
| 408 | clear_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags); | ||
| 409 | pr_debug("***** Event detetion unblocked *****\n"); | ||
| 410 | /* Unhold reference for query submission */ | ||
| 411 | acpi_ec_complete_request(ec); | ||
| 412 | ec_debug_ref(ec, "Decrease query\n"); | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 416 | static void acpi_ec_enable_event(struct acpi_ec *ec) | ||
| 417 | { | ||
| 418 | unsigned long flags; | ||
| 419 | |||
| 420 | spin_lock_irqsave(&ec->lock, flags); | ||
| 421 | set_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags); | ||
| 422 | /* | ||
| 423 | * An event may be pending even with SCI_EVT=0, so QR_EC should | ||
| 424 | * always be issued right after started. | ||
| 425 | */ | ||
| 426 | acpi_ec_submit_detection(ec); | ||
| 427 | spin_unlock_irqrestore(&ec->lock, flags); | ||
| 428 | } | 349 | } |
| 429 | 350 | ||
| 430 | static int ec_transaction_completed(struct acpi_ec *ec) | 351 | static int ec_transaction_completed(struct acpi_ec *ec) |
| @@ -468,7 +389,6 @@ static void advance_transaction(struct acpi_ec *ec) | |||
| 468 | t->rdata[t->ri++] = acpi_ec_read_data(ec); | 389 | t->rdata[t->ri++] = acpi_ec_read_data(ec); |
| 469 | if (t->rlen == t->ri) { | 390 | if (t->rlen == t->ri) { |
| 470 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 391 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
| 471 | acpi_ec_complete_event(ec); | ||
| 472 | if (t->command == ACPI_EC_COMMAND_QUERY) | 392 | if (t->command == ACPI_EC_COMMAND_QUERY) |
| 473 | pr_debug("***** Command(%s) hardware completion *****\n", | 393 | pr_debug("***** Command(%s) hardware completion *****\n", |
| 474 | acpi_ec_cmd_string(t->command)); | 394 | acpi_ec_cmd_string(t->command)); |
| @@ -479,7 +399,6 @@ static void advance_transaction(struct acpi_ec *ec) | |||
| 479 | } else if (t->wlen == t->wi && | 399 | } else if (t->wlen == t->wi && |
| 480 | (status & ACPI_EC_FLAG_IBF) == 0) { | 400 | (status & ACPI_EC_FLAG_IBF) == 0) { |
