Commit 98ada3c5 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

ACPI: EC: Simplify acpi_ec_ecdt_start() and acpi_ec_init()

Notice that the return value of acpi_ec_init() is discarded anyway,
so it can be void and it doesn't need to check the return values of
acpi_bus_register_driver() and acpi_ec_ecdt_start() called by it.
Thus the latter can be void too and it really has nothing to do
if acpi_ec_add() has already found an EC matching the boot one in the
namespace.  Also, acpi_ec_ecdt_get_handle() can be folded into it.

Modify the code accordingly and while at it create a propoer kerneldoc
comment to document acpi_ec_ecdt_start() and move the remark regarding
ASUS X550ZE along with the related bug URL from acpi_ec_init() into
that comment.

Additionally, fix up a stale comment in acpi_ec_init().
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 03e9a0e0
...@@ -1594,25 +1594,6 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device) ...@@ -1594,25 +1594,6 @@ static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device)
return ret; return ret;
} }
static bool acpi_ec_ecdt_get_handle(acpi_handle *phandle)
{
struct acpi_table_ecdt *ecdt_ptr;
acpi_status status;
acpi_handle handle;
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_FAILURE(status))
return false;
status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
if (ACPI_FAILURE(status))
return false;
*phandle = handle;
return true;
}
static int acpi_ec_add(struct acpi_device *device) static int acpi_ec_add(struct acpi_device *device)
{ {
struct acpi_ec *ec; struct acpi_ec *ec;
...@@ -1784,35 +1765,42 @@ void __init acpi_ec_dsdt_probe(void) ...@@ -1784,35 +1765,42 @@ void __init acpi_ec_dsdt_probe(void)
} }
/* /*
* If the DSDT EC is not functioning, we still need to prepare a fully * acpi_ec_ecdt_start - Finalize the boot ECDT EC initialization.
* functioning ECDT EC first in order to handle the events. *
* https://bugzilla.kernel.org/show_bug.cgi?id=115021 * First, look for an ACPI handle for the boot ECDT EC if acpi_ec_add() has not
* found a matching object in the namespace.
*
* Next, in case the DSDT EC is not functioning, it is still necessary to
* provide a functional ECDT EC to handle events, so add an extra device object
* to represent it (see https://bugzilla.kernel.org/show_bug.cgi?id=115021).
*
* This is useful on platforms with valid ECDT and invalid DSDT EC settings,
* like ASUS X550ZE (see https://bugzilla.kernel.org/show_bug.cgi?id=196847).
*/ */
static int __init acpi_ec_ecdt_start(void) static void __init acpi_ec_ecdt_start(void)
{ {
struct acpi_table_ecdt *ecdt_ptr;
acpi_handle handle; acpi_handle handle;
acpi_status status;
if (!boot_ec) /* Bail out if a matching EC has been found in the namespace. */
return -ENODEV; if (!boot_ec || boot_ec->handle != ACPI_ROOT_OBJECT)
/* In case acpi_ec_ecdt_start() is called after acpi_ec_add() */ return;
if (!boot_ec_is_ecdt)
return -ENODEV;
/* /* Look up the object pointed to from the ECDT in the namespace. */
* At this point, the namespace and the GPE is initialized, so status = acpi_get_table(ACPI_SIG_ECDT, 1,
* start to find the namespace objects and handle the events. (struct acpi_table_header **)&ecdt_ptr);
* if (ACPI_FAILURE(status))
* Note: ec->handle can be valid if this function is called after return;
* acpi_ec_add(), hence the fast path.
*/ status = acpi_get_handle(NULL, ecdt_ptr->id, &handle);
if (boot_ec->handle == ACPI_ROOT_OBJECT) { if (ACPI_FAILURE(status))
if (!acpi_ec_ecdt_get_handle(&handle)) return;
return -ENODEV;
boot_ec->handle = handle;
}
/* Register to ACPI bus with PM ops attached */ boot_ec->handle = handle;
return acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC);
/* Add a special ACPI device object to represent the boot EC. */
acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC);
} }
#if 0 #if 0
...@@ -2156,14 +2144,13 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { ...@@ -2156,14 +2144,13 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = {
{ }, { },
}; };
int __init acpi_ec_init(void) void __init acpi_ec_init(void)
{ {
int result; int result;
int ecdt_fail, dsdt_fail;
result = acpi_ec_init_workqueues(); result = acpi_ec_init_workqueues();
if (result) if (result)
return result; return;
/* /*
* Disable EC wakeup on following systems to prevent periodic * Disable EC wakeup on following systems to prevent periodic
...@@ -2174,16 +2161,10 @@ int __init acpi_ec_init(void) ...@@ -2174,16 +2161,10 @@ int __init acpi_ec_init(void)
pr_debug("Disabling EC wakeup on suspend-to-idle\n"); pr_debug("Disabling EC wakeup on suspend-to-idle\n");
} }
/* Drivers must be started after acpi_ec_query_init() */ /* Driver must be registered after acpi_ec_init_workqueues(). */
dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver); acpi_bus_register_driver(&acpi_ec_driver);
/*
* Register ECDT to ACPI bus only when PNP0C09 probe fails. This is acpi_ec_ecdt_start();
* useful for platforms (confirmed on ASUS X550ZE) with valid ECDT
* settings but invalid DSDT settings.
* https://bugzilla.kernel.org/show_bug.cgi?id=196847
*/
ecdt_fail = acpi_ec_ecdt_start();
return ecdt_fail && dsdt_fail ? -ENODEV : 0;
} }
/* EC driver currently not unloadable */ /* EC driver currently not unloadable */
......
...@@ -190,7 +190,7 @@ extern struct acpi_ec *first_ec; ...@@ -190,7 +190,7 @@ extern struct acpi_ec *first_ec;
/* External interfaces use first EC only, so remember */ /* External interfaces use first EC only, so remember */
typedef int (*acpi_ec_query_func) (void *data); typedef int (*acpi_ec_query_func) (void *data);
int acpi_ec_init(void); void acpi_ec_init(void);
void acpi_ec_ecdt_probe(void); void acpi_ec_ecdt_probe(void);
void acpi_ec_dsdt_probe(void); void acpi_ec_dsdt_probe(void);
void acpi_ec_block_transactions(void); void acpi_ec_block_transactions(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment