diff options
author | Hans de Goede <hdegoede@redhat.com> | 2022-07-04 13:38:12 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2022-10-03 15:27:59 +0200 |
commit | ead772dd15412719e033617966ec7e3a14bd4d89 (patch) | |
tree | c03bb5de1c93c36a5902b0c6a3211aada2f0d483 | |
parent | 7021087eedb0d7156286e9e4f255e93c07816921 (diff) | |
download | acpica-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.c | 101 | ||||
-rw-r--r-- | source/include/acpixf.h | 15 |
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, |