mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-27 14:43:58 +08:00
* Fix i10nm_edac loading on some Ice Lake and Tremont/Jacobsville
steppings due to the offset change of the bus number configuration register, by Qiuxu Zhuo. * The usual cleanups and fixes all over the place. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAl7Uzs0ACgkQEsHwGGHe VUorZw//WEEQk05CSgxky5SgJ2sM8DErvU/bqjJfLJz/qeuFF8XqhAuFFIAxuvfl ujbPTDEjLh3JkqOEnGAL1FTb44hZ91qEZZty1cqaDHFUjMcw+aevYFjxH/HprZYY CO/yxgKSB+3xvJ8IzGZheh3sB7n0fllZ2dB8T5gyQWqZe3zCbRCvfyQKkRNOCbJq pcUuHjCdZ4KPmLlg3E+WfEu1enRD0plNHUQsHpH3a1BH9iNoY6yNFlYM9NjO/QJ2 wY6mZ06fK/5P101wBGiyKfMsd4BvlalksVKJMr/qA0xVq8xVyk2J22L6ZyRkusW5 GOCbRXmKQm3ntLr9Kal3hYbt4AvPZW7TCok3vvBerJTTCcSrS1KAJKnVq/gnu9Zb a8Ygyv7nkPlVcfX/t4mQDpG2kdQ/+wmNMZiMPpjoAmLzY9t9n4UPSetuvVFr+SPH WW+iTmmBC7Z/ICVJiKxRFCK9MZPtvoxfBOhXWXRAcF+6ncnToeDTnub7Uy9Siubg 5ctUJ2/JOj9h0XdhMZ/xIMk2ApPzWKlIUJDx6+5vniKFWhiOoVdAx2pNTh8gi6vB AurblD/BF7tfQz2RrM8i6rJCSsxj7EuyNwg4LKHSw2go438E3CsoFzy+PDUSngpy qriZmvOYqUA38leLr3frPG74NtAog/9lGEf7JJ0Z8tZVirBweD0= =qWOj -----END PGP SIGNATURE----- Merge tag 'edac_updates_for_5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras Pull EDAC updates from Borislav Petkov: - Fix i10nm_edac loading on some Ice Lake and Tremont/Jacobsville steppings due to the offset change of the bus number configuration register, by Qiuxu Zhuo. - The usual cleanups and fixes all over the place. * tag 'edac_updates_for_5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: EDAC/amd64: Remove redundant assignment to variable ret in hw_info_get() EDAC/skx: Use the mcmtr register to retrieve close_pg/bank_xor_enable EDAC/i10nm: Update driver to support different bus number config register offsets EDAC, {skx,i10nm}: Make some configurations CPU model specific EDAC/amd8131: Remove defined but not used bridge_str EDAC/thunderx: Make symbols static MAINTAINERS: Remove sifive_l2_cache.c from EDAC-SIFIVE pattern EDAC/xgene: Remove set but not used address local var EDAC/armada_xp: Fix some log messages
This commit is contained in:
commit
8b11dd54ad
@ -6193,7 +6193,6 @@ M: Yash Shah <yash.shah@sifive.com>
|
||||
L: linux-edac@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/edac/sifive_edac.c
|
||||
F: drivers/soc/sifive_l2_cache.c
|
||||
|
||||
EDAC-SKYLAKE
|
||||
M: Tony Luck <tony.luck@intel.com>
|
||||
|
@ -3403,7 +3403,7 @@ static const struct attribute_group *amd64_edac_attr_groups[] = {
|
||||
static int hw_info_get(struct amd64_pvt *pvt)
|
||||
{
|
||||
u16 pci_id1, pci_id2;
|
||||
int ret = -EINVAL;
|
||||
int ret;
|
||||
|
||||
if (pvt->fam >= 0x17) {
|
||||
pvt->umc = kcalloc(fam_type->max_mcs, sizeof(struct amd64_umc), GFP_KERNEL);
|
||||
|
@ -44,14 +44,6 @@ static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
|
||||
" PCI Access Write Error at 0x%x\n", reg);
|
||||
}
|
||||
|
||||
static char * const bridge_str[] = {
|
||||
[NORTH_A] = "NORTH A",
|
||||
[NORTH_B] = "NORTH B",
|
||||
[SOUTH_A] = "SOUTH A",
|
||||
[SOUTH_B] = "SOUTH B",
|
||||
[NO_BRIDGE] = "NO BRIDGE",
|
||||
};
|
||||
|
||||
/* Support up to two AMD8131 chipsets on a platform */
|
||||
static struct amd8131_dev_info amd8131_devices[] = {
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ struct axp_mc_drvdata {
|
||||
char msg[128];
|
||||
};
|
||||
|
||||
/* derived from "DRAM Address Multiplexing" in the ARAMDA XP Functional Spec */
|
||||
/* derived from "DRAM Address Multiplexing" in the ARMADA XP Functional Spec */
|
||||
static uint32_t axp_mc_calc_address(struct axp_mc_drvdata *drvdata,
|
||||
uint8_t cs, uint8_t bank, uint16_t row,
|
||||
uint16_t col)
|
||||
@ -160,12 +160,12 @@ static void axp_mc_check(struct mem_ctl_info *mci)
|
||||
if (cnt_sbe)
|
||||
cnt_sbe--;
|
||||
else
|
||||
dev_warn(mci->pdev, "inconsistent SBE count detected");
|
||||
dev_warn(mci->pdev, "inconsistent SBE count detected\n");
|
||||
} else {
|
||||
if (cnt_dbe)
|
||||
cnt_dbe--;
|
||||
else
|
||||
dev_warn(mci->pdev, "inconsistent DBE count detected");
|
||||
dev_warn(mci->pdev, "inconsistent DBE count detected\n");
|
||||
}
|
||||
|
||||
/* report earlier errors */
|
||||
@ -304,7 +304,7 @@ static int axp_mc_probe(struct platform_device *pdev)
|
||||
|
||||
config = readl(base + SDRAM_CONFIG_REG);
|
||||
if (!(config & SDRAM_CONFIG_ECC_MASK)) {
|
||||
dev_warn(&pdev->dev, "SDRAM ECC is not enabled");
|
||||
dev_warn(&pdev->dev, "SDRAM ECC is not enabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -532,9 +532,9 @@ static int aurora_l2_probe(struct platform_device *pdev)
|
||||
|
||||
l2x0_aux_ctrl = readl(base + L2X0_AUX_CTRL);
|
||||
if (!(l2x0_aux_ctrl & AURORA_ACR_PARITY_EN))
|
||||
dev_warn(&pdev->dev, "tag parity is not enabled");
|
||||
dev_warn(&pdev->dev, "tag parity is not enabled\n");
|
||||
if (!(l2x0_aux_ctrl & AURORA_ACR_ECC_EN))
|
||||
dev_warn(&pdev->dev, "data ECC is not enabled");
|
||||
dev_warn(&pdev->dev, "data ECC is not enabled\n");
|
||||
|
||||
dci = edac_device_alloc_ctl_info(sizeof(*drvdata),
|
||||
"cpu", 1, "L", 1, 2, NULL, 0, 0);
|
||||
@ -618,7 +618,7 @@ static int __init armada_xp_edac_init(void)
|
||||
|
||||
res = platform_register_drivers(drivers, ARRAY_SIZE(drivers));
|
||||
if (res)
|
||||
pr_warn("Aramda XP EDAC drivers fail to register\n");
|
||||
pr_warn("Armada XP EDAC drivers fail to register\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -122,10 +122,22 @@ static int i10nm_get_all_munits(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct res_config i10nm_cfg0 = {
|
||||
.type = I10NM,
|
||||
.decs_did = 0x3452,
|
||||
.busno_cfg_offset = 0xcc,
|
||||
};
|
||||
|
||||
static struct res_config i10nm_cfg1 = {
|
||||
.type = I10NM,
|
||||
.decs_did = 0x3452,
|
||||
.busno_cfg_offset = 0xd0,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id i10nm_cpuids[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, &i10nm_cfg0),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, &i10nm_cfg0),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D, &i10nm_cfg1),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids);
|
||||
@ -161,7 +173,7 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci)
|
||||
mtr, mcddrtcfg, imc->mc, i, j);
|
||||
|
||||
if (IS_DIMM_PRESENT(mtr))
|
||||
ndimms += skx_get_dimm_info(mtr, 0, dimm,
|
||||
ndimms += skx_get_dimm_info(mtr, 0, 0, dimm,
|
||||
imc, i, j);
|
||||
else if (IS_NVDIMM_PRESENT(mcddrtcfg, j))
|
||||
ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
|
||||
@ -234,6 +246,7 @@ static int __init i10nm_init(void)
|
||||
{
|
||||
u8 mc = 0, src_id = 0, node_id = 0;
|
||||
const struct x86_cpu_id *id;
|
||||
struct res_config *cfg;
|
||||
const char *owner;
|
||||
struct skx_dev *d;
|
||||
int rc, i, off[3] = {0xd0, 0xc8, 0xcc};
|
||||
@ -249,11 +262,17 @@ static int __init i10nm_init(void)
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
cfg = (struct res_config *)id->driver_data;
|
||||
|
||||
/* Newer steppings have different offset for ATOM_TREMONT_D/ICELAKE_X */
|
||||
if (boot_cpu_data.x86_stepping >= 4)
|
||||
cfg->busno_cfg_offset = 0xd0;
|
||||
|
||||
rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = skx_get_all_bus_mappings(0x3452, 0xcc, I10NM, &i10nm_edac_list);
|
||||
rc = skx_get_all_bus_mappings(cfg, &i10nm_edac_list);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
if (rc == 0) {
|
||||
|
@ -157,33 +157,35 @@ fail:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static struct res_config skx_cfg = {
|
||||
.type = SKX,
|
||||
.decs_did = 0x2016,
|
||||
.busno_cfg_offset = 0xcc,
|
||||
};
|
||||
|
||||
static const struct x86_cpu_id skx_cpuids[] = {
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, NULL),
|
||||
X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X, &skx_cfg),
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
|
||||
|
||||
#define SKX_GET_MTMTR(dev, reg) \
|
||||
pci_read_config_dword((dev), 0x87c, &(reg))
|
||||
|
||||
static bool skx_check_ecc(struct pci_dev *pdev)
|
||||
static bool skx_check_ecc(u32 mcmtr)
|
||||
{
|
||||
u32 mtmtr;
|
||||
|
||||
SKX_GET_MTMTR(pdev, mtmtr);
|
||||
|
||||
return !!GET_BITFIELD(mtmtr, 2, 2);
|
||||
return !!GET_BITFIELD(mcmtr, 2, 2);
|
||||
}
|
||||
|
||||
static int skx_get_dimm_config(struct mem_ctl_info *mci)
|
||||
{
|
||||
struct skx_pvt *pvt = mci->pvt_info;
|
||||
u32 mtr, mcmtr, amap, mcddrtcfg;
|
||||
struct skx_imc *imc = pvt->imc;
|
||||
u32 mtr, amap, mcddrtcfg;
|
||||
struct dimm_info *dimm;
|
||||
int i, j;
|
||||
int ndimms;
|
||||
|
||||
/* Only the mcmtr on the first channel is effective */
|
||||
pci_read_config_dword(imc->chan[0].cdev, 0x87c, &mcmtr);
|
||||
|
||||
for (i = 0; i < SKX_NUM_CHANNELS; i++) {
|
||||
ndimms = 0;
|
||||
pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap);
|
||||
@ -193,14 +195,14 @@ static int skx_get_dimm_config(struct mem_ctl_info *mci)
|
||||
pci_read_config_dword(imc->chan[i].cdev,
|
||||
0x80 + 4 * j, &mtr);
|
||||
if (IS_DIMM_PRESENT(mtr)) {
|
||||
ndimms += skx_get_dimm_info(mtr, amap, dimm, imc, i, j);
|
||||
ndimms += skx_get_dimm_info(mtr, mcmtr, amap, dimm, imc, i, j);
|
||||
} else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) {
|
||||
ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
|
||||
EDAC_MOD_STR);
|
||||
nvdimm_count++;
|
||||
}
|
||||
}
|
||||
if (ndimms && !skx_check_ecc(imc->chan[0].cdev)) {
|
||||
if (ndimms && !skx_check_ecc(mcmtr)) {
|
||||
skx_printk(KERN_ERR, "ECC is disabled on imc %d\n", imc->mc);
|
||||
return -ENODEV;
|
||||
}
|
||||
@ -641,6 +643,7 @@ static inline void teardown_skx_debug(void) {}
|
||||
static int __init skx_init(void)
|
||||
{
|
||||
const struct x86_cpu_id *id;
|
||||
struct res_config *cfg;
|
||||
const struct munit *m;
|
||||
const char *owner;
|
||||
int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8};
|
||||
@ -657,11 +660,13 @@ static int __init skx_init(void)
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
cfg = (struct res_config *)id->driver_data;
|
||||
|
||||
rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = skx_get_all_bus_mappings(0x2016, 0xcc, SKX, &skx_edac_list);
|
||||
rc = skx_get_all_bus_mappings(cfg, &skx_edac_list);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
if (rc == 0) {
|
||||
|
@ -197,12 +197,11 @@ static int get_width(u32 mtr)
|
||||
}
|
||||
|
||||
/*
|
||||
* We use the per-socket device @did to count how many sockets are present,
|
||||
* We use the per-socket device @cfg->did to count how many sockets are present,
|
||||
* and to detemine which PCI buses are associated with each socket. Allocate
|
||||
* and build the full list of all the skx_dev structures that we need here.
|
||||
*/
|
||||
int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
|
||||
struct list_head **list)
|
||||
int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
|
||||
{
|
||||
struct pci_dev *pdev, *prev;
|
||||
struct skx_dev *d;
|
||||
@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
|
||||
|
||||
prev = NULL;
|
||||
for (;;) {
|
||||
pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, prev);
|
||||
pdev = pci_get_device(PCI_VENDOR_ID_INTEL, cfg->decs_did, prev);
|
||||
if (!pdev)
|
||||
break;
|
||||
ndev++;
|
||||
@ -221,7 +220,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (pci_read_config_dword(pdev, off, ®)) {
|
||||
if (pci_read_config_dword(pdev, cfg->busno_cfg_offset, ®)) {
|
||||
kfree(d);
|
||||
pci_dev_put(pdev);
|
||||
skx_printk(KERN_ERR, "Failed to read bus idx\n");
|
||||
@ -230,7 +229,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
|
||||
|
||||
d->bus[0] = GET_BITFIELD(reg, 0, 7);
|
||||
d->bus[1] = GET_BITFIELD(reg, 8, 15);
|
||||
if (type == SKX) {
|
||||
if (cfg->type == SKX) {
|
||||
d->seg = pci_domain_nr(pdev->bus);
|
||||
d->bus[2] = GET_BITFIELD(reg, 16, 23);
|
||||
d->bus[3] = GET_BITFIELD(reg, 24, 31);
|
||||
@ -304,7 +303,7 @@ static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add,
|
||||
#define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 6, "rows")
|
||||
#define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols")
|
||||
|
||||
int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm,
|
||||
int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
|
||||
struct skx_imc *imc, int chan, int dimmno)
|
||||
{
|
||||
int banks = 16, ranks, rows, cols, npages;
|
||||
@ -324,8 +323,8 @@ int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm,
|
||||
imc->mc, chan, dimmno, size, npages,
|
||||
banks, 1 << ranks, rows, cols);
|
||||
|
||||
imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mtr, 0, 0);
|
||||
imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mtr, 9, 9);
|
||||
imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mcmtr, 0, 0);
|
||||
imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mcmtr, 9, 9);
|
||||
imc->chan[chan].dimms[dimmno].fine_grain_bank = GET_BITFIELD(amap, 0, 0);
|
||||
imc->chan[chan].dimms[dimmno].rowbits = rows;
|
||||
imc->chan[chan].dimms[dimmno].colbits = cols;
|
||||
|
@ -112,6 +112,14 @@ struct decoded_addr {
|
||||
int bank_group;
|
||||
};
|
||||
|
||||
struct res_config {
|
||||
enum type type;
|
||||
/* Configuration agent device ID */
|
||||
unsigned int decs_did;
|
||||
/* Default bus number configuration register offset */
|
||||
int busno_cfg_offset;
|
||||
};
|
||||
|
||||
typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci);
|
||||
typedef bool (*skx_decode_f)(struct decoded_addr *res);
|
||||
typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len);
|
||||
@ -123,12 +131,11 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
|
||||
int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
|
||||
int skx_get_node_id(struct skx_dev *d, u8 *id);
|
||||
|
||||
int skx_get_all_bus_mappings(unsigned int did, int off, enum type,
|
||||
struct list_head **list);
|
||||
int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list);
|
||||
|
||||
int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm);
|
||||
|
||||
int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm,
|
||||
int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm,
|
||||
struct skx_imc *imc, int chan, int dimmno);
|
||||
|
||||
int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
|
||||
|
@ -1278,7 +1278,7 @@ OCX_DEBUGFS_ATTR(lne23_badcnt, OCX_LNE_BAD_CNT(23));
|
||||
|
||||
OCX_DEBUGFS_ATTR(com_int, OCX_COM_INT_W1S);
|
||||
|
||||
struct debugfs_entry *ocx_dfs_ents[] = {
|
||||
static struct debugfs_entry *ocx_dfs_ents[] = {
|
||||
&debugfs_tlk0_ecc_ctl,
|
||||
&debugfs_tlk1_ecc_ctl,
|
||||
&debugfs_tlk2_ecc_ctl,
|
||||
@ -1919,19 +1919,19 @@ err_free:
|
||||
|
||||
L2C_DEBUGFS_ATTR(tad_int, L2C_TAD_INT_W1S);
|
||||
|
||||
struct debugfs_entry *l2c_tad_dfs_ents[] = {
|
||||
static struct debugfs_entry *l2c_tad_dfs_ents[] = {
|
||||
&debugfs_tad_int,
|
||||
};
|
||||
|
||||
L2C_DEBUGFS_ATTR(cbc_int, L2C_CBC_INT_W1S);
|
||||
|
||||
struct debugfs_entry *l2c_cbc_dfs_ents[] = {
|
||||
static struct debugfs_entry *l2c_cbc_dfs_ents[] = {
|
||||
&debugfs_cbc_int,
|
||||
};
|
||||
|
||||
L2C_DEBUGFS_ATTR(mci_int, L2C_MCI_INT_W1S);
|
||||
|
||||
struct debugfs_entry *l2c_mci_dfs_ents[] = {
|
||||
static struct debugfs_entry *l2c_mci_dfs_ents[] = {
|
||||
&debugfs_mci_int,
|
||||
};
|
||||
|
||||
|
@ -1349,7 +1349,6 @@ static int xgene_edac_l3_remove(struct xgene_edac_dev_ctx *l3)
|
||||
#define WORD_ALIGNED_ERR_MASK BIT(28)
|
||||
#define PAGE_ACCESS_ERR_MASK BIT(27)
|
||||
#define WRITE_ACCESS_MASK BIT(26)
|
||||
#define RBERRADDR_RD(src) ((src) & 0x03FFFFFF)
|
||||
|
||||
static const char * const soc_mem_err_v1[] = {
|
||||
"10GbE0",
|
||||
@ -1483,13 +1482,11 @@ static void xgene_edac_rb_report(struct edac_device_ctl_info *edac_dev)
|
||||
return;
|
||||
if (reg & STICKYERR_MASK) {
|
||||
bool write;
|
||||
u32 address;
|
||||
|
||||
dev_err(edac_dev->dev, "IOB bus access error(s)\n");
|
||||
if (regmap_read(ctx->edac->rb_map, RBEIR, ®))
|
||||
return;
|
||||
write = reg & WRITE_ACCESS_MASK ? 1 : 0;
|
||||
address = RBERRADDR_RD(reg);
|
||||
if (reg & AGENT_OFFLINE_ERR_MASK)
|
||||
dev_err(edac_dev->dev,
|
||||
"IOB bus %s access to offline agent error\n",
|
||||
|
Loading…
Reference in New Issue
Block a user