aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2016-08-03 04:01:24 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-08-30 18:32:10 -0400
commit750f628be68e8b8e1624d8abd003b9f1fc758ed6 (patch)
treefe4ea4b8c29a0448420106ed5a7e4ed2ec793464
parentdf45db6177f8dde380d44149cca46ad800a00575 (diff)
ACPI / EC: Add EC_FLAGS_QUERY_ENABLED to reveal a hidden logic
There is a hidden logic in the EC driver: 1. During boot, EC_FLAGS_QUERY_PENDING is responsible for blocking event handling; 2. During suspend, EC_FLAGS_STARTED is responsible for blocking event handling. This patch uses a new EC_FLAGS_QUERY_ENABLED flag to make this hidden logic explicit and have code cleaned up. No functional change. Signed-off-by: Lv Zheng <lv.zheng@intel.com> Tested-by: Todd E Brandt <todd.e.brandt@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/ec.c103
1 files changed, 71 insertions, 32 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 6f6c7d1eaf8c..4ab34d7dd943 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -104,6 +104,7 @@ enum ec_command {
104#define ACPI_EC_MAX_QUERIES 16 /* Maximum number of parallel queries */ 104#define ACPI_EC_MAX_QUERIES 16 /* Maximum number of parallel queries */
105 105
106enum { 106enum {
107 EC_FLAGS_QUERY_ENABLED, /* Query is enabled */
107 EC_FLAGS_QUERY_PENDING, /* Query is pending */ 108 EC_FLAGS_QUERY_PENDING, /* Query is pending */
108 EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */ 109 EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */
109 EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */ 110 EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */
@@ -239,6 +240,22 @@ static bool acpi_ec_started(struct acpi_ec *ec)
239 !test_bit(EC_FLAGS_STOPPED, &ec->flags); 240 !test_bit(EC_FLAGS_STOPPED, &ec->flags);
240} 241}
241 242
243static bool acpi_ec_event_enabled(struct acpi_ec *ec)
244{
245 /*
246 * There is an OSPM early stage logic. During the early stages
247 * (boot/resume), OSPMs shouldn't enable the event handling, only
248 * the EC transactions are allowed to be performed.
249 */
250 if (!test_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))
251 return false;
252 /*
253 * The EC event handling is automatically disabled as soon as the
254 * EC driver is stopped.
255 */
256 return test_bit(EC_FLAGS_STARTED, &ec->flags);
257}
258
242static bool acpi_ec_flushed(struct acpi_ec *ec) 259static bool acpi_ec_flushed(struct acpi_ec *ec)
243{ 260{
244 return ec->reference_count == 1; 261 return ec->reference_count == 1;
@@ -429,7 +446,8 @@ static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec)
429 446
430static void acpi_ec_submit_query(struct acpi_ec *ec) 447static void acpi_ec_submit_query(struct acpi_ec *ec)
431{ 448{
432 if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { 449 if (acpi_ec_event_enabled(ec) &&
450 !test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
433 ec_dbg_evt("Command(%s) submitted/blocked", 451 ec_dbg_evt("Command(%s) submitted/blocked",
434 acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); 452 acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY));
435 ec->nr_pending_queries++; 453 ec->nr_pending_queries++;
@@ -446,6 +464,52 @@ static void acpi_ec_complete_query(struct acpi_ec *ec)
446 } 464 }
447} 465}
448 466
467static inline void __acpi_ec_enable_event(struct acpi_ec *ec)
468{
469 if (!test_and_set_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))
470 ec_log_drv("event unblocked");
471}
472
473static inline void __acpi_ec_disable_event(struct acpi_ec *ec)
474{
475 if (test_and_clear_bit(EC_FLAGS_QUERY_ENABLED, &ec->flags))
476 ec_log_drv("event blocked");
477}
478
479/*
480 * Process _Q events that might have accumulated in the EC.
481 * Run with locked ec mutex.
482 */
483static void acpi_ec_clear(struct acpi_ec *ec)
484{
485 int i, status;
486 u8 value = 0;
487
488 for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
489 status = acpi_ec_query(ec, &value);
490 if (status || !value)
491 break;
492 }
493 if (unlikely(i == ACPI_EC_CLEAR_MAX))
494 pr_warn("Warning: Maximum of %d stale EC events cleared\n", i);
495 else
496 pr_info("%d stale EC events cleared\n", i);
497}
498
499static void acpi_ec_enable_event(struct acpi_ec *ec)
500{
501 unsigned long flags;
502
503 spin_lock_irqsave(&ec->lock, flags);
504 if (acpi_ec_started(ec))
505 __acpi_ec_enable_event(ec);
506 spin_unlock_irqrestore(&ec->lock, flags);
507
508 /* Drain additional events if hardware requires that */
509 if (EC_FLAGS_CLEAR_ON_RESUME)
510 acpi_ec_clear(ec);
511}
512
449static bool acpi_ec_guard_event(struct acpi_ec *ec) 513static bool acpi_ec_guard_event(struct acpi_ec *ec)
450{ 514{
451 bool guarded = true; 515 bool guarded = true;
@@ -832,27 +896,6 @@ acpi_handle ec_get_handle(void)
832} 896}
833EXPORT_SYMBOL(ec_get_handle); 897EXPORT_SYMBOL(ec_get_handle);
834 898
835/*
836 * Process _Q events that might have accumulated in the EC.
837 * Run with locked ec mutex.
838 */
839static void acpi_ec_clear(struct acpi_ec *ec)
840{
841 int i, status;
842 u8 value = 0;
843
844 for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
845 status = acpi_ec_query(ec, &value);
846 if (status || !value)
847 break;
848 }
849
850 if (unlikely(i == ACPI_EC_CLEAR_MAX))
851 pr_warn("Warning: Maximum of %d stale EC events cleared\n", i);
852 else
853 pr_info("%d stale EC events cleared\n", i);
854}
855
856static void acpi_ec_start(struct acpi_ec *ec, bool resuming) 899static void acpi_ec_start(struct acpi_ec *ec, bool resuming)
857{ 900{
858 unsigned long flags; 901 unsigned long flags;
@@ -864,7 +907,8 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming)
864 if (!resuming) { 907 if (!resuming) {
865 acpi_ec_submit_request(ec); 908 acpi_ec_submit_request(ec);
866 ec_dbg_ref(ec, "Increase driver"); 909 ec_dbg_ref(ec, "Increase driver");
867 } 910 } else
911 __acpi_ec_enable_event(ec);
868 ec_log_drv("EC started"); 912 ec_log_drv("EC started");
869 } 913 }
870 spin_unlock_irqrestore(&ec->lock, flags); 914 spin_unlock_irqrestore(&ec->lock, flags);
@@ -896,7 +940,8 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
896 if (!suspending) { 940 if (!suspending) {
897 acpi_ec_complete_request(ec); 941 acpi_ec_complete_request(ec);
898 ec_dbg_ref(ec, "Decrease driver"); 942 ec_dbg_ref(ec, "Decrease driver");
899 } 943 } else
944 __acpi_ec_disable_event(ec);
900 clear_bit(EC_FLAGS_STARTED, &ec->flags); 945 clear_bit(EC_FLAGS_STARTED, &ec->flags);
901 clear_bit(EC_FLAGS_STOPPED, &ec->flags); 946 clear_bit(EC_FLAGS_STOPPED, &ec->flags);
902 ec_log_drv("EC stopped"); 947 ec_log_drv("EC stopped");
@@ -927,8 +972,7 @@ void acpi_ec_unblock_transactions(void)
927 /* Allow transactions to be carried out again */ 972 /* Allow transactions to be carried out again */
928 acpi_ec_start(ec, true); 973 acpi_ec_start(ec, true);
929 974
930 if (EC_FLAGS_CLEAR_ON_RESUME) 975 acpi_ec_enable_event(ec);
931 acpi_ec_clear(ec);
932} 976}
933 977
934void acpi_ec_unblock_transactions_early(void) 978void acpi_ec_unblock_transactions_early(void)
@@ -1234,7 +1278,6 @@ static struct acpi_ec *make_acpi_ec(void)
1234 1278
1235 if (!ec) 1279 if (!ec)
1236 return NULL; 1280 return NULL;
1237 ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
1238 mutex_init(&ec->mutex); 1281 mutex_init(&ec->mutex);
1239 init_waitqueue_head(&ec->wait); 1282 init_waitqueue_head(&ec->wait);
1240 INIT_LIST_HEAD(&ec->list); 1283 INIT_LIST_HEAD(&ec->list);
@@ -1421,11 +1464,7 @@ static int acpi_ec_add(struct acpi_device *device)
1421 acpi_walk_dep_device_list(ec->handle); 1464 acpi_walk_dep_device_list(ec->handle);
1422 1465
1423 /* EC is fully operational, allow queries */ 1466 /* EC is fully operational, allow queries */
1424 clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); 1467 acpi_ec_enable_event(ec);
1425
1426 /* Clear stale _Q events if hardware might require that */
1427 if (EC_FLAGS_CLEAR_ON_RESUME)
1428 acpi_ec_clear(ec);
1429 return ret; 1468 return ret;
1430} 1469}
1431 1470