diff options
| author | Steven Price <steven.price@arm.com> | 2026-10-02 07:14:58 +0100 |
|---|---|---|
| committer | Catalin Marinas <catalin.marinas@arm.com> | 2026-10-02 18:32:26 +0100 |
| commit | 24657f2ce53695e7f750c776cb007812a4d6dea3 (patch) | |
| tree | fa3e81bbee47fdf332cea92072a6bab4bfb2b0cc /include/linux | |
| parent | 9e201043cbd2194299c7d1c7ba0d8e9dbb04e79e (diff) | |
| download | linux-24657f2ce53695e7f750c776cb007812a4d6dea3.tar.gz linux-24657f2ce53695e7f750c776cb007812a4d6dea3.zip | |
firmware: arm_rmm: Check for RMI support at init
Query the RMI version number and check if it is a compatible version.
All RMM feature registers are read and exposed for future code to
use. Also restrict the support to SMC conduit.
We only support this for Little Endian kernels, the Big Endian kernel
support is anyway marked BROKEN and is being removed.
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Gavin Shan <gshan@redhat.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Co-developed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/arm-rmi-cmds.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/include/linux/arm-rmi-cmds.h b/include/linux/arm-rmi-cmds.h new file mode 100644 index 000000000000..9718f2f5a88b --- /dev/null +++ b/include/linux/arm-rmi-cmds.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2026 ARM Ltd. + */ + +#ifndef __LINUX_ARM_RMI_CMDS_H_ +#define __LINUX_ARM_RMI_CMDS_H_ + +#include <linux/arm-smccc-rmi.h> +#include <linux/bug.h> +#include <linux/processor.h> +#include <linux/types.h> + +#define RMM_BLOCKED_RETRY_COUNT 2 +/* + * rmi_smccc_invoke: Invoke the RMI call and return the results, retrying the + * command when status is RMI_BUSY. If we encounter RMI_BLOCKED, we retry + * it one more time before we give up. The caller is supposed to handle the + * result and reissue if required. + * + * We don't expect to see RMI_BLOCKED on a practical system, except when + * there are parallel requests that results in long standing operation, + * with one blocking the other. + * + * @regs: Input parameters filled in. Updated with the output results + * after the call. + */ +static inline void rmi_smccc_invoke(struct arm_smccc_1_2_regs *regs) +{ + struct arm_smccc_1_2_regs args = *regs; + long status; + int i = 0; + + while (i < RMM_BLOCKED_RETRY_COUNT) { + arm_smccc_1_2_smc(&args, regs); + + status = RMI_RESULT_STATUS(regs->a0); + if (status != RMI_BUSY && status != RMI_BLOCKED) + break; + if (status == RMI_BLOCKED) + i++; + cpu_relax(); + } +} + +unsigned long rmi_feat_reg(unsigned int index); + +#endif /* __LINUX_ARM_RMI_CMDS_H_ */ |
