diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-13 15:38:20 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-02-13 15:38:20 -0500 |
commit | 69bf75e9ae2d02304fe42b32daaa8d173705afc6 (patch) | |
tree | 61a9680212f3718930039d8221c6758d8742e872 | |
parent | 872912352c5be930e9568e5f3b6d73107d9f278d (diff) | |
parent | 37d11391c2de8a846da50a2972a82289e65e5ea6 (diff) |
Merge branch 'acpi-ec'
* acpi-ec:
Revert "ACPI / EC: Add query flushing support"
Revert "ACPI / EC: Add GPE reference counting debugging messages"
-rw-r--r-- | drivers/acpi/ec.c | 125 |
1 files changed, 18 insertions, 107 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) { |
481 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 401 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
482 | acpi_ec_complete_event(ec); | ||
483 | wakeup = true; | 402 | wakeup = true; |
484 | } | 403 | } |
485 | goto out; | 404 | goto out; |
@@ -488,17 +407,16 @@ static void advance_transaction(struct acpi_ec *ec) | |||
488 | !(status & ACPI_EC_FLAG_SCI) && | 407 | !(status & ACPI_EC_FLAG_SCI) && |
489 | (t->command == ACPI_EC_COMMAND_QUERY)) { | 408 | (t->command == ACPI_EC_COMMAND_QUERY)) { |
490 | t->flags |= ACPI_EC_COMMAND_POLL; | 409 | t->flags |= ACPI_EC_COMMAND_POLL; |
491 | acpi_ec_complete_detection(ec); | 410 | acpi_ec_complete_query(ec); |
492 | t->rdata[t->ri++] = 0x00; | 411 | t->rdata[t->ri++] = 0x00; |
493 | t->flags |= ACPI_EC_COMMAND_COMPLETE; | 412 | t->flags |= ACPI_EC_COMMAND_COMPLETE; |
494 | acpi_ec_complete_event(ec); | ||
495 | pr_debug("***** Command(%s) software completion *****\n", | 413 | pr_debug("***** Command(%s) software completion *****\n", |
496 | acpi_ec_cmd_string(t->command)); | 414 | acpi_ec_cmd_string(t->command)); |
497 | wakeup = true; | 415 | wakeup = true; |
498 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { | 416 | } else if ((status & ACPI_EC_FLAG_IBF) == 0) { |
499 | acpi_ec_write_cmd(ec, t->command); | 417 | acpi_ec_write_cmd(ec, t->command); |
500 | t->flags |= ACPI_EC_COMMAND_POLL; | 418 | t->flags |= ACPI_EC_COMMAND_POLL; |
501 | acpi_ec_complete_detection(ec); | 419 | acpi_ec_complete_query(ec); |
502 | } else | 420 | } else |
503 | goto err; | 421 | goto err; |
504 | goto out; | 422 | goto out; |
@@ -519,7 +437,7 @@ err: | |||
519 | } | 437 | } |
520 | out: | 438 | out: |
521 | if (status & ACPI_EC_FLAG_SCI) | 439 | if (status & ACPI_EC_FLAG_SCI) |
522 | acpi_ec_submit_detection(ec); | 440 | acpi_ec_submit_query(ec); |
523 | if (wakeup && in_interrupt()) | 441 | if (wakeup && in_interrupt()) |
524 | wake_up(&ec->wait); | 442 | wake_up(&ec->wait); |
525 | } | 443 | } |
@@ -580,11 +498,10 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
580 | /* start transaction */ | 498 | /* start transaction */ |
581 | spin_lock_irqsave(&ec->lock, tmp); | 499 | spin_lock_irqsave(&ec->lock, tmp); |
582 | /* Enable GPE for command processing (IBF=0/OBF=1) */ | 500 | /* Enable GPE for command processing (IBF=0/OBF=1) */ |
583 | if (!acpi_ec_submit_flushable_request(ec, true)) { | 501 | if (!acpi_ec_submit_flushable_request(ec)) { |
584 | ret = -EINVAL; | 502 | ret = -EINVAL; |
585 | goto unlock; | 503 | goto unlock; |
586 | } | 504 | } |
587 | ec_debug_ref(ec, "Increase command\n"); | ||
588 | /* following two actions should be kept atomic */ | 505 | /* following two actions should be kept atomic */ |
589 | ec->curr = t; | 506 | ec->curr = t; |
590 | pr_debug("***** Command(%s) started *****\n", | 507 | pr_debug("***** Command(%s) started *****\n", |
@@ -600,7 +517,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
600 | ec->curr = NULL; | 517 | ec->curr = NULL; |
601 | /* Disable GPE for command processing (IBF=0/OBF=1) */ | 518 | /* Disable GPE for command processing (IBF=0/OBF=1) */ |
602 | acpi_ec_complete_request(ec); | 519 | acpi_ec_complete_request(ec); |
603 | ec_debug_ref(ec, "Decrease command\n"); | ||
604 | unlock: | 520 | unlock: |
605 | spin_unlock_irqrestore(&ec->lock, tmp); | 521 | spin_unlock_irqrestore(&ec->lock, tmp); |
606 | return ret; | 522 | return ret; |
@@ -762,10 +678,8 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming) | |||
762 | if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { | 678 | if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { |
763 | pr_debug("+++++ Starting EC +++++\n"); | 679 | pr_debug("+++++ Starting EC +++++\n"); |
764 | /* Enable GPE for event processing (SCI_EVT=1) */ | 680 | /* Enable GPE for event processing (SCI_EVT=1) */ |
765 | if (!resuming) { | 681 | if (!resuming) |
766 | acpi_ec_submit_request(ec); | 682 | acpi_ec_submit_request(ec); |
767 | ec_debug_ref(ec, "Increase driver\n"); | ||
768 | } | ||
769 | pr_info("+++++ EC started +++++\n"); | 683 | pr_info("+++++ EC started +++++\n"); |
770 | } | 684 | } |
771 | spin_unlock_irqrestore(&ec->lock, flags); | 685 | spin_unlock_irqrestore(&ec->lock, flags); |
@@ -794,10 +708,8 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) | |||
794 | wait_event(ec->wait, acpi_ec_stopped(ec)); | 708 | wait_event(ec->wait, acpi_ec_stopped(ec)); |
795 | spin_lock_irqsave(&ec->lock, flags); | 709 | spin_lock_irqsave(&ec->lock, flags); |
796 | /* Disable GPE for event processing (SCI_EVT=1) */ | 710 | /* Disable GPE for event processing (SCI_EVT=1) */ |
797 | if (!suspending) { | 711 | if (!suspending) |
798 | acpi_ec_complete_request(ec); | 712 | acpi_ec_complete_request(ec); |
799 | ec_debug_ref(ec, "Decrease driver\n"); | ||
800 | } | ||
801 | clear_bit(EC_FLAGS_STARTED, &ec->flags); | 713 | clear_bit(EC_FLAGS_STARTED, &ec->flags); |
802 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); | 714 | clear_bit(EC_FLAGS_STOPPED, &ec->flags); |
803 | pr_info("+++++ EC stopped +++++\n"); | 715 | pr_info("+++++ EC stopped +++++\n"); |
@@ -967,9 +879,7 @@ static void acpi_ec_gpe_poller(struct work_struct *work) | |||
967 | { | 879 | { |
968 | struct acpi_ec *ec = container_of(work, struct acpi_ec, work); | 880 | struct acpi_ec *ec = container_of(work, struct acpi_ec, work); |
969 | 881 | ||
970 | pr_debug("***** Event poller started *****\n"); | ||
971 | acpi_ec_query(ec, NULL); | 882 | acpi_ec_query(ec, NULL); |
972 | pr_debug("***** Event poller stopped *****\n"); | ||
973 | } | 883 | } |
974 | 884 | ||
975 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | 885 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
@@ -1039,6 +949,7 @@ static struct acpi_ec *make_acpi_ec(void) | |||
1039 | 949 | ||
1040 | if (!ec) | 950 | if (!ec) |
1041 | return NULL; | 951 | return NULL; |
952 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; | ||
1042 | mutex_init(&ec->mutex); | 953 | mutex_init(&ec->mutex); |
1043 | init_waitqueue_head(&ec->wait); | 954 | init_waitqueue_head(&ec->wait); |
1044 | INIT_LIST_HEAD(&ec->list); | 955 | INIT_LIST_HEAD(&ec->list); |
@@ -1189,7 +1100,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
1189 | ret = ec_install_handlers(ec); | 1100 | ret = ec_install_handlers(ec); |
1190 | 1101 | ||
1191 | /* EC is fully operational, allow queries */ | 1102 | /* EC is fully operational, allow queries */ |
1192 | acpi_ec_enable_event(ec); | 1103 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
1193 | 1104 | ||
1194 | /* Clear stale _Q events if hardware might require that */ | 1105 | /* Clear stale _Q events if hardware might require that */ |
1195 | if (EC_FLAGS_CLEAR_ON_RESUME) | 1106 | if (EC_FLAGS_CLEAR_ON_RESUME) |