aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2017-01-20 03:42:48 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-21 03:31:24 -0400
commit0dd962118a201a19d8c5c01e4909bfc07c288d6c (patch)
tree1ad030e09ee0f169d008bb1a73b11be3275a3a2c
parentc07479f4b10ac3faa5168881e7751681d59de7e7 (diff)
ACPI / EC: Use busy polling mode when GPE is not enabled
commit c3a696b6e8f8f75f9f75e556a9f9f6472eae2655 upstream. When GPE is not enabled, it is not efficient to use the wait polling mode as it introduces an unexpected scheduler delay. So before the GPE handler is installed, this patch uses busy polling mode for all EC(s) and the logic can be applied to non boot EC(s) during the suspend/resume process. Link: https://bugzilla.kernel.org/show_bug.cgi?id=191561 Tested-by: Jakobus Schurz <jakobus.schurz@gmail.com> Tested-by: Chen Yu <yu.c.chen@intel.com> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Cc: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/acpi/ec.c62
-rw-r--r--drivers/acpi/internal.h4
2 files changed, 32 insertions, 34 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 48e19d013170..22ca89242518 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -729,12 +729,12 @@ static void start_transaction(struct acpi_ec *ec)
729 729
730static int ec_guard(struct acpi_ec *ec) 730static int ec_guard(struct acpi_ec *ec)
731{ 731{
732 unsigned long guard = usecs_to_jiffies(ec_polling_guard); 732 unsigned long guard = usecs_to_jiffies(ec->polling_guard);
733 unsigned long timeout = ec->timestamp + guard; 733 unsigned long timeout = ec->timestamp + guard;
734 734
735 /* Ensure guarding period before polling EC status */ 735 /* Ensure guarding period before polling EC status */
736 do { 736 do {
737 if (ec_busy_polling) { 737 if (ec->busy_polling) {
738 /* Perform busy polling */ 738 /* Perform busy polling */
739 if (ec_transaction_completed(ec)) 739 if (ec_transaction_completed(ec))
740 return 0; 740 return 0;
@@ -998,6 +998,28 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
998 spin_unlock_irqrestore(&ec->lock, flags); 998 spin_unlock_irqrestore(&ec->lock, flags);
999} 999}
1000 1000
1001static void acpi_ec_enter_noirq(struct acpi_ec *ec)
1002{
1003 unsigned long flags;
1004
1005 spin_lock_irqsave(&ec->lock, flags);
1006 ec->busy_polling = true;
1007 ec->polling_guard = 0;
1008 ec_log_drv("interrupt blocked");
1009 spin_unlock_irqrestore(&ec->lock, flags);
1010}
1011
1012static void acpi_ec_leave_noirq(struct acpi_ec *ec)
1013{
1014 unsigned long flags;
1015
1016 spin_lock_irqsave(&ec->lock, flags);
1017 ec->busy_polling = ec_busy_polling;
1018 ec->polling_guard = ec_polling_guard;
1019 ec_log_drv("interrupt unblocked");
1020 spin_unlock_irqrestore(&ec->lock, flags);
1021}
1022
1001void acpi_ec_block_transactions(void) 1023void acpi_ec_block_transactions(void)
1002{ 1024{
1003 struct acpi_ec *ec = first_ec; 1025 struct acpi_ec *ec = first_ec;
@@ -1278,7 +1300,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
1278 if (function != ACPI_READ && function != ACPI_WRITE) 1300 if (function != ACPI_READ && function != ACPI_WRITE)
1279 return AE_BAD_PARAMETER; 1301 return AE_BAD_PARAMETER;
1280 1302
1281 if (ec_busy_polling || bits > 8) 1303 if (ec->busy_polling || bits > 8)
1282 acpi_ec_burst_enable(ec); 1304 acpi_ec_burst_enable(ec);
1283 1305
1284 for (i = 0; i < bytes; ++i, ++address, ++value) 1306 for (i = 0; i < bytes; ++i, ++address, ++value)
@@ -1286,7 +1308,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
1286 acpi_ec_read(ec, address, value) : 1308 acpi_ec_read(ec, address, value) :
1287 acpi_ec_write(ec, address, *value); 1309 acpi_ec_write(ec, address, *value);
1288 1310
1289 if (ec_busy_polling || bits > 8) 1311 if (ec->busy_polling || bits > 8)
1290 acpi_ec_burst_disable(ec); 1312 acpi_ec_burst_disable(ec);
1291 1313
1292 switch (result) { 1314 switch (result) {
@@ -1329,6 +1351,8 @@ static struct acpi_ec *acpi_ec_alloc(void)
1329 spin_lock_init(&ec->lock); 1351 spin_lock_init(&ec->lock);
1330 INIT_WORK(&ec->work, acpi_ec_event_handler); 1352 INIT_WORK(&ec->work, acpi_ec_event_handler);
1331 ec->timestamp = jiffies; 1353 ec->timestamp = jiffies;
1354 ec->busy_polling = true;
1355 ec->polling_guard = 0;
1332 return ec; 1356 return ec;
1333} 1357}
1334 1358
@@ -1390,6 +1414,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
1390 acpi_ec_start(ec, false); 1414 acpi_ec_start(ec, false);
1391 1415
1392 if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { 1416 if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
1417 acpi_ec_enter_noirq(ec);
1393 status = acpi_install_address_space_handler(ec->handle, 1418 status = acpi_install_address_space_handler(ec->handle,
1394 ACPI_ADR_SPACE_EC, 1419 ACPI_ADR_SPACE_EC,
1395 &acpi_ec_space_handler, 1420 &acpi_ec_space_handler,
@@ -1429,6 +1454,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
1429 /* This is not fatal as we can poll EC events */ 1454 /* This is not fatal as we can poll EC events */
1430 if (ACPI_SUCCESS(status)) { 1455 if (ACPI_SUCCESS(status)) {
1431 set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); 1456 set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags);
1457 acpi_ec_leave_noirq(ec);
1432 if (test_bit(EC_FLAGS_STARTED, &ec->flags) && 1458 if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
1433 ec->reference_count >= 1) 1459 ec->reference_count >= 1)
1434 acpi_ec_enable_gpe(ec, true); 1460 acpi_ec_enable_gpe(ec, true);
@@ -1839,34 +1865,6 @@ error:
1839} 1865}
1840 1866
1841#ifdef CONFIG_PM_SLEEP 1867#ifdef CONFIG_PM_SLEEP
1842static void acpi_ec_enter_noirq(struct acpi_ec *ec)
1843{
1844 unsigned long flags;
1845
1846 if (ec == first_ec) {
1847 spin_lock_irqsave(&ec->lock, flags);
1848 ec->saved_busy_polling = ec_busy_polling;
1849 ec->saved_polling_guard = ec_polling_guard;
1850 ec_busy_polling = true;
1851 ec_polling_guard = 0;
1852 ec_log_drv("interrupt blocked");
1853 spin_unlock_irqrestore(&ec->lock, flags);
1854 }
1855}
1856
1857static void acpi_ec_leave_noirq(struct acpi_ec *ec)
1858{
1859 unsigned long flags;
1860
1861 if (ec == first_ec) {
1862 spin_lock_irqsave(&ec->lock, flags);
1863 ec_busy_polling = ec->saved_busy_polling;
1864 ec_polling_guard = ec->saved_polling_guard;
1865 ec_log_drv("interrupt unblocked");
1866 spin_unlock_irqrestore(&ec->lock, flags);
1867 }
1868}
1869
1870static int acpi_ec_suspend_noirq(struct device *dev) 1868static int acpi_ec_suspend_noirq(struct device *dev)
1871{ 1869{
1872 struct acpi_ec *ec = 1870 struct acpi_ec *ec =
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 0c452265c111..219b90bc0922 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -172,8 +172,8 @@ struct acpi_ec {
172 struct work_struct work; 172 struct work_struct work;
173 unsigned long timestamp; 173 unsigned long timestamp;
174 unsigned long nr_pending_queries; 174 unsigned long nr_pending_queries;
175 bool saved_busy_polling; 175 bool busy_polling;
176 unsigned int saved_polling_guard; 176 unsigned int polling_guard;
177}; 177};
178 178
179extern struct acpi_ec *first_ec; 179extern struct acpi_ec *first_ec;