[PATCH v8 5/7] RAS/AMD/ATL: Remove the standalone SPA translation interface

From: Yazen Ghannam

Date: Mon Jul 27 2026 - 17:29:28 EST


All consumers now use the unified amd_translate_umc_mca_addr() interface,
which is routed through the RAS core in the same way. The older
amd_convert_umc_mca_addr_to_sys_addr() interface and its separate
register/unregister pair are no longer used.

Remove amd_convert_umc_mca_addr_to_sys_addr() together with
amd_atl_register_decoder()/amd_atl_unregister_decoder() and the associated
function pointer.

The unified interface performs the PRM translation itself, so
convert_umc_mca_addr_to_sys_addr() is now only the native Data Fabric
fallback. Make it static and drop its PRM attempt. Have it use the socket
ID that amd_atl_umc_translate_addr() already stores in struct atl_err. With
no remaining users, remove the prm_umc_norm_to_sys_addr() wrapper.

No functional change intended.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
---
drivers/ras/amd/atl/core.c | 2 --
drivers/ras/amd/atl/internal.h | 2 --
drivers/ras/amd/atl/prm.c | 17 -----------------
drivers/ras/amd/atl/umc.c | 9 ++-------
drivers/ras/ras.c | 29 -----------------------------
include/linux/ras.h | 5 -----
6 files changed, 2 insertions(+), 62 deletions(-)

diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index b754eaef8585..cb944d3473ba 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -209,7 +209,6 @@ static int __init amd_atl_init(void)

/* Increment this module's recount so that it can't be easily unloaded. */
__module_get(THIS_MODULE);
- amd_atl_register_decoder(convert_umc_mca_addr_to_sys_addr);
amd_atl_register_umc_translator(amd_atl_umc_translate_addr);

pr_info("AMD Address Translation Library initialized\n");
@@ -222,7 +221,6 @@ static int __init amd_atl_init(void)
*/
static void __exit amd_atl_exit(void)
{
- amd_atl_unregister_decoder();
amd_atl_unregister_umc_translator();
}

diff --git a/drivers/ras/amd/atl/internal.h b/drivers/ras/amd/atl/internal.h
index 0086bf0ff24f..0ebab3732886 100644
--- a/drivers/ras/amd/atl/internal.h
+++ b/drivers/ras/amd/atl/internal.h
@@ -279,7 +279,6 @@ int denormalize_address(struct addr_ctx *ctx);
int dehash_address(struct addr_ctx *ctx);

unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr);
-unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
void amd_atl_umc_translate_addr(struct atl_err *err);

u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
@@ -289,7 +288,6 @@ u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
extern const guid_t norm_to_sys_guid;

int prm_umc_norm_to_addr(guid_t guid, struct atl_umc_addr *addr, void *out_buf);
-unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 umc_bank_inst_id, unsigned long addr);

/*
* Make a gap in @data that is @num_bits long starting at @bit_num.
diff --git a/drivers/ras/amd/atl/prm.c b/drivers/ras/amd/atl/prm.c
index 5d9f0cb9eadb..76f7cc1ac31b 100644
--- a/drivers/ras/amd/atl/prm.c
+++ b/drivers/ras/amd/atl/prm.c
@@ -43,20 +43,3 @@ int prm_umc_norm_to_addr(guid_t guid, struct atl_umc_addr *addr, void *out_buf)

return ret;
}
-
-unsigned long prm_umc_norm_to_sys_addr(u8 socket_id, u64 bank_id, unsigned long addr)
-{
- struct atl_umc_addr uaddr = {
- .addr = addr,
- .socket_id = socket_id,
- .ipid = bank_id,
- };
- unsigned long sys_addr;
- int ret;
-
- ret = prm_umc_norm_to_addr(norm_to_sys_guid, &uaddr, &sys_addr);
- if (ret)
- return ret;
-
- return sys_addr;
-}
diff --git a/drivers/ras/amd/atl/umc.c b/drivers/ras/amd/atl/umc.c
index 33a9ab7b959b..18f3a76a66e3 100644
--- a/drivers/ras/amd/atl/umc.c
+++ b/drivers/ras/amd/atl/umc.c
@@ -402,21 +402,16 @@ static u8 get_coh_st_inst_id(struct atl_err *err)
return FIELD_GET(UMC_CHANNEL_NUM, err->ipid);
}

-unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
+static unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
{
- u8 socket_id = topology_physical_package_id(err->cpu);
+ u8 socket_id = err->socket_id;
u8 coh_st_inst_id = get_coh_st_inst_id(err);
unsigned long addr = get_addr(err->addr);
u8 die_id = get_die_id(err);
- unsigned long ret_addr;

pr_debug("socket_id=0x%x die_id=0x%x coh_st_inst_id=0x%x addr=0x%016lx",
socket_id, die_id, coh_st_inst_id, addr);

- ret_addr = prm_umc_norm_to_sys_addr(socket_id, err->ipid, addr);
- if (!IS_ERR_VALUE(ret_addr) || df_cfg.flags.prm_only)
- return ret_addr;
-
return norm_to_sys_addr(socket_id, die_id, coh_st_inst_id, addr);
}

diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index 6032f1cfce91..c6150d44f765 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -11,35 +11,6 @@
#include <linux/uuid.h>

#if IS_ENABLED(CONFIG_AMD_ATL)
-/*
- * Once set, this function pointer should never be unset.
- *
- * The library module will set this pointer if it successfully loads. The module
- * should not be unloaded except for testing and debug purposes.
- */
-static unsigned long (*amd_atl_umc_na_to_spa)(struct atl_err *err);
-
-void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *))
-{
- amd_atl_umc_na_to_spa = f;
-}
-EXPORT_SYMBOL_GPL(amd_atl_register_decoder);
-
-void amd_atl_unregister_decoder(void)
-{
- amd_atl_umc_na_to_spa = NULL;
-}
-EXPORT_SYMBOL_GPL(amd_atl_unregister_decoder);
-
-unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err)
-{
- if (!amd_atl_umc_na_to_spa)
- return -EINVAL;
-
- return amd_atl_umc_na_to_spa(err);
-}
-EXPORT_SYMBOL_GPL(amd_convert_umc_mca_addr_to_sys_addr);
-
/*
* Set by the library module when it loads. Left registered while the module is
* resident; consumers keep no direct dependency on the library, so translation
diff --git a/include/linux/ras.h b/include/linux/ras.h
index df1a1485ea16..abb86f954a3a 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -60,18 +60,13 @@ struct atl_err {
};

#if IS_ENABLED(CONFIG_AMD_ATL)
-void amd_atl_register_decoder(unsigned long (*f)(struct atl_err *));
-void amd_atl_unregister_decoder(void);
void amd_retire_dram_row(struct atl_err *err);
-unsigned long amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err);

void amd_atl_register_umc_translator(void (*f)(struct atl_err *));
void amd_atl_unregister_umc_translator(void);
void amd_translate_umc_mca_addr(struct atl_err *err);
#else
static inline void amd_retire_dram_row(struct atl_err *err) { }
-static inline unsigned long
-amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; }
static inline void amd_translate_umc_mca_addr(struct atl_err *err) { }
#endif /* CONFIG_AMD_ATL */

--
2.53.0