[PATCH v8 2/7] RAS/AMD/ATL: Refactor PRM address translation into a common helper
From: Yazen Ghannam
Date: Mon Jul 27 2026 - 17:29:11 EST
Every PRM address translation follows the same pattern. Each fills a
parameter buffer, invokes the handler, and checks the result. Only the
handler GUID and the output buffer differ.
Factor this common sequence into prm_umc_norm_to_addr(). Convert
prm_umc_norm_to_sys_addr() to use it. Rename the parameter buffer struct
accordingly. The struct is no longer specific to the system physical
address translation. Also include the error code in the failure message to
make it more informative.
This is in preparation for adding more PRM address translation handlers.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
---
drivers/ras/amd/atl/internal.h | 2 ++
drivers/ras/amd/atl/prm.c | 35 +++++++++++++++++++++-------------
2 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index 4fc4bc3c3500..9f4d2a5b6c14 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -287,6 +287,8 @@ u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
/* GUIDs for PRM handlers */
extern const guid_t norm_to_sys_guid;
+int prm_umc_norm_to_addr(guid_t guid, u8 socket_id, u64 umc_bank_inst_id,
+ unsigned long addr, void *out_buf);
unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);
/*
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index 0f9bfa96e16a..0934f890745d 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -18,36 +18,45 @@
#include <linux/prmt.h>
-/*
- * PRM parameter buffer - normalized to system physical address, as described
- * in the "PRM Parameter Buffer" section of the AMD ACPI Porting Guide.
- */
-struct norm_to_sys_param_buf {
+/* See "PRM Parameter Buffer" in the AMD ACPI Porting Guide. */
+struct param_buf {
u64 norm_addr;
u8 socket;
u64 bank_id;
void *out_buf;
} __packed;
-unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
+int prm_umc_norm_to_addr(guid_t guid, u8 socket_id, u64 bank_id,
+ unsigned long addr, void *out_buf)
{
- struct norm_to_sys_param_buf p_buf;
- unsigned long ret_addr;
+ struct param_buf p_buf;
int ret;
p_buf.norm_addr = addr;
p_buf.socket = socket_id;
p_buf.bank_id = bank_id;
- p_buf.out_buf = &ret_addr;
+ p_buf.out_buf = out_buf;
- ret = acpi_call_prm_handler(norm_to_sys_guid, &p_buf);
+ ret = acpi_call_prm_handler(guid, &p_buf);
if (!ret)
- return ret_addr;
+ return 0;
if (ret == -ENODEV)
- pr_debug("PRM module/handler not available\n");
+ pr_debug("PRM module/handler not available: %d\n", ret);
else
- pr_notice_once("PRM address translation failed\n");
+ pr_notice_once("PRM address translation failed: %d\n", ret);
return ret;
}
+
+unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
+{
+ unsigned long sys_addr;
+ int ret;
+
+ ret = prm_umc_norm_to_addr(norm_to_sys_guid, socket_id, bank_id, addr, &sys_addr);
+ if (ret)
+ return ret;
+
+ return sys_addr;
+}
--
2.53.0