mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 15:41:36 +00:00
f42039d10b
* arm64/for-next/perf: docs: perf: Fix warning from 'make htmldocs' in hisi-pmu.rst docs: perf: Add new description for HiSilicon UC PMU drivers/perf: hisi: Add support for HiSilicon UC PMU driver drivers/perf: hisi: Add support for HiSilicon H60PA and PAv3 PMU driver perf: arm_cspmu: Add missing MODULE_DEVICE_TABLE perf/arm-cmn: Add sysfs identifier perf/arm-cmn: Revamp model detection perf/arm_dmc620: Add cpumask dt-bindings: perf: fsl-imx-ddr: Add i.MX93 compatible drivers/perf: imx_ddr: Add support for NXP i.MX9 SoC DDRC PMU driver perf/arm_cspmu: Decouple APMT dependency perf/arm_cspmu: Clean up ACPI dependency ACPI/APMT: Don't register invalid resource perf/arm_cspmu: Fix event attribute type perf: arm_cspmu: Set irq affinitiy only if overflow interrupt is used drivers/perf: hisi: Don't migrate perf to the CPU going to teardown drivers/perf: apple_m1: Force 63bit counters for M2 CPUs perf/arm-cmn: Fix DTC reset perf: qcom_l2_pmu: Make l2_cache_pmu_probe_cluster() more robust perf/arm-cci: Slightly optimize cci_pmu_sync_counters() * for-next/kpti: : Simplify KPTI trampoline exit code arm64: entry: Simplify tramp_alias macro and tramp_exit routine arm64: entry: Preserve/restore X29 even for compat tasks * for-next/missing-proto-warn: : Address -Wmissing-prototype warnings arm64: add alt_cb_patch_nops prototype arm64: move early_brk64 prototype to header arm64: signal: include asm/exception.h arm64: kaslr: add kaslr_early_init() declaration arm64: flush: include linux/libnvdimm.h arm64: module-plts: inline linux/moduleloader.h arm64: hide unused is_valid_bugaddr() arm64: efi: add efi_handle_corrupted_x18 prototype arm64: cpuidle: fix #ifdef for acpi functions arm64: kvm: add prototypes for functions called in asm arm64: spectre: provide prototypes for internal functions arm64: move cpu_suspend_set_dbg_restorer() prototype to header arm64: avoid prototype warnings for syscalls arm64: add scs_patch_vmlinux prototype arm64: xor-neon: mark xor_arm64_neon_*() static * for-next/iss2-decode: : Add decode of ISS2 to data abort reports arm64/esr: Add decode of ISS2 to data abort reporting arm64/esr: Use GENMASK() for the ISS mask * for-next/kselftest: : Various arm64 kselftest improvements kselftest/arm64: Log signal code and address for unexpected signals kselftest/arm64: Add a smoke test for ptracing hardware break/watch points * for-next/misc: : Miscellaneous patches arm64: alternatives: make clean_dcache_range_nopatch() noinstr-safe arm64: hibernate: remove WARN_ON in save_processor_state arm64/fpsimd: Exit streaming mode when flushing tasks arm64: mm: fix VA-range sanity check arm64/mm: remove now-superfluous ISBs from TTBR writes arm64: consolidate rox page protection logic arm64: set __exception_irq_entry with __irq_entry as a default arm64: syscall: unmask DAIF for tracing status arm64: lockdep: enable checks for held locks when returning to userspace arm64/cpucaps: increase string width to properly format cpucaps.h arm64/cpufeature: Use helper for ECV CNTPOFF cpufeature * for-next/feat_mops: : Support for ARMv8.8 memcpy instructions in userspace kselftest/arm64: add MOPS to hwcap test arm64: mops: allow disabling MOPS from the kernel command line arm64: mops: detect and enable FEAT_MOPS arm64: mops: handle single stepping after MOPS exception arm64: mops: handle MOPS exceptions KVM: arm64: hide MOPS from guests arm64: mops: don't disable host MOPS instructions from EL2 arm64: mops: document boot requirements for MOPS KVM: arm64: switch HCRX_EL2 between host and guest arm64: cpufeature: detect FEAT_HCX KVM: arm64: initialize HCRX_EL2 * for-next/module-alloc: : Make the arm64 module allocation code more robust (clean-up, VA range expansion) arm64: module: rework module VA range selection arm64: module: mandate MODULE_PLTS arm64: module: move module randomization to module.c arm64: kaslr: split kaslr/module initialization arm64: kasan: remove !KASAN_VMALLOC remnants arm64: module: remove old !KASAN_VMALLOC logic * for-next/sysreg: (21 commits) : More sysreg conversions to automatic generation arm64/sysreg: Convert TRBIDR_EL1 register to automatic generation arm64/sysreg: Convert TRBTRG_EL1 register to automatic generation arm64/sysreg: Convert TRBMAR_EL1 register to automatic generation arm64/sysreg: Convert TRBSR_EL1 register to automatic generation arm64/sysreg: Convert TRBBASER_EL1 register to automatic generation arm64/sysreg: Convert TRBPTR_EL1 register to automatic generation arm64/sysreg: Convert TRBLIMITR_EL1 register to automatic generation arm64/sysreg: Rename TRBIDR_EL1 fields per auto-gen tools format arm64/sysreg: Rename TRBTRG_EL1 fields per auto-gen tools format arm64/sysreg: Rename TRBMAR_EL1 fields per auto-gen tools format arm64/sysreg: Rename TRBSR_EL1 fields per auto-gen tools format arm64/sysreg: Rename TRBBASER_EL1 fields per auto-gen tools format arm64/sysreg: Rename TRBPTR_EL1 fields per auto-gen tools format arm64/sysreg: Rename TRBLIMITR_EL1 fields per auto-gen tools format arm64/sysreg: Convert OSECCR_EL1 to automatic generation arm64/sysreg: Convert OSDTRTX_EL1 to automatic generation arm64/sysreg: Convert OSDTRRX_EL1 to automatic generation arm64/sysreg: Convert OSLAR_EL1 to automatic generation arm64/sysreg: Standardise naming of bitfield constants in OSL[AS]R_EL1 arm64/sysreg: Convert MDSCR_EL1 to automatic register generation ... * for-next/cpucap: : arm64 cpucap clean-up arm64: cpufeature: fold cpus_set_cap() into update_cpu_capabilities() arm64: cpufeature: use cpucap naming arm64: alternatives: use cpucap naming arm64: standardise cpucap bitmap names * for-next/acpi: : Various arm64-related ACPI patches ACPI: bus: Consolidate all arm specific initialisation into acpi_arm_init() * for-next/kdump: : Simplify the crashkernel reservation behaviour of crashkernel=X,high on arm64 arm64: add kdump.rst into index.rst Documentation: add kdump.rst to present crashkernel reservation on arm64 arm64: kdump: simplify the reservation behaviour of crashkernel=,high * for-next/acpi-doc: : Update ACPI documentation for Arm systems Documentation/arm64: Update ACPI tables from BBR Documentation/arm64: Update references in arm-acpi Documentation/arm64: Update ARM and arch reference * for-next/doc: : arm64 documentation updates Documentation/arm64: Add ptdump documentation * for-next/tpidr2-fix: : Fix the TPIDR2_EL0 register restoring on sigreturn kselftest/arm64: Add a test case for TPIDR2 restore arm64/signal: Restore TPIDR2 register rather than memory state
181 lines
3.9 KiB
C
181 lines
3.9 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* ARM APMT table support.
|
|
* Design document number: ARM DEN0117.
|
|
*
|
|
* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES.
|
|
*
|
|
*/
|
|
|
|
#define pr_fmt(fmt) "ACPI: APMT: " fmt
|
|
|
|
#include <linux/acpi.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/platform_device.h>
|
|
#include "init.h"
|
|
|
|
#define DEV_NAME "arm-cs-arch-pmu"
|
|
|
|
/* There can be up to 3 resources: page 0 and 1 address, and interrupt. */
|
|
#define DEV_MAX_RESOURCE_COUNT 3
|
|
|
|
/* Root pointer to the mapped APMT table */
|
|
static struct acpi_table_header *apmt_table;
|
|
|
|
static int __init apmt_init_resources(struct resource *res,
|
|
struct acpi_apmt_node *node)
|
|
{
|
|
int irq, trigger;
|
|
int num_res = 0;
|
|
|
|
res[num_res].start = node->base_address0;
|
|
res[num_res].end = node->base_address0 + SZ_4K - 1;
|
|
res[num_res].flags = IORESOURCE_MEM;
|
|
|
|
num_res++;
|
|
|
|
if (node->flags & ACPI_APMT_FLAGS_DUAL_PAGE) {
|
|
res[num_res].start = node->base_address1;
|
|
res[num_res].end = node->base_address1 + SZ_4K - 1;
|
|
res[num_res].flags = IORESOURCE_MEM;
|
|
|
|
num_res++;
|
|
}
|
|
|
|
if (node->ovflw_irq != 0) {
|
|
trigger = (node->ovflw_irq_flags & ACPI_APMT_OVFLW_IRQ_FLAGS_MODE);
|
|
trigger = (trigger == ACPI_APMT_OVFLW_IRQ_FLAGS_MODE_LEVEL) ?
|
|
ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
|
|
irq = acpi_register_gsi(NULL, node->ovflw_irq, trigger,
|
|
ACPI_ACTIVE_HIGH);
|
|
|
|
if (irq <= 0) {
|
|
pr_warn("APMT could not register gsi hwirq %d\n", irq);
|
|
return num_res;
|
|
}
|
|
|
|
res[num_res].start = irq;
|
|
res[num_res].end = irq;
|
|
res[num_res].flags = IORESOURCE_IRQ;
|
|
|
|
num_res++;
|
|
}
|
|
|
|
return num_res;
|
|
}
|
|
|
|
/**
|
|
* apmt_add_platform_device() - Allocate a platform device for APMT node
|
|
* @node: Pointer to device ACPI APMT node
|
|
* @fwnode: fwnode associated with the APMT node
|
|
*
|
|
* Returns: 0 on success, <0 failure
|
|
*/
|
|
static int __init apmt_add_platform_device(struct acpi_apmt_node *node,
|
|
struct fwnode_handle *fwnode)
|
|
{
|
|
struct platform_device *pdev;
|
|
int ret, count;
|
|
struct resource res[DEV_MAX_RESOURCE_COUNT];
|
|
|
|
pdev = platform_device_alloc(DEV_NAME, PLATFORM_DEVID_AUTO);
|
|
if (!pdev)
|
|
return -ENOMEM;
|
|
|
|
memset(res, 0, sizeof(res));
|
|
|
|
count = apmt_init_resources(res, node);
|
|
|
|
ret = platform_device_add_resources(pdev, res, count);
|
|
if (ret)
|
|
goto dev_put;
|
|
|
|
/*
|
|
* Add a copy of APMT node pointer to platform_data to be used to
|
|
* retrieve APMT data information.
|
|
*/
|
|
ret = platform_device_add_data(pdev, &node, sizeof(node));
|
|
if (ret)
|
|
goto dev_put;
|
|
|
|
pdev->dev.fwnode = fwnode;
|
|
|
|
ret = platform_device_add(pdev);
|
|
|
|
if (ret)
|
|
goto dev_put;
|
|
|
|
return 0;
|
|
|
|
dev_put:
|
|
platform_device_put(pdev);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int __init apmt_init_platform_devices(void)
|
|
{
|
|
struct acpi_apmt_node *apmt_node;
|
|
struct acpi_table_apmt *apmt;
|
|
struct fwnode_handle *fwnode;
|
|
u64 offset, end;
|
|
int ret;
|
|
|
|
/*
|
|
* apmt_table and apmt both point to the start of APMT table, but
|
|
* have different struct types
|
|
*/
|
|
apmt = (struct acpi_table_apmt *)apmt_table;
|
|
offset = sizeof(*apmt);
|
|
end = apmt->header.length;
|
|
|
|
while (offset < end) {
|
|
apmt_node = ACPI_ADD_PTR(struct acpi_apmt_node, apmt,
|
|
offset);
|
|
|
|
fwnode = acpi_alloc_fwnode_static();
|
|
if (!fwnode)
|
|
return -ENOMEM;
|
|
|
|
ret = apmt_add_platform_device(apmt_node, fwnode);
|
|
if (ret) {
|
|
acpi_free_fwnode_static(fwnode);
|
|
return ret;
|
|
}
|
|
|
|
offset += apmt_node->length;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void __init acpi_apmt_init(void)
|
|
{
|
|
acpi_status status;
|
|
int ret;
|
|
|
|
/**
|
|
* APMT table nodes will be used at runtime after the apmt init,
|
|
* so we don't need to call acpi_put_table() to release
|
|
* the APMT table mapping.
|
|
*/
|
|
status = acpi_get_table(ACPI_SIG_APMT, 0, &apmt_table);
|
|
|
|
if (ACPI_FAILURE(status)) {
|
|
if (status != AE_NOT_FOUND) {
|
|
const char *msg = acpi_format_exception(status);
|
|
|
|
pr_err("Failed to get APMT table, %s\n", msg);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
ret = apmt_init_platform_devices();
|
|
if (ret) {
|
|
pr_err("Failed to initialize APMT platform devices, ret: %d\n", ret);
|
|
acpi_put_table(apmt_table);
|
|
}
|
|
}
|