diff options
Diffstat (limited to 'drivers/edac/ghes_edac.c')
-rw-r--r-- | drivers/edac/ghes_edac.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c index 68b6ee18bea6..473aeec4b1da 100644 --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -91,6 +91,7 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) struct dimm_info *dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, dimm_fill->count, 0, 0); + u16 rdr_mask = BIT(7) | BIT(13); if (entry->size == 0xffff) { pr_info("Can't get DIMM%i size\n", @@ -99,22 +100,21 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) } else if (entry->size == 0x7fff) { dimm->nr_pages = MiB_TO_PAGES(entry->extended_size); } else { - if (entry->size & 1 << 15) - dimm->nr_pages = MiB_TO_PAGES((entry->size & - 0x7fff) << 10); + if (entry->size & BIT(15)) + dimm->nr_pages = MiB_TO_PAGES((entry->size & 0x7fff) << 10); else dimm->nr_pages = MiB_TO_PAGES(entry->size); } switch (entry->memory_type) { case 0x12: - if (entry->type_detail & 1 << 13) + if (entry->type_detail & BIT(13)) dimm->mtype = MEM_RDDR; else dimm->mtype = MEM_DDR; break; case 0x13: - if (entry->type_detail & 1 << 13) + if (entry->type_detail & BIT(13)) dimm->mtype = MEM_RDDR2; else dimm->mtype = MEM_DDR2; @@ -123,20 +123,29 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) dimm->mtype = MEM_FB_DDR2; break; case 0x18: - if (entry->type_detail & 1 << 13) + if (entry->type_detail & BIT(12)) + dimm->mtype = MEM_NVDIMM; + else if (entry->type_detail & BIT(13)) dimm->mtype = MEM_RDDR3; else dimm->mtype = MEM_DDR3; break; + case 0x1a: + if (entry->type_detail & BIT(12)) + dimm->mtype = MEM_NVDIMM; + else if (entry->type_detail & BIT(13)) + dimm->mtype = MEM_RDDR4; + else + dimm->mtype = MEM_DDR4; + break; default: - if (entry->type_detail & 1 << 6) + if (entry->type_detail & BIT(6)) dimm->mtype = MEM_RMBS; - else if ((entry->type_detail & ((1 << 7) | (1 << 13))) - == ((1 << 7) | (1 << 13))) + else if ((entry->type_detail & rdr_mask) == rdr_mask) dimm->mtype = MEM_RDR; - else if (entry->type_detail & 1 << 7) + else if (entry->type_detail & BIT(7)) dimm->mtype = MEM_SDR; - else if (entry->type_detail & 1 << 9) + else if (entry->type_detail & BIT(9)) dimm->mtype = MEM_EDO; else dimm->mtype = MEM_UNKNOWN; @@ -172,8 +181,7 @@ static void ghes_edac_dmidecode(const struct dmi_header *dh, void *arg) } } -void ghes_edac_report_mem_error(struct ghes *ghes, int sev, - struct cper_sec_mem_err *mem_err) +void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err) { enum hw_event_mc_err_type type; struct edac_raw_error_desc *e; @@ -183,10 +191,8 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev, char *p; u8 grain_bits; - if (!pvt) { - pr_err("Internal error: Can't find EDAC structure\n"); + if (!pvt) return; - } /* * We can do the locking below because GHES defers error processing @@ -434,12 +440,16 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) struct mem_ctl_info *mci; struct edac_mc_layer layers[1]; struct ghes_edac_dimm_fill dimm_fill; - int idx; + int idx = -1; - /* Check if safe to enable on this system */ - idx = acpi_match_platform_list(plat_list); - if (!force_load && idx < 0) - return 0; + if (IS_ENABLED(CONFIG_X86)) { + /* Check if safe to enable on this system */ + idx = acpi_match_platform_list(plat_list); + if (!force_load && idx < 0) + return -ENODEV; + } else { + idx = 0; + } /* * We have only one logical memory controller to which all DIMMs belong. @@ -519,6 +529,9 @@ void ghes_edac_unregister(struct ghes *ghes) { struct mem_ctl_info *mci; + if (!ghes_pvt) + return; + mci = ghes_pvt->mci; edac_mc_del_mc(mci->pdev); edac_mc_free(mci); |