Skip to content

Commit

Permalink
Allow AddressSpaceHandler Install and _REG execution as 2 separate steps
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jwrdegoede committed Oct 3, 2022
1 parent 7021087 commit ead772d
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 6 deletions.
101 changes: 95 additions & 6 deletions source/components/events/evxfregn.c
Expand Up @@ -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
*
Expand All @@ -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;
Expand Down Expand Up @@ -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)


/*******************************************************************************
*
Expand Down Expand Up @@ -387,3 +417,62 @@ AcpiRemoveAddressSpaceHandler (
}

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)
15 changes: 15 additions & 0 deletions source/include/acpixf.h
Expand Up @@ -942,6 +942,21 @@ AcpiInstallAddressSpaceHandler (
ACPI_ADR_SPACE_SETUP Setup,
void *Context))

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 (
Expand Down

0 comments on commit ead772d

Please sign in to comment.