summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2022-07-04 13:38:12 +0200
committerHans de Goede <hdegoede@redhat.com>2022-10-03 15:27:59 +0200
commitead772dd15412719e033617966ec7e3a14bd4d89 (patch)
treec03bb5de1c93c36a5902b0c6a3211aada2f0d483
parent7021087eedb0d7156286e9e4f255e93c07816921 (diff)
downloadacpica-ead772dd15412719e033617966ec7e3a14bd4d89.tar.gz
Allow AddressSpaceHandler Install and _REG execution as 2 separate steps
ACPI-2.0 says that the EC OpRegion handler must be available immediately (like the standard default OpRegion handlers): Quoting from the ACPI spec version 6.3: "6.5.4 _REG (Region) ... 2. OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. These operation regions may become inaccessible after OSPM runs _REG(EmbeddedControl, 0)." So the OS must probe the ECDT described EC and install the OpRegion handler before calling AcpiEnableSubsystem() and AcpiInitializeObjects(). This is a problem because calling AcpiInstallAddressSpaceHandler() does not just install the OpRegion handler, it also runs the EC's _REG method. This _REG method may rely on initialization done by the _INI methods of one of the PCI / _SB root devices. For the other early/default OpRegion handlers the OpRegion handler install and the _REG execution is split into 2 separate steps: 1. AcpiEvInstallRegionHandlers(), called early from AcpiLoadTables() 2. AcpiEvInitializeOpRegions(), called from AcpiInitializeObjects() To fix the EC OpRegion issue, add 2 bew functions: 1. AcpiInstallAddressSpaceHandlerNo_Reg() 2. AcpiExecuteRegMethods() to allow doing things in 2 steps for other OpRegion handlers, like the EC handler, too. Note that the comment describing AcpiEvInstallRegionHandlers() even has an alinea describing this problem. Using the new methods allows users to avoid this problem. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=214899 Reported-and-tested-by: Johannes Penßel <johannespenssel@posteo.net> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r--source/components/events/evxfregn.c101
-rw-r--r--source/include/acpixf.h15
2 files changed, 110 insertions, 6 deletions
diff --git a/source/components/events/evxfregn.c b/source/components/events/evxfregn.c
index ee44e10d5..b7f3d28d1 100644
--- a/source/components/events/evxfregn.c
+++ b/source/components/events/evxfregn.c
@@ -163,13 +163,14 @@
/*******************************************************************************
*
- * FUNCTION: AcpiInstallAddressSpaceHandler
+ * FUNCTION: AcpiInstallAddressSpaceHandlerInternal
*
* PARAMETERS: Device - Handle for the device
* SpaceId - The address space ID
* Handler - Address of the handler
* Setup - Address of the setup function
* Context - Value passed to the handler on each access
+ * Run_Reg - Run _REG methods for this address space?
*
* RETURN: Status
*
@@ -180,16 +181,19 @@
* are executed here, and these methods can only be safely executed after
* the default handlers have been installed and the hardware has been
* initialized (via AcpiEnableSubsystem.)
+ * To avoid this problem pass FALSE for Run_Reg and later on call
+ * AcpiExecuteRegMethods() to execute _REG.
*
******************************************************************************/
-ACPI_STATUS
-AcpiInstallAddressSpaceHandler (
+static ACPI_STATUS
+AcpiInstallAddressSpaceHandlerInternal (
ACPI_HANDLE Device,
ACPI_ADR_SPACE_TYPE SpaceId,
ACPI_ADR_SPACE_HANDLER Handler,
ACPI_ADR_SPACE_SETUP Setup,
- void *Context)
+ void *Context,
+ BOOLEAN Run_Reg)
{
ACPI_NAMESPACE_NODE *Node;
ACPI_STATUS Status;
@@ -231,16 +235,42 @@ AcpiInstallAddressSpaceHandler (
/* Run all _REG methods for this address space */
- AcpiEvExecuteRegMethods (Node, SpaceId, ACPI_REG_CONNECT);
-
+ if (Run_Reg)
+ {
+ AcpiEvExecuteRegMethods (Node, SpaceId, ACPI_REG_CONNECT);
+ }
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
return_ACPI_STATUS (Status);
}
+ACPI_STATUS
+AcpiInstallAddressSpaceHandler (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context)
+{
+ return AcpiInstallAddressSpaceHandlerInternal (Device, SpaceId, Handler, Setup, Context, TRUE);
+}
+
ACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandler)
+ACPI_STATUS
+AcpiInstallAddressSpaceHandlerNo_Reg (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context)
+{
+ return AcpiInstallAddressSpaceHandlerInternal (Device, SpaceId, Handler, Setup, Context, FALSE);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiInstallAddressSpaceHandlerNo_Reg)
+
/*******************************************************************************
*
@@ -387,3 +417,62 @@ UnlockAndExit:
}
ACPI_EXPORT_SYMBOL (AcpiRemoveAddressSpaceHandler)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiExecuteRegMethods
+ *
+ * PARAMETERS: Device - Handle for the device
+ * SpaceId - The address space ID
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute _REG for all OpRegions of a given SpaceId.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiExecuteRegMethods (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId)
+{
+ ACPI_NAMESPACE_NODE *Node;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiExecuteRegMethods);
+
+
+ /* Parameter validation */
+
+ if (!Device)
+ {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ /* Convert and validate the device handle */
+
+ Node = AcpiNsValidateHandle (Device);
+ if (Node)
+ {
+ /* Run all _REG methods for this address space */
+
+ AcpiEvExecuteRegMethods (Node, SpaceId, ACPI_REG_CONNECT);
+ }
+ else
+ {
+ Status = AE_BAD_PARAMETER;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiExecuteRegMethods)
diff --git a/source/include/acpixf.h b/source/include/acpixf.h
index f62c16cbd..a38102697 100644
--- a/source/include/acpixf.h
+++ b/source/include/acpixf.h
@@ -944,6 +944,21 @@ AcpiInstallAddressSpaceHandler (
ACPI_EXTERNAL_RETURN_STATUS (
ACPI_STATUS
+AcpiInstallAddressSpaceHandlerNo_Reg(
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId,
+ ACPI_ADR_SPACE_HANDLER Handler,
+ ACPI_ADR_SPACE_SETUP Setup,
+ void *Context))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
+AcpiExecuteRegMethods (
+ ACPI_HANDLE Device,
+ ACPI_ADR_SPACE_TYPE SpaceId))
+
+ACPI_EXTERNAL_RETURN_STATUS (
+ACPI_STATUS
AcpiRemoveAddressSpaceHandler (
ACPI_HANDLE Device,
ACPI_ADR_SPACE_TYPE SpaceId,