aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec.c
diff options
context:
space:
mode:
authorLv Zheng <lv.zheng@intel.com>2016-09-07 04:50:21 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2016-09-09 20:33:50 -0400
commit2a5708409e4e05446eb1a89ecb48641d6fd5d5a9 (patch)
tree9bdc01a1024724f61bb00e774284548921f24247 /drivers/acpi/ec.c
parent46922d2a3aff5122253d97e64500801c08f4f2c0 (diff)
ACPI / EC: Fix a gap that ECDT EC cannot handle EC events
It is possible to register _Qxx from namespace and use the ECDT EC to perform event handling. The reported bug reveals that Windows is using ECDT in this way in case the namespace EC is not present. This patch facilitates Linux to support ECDT in this way. Link: https://bugzilla.kernel.org/show_bug.cgi?id=115021 Reported-and-tested-by: Luya Tshimbalanga <luya@fedoraproject.org> Tested-by: Jonh Henderson <jw.hendy@gmail.com> Reviewed-by: Peter Wu <peter@lekensteyn.nl> Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/ec.c')
-rw-r--r--drivers/acpi/ec.c119
1 files changed, 96 insertions, 23 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 50895fff6964..2ae9194cc630 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -109,6 +109,7 @@ enum {
109 EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */ 109 EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */
110 EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */ 110 EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */
111 EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */ 111 EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */
112 EC_FLAGS_EVT_HANDLER_INSTALLED, /* _Qxx handlers installed */
112 EC_FLAGS_STARTED, /* Driver is started */ 113 EC_FLAGS_STARTED, /* Driver is started */
113 EC_FLAGS_STOPPED, /* Driver is stopped */ 114 EC_FLAGS_STOPPED, /* Driver is stopped */
114 EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the 115 EC_FLAGS_COMMAND_STORM, /* GPE storms occurred to the
@@ -1380,7 +1381,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
1380 * handler is not installed, which means "not able to handle 1381 * handler is not installed, which means "not able to handle
1381 * transactions". 1382 * transactions".
1382 */ 1383 */
1383static int ec_install_handlers(struct acpi_ec *ec) 1384static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
1384{ 1385{
1385 acpi_status status; 1386 acpi_status status;
1386 1387
@@ -1409,6 +1410,16 @@ static int ec_install_handlers(struct acpi_ec *ec)
1409 set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); 1410 set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
1410 } 1411 }
1411 1412
1413 if (!handle_events)
1414 return 0;
1415
1416 if (!test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) {
1417 /* Find and register all query methods */
1418 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
1419 acpi_ec_register_query_methods,
1420 NULL, ec, NULL);
1421 set_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags);
1422 }
1412 if (!test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) { 1423 if (!test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) {
1413 status = acpi_install_gpe_raw_handler(NULL, ec->gpe, 1424 status = acpi_install_gpe_raw_handler(NULL, ec->gpe,
1414 ACPI_GPE_EDGE_TRIGGERED, 1425 ACPI_GPE_EDGE_TRIGGERED,
@@ -1419,6 +1430,9 @@ static int ec_install_handlers(struct acpi_ec *ec)
1419 if (test_bit(EC_FLAGS_STARTED, &ec->flags) && 1430 if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
1420 ec->reference_count >= 1) 1431 ec->reference_count >= 1)
1421 acpi_ec_enable_gpe(ec, true); 1432 acpi_ec_enable_gpe(ec, true);
1433
1434 /* EC is fully operational, allow queries */
1435 acpi_ec_enable_event(ec);
1422 } 1436 }
1423 } 1437 }
1424 1438
@@ -1453,13 +1467,17 @@ static void ec_remove_handlers(struct acpi_ec *ec)
1453 pr_err("failed to remove gpe handler\n"); 1467 pr_err("failed to remove gpe handler\n");
1454 clear_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); 1468 clear_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags);
1455 } 1469 }
1470 if (test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) {
1471 acpi_ec_remove_query_handlers(ec, true, 0);
1472 clear_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags);
1473 }
1456} 1474}
1457 1475
1458static int acpi_ec_setup(struct acpi_ec *ec) 1476static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events)
1459{ 1477{
1460 int ret; 1478 int ret;
1461 1479
1462 ret = ec_install_handlers(ec); 1480 ret = ec_install_handlers(ec, handle_events);
1463 if (ret) 1481 if (ret)
1464 return ret; 1482 return ret;
1465 1483
@@ -1475,18 +1493,33 @@ static int acpi_ec_setup(struct acpi_ec *ec)
1475 return ret; 1493 return ret;
1476} 1494}
1477 1495
1478static int acpi_config_boot_ec(struct acpi_ec *ec, bool is_ecdt) 1496static int acpi_config_boot_ec(struct acpi_ec *ec, acpi_handle handle,
1497 bool handle_events, bool is_ecdt)
1479{ 1498{
1480 int ret; 1499 int ret;
1481 1500
1482 if (boot_ec) 1501 /*
1502 * Changing the ACPI handle results in a re-configuration of the
1503 * boot EC. And if it happens after the namespace initialization,
1504 * it causes _REG evaluations.
1505 */
1506 if (boot_ec && boot_ec->handle != handle)
1483 ec_remove_handlers(boot_ec); 1507 ec_remove_handlers(boot_ec);
1484 1508
1485 /* Unset old boot EC */ 1509 /* Unset old boot EC */
1486 if (boot_ec != ec) 1510 if (boot_ec != ec)
1487 acpi_ec_free(boot_ec); 1511 acpi_ec_free(boot_ec);
1488 1512
1489 ret = acpi_ec_setup(ec); 1513 /*
1514 * ECDT device creation is split into acpi_ec_ecdt_probe() and
1515 * acpi_ec_ecdt_start(). This function takes care of completing the
1516 * ECDT parsing logic as the handle update should be performed
1517 * between the installation/uninstallation of the handlers.
1518 */
1519 if (ec->handle != handle)
1520 ec->handle = handle;
1521
1522 ret = acpi_ec_setup(ec, handle_events);
1490 if (ret) 1523 if (ret)
1491 return ret; 1524 return ret;
1492 1525
@@ -1494,9 +1527,12 @@ static int acpi_config_boot_ec(struct acpi_ec *ec, bool is_ecdt)
1494 if (!boot_ec) { 1527 if (!boot_ec) {
1495 boot_ec = ec; 1528 boot_ec = ec;
1496 boot_ec_is_ecdt = is_ecdt; 1529 boot_ec_is_ecdt = is_ecdt;
1497 acpi_handle_info(boot_ec->handle, "Used as boot %s EC\n",
1498 is_ecdt ? "ECDT" : "DSDT");
1499 } 1530 }
1531
1532 acpi_handle_info(boot_ec->handle,
1533 "Used as boot %s EC to handle transactions%s\n",
1534 is_ecdt ? "ECDT" : "DSDT",
1535 handle_events ? " and events" : "");
1500 return ret; 1536 return ret;
1501} 1537}
1502 1538
@@ -1517,11 +1553,7 @@ static int acpi_ec_add(struct acpi_device *device)
1517 goto err_alloc; 1553 goto err_alloc;
1518 } 1554 }
1519 1555
1520 /* Find and register all query methods */ 1556 ret = acpi_config_boot_ec(ec, device->handle, true, false);
1521 acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
1522 acpi_ec_register_query_methods, NULL, ec, NULL);
1523
1524 ret = acpi_config_boot_ec(ec, false);
1525 if (ret) 1557 if (ret)
1526 goto err_query; 1558 goto err_query;
1527 1559
@@ -1534,9 +1566,6 @@ static int acpi_ec_add(struct acpi_device *device)
1534 1566
1535 /* Reprobe devices depending on the EC */ 1567 /* Reprobe devices depending on the EC */
1536 acpi_walk_dep_device_list(ec->handle); 1568 acpi_walk_dep_device_list(ec->handle);
1537
1538 /* EC is fully operational, allow queries */
1539 acpi_ec_enable_event(ec);
1540 return 0; 1569 return 0;
1541 1570
1542err_query: 1571err_query:
@@ -1555,7 +1584,6 @@ static int acpi_ec_remove(struct acpi_device *device)
1555 1584
1556 ec = acpi_driver_data(device); 1585 ec = acpi_driver_data(device);
1557 ec_remove_handlers(ec); 1586 ec_remove_handlers(ec);
1558 acpi_ec_remove_query_handlers(ec, true, 0);
1559 release_region(ec->data_addr, 1); 1587 release_region(ec->data_addr, 1);
1560 release_region(ec->command_addr, 1); 1588 release_region(ec->command_addr, 1);
1561 device->driver_data = NULL; 1589 device->driver_data = NULL;
@@ -1601,9 +1629,8 @@ int __init acpi_ec_dsdt_probe(void)
1601 if (!ec) 1629 if (!ec)
1602 return -ENOMEM; 1630 return -ENOMEM;
1603 /* 1631 /*
1604 * Finding EC from DSDT if there is no ECDT EC available. When this 1632 * At this point, the namespace is initialized, so start to find
1605 * function is invoked, ACPI tables have been fully loaded, we can 1633 * the namespace objects.
1606 * walk namespace now.
1607 */ 1634 */
1608 status = acpi_get_devices(ec_device_ids[0].id, 1635 status = acpi_get_devices(ec_device_ids[0].id,
1609 ec_parse_device, ec, NULL); 1636 ec_parse_device, ec, NULL);
@@ -1611,13 +1638,55 @@ int __init acpi_ec_dsdt_probe(void)
1611 ret = -ENODEV; 1638 ret = -ENODEV;
1612 goto error; 1639 goto error;
1613 } 1640 }
1614 ret = acpi_config_boot_ec(ec, false); 1641 /*
1642 * When the DSDT EC is available, always re-configure boot EC to
1643 * have _REG evaluated. _REG can only be evaluated after the
1644 * namespace initialization.
1645 * At this point, the GPE is not fully initialized, so do not to
1646 * handle the events.
1647 */
1648 ret = acpi_config_boot_ec(ec, ec->handle, false, false);
1615error: 1649error:
1616 if (ret) 1650 if (ret)
1617 acpi_ec_free(ec); 1651 acpi_ec_free(ec);
1618 return ret; 1652 return ret;
1619} 1653}
1620 1654
1655/*
1656 * If the DSDT EC is not functioning, we still need to prepare a fully
1657 * functioning ECDT EC first in order to handle the events.
1658 * https://bugzilla.kernel.org/show_bug.cgi?id=115021
1659 */
1660int __init acpi_ec_ecdt_start(void)
1661{
1662 struct acpi_table_ecdt *ecdt_ptr;
1663 acpi_status status;
1664 acpi_handle handle;
1665
1666 if (!boot_ec)
1667 return -ENODEV;
1668 /*
1669 * The DSDT EC should have already been started in
1670 * acpi_ec_add().
1671 */
1672 if (!boot_ec_is_ecdt)
1673 return -ENODEV;
1674
1675 status = acpi_get_table(ACPI_SIG_ECDT, 1,
1676 (struct acpi_table_header **)&ecdt_ptr);
1677 if (ACPI_FAILURE(status))
1678 return -ENODEV;
1679
1680 /*
1681 * At this point, the namespace and the GPE is initialized, so
1682 * start to find the namespace objects and handle the events.
1683 */
1684 status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
1685 if (ACPI_FAILURE(status))
1686 return -ENODEV;
1687 return acpi_config_boot_ec(boot_ec, handle, true, true);
1688}
1689
1621#if 0 1690#if 0
1622/* 1691/*
1623 * Some EC firmware variations refuses to respond QR_EC when SCI_EVT is not 1692 * Some EC firmware variations refuses to respond QR_EC when SCI_EVT is not
@@ -1720,8 +1789,12 @@ int __init acpi_ec_ecdt_probe(void)
1720 ec->data_addr = ecdt_ptr->data.address; 1789 ec->data_addr = ecdt_ptr->data.address;
1721 } 1790 }
1722 ec->gpe = ecdt_ptr->gpe; 1791 ec->gpe = ecdt_ptr->gpe;
1723 ec->handle = ACPI_ROOT_OBJECT; 1792
1724 ret = acpi_config_boot_ec(ec, true); 1793 /*
1794 * At this point, the namespace is not initialized, so do not find
1795 * the namespace objects, or handle the events.
1796 */
1797 ret = acpi_config_boot_ec(ec, ACPI_ROOT_OBJECT, false, true);
1725error: 1798error:
1726 if (ret) 1799 if (ret)
1727 acpi_ec_free(ec); 1800 acpi_ec_free(ec);