diff options
| -rw-r--r-- | drivers/acpi/ec.c | 62 | ||||
| -rw-r--r-- | drivers/acpi/internal.h | 4 |
2 files changed, 32 insertions, 34 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 6a32cd4ec9da..c24235d8fb52 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
| @@ -704,12 +704,12 @@ static void start_transaction(struct acpi_ec *ec) | |||
| 704 | 704 | ||
| 705 | static int ec_guard(struct acpi_ec *ec) | 705 | static int ec_guard(struct acpi_ec *ec) |
| 706 | { | 706 | { |
| 707 | unsigned long guard = usecs_to_jiffies(ec_polling_guard); | 707 | unsigned long guard = usecs_to_jiffies(ec->polling_guard); |
| 708 | unsigned long timeout = ec->timestamp + guard; | 708 | unsigned long timeout = ec->timestamp + guard; |
| 709 | 709 | ||
| 710 | /* Ensure guarding period before polling EC status */ | 710 | /* Ensure guarding period before polling EC status */ |
| 711 | do { | 711 | do { |
| 712 | if (ec_busy_polling) { | 712 | if (ec->busy_polling) { |
| 713 | /* Perform busy polling */ | 713 | /* Perform busy polling */ |
| 714 | if (ec_transaction_completed(ec)) | 714 | if (ec_transaction_completed(ec)) |
| 715 | return 0; | 715 | return 0; |
| @@ -973,6 +973,28 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) | |||
| 973 | spin_unlock_irqrestore(&ec->lock, flags); | 973 | spin_unlock_irqrestore(&ec->lock, flags); |
| 974 | } | 974 | } |
| 975 | 975 | ||
| 976 | static void acpi_ec_enter_noirq(struct acpi_ec *ec) | ||
| 977 | { | ||
| 978 | unsigned long flags; | ||
| 979 | |||
| 980 | spin_lock_irqsave(&ec->lock, flags); | ||
| 981 | ec->busy_polling = true; | ||
| 982 | ec->polling_guard = 0; | ||
| 983 | ec_log_drv("interrupt blocked"); | ||
| 984 | spin_unlock_irqrestore(&ec->lock, flags); | ||
| 985 | } | ||
| 986 | |||
| 987 | static void acpi_ec_leave_noirq(struct acpi_ec *ec) | ||
| 988 | { | ||
| 989 | unsigned long flags; | ||
| 990 | |||
| 991 | spin_lock_irqsave(&ec->lock, flags); | ||
| 992 | ec->busy_polling = ec_busy_polling; | ||
| 993 | ec->polling_guard = ec_polling_guard; | ||
| 994 | ec_log_drv("interrupt unblocked"); | ||
| 995 | spin_unlock_irqrestore(&ec->lock, flags); | ||
| 996 | } | ||
| 997 | |||
| 976 | void acpi_ec_block_transactions(void) | 998 | void acpi_ec_block_transactions(void) |
| 977 | { | 999 | { |
| 978 | struct acpi_ec *ec = first_ec; | 1000 | struct acpi_ec *ec = first_ec; |
| @@ -1253,7 +1275,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
| 1253 | if (function != ACPI_READ && function != ACPI_WRITE) | 1275 | if (function != ACPI_READ && function != ACPI_WRITE) |
| 1254 | return AE_BAD_PARAMETER; | 1276 | return AE_BAD_PARAMETER; |
| 1255 | 1277 | ||
| 1256 | if (ec_busy_polling || bits > 8) | 1278 | if (ec->busy_polling || bits > 8) |
| 1257 | acpi_ec_burst_enable(ec); | 1279 | acpi_ec_burst_enable(ec); |
| 1258 | 1280 | ||
| 1259 | for (i = 0; i < bytes; ++i, ++address, ++value) | 1281 | for (i = 0; i < bytes; ++i, ++address, ++value) |
| @@ -1261,7 +1283,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
| 1261 | acpi_ec_read(ec, address, value) : | 1283 | acpi_ec_read(ec, address, value) : |
| 1262 | acpi_ec_write(ec, address, *value); | 1284 | acpi_ec_write(ec, address, *value); |
| 1263 | 1285 | ||
| 1264 | if (ec_busy_polling || bits > 8) | 1286 | if (ec->busy_polling || bits > 8) |
| 1265 | acpi_ec_burst_disable(ec); | 1287 | acpi_ec_burst_disable(ec); |
| 1266 | 1288 | ||
| 1267 | switch (result) { | 1289 | switch (result) { |
| @@ -1304,6 +1326,8 @@ static struct acpi_ec *acpi_ec_alloc(void) | |||
| 1304 | spin_lock_init(&ec->lock); | 1326 | spin_lock_init(&ec->lock); |
| 1305 | INIT_WORK(&ec->work, acpi_ec_event_handler); | 1327 | INIT_WORK(&ec->work, acpi_ec_event_handler); |
| 1306 | ec->timestamp = jiffies; | 1328 | ec->timestamp = jiffies; |
| 1329 | ec->busy_polling = true; | ||
| 1330 | ec->polling_guard = 0; | ||
| 1307 | return ec; | 1331 | return ec; |
| 1308 | } | 1332 | } |
| 1309 | 1333 | ||
| @@ -1365,6 +1389,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) | |||
| 1365 | acpi_ec_start(ec, false); | 1389 | acpi_ec_start(ec, false); |
| 1366 | 1390 | ||
| 1367 | if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { | 1391 | if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) { |
| 1392 | acpi_ec_enter_noirq(ec); | ||
| 1368 | status = acpi_install_address_space_handler(ec->handle, | 1393 | status = acpi_install_address_space_handler(ec->handle, |
| 1369 | ACPI_ADR_SPACE_EC, | 1394 | ACPI_ADR_SPACE_EC, |
| 1370 | &acpi_ec_space_handler, | 1395 | &acpi_ec_space_handler, |
| @@ -1404,6 +1429,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) | |||
| 1404 | /* This is not fatal as we can poll EC events */ | 1429 | /* This is not fatal as we can poll EC events */ |
| 1405 | if (ACPI_SUCCESS(status)) { | 1430 | if (ACPI_SUCCESS(status)) { |
| 1406 | set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); | 1431 | set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); |
| 1432 | acpi_ec_leave_noirq(ec); | ||
| 1407 | if (test_bit(EC_FLAGS_STARTED, &ec->flags) && | 1433 | if (test_bit(EC_FLAGS_STARTED, &ec->flags) && |
| 1408 | ec->reference_count >= 1) | 1434 | ec->reference_count >= 1) |
| 1409 | acpi_ec_enable_gpe(ec, true); | 1435 | acpi_ec_enable_gpe(ec, true); |
| @@ -1786,34 +1812,6 @@ error: | |||
| 1786 | } | 1812 | } |
| 1787 | 1813 | ||
| 1788 | #ifdef CONFIG_PM_SLEEP | 1814 | #ifdef CONFIG_PM_SLEEP |
| 1789 | static void acpi_ec_enter_noirq(struct acpi_ec *ec) | ||
| 1790 | { | ||
| 1791 | unsigned long flags; | ||
| 1792 | |||
| 1793 | if (ec == first_ec) { | ||
| 1794 | spin_lock_irqsave(&ec->lock, flags); | ||
| 1795 | ec->saved_busy_polling = ec_busy_polling; | ||
| 1796 | ec->saved_polling_guard = ec_polling_guard; | ||
| 1797 | ec_busy_polling = true; | ||
| 1798 | ec_polling_guard = 0; | ||
| 1799 | ec_log_drv("interrupt blocked"); | ||
| 1800 | spin_unlock_irqrestore(&ec->lock, flags); | ||
| 1801 | } | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | static void acpi_ec_leave_noirq(struct acpi_ec *ec) | ||
| 1805 | { | ||
| 1806 | unsigned long flags; | ||
| 1807 | |||
| 1808 | if (ec == first_ec) { | ||
| 1809 | spin_lock_irqsave(&ec->lock, flags); | ||
| 1810 | ec_busy_polling = ec->saved_busy_polling; | ||
| 1811 | ec_polling_guard = ec->saved_polling_guard; | ||
| 1812 | ec_log_drv("interrupt unblocked"); | ||
| 1813 | spin_unlock_irqrestore(&ec->lock, flags); | ||
| 1814 | } | ||
| 1815 | } | ||
| 1816 | |||
| 1817 | static int acpi_ec_suspend_noirq(struct device *dev) | 1815 | static int acpi_ec_suspend_noirq(struct device *dev) |
| 1818 | { | 1816 | { |
| 1819 | struct acpi_ec *ec = | 1817 | 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 | ||
| 179 | extern struct acpi_ec *first_ec; | 179 | extern struct acpi_ec *first_ec; |
