diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 01cc86f697c8..fe148f1f2319 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -333,7 +333,7 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg, n += scnprintf(msg + n, len - n, "%.16llx ", log); /* Clear RRL status if RRL in Linux control mode. */ - if (retry_rd_err_log == 2 && !j && (log & status_mask)) + if (res_cfg->rrl_ctrl_mode == RRL_CTRL_LINUX && !j && (log & status_mask)) skx_write_imc_reg(imc, ch, offset, width, log & ~status_mask); } } @@ -1207,9 +1207,10 @@ static int __init i10nm_init(void) mce_register_decode_chain(&i10nm_mce_dec); skx_setup_debug("i10nm_test"); + res_cfg->rrl_ctrl_mode = retry_rd_err_log; if (retry_rd_err_log && res_cfg->reg_rrl_ddr) { skx_set_show_rrl(show_retry_rd_err_log); - if (retry_rd_err_log == 2) + if (retry_rd_err_log == RRL_CTRL_LINUX) enable_retry_rd_err_log(true); } @@ -1230,7 +1231,7 @@ static void __exit i10nm_exit(void) skx_set_decode(NULL); if (retry_rd_err_log && res_cfg->reg_rrl_ddr) { - if (retry_rd_err_log == 2) + if (retry_rd_err_log == RRL_CTRL_LINUX) enable_retry_rd_err_log(false); skx_set_show_rrl(NULL); } diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index f7f016db122f..4091431356d6 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -93,6 +93,15 @@ enum rrl_source_type { RRL_SRC_FRE_DEMAND, }; +enum rrl_ctrl_mode { + /* Linux does not control RRL or reports values. */ + RRL_CTRL_NONE, + /* Firmware retains control. Linux only reports values. */ + RRL_CTRL_BIOS, + /* Linux takes control, resets mode bits, and clears valid/UC bits; reports values. */ + RRL_CTRL_LINUX, +}; + /* RRL registers per {,sub-,pseudo-}channel. */ struct reg_rrl { /* RRL register parts. */ @@ -272,6 +281,8 @@ struct res_config { struct reg_rrl *reg_rrl_ddr; /* RRL register sets per HBM channel */ struct reg_rrl *reg_rrl_hbm[2]; + /* RRL control mode */ + enum rrl_ctrl_mode rrl_ctrl_mode; union { /* {skx,i10nm}_edac */ struct {