Commit e81c782c authored by Sudeep Holla's avatar Sudeep Holla Committed by Rafael J. Wysocki
Browse files

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: default avatarSudeep Holla <sudeep.holla@arm.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 094226ad
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
// 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 −0
Original line number Diff line number Diff line
@@ -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();
+7 −0
Original line number Diff line number Diff line
@@ -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);