ACPI: Implement a generic FFH Opregion handler

This registers the FFH OpRegion handler before ACPI tables are
loaded. The platform support for the same is checked via Platform-Wide
OSPM Capabilities(OSC) before registering the OpRegion handler.

It relies on the special context data passed to offset and the length.
However the interpretation of the values is platform/architecture
specific. This generic handler just passed all the information to
the platform/architecture specific callback. It also implements the
default callbacks which return as not supported.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Sudeep Holla 2022-11-10 13:45:04 +00:00 committed by Rafael J. Wysocki
parent 094226ad94
commit e81c782c16
5 changed files with 79 additions and 0 deletions

View file

@ -564,6 +564,16 @@ config ACPI_PCC
Enable this feature if you want to set up and install the PCC Address
Space handler to handle PCC OpRegion in the firmware.
config ACPI_FFH
bool "ACPI FFH Address Space"
default n
help
The FFH(Fixed Function Hardware) Address Space also referred as FFH
Operation Region allows to define platform specific opregion.
Enable this feature if you want to set up and install the FFH Address
Space handler to handle FFH OpRegion in the firmware.
source "drivers/acpi/pmic/Kconfig"
config ACPI_VIOT

View file

@ -68,6 +68,7 @@ acpi-$(CONFIG_ACPI_GENERIC_GSI) += irq.o
acpi-$(CONFIG_ACPI_WATCHDOG) += acpi_watchdog.o
acpi-$(CONFIG_ACPI_PRMT) += prmt.o
acpi-$(CONFIG_ACPI_PCC) += acpi_pcc.o
acpi-$(CONFIG_ACPI_FFH) += acpi_ffh.o
# Address translation
acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o

55
drivers/acpi/acpi_ffh.c Normal file
View file

@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Author: Sudeep Holla <sudeep.holla@arm.com>
* Copyright 2022 Arm Limited
*/
#include <linux/kernel.h>
#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/idr.h>
#include <linux/io.h>
#include <linux/arm-smccc.h>
static struct acpi_ffh_info ffh_ctx;
int __weak acpi_ffh_address_space_arch_setup(void *handler_ctxt,
void **region_ctxt)
{
return -EOPNOTSUPP;
}
int __weak acpi_ffh_address_space_arch_handler(acpi_integer *value,
void *region_context)
{
return -EOPNOTSUPP;
}
static acpi_status
acpi_ffh_address_space_setup(acpi_handle region_handle, u32 function,
void *handler_context, void **region_context)
{
return acpi_ffh_address_space_arch_setup(handler_context,
region_context);
}
static acpi_status
acpi_ffh_address_space_handler(u32 function, acpi_physical_address addr,
u32 bits, acpi_integer *value,
void *handler_context, void *region_context)
{
return acpi_ffh_address_space_arch_handler(value, region_context);
}
void __init acpi_init_ffh(void)
{
acpi_status status;
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
ACPI_ADR_SPACE_FIXED_HARDWARE,
&acpi_ffh_address_space_handler,
&acpi_ffh_address_space_setup,
&ffh_ctx);
if (ACPI_FAILURE(status))
pr_alert("OperationRegion handler could not be installed\n");
}

View file

@ -300,6 +300,8 @@ EXPORT_SYMBOL_GPL(osc_sb_native_usb4_support_confirmed);
bool osc_sb_cppc2_support_acked;
bool osc_sb_ffh_opregion_support_confirmed;
static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
static void acpi_bus_osc_negotiate_platform_control(void)
{
@ -383,6 +385,8 @@ static void acpi_bus_osc_negotiate_platform_control(void)
capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT;
osc_cpc_flexible_adr_space_confirmed =
capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_CPC_FLEXIBLE_ADR_SPACE;
osc_sb_ffh_opregion_support_confirmed =
capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_FFH_OPR_SUPPORT;
}
kfree(context.ret.pointer);
@ -1408,6 +1412,8 @@ static int __init acpi_init(void)
disable_acpi();
return result;
}
if (osc_sb_ffh_opregion_support_confirmed)
acpi_init_ffh();
pci_mmcfg_late_init();
acpi_iort_init();

View file

@ -586,6 +586,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
#define OSC_SB_CPC_FLEXIBLE_ADR_SPACE 0x00004000
#define OSC_SB_NATIVE_USB4_SUPPORT 0x00040000
#define OSC_SB_PRM_SUPPORT 0x00200000
#define OSC_SB_FFH_OPR_SUPPORT 0x00400000
extern bool osc_sb_apei_support_acked;
extern bool osc_pc_lpi_support_confirmed;
@ -1488,6 +1489,12 @@ void acpi_init_pcc(void);
static inline void acpi_init_pcc(void) { }
#endif
#ifdef CONFIG_ACPI_FFH
void acpi_init_ffh(void);
#else
static inline void acpi_init_ffh(void) { }
#endif
#ifdef CONFIG_ACPI
extern void acpi_device_notify(struct device *dev);
extern void acpi_device_notify_remove(struct device *dev);