Merge branches 'acpi-tables', 'acpi-debug', 'acpi-ec' and 'acpi-dptf'
* acpi-tables: ACPI/PPTT: Add acpi_pptt_warn_missing() to consolidate logs ACPI / tables: table override from built-in initrd * acpi-debug: ACPI: debug: Clean up acpi_aml_init() ACPI: no need to check return value of debugfs_create functions * acpi-ec: Revert "ACPI / EC: Remove old CLEAR_ON_RESUME quirk" ACPI: EC: Simplify boot EC checks in acpi_ec_add() ACPI: EC: Eliminate acpi_config_boot_ec() ACPI: EC: Make acpi_ec_dsdt_probe() more straightforward ACPI: EC: Make acpi_ec_ecdt_probe() more straightforward ACPI: EC: Declare boot_ec as static ACPI: EC: Clean up probing for early EC * acpi-dptf: ACPI / DPTF: remove header search path to the parent directory
This commit is contained in:
commit
511514f1d9
|
@ -14,6 +14,10 @@ upgrade the ACPI execution environment that is defined by the ACPI tables
|
|||
via upgrading the ACPI tables provided by the BIOS with an instrumented,
|
||||
modified, more recent version one, or installing brand new ACPI tables.
|
||||
|
||||
When building initrd with kernel in a single image, option
|
||||
ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD should also be true for this
|
||||
feature to work.
|
||||
|
||||
For a full list of ACPI tables that can be upgraded/installed, take a look
|
||||
at the char *table_sigs[MAX_ACPI_SIGNATURE]; definition in
|
||||
drivers/acpi/tables.c.
|
||||
|
|
|
@ -357,6 +357,16 @@ config ACPI_TABLE_UPGRADE
|
|||
initrd, therefore it's safe to say Y.
|
||||
See Documentation/acpi/initrd_table_override.txt for details
|
||||
|
||||
config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD
|
||||
bool "Override ACPI tables from built-in initrd"
|
||||
depends on ACPI_TABLE_UPGRADE
|
||||
depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION=""
|
||||
help
|
||||
This option provides functionality to override arbitrary ACPI tables
|
||||
from built-in uncompressed initrd.
|
||||
|
||||
See Documentation/acpi/initrd_table_override.txt for details
|
||||
|
||||
config ACPI_DEBUG
|
||||
bool "Debug Statements"
|
||||
help
|
||||
|
|
|
@ -750,48 +750,36 @@ static const struct acpi_debugger_ops acpi_aml_debugger = {
|
|||
|
||||
int __init acpi_aml_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!acpi_debugfs_dir) {
|
||||
ret = -ENOENT;
|
||||
goto err_exit;
|
||||
}
|
||||
int ret;
|
||||
|
||||
/* Initialize AML IO interface */
|
||||
mutex_init(&acpi_aml_io.lock);
|
||||
init_waitqueue_head(&acpi_aml_io.wait);
|
||||
acpi_aml_io.out_crc.buf = acpi_aml_io.out_buf;
|
||||
acpi_aml_io.in_crc.buf = acpi_aml_io.in_buf;
|
||||
|
||||
acpi_aml_dentry = debugfs_create_file("acpidbg",
|
||||
S_IFREG | S_IRUGO | S_IWUSR,
|
||||
acpi_debugfs_dir, NULL,
|
||||
&acpi_aml_operations);
|
||||
if (acpi_aml_dentry == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err_exit;
|
||||
}
|
||||
ret = acpi_register_debugger(THIS_MODULE, &acpi_aml_debugger);
|
||||
if (ret)
|
||||
goto err_fs;
|
||||
acpi_aml_initialized = true;
|
||||
|
||||
err_fs:
|
||||
ret = acpi_register_debugger(THIS_MODULE, &acpi_aml_debugger);
|
||||
if (ret) {
|
||||
debugfs_remove(acpi_aml_dentry);
|
||||
acpi_aml_dentry = NULL;
|
||||
return ret;
|
||||
}
|
||||
err_exit:
|
||||
return ret;
|
||||
|
||||
acpi_aml_initialized = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __exit acpi_aml_exit(void)
|
||||
{
|
||||
if (acpi_aml_initialized) {
|
||||
acpi_unregister_debugger(&acpi_aml_debugger);
|
||||
if (acpi_aml_dentry) {
|
||||
debugfs_remove(acpi_aml_dentry);
|
||||
acpi_aml_dentry = NULL;
|
||||
}
|
||||
debugfs_remove(acpi_aml_dentry);
|
||||
acpi_aml_dentry = NULL;
|
||||
acpi_aml_initialized = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -679,7 +679,6 @@ static int __init einj_init(void)
|
|||
{
|
||||
int rc;
|
||||
acpi_status status;
|
||||
struct dentry *fentry;
|
||||
struct apei_exec_context ctx;
|
||||
|
||||
if (acpi_disabled) {
|
||||
|
@ -707,25 +706,13 @@ static int __init einj_init(void)
|
|||
|
||||
rc = -ENOMEM;
|
||||
einj_debug_dir = debugfs_create_dir("einj", apei_get_debugfs_dir());
|
||||
if (!einj_debug_dir) {
|
||||
pr_err("Error creating debugfs node.\n");
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
fentry = debugfs_create_file("available_error_type", S_IRUSR,
|
||||
einj_debug_dir, NULL,
|
||||
&available_error_type_fops);
|
||||
if (!fentry)
|
||||
goto err_cleanup;
|
||||
|
||||
fentry = debugfs_create_file("error_type", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, NULL, &error_type_fops);
|
||||
if (!fentry)
|
||||
goto err_cleanup;
|
||||
fentry = debugfs_create_file("error_inject", S_IWUSR,
|
||||
einj_debug_dir, NULL, &error_inject_fops);
|
||||
if (!fentry)
|
||||
goto err_cleanup;
|
||||
debugfs_create_file("available_error_type", S_IRUSR, einj_debug_dir,
|
||||
NULL, &available_error_type_fops);
|
||||
debugfs_create_file("error_type", S_IRUSR | S_IWUSR, einj_debug_dir,
|
||||
NULL, &error_type_fops);
|
||||
debugfs_create_file("error_inject", S_IWUSR, einj_debug_dir,
|
||||
NULL, &error_inject_fops);
|
||||
|
||||
apei_resources_init(&einj_resources);
|
||||
einj_exec_ctx_init(&ctx);
|
||||
|
@ -750,66 +737,37 @@ static int __init einj_init(void)
|
|||
rc = -ENOMEM;
|
||||
einj_param = einj_get_parameter_address();
|
||||
if ((param_extension || acpi5) && einj_param) {
|
||||
fentry = debugfs_create_x32("flags", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_flags);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param1);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param2);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param3", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param3);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x64("param4", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &error_param4);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
|
||||
fentry = debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, ¬rigger);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
debugfs_create_x32("flags", S_IRUSR | S_IWUSR, einj_debug_dir,
|
||||
&error_flags);
|
||||
debugfs_create_x64("param1", S_IRUSR | S_IWUSR, einj_debug_dir,
|
||||
&error_param1);
|
||||
debugfs_create_x64("param2", S_IRUSR | S_IWUSR, einj_debug_dir,
|
||||
&error_param2);
|
||||
debugfs_create_x64("param3", S_IRUSR | S_IWUSR, einj_debug_dir,
|
||||
&error_param3);
|
||||
debugfs_create_x64("param4", S_IRUSR | S_IWUSR, einj_debug_dir,
|
||||
&error_param4);
|
||||
debugfs_create_x32("notrigger", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, ¬rigger);
|
||||
}
|
||||
|
||||
if (vendor_dev[0]) {
|
||||
vendor_blob.data = vendor_dev;
|
||||
vendor_blob.size = strlen(vendor_dev);
|
||||
fentry = debugfs_create_blob("vendor", S_IRUSR,
|
||||
einj_debug_dir, &vendor_blob);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
fentry = debugfs_create_x32("vendor_flags", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &vendor_flags);
|
||||
if (!fentry)
|
||||
goto err_unmap;
|
||||
debugfs_create_blob("vendor", S_IRUSR, einj_debug_dir,
|
||||
&vendor_blob);
|
||||
debugfs_create_x32("vendor_flags", S_IRUSR | S_IWUSR,
|
||||
einj_debug_dir, &vendor_flags);
|
||||
}
|
||||
|
||||
pr_info("Error INJection is initialized.\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_unmap:
|
||||
if (einj_param) {
|
||||
acpi_size size = (acpi5) ?
|
||||
sizeof(struct set_error_type_with_address) :
|
||||
sizeof(struct einj_parameter);
|
||||
|
||||
acpi_os_unmap_iomem(einj_param, size);
|
||||
pr_err("Error creating param extension debugfs nodes.\n");
|
||||
}
|
||||
apei_exec_post_unmap_gars(&ctx);
|
||||
err_release:
|
||||
apei_resources_release(&einj_resources);
|
||||
err_fini:
|
||||
apei_resources_fini(&einj_resources);
|
||||
err_cleanup:
|
||||
pr_err("Error creating primary debugfs nodes.\n");
|
||||
debugfs_remove_recursive(einj_debug_dir);
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -79,14 +79,8 @@ static const struct file_operations cm_fops = {
|
|||
|
||||
static int __init acpi_custom_method_init(void)
|
||||
{
|
||||
if (acpi_debugfs_dir == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
|
||||
acpi_debugfs_dir, NULL, &cm_fops);
|
||||
if (cm_dentry == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
obj-$(CONFIG_ACPI) += int340x_thermal.o
|
||||
obj-$(CONFIG_DPTF_POWER) += dptf_power.o
|
||||
|
||||
ccflags-y += -Idrivers/acpi
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
#define INT3401_DEVICE 0X01
|
||||
static const struct acpi_device_id int340x_thermal_device_ids[] = {
|
||||
|
|
|
@ -186,14 +186,17 @@ static void advance_transaction(struct acpi_ec *ec);
|
|||
static void acpi_ec_event_handler(struct work_struct *work);
|
||||
static void acpi_ec_event_processor(struct work_struct *work);
|
||||
|
||||
struct acpi_ec *boot_ec, *first_ec;
|
||||
struct acpi_ec *first_ec;
|
||||
EXPORT_SYMBOL(first_ec);
|
||||
|
||||
static struct acpi_ec *boot_ec;
|
||||
static bool boot_ec_is_ecdt = false;
|
||||
static struct workqueue_struct *ec_query_wq;
|
||||
|
||||
static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */
|
||||
static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */
|
||||
static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */
|
||||
static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* Logging/Debugging
|
||||
|
@ -499,6 +502,26 @@ static inline void __acpi_ec_disable_event(struct acpi_ec *ec)
|
|||
ec_log_drv("event blocked");
|
||||
}
|
||||
|
||||
/*
|
||||
* Process _Q events that might have accumulated in the EC.
|
||||
* Run with locked ec mutex.
|
||||
*/
|
||||
static void acpi_ec_clear(struct acpi_ec *ec)
|
||||
{
|
||||
int i, status;
|
||||
u8 value = 0;
|
||||
|
||||
for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) {
|
||||
status = acpi_ec_query(ec, &value);
|
||||
if (status || !value)
|
||||
break;
|
||||
}
|
||||
if (unlikely(i == ACPI_EC_CLEAR_MAX))
|
||||
pr_warn("Warning: Maximum of %d stale EC events cleared\n", i);
|
||||
else
|
||||
pr_info("%d stale EC events cleared\n", i);
|
||||
}
|
||||
|
||||
static void acpi_ec_enable_event(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -507,6 +530,10 @@ static void acpi_ec_enable_event(struct acpi_ec *ec)
|
|||
if (acpi_ec_started(ec))
|
||||
__acpi_ec_enable_event(ec);
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
|
||||
/* Drain additional events if hardware requires that */
|
||||
if (EC_FLAGS_CLEAR_ON_RESUME)
|
||||
acpi_ec_clear(ec);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -1539,49 +1566,6 @@ static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int acpi_config_boot_ec(struct acpi_ec *ec, acpi_handle handle,
|
||||
bool handle_events, bool is_ecdt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Changing the ACPI handle results in a re-configuration of the
|
||||
* boot EC. And if it happens after the namespace initialization,
|
||||
* it causes _REG evaluations.
|
||||
*/
|
||||
if (boot_ec && boot_ec->handle != handle)
|
||||
ec_remove_handlers(boot_ec);
|
||||
|
||||
/* Unset old boot EC */
|
||||
if (boot_ec != ec)
|
||||
acpi_ec_free(boot_ec);
|
||||
|
||||
/*
|
||||
* ECDT device creation is split into acpi_ec_ecdt_probe() and
|
||||
* acpi_ec_ecdt_start(). This function takes care of completing the
|
||||
* ECDT parsing logic as the handle update should be performed
|
||||
* between the installation/uninstallation of the handlers.
|
||||
*/
|
||||
if (ec->handle != handle)
|
||||
ec->handle = handle;
|
||||
|
||||
ret = acpi_ec_setup(ec, handle_events);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set new boot EC */
|
||||
if (!boot_ec) {
|
||||
boot_ec = ec;
|
||||
boot_ec_is_ecdt = is_ecdt;
|
||||
}
|
||||
|
||||
acpi_handle_info(boot_ec->handle,
|
||||
"Used as boot %s EC to handle transactions%s\n",
|
||||
is_ecdt ? "ECDT" : "DSDT",
|
||||
handle_events ? " and events" : "");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool acpi_ec_ecdt_get_handle(acpi_handle *phandle)
|
||||
{
|
||||
struct acpi_table_ecdt *ecdt_ptr;
|
||||
|
@ -1601,43 +1585,34 @@ static bool acpi_ec_ecdt_get_handle(acpi_handle *phandle)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool acpi_is_boot_ec(struct acpi_ec *ec)
|
||||
{
|
||||
if (!boot_ec)
|
||||
return false;
|
||||
if (ec->command_addr == boot_ec->command_addr &&
|
||||
ec->data_addr == boot_ec->data_addr)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int acpi_ec_add(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_ec *ec = NULL;
|
||||
int ret;
|
||||
bool is_ecdt = false;
|
||||
bool dep_update = true;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
|
||||
|
||||
if (!strcmp(acpi_device_hid(device), ACPI_ECDT_HID)) {
|
||||
is_ecdt = true;
|
||||
boot_ec_is_ecdt = true;
|
||||
ec = boot_ec;
|
||||
dep_update = false;
|
||||
} else {
|
||||
ec = acpi_ec_alloc();
|
||||
if (!ec)
|
||||
return -ENOMEM;
|
||||
|
||||
status = ec_parse_device(device->handle, 0, ec, NULL);
|
||||
if (status != AE_CTRL_TERMINATE) {
|
||||
ret = -EINVAL;
|
||||
goto err_alloc;
|
||||
}
|
||||
}
|
||||
|
||||
if (acpi_is_boot_ec(ec)) {
|
||||
boot_ec_is_ecdt = is_ecdt;
|
||||
if (!is_ecdt) {
|
||||
if (boot_ec && ec->command_addr == boot_ec->command_addr &&
|
||||
ec->data_addr == boot_ec->data_addr) {
|
||||
boot_ec_is_ecdt = false;
|
||||
/*
|
||||
* Trust PNP0C09 namespace location rather than
|
||||
* ECDT ID. But trust ECDT GPE rather than _GPE
|
||||
|
@ -1649,12 +1624,17 @@ static int acpi_ec_add(struct acpi_device *device)
|
|||
acpi_ec_free(ec);
|
||||
ec = boot_ec;
|
||||
}
|
||||
ret = acpi_config_boot_ec(ec, ec->handle, true, is_ecdt);
|
||||
} else
|
||||
ret = acpi_ec_setup(ec, true);
|
||||
}
|
||||
|
||||
ret = acpi_ec_setup(ec, true);
|
||||
if (ret)
|
||||
goto err_query;
|
||||
|
||||
if (ec == boot_ec)
|
||||
acpi_handle_info(boot_ec->handle,
|
||||
"Boot %s EC used to handle transactions and events\n",
|
||||
boot_ec_is_ecdt ? "ECDT" : "DSDT");
|
||||
|
||||
device->driver_data = ec;
|
||||
|
||||
ret = !!request_region(ec->data_addr, 1, "EC data");
|
||||
|
@ -1662,7 +1642,7 @@ static int acpi_ec_add(struct acpi_device *device)
|
|||
ret = !!request_region(ec->command_addr, 1, "EC cmd");
|
||||
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
|
||||
|
||||
if (!is_ecdt) {
|
||||
if (dep_update) {
|
||||
/* Reprobe devices depending on the EC */
|
||||
acpi_walk_dep_device_list(ec->handle);
|
||||
}
|
||||
|
@ -1730,10 +1710,10 @@ static const struct acpi_device_id ec_device_ids[] = {
|
|||
* namespace EC before the main ACPI device enumeration process. It is
|
||||
* retained for historical reason and will be deprecated in the future.
|
||||
*/
|
||||
int __init acpi_ec_dsdt_probe(void)
|
||||
void __init acpi_ec_dsdt_probe(void)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_ec *ec;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -1743,21 +1723,22 @@ int __init acpi_ec_dsdt_probe(void)
|
|||
* picking up an invalid EC device.
|
||||
*/
|
||||
if (boot_ec)
|
||||
return -ENODEV;
|
||||
return;
|
||||
|
||||
ec = acpi_ec_alloc();
|
||||
if (!ec)
|
||||
return -ENOMEM;
|
||||
return;
|
||||
|
||||
/*
|
||||
* At this point, the namespace is initialized, so start to find
|
||||
* the namespace objects.
|
||||
*/
|
||||
status = acpi_get_devices(ec_device_ids[0].id,
|
||||
ec_parse_device, ec, NULL);
|
||||
status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, ec, NULL);
|
||||
if (ACPI_FAILURE(status) || !ec->handle) {
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
acpi_ec_free(ec);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the DSDT EC is available, always re-configure boot EC to
|
||||
* have _REG evaluated. _REG can only be evaluated after the
|
||||
|
@ -1765,11 +1746,16 @@ int __init acpi_ec_dsdt_probe(void)
|
|||
* At this point, the GPE is not fully initialized, so do not to
|
||||
* handle the events.
|
||||
*/
|
||||
ret = acpi_config_boot_ec(ec, ec->handle, false, false);
|
||||
error:
|
||||
if (ret)
|
||||
ret = acpi_ec_setup(ec, false);
|
||||
if (ret) {
|
||||
acpi_ec_free(ec);
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
boot_ec = ec;
|
||||
|
||||
acpi_handle_info(ec->handle,
|
||||
"Boot DSDT EC used to handle transactions\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1820,6 +1806,31 @@ static int ec_flag_query_handshake(const struct dmi_system_id *id)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On some hardware it is necessary to clear events accumulated by the EC during
|
||||
* sleep. These ECs stop reporting GPEs until they are manually polled, if too
|
||||
* many events are accumulated. (e.g. Samsung Series 5/9 notebooks)
|
||||
*
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=44161
|
||||
*
|
||||
* Ideally, the EC should also be instructed NOT to accumulate events during
|
||||
* sleep (which Windows seems to do somehow), but the interface to control this
|
||||
* behaviour is not known at this time.
|
||||
*
|
||||
* Models known to be affected are Samsung 530Uxx/535Uxx/540Uxx/550Pxx/900Xxx,
|
||||
* however it is very likely that other Samsung models are affected.
|
||||
*
|
||||
* On systems which don't accumulate _Q events during sleep, this extra check
|
||||
* should be harmless.
|
||||
*/
|
||||
static int ec_clear_on_resume(const struct dmi_system_id *id)
|
||||
{
|
||||
pr_debug("Detected system needing EC poll on resume.\n");
|
||||
EC_FLAGS_CLEAR_ON_RESUME = 1;
|
||||
ec_event_clearing = ACPI_EC_EVT_TIMING_STATUS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some ECDTs contain wrong register addresses.
|
||||
* MSI MS-171F
|
||||
|
@ -1869,39 +1880,38 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = {
|
|||
ec_honor_ecdt_gpe, "ASUS X580VD", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL},
|
||||
{
|
||||
ec_clear_on_resume, "Samsung hardware", {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL},
|
||||
{},
|
||||
};
|
||||
|
||||
int __init acpi_ec_ecdt_probe(void)
|
||||
void __init acpi_ec_ecdt_probe(void)
|
||||
{
|
||||
int ret;
|
||||
acpi_status status;
|
||||
struct acpi_table_ecdt *ecdt_ptr;
|
||||
struct acpi_ec *ec;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
ec = acpi_ec_alloc();
|
||||
if (!ec)
|
||||
return -ENOMEM;
|
||||
/*
|
||||
* Generate a boot ec context
|
||||
*/
|
||||
/* Generate a boot ec context. */
|
||||
dmi_check_system(ec_dmi_table);
|
||||
status = acpi_get_table(ACPI_SIG_ECDT, 1,
|
||||
(struct acpi_table_header **)&ecdt_ptr);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
if (!ecdt_ptr->control.address || !ecdt_ptr->data.address) {
|
||||
/*
|
||||
* Asus X50GL:
|
||||
* https://bugzilla.kernel.org/show_bug.cgi?id=11880
|
||||
*/
|
||||
ret = -ENODEV;
|
||||
goto error;
|
||||
return;
|
||||
}
|
||||
|
||||
ec = acpi_ec_alloc();
|
||||
if (!ec)
|
||||
return;
|
||||
|
||||
if (EC_FLAGS_CORRECT_ECDT) {
|
||||
ec->command_addr = ecdt_ptr->data.address;
|
||||
ec->data_addr = ecdt_ptr->control.address;
|
||||
|
@ -1910,16 +1920,22 @@ int __init acpi_ec_ecdt_probe(void)
|
|||
ec->data_addr = ecdt_ptr->data.address;
|
||||
}
|
||||
ec->gpe = ecdt_ptr->gpe;
|
||||
ec->handle = ACPI_ROOT_OBJECT;
|
||||
|
||||
/*
|
||||
* At this point, the namespace is not initialized, so do not find
|
||||
* the namespace objects, or handle the events.
|
||||
*/
|
||||
ret = acpi_config_boot_ec(ec, ACPI_ROOT_OBJECT, false, true);
|
||||
error:
|
||||
if (ret)
|
||||
ret = acpi_ec_setup(ec, false);
|
||||
if (ret) {
|
||||
acpi_ec_free(ec);
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
boot_ec = ec;
|
||||
boot_ec_is_ecdt = true;
|
||||
|
||||
pr_info("Boot ECDT EC used to handle transactions\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
|
|
@ -108,52 +108,32 @@ static const struct file_operations acpi_ec_io_ops = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count)
|
||||
static void acpi_ec_add_debugfs(struct acpi_ec *ec, unsigned int ec_device_count)
|
||||
{
|
||||
struct dentry *dev_dir;
|
||||
char name[64];
|
||||
umode_t mode = 0400;
|
||||
|
||||
if (ec_device_count == 0) {
|
||||
if (ec_device_count == 0)
|
||||
acpi_ec_debugfs_dir = debugfs_create_dir("ec", NULL);
|
||||
if (!acpi_ec_debugfs_dir)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sprintf(name, "ec%u", ec_device_count);
|
||||
dev_dir = debugfs_create_dir(name, acpi_ec_debugfs_dir);
|
||||
if (!dev_dir) {
|
||||
if (ec_device_count != 0)
|
||||
goto error;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!debugfs_create_x32("gpe", 0444, dev_dir, &first_ec->gpe))
|
||||
goto error;
|
||||
if (!debugfs_create_bool("use_global_lock", 0444, dev_dir,
|
||||
&first_ec->global_lock))
|
||||
goto error;
|
||||
debugfs_create_x32("gpe", 0444, dev_dir, &first_ec->gpe);
|
||||
debugfs_create_bool("use_global_lock", 0444, dev_dir,
|
||||
&first_ec->global_lock);
|
||||
|
||||
if (write_support)
|
||||
mode = 0600;
|
||||
if (!debugfs_create_file("io", mode, dev_dir, ec, &acpi_ec_io_ops))
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
debugfs_remove_recursive(acpi_ec_debugfs_dir);
|
||||
return -ENOMEM;
|
||||
debugfs_create_file("io", mode, dev_dir, ec, &acpi_ec_io_ops);
|
||||
}
|
||||
|
||||
static int __init acpi_ec_sys_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
if (first_ec)
|
||||
err = acpi_ec_add_debugfs(first_ec, 0);
|
||||
else
|
||||
err = -ENODEV;
|
||||
return err;
|
||||
acpi_ec_add_debugfs(first_ec, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_ec_sys_exit(void)
|
||||
|
|
|
@ -192,8 +192,8 @@ extern struct acpi_ec *first_ec;
|
|||
typedef int (*acpi_ec_query_func) (void *data);
|
||||
|
||||
int acpi_ec_init(void);
|
||||
int acpi_ec_ecdt_probe(void);
|
||||
int acpi_ec_dsdt_probe(void);
|
||||
void acpi_ec_ecdt_probe(void);
|
||||
void acpi_ec_dsdt_probe(void);
|
||||
void acpi_ec_block_transactions(void);
|
||||
void acpi_ec_unblock_transactions(void);
|
||||
void acpi_ec_mark_gpe_for_wake(void);
|
||||
|
|
|
@ -451,6 +451,11 @@ static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_ta
|
|||
return cpu;
|
||||
}
|
||||
|
||||
static void acpi_pptt_warn_missing(void)
|
||||
{
|
||||
pr_warn_once("No PPTT table found, cpu and cache topology may be inaccurate\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
|
||||
* @table: Pointer to the head of the PPTT table
|
||||
|
@ -498,7 +503,7 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
|
|||
|
||||
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n");
|
||||
acpi_pptt_warn_missing();
|
||||
return -ENOENT;
|
||||
}
|
||||
retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
|
||||
|
@ -531,7 +536,7 @@ int acpi_find_last_cache_level(unsigned int cpu)
|
|||
acpi_cpu_id = get_acpi_id_for_cpu(cpu);
|
||||
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_warn_once("No PPTT table found, cache topology may be inaccurate\n");
|
||||
acpi_pptt_warn_missing();
|
||||
} else {
|
||||
number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id);
|
||||
acpi_put_table(table);
|
||||
|
@ -563,7 +568,7 @@ int cache_setup_acpi(unsigned int cpu)
|
|||
|
||||
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_warn_once("No PPTT table found, cache topology may be inaccurate\n");
|
||||
acpi_pptt_warn_missing();
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
@ -617,7 +622,7 @@ int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
|
|||
|
||||
status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_warn_once("No PPTT table found, topology may be inaccurate\n");
|
||||
acpi_pptt_warn_missing();
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
|
@ -473,14 +473,22 @@ static DECLARE_BITMAP(acpi_initrd_installed, NR_ACPI_INITRD_TABLES);
|
|||
|
||||
void __init acpi_table_upgrade(void)
|
||||
{
|
||||
void *data = (void *)initrd_start;
|
||||
size_t size = initrd_end - initrd_start;
|
||||
void *data;
|
||||
size_t size;
|
||||
int sig, no, table_nr = 0, total_offset = 0;
|
||||
long offset = 0;
|
||||
struct acpi_table_header *table;
|
||||
char cpio_path[32] = "kernel/firmware/acpi/";
|
||||
struct cpio_data file;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD)) {
|
||||
data = __initramfs_start;
|
||||
size = __initramfs_size;
|
||||
} else {
|
||||
data = (void *)initrd_start;
|
||||
size = initrd_end - initrd_start;
|
||||
}
|
||||
|
||||
if (data == NULL || size == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -25,3 +25,6 @@ extern phys_addr_t phys_initrd_start;
|
|||
extern unsigned long phys_initrd_size;
|
||||
|
||||
extern unsigned int real_root_dev;
|
||||
|
||||
extern char __initramfs_start[];
|
||||
extern unsigned long __initramfs_size;
|
||||
|
|
Loading…
Reference in New Issue