Skip to content

Commit

Permalink
ACPI: Implement a generic FFH Opregion handler
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sudeep Holla authored and Rafael J. Wysocki committed Nov 14, 2022
1 parent 094226a commit e81c782
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 0 deletions.
10 changes: 10 additions & 0 deletions drivers/acpi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/acpi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
55 changes: 55 additions & 0 deletions drivers/acpi/acpi_ffh.c
Original file line number Diff line number Diff line change
@@ -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");
}
6 changes: 6 additions & 0 deletions drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
7 changes: 7 additions & 0 deletions include/linux/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit e81c782

Please sign in to comment.