History

Merge tag 'edac_for_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC updates from Borislav Petkov: "The new thing this time around is that we have three maintainers now and a new, old repo. New because it is new for the EDAC tree which is hosted there from now on and old because it is Tony's and mine's old RAS repo which we still use occasionally when the stuff isn't in tip. Summary: - EDAC tree has three maintainers and one new designated reviewer now, so that the work can scale better. - New driver for Mellanox' BlueField SoC DDR controller (Shravan Kumar Ramani) - AMD Rome support in amd64_edac (Yazen Ghannam and Isaac Vaughn) - Misc fixes, cleanups and code improvements" * tag 'edac_for_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: EDAC/amd64: Add PCI device IDs for family 17h, model 70h MAINTAINERS: Add Robert as a EDAC reviewer EDAC/mc_sysfs: Make debug messages consistent EDAC/mc_sysfs: Remove pointless gotos EDAC: Prefer 'unsigned int' to bare use of 'unsigned' EDAC/amd64: Support asymmetric dual-rank DIMMs EDAC/amd64: Cache secondary Chip Select registers EDAC/amd64: Decode syndrome before translating address EDAC/amd64: Find Chip Select memory size using Address Mask EDAC/amd64: Initialize DIMM info for systems with more than two channels EDAC/amd64: Recognize DRAM device type ECC capability EDAC/amd64: Support more than two controllers for chip selects handling EDAC/mc: Cleanup _edac_mc_free() code EDAC, pnd2: Fix ioremap() size in dnv_rd_reg() EDAC, mellanox: Add ECC support for BlueField DDR4 EDAC/altera: Use the proper type for the IRQ status bits EDAC/mc: Fix grain_bits calculation edac: altera: Move Stratix10 SDRAM ECC to peripheral MAINTAINERS: update EDAC entry to reflect current tree and maintainers

Linus Torvalds committed 7 years ago

Commit ff881842 parents a7bd4bc 3e443eb15 files · +803 −226Browse files

Unified · Split

15 files
  1. MAINTAINERS +8 −2
  2. drivers/edac/Kconfig +7 −0
  3. drivers/edac/Makefile +1 −0
  4. drivers/edac/altera_edac.c +53 −5
  5. drivers/edac/altera_edac.h +24 −1
  6. drivers/edac/amd64_edac.c +249 −122
  7. drivers/edac/amd64_edac.h +12 −3
  8. drivers/edac/bluefield_edac.c +356 −0
  9. drivers/edac/edac_mc.c +28 −25
  10. drivers/edac/edac_mc.h +3 −3
  11. drivers/edac/edac_mc_sysfs.c +41 −51
  12. drivers/edac/ghes_edac.c +1 −1
  13. drivers/edac/i5100_edac.c +9 −7
  14. drivers/edac/pnd2_edac.c +6 −1
  15. include/linux/edac.h +5 −5
MAINTAINERS+8−2
@@ -5761,6 +5761,11 @@ S: Supported · 5760 unmodified lines
57615761 F: drivers/edac/aspeed_edac.c
57625762 F: Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
57635763
5764+EDAC-BLUEFIELD
5765+M: Shravan Kumar Ramani <sramani@mellanox.com>
5766+S: Supported
5767+F: drivers/edac/bluefield_edac.c
5768+
57645769 EDAC-CALXEDA
57655770 M: Robert Richter <rric@kernel.org>
57665771 L: linux-edac@vger.kernel.org
@@ -5785,10 +5790,11 @@ F: drivers/edac/thunderx_edac* · 18 unmodified lines
57855790 EDAC-CORE
57865791 M: Borislav Petkov <bp@alien8.de>
57875792 M: Mauro Carvalho Chehab <mchehab@kernel.org>
5793+M: Tony Luck <tony.luck@intel.com>
57885794 R: James Morse <james.morse@arm.com>
5795+R: Robert Richter <rrichter@marvell.com>
57895796 L: linux-edac@vger.kernel.org
5790−T: git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next
5791−T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git linux_next
5797+T: git git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git edac-for-next
57925798 S: Supported
57935799 F: Documentation/admin-guide/ras.rst
57945800 F: Documentation/driver-api/edac.rst
drivers/edac/Kconfig+7−0
@@ -510,4 +510,11 @@ config EDAC_ASPEED · 509 unmodified lines
510510 First, ECC must be configured in the bootloader. Then, this driver
511511 will expose error counters via the EDAC kernel framework.
512512
513+config EDAC_BLUEFIELD
514+ tristate "Mellanox BlueField Memory ECC"
515+ depends on ARM64 && ((MELLANOX_PLATFORM && ACPI) || COMPILE_TEST)
516+ help
517+ Support for error detection and correction on the
518+ Mellanox BlueField SoCs.
519+
513520 endif # EDAC
drivers/edac/Makefile+1−0
@@ -85,3 +85,4 @@ obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o · 84 unmodified lines
8585 obj-$(CONFIG_EDAC_TI) += ti_edac.o
8686 obj-$(CONFIG_EDAC_QCOM) += qcom_edac.o
8787 obj-$(CONFIG_EDAC_ASPEED) += aspeed_edac.o
88+obj-$(CONFIG_EDAC_BLUEFIELD) += bluefield_edac.o
drivers/edac/altera_edac.c+53−5
@@ -222,7 +222,6 @@ static unsigned long get_total_mem(void) · 221 unmodified lines
222222 static const struct of_device_id altr_sdram_ctrl_of_match[] = {
223223 { .compatible = "altr,sdram-edac", .data = &c5_data},
224224 { .compatible = "altr,sdram-edac-a10", .data = &a10_data},
225− { .compatible = "altr,sdram-edac-s10", .data = &a10_data},
226225 {},
227226 };
228227 MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
@@ -1170,6 +1169,24 @@ static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat) · 941 unmodified lines
11701169 return 0;
11711170 }
11721171
1172+/*********************** SDRAM EDAC Device Functions *********************/
1173+
1174+#ifdef CONFIG_EDAC_ALTERA_SDRAM
1175+
1176+static const struct edac_device_prv_data s10_sdramecc_data = {
1177+ .setup = altr_check_ecc_deps,
1178+ .ce_clear_mask = ALTR_S10_ECC_SERRPENA,
1179+ .ue_clear_mask = ALTR_S10_ECC_DERRPENA,
1180+ .ecc_enable_mask = ALTR_S10_ECC_EN,
1181+ .ecc_en_ofst = ALTR_S10_ECC_CTRL_SDRAM_OFST,
1182+ .ce_set_mask = ALTR_S10_ECC_TSERRA,
1183+ .ue_set_mask = ALTR_S10_ECC_TDERRA,
1184+ .set_err_ofst = ALTR_S10_ECC_INTTEST_OFST,
1185+ .ecc_irq_handler = altr_edac_a10_ecc_irq,
1186+ .inject_fops = &altr_edac_a10_device_inject_fops,
1187+};
1188+#endif /* CONFIG_EDAC_ALTERA_SDRAM */
1189+
11731190 /*********************** OCRAM EDAC Device Functions *********************/
11741191
11751192 #ifdef CONFIG_EDAC_ALTERA_OCRAM
@@ -1758,6 +1775,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = { · 582 unmodified lines
17581775 #endif
17591776 #ifdef CONFIG_EDAC_ALTERA_SDMMC
17601777 { .compatible = "altr,socfpga-sdmmc-ecc", .data = &a10_sdmmcecca_data },
1778+#endif
1779+#ifdef CONFIG_EDAC_ALTERA_SDRAM
1780+ { .compatible = "altr,sdram-edac-s10", .data = &s10_sdramecc_data },
17611781 #endif
17621782 {},
17631783 };
@@ -1866,6 +1886,7 @@ static void altr_edac_a10_irq_handler(struct irq_desc *desc) · 102 unmodified lines
18661886 struct altr_arria10_edac *edac = irq_desc_get_handler_data(desc);
18671887 struct irq_chip *chip = irq_desc_get_chip(desc);
18681888 int irq = irq_desc_get_irq(desc);
1889+ unsigned long bits;
18691890
18701891 dberr = (irq == edac->db_irq) ? 1 : 0;
18711892 sm_offset = dberr ? A10_SYSMGR_ECC_INTSTAT_DERR_OFST :
@@ -1875,7 +1896,8 @@ static void altr_edac_a10_irq_handler(struct irq_desc *desc) · 3 unmodified lines
18751896
18761897 regmap_read(edac->ecc_mgr_map, sm_offset, &irq_status);
18771898
1878− for_each_set_bit(bit, (unsigned long *)&irq_status, 32) {
1899+ bits = irq_status;
1900+ for_each_set_bit(bit, &bits, 32) {
18791901 irq = irq_linear_revmap(edac->domain, dberr * 32 + bit);
18801902 if (irq)
18811903 generic_handle_irq(irq);
@@ -1889,6 +1911,10 @@ static int validate_parent_available(struct device_node *np) · 7 unmodified lines
18891911 struct device_node *parent;
18901912 int ret = 0;
18911913
1914+ /* SDRAM must be present for Linux (implied parent) */
1915+ if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
1916+ return 0;
1917+
18921918 /* Ensure parent device is enabled if parent node exists */
18931919 parent = of_parse_phandle(np, "altr,ecc-parent", 0);
18941920 if (parent && !of_device_is_available(parent))
@@ -1898,6 +1924,22 @@ static int validate_parent_available(struct device_node *np) · 3 unmodified lines
18981924 return ret;
18991925 }
19001926
1927+static int get_s10_sdram_edac_resource(struct device_node *np,
1928+ struct resource *res)
1929+{
1930+ struct device_node *parent;
1931+ int ret;
1932+
1933+ parent = of_parse_phandle(np, "altr,sdr-syscon", 0);
1934+ if (!parent)
1935+ return -ENODEV;
1936+
1937+ ret = of_address_to_resource(parent, 0, res);
1938+ of_node_put(parent);
1939+
1940+ return ret;
1941+}
1942+
19011943 static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
19021944 struct device_node *np)
19031945 {
@@ -1925,7 +1967,11 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac, · 21 unmodified lines
19251967 if (!devres_open_group(edac->dev, altr_edac_a10_device_add, GFP_KERNEL))
19261968 return -ENOMEM;
19271969
1928− rc = of_address_to_resource(np, 0, &res);
1970+ if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
1971+ rc = get_s10_sdram_edac_resource(np, &res);
1972+ else
1973+ rc = of_address_to_resource(np, 0, &res);
1974+
19291975 if (rc < 0) {
19301976 edac_printk(KERN_ERR, EDAC_DEVICE,
19311977 "%s: no resource address\n", ecc_name);
@@ -2231,13 +2277,15 @@ static int altr_edac_a10_probe(struct platform_device *pdev) · 299 unmodified lines
22312277 of_device_is_compatible(child, "altr,socfpga-dma-ecc") ||
22322278 of_device_is_compatible(child, "altr,socfpga-usb-ecc") ||
22332279 of_device_is_compatible(child, "altr,socfpga-qspi-ecc") ||
2280+#ifdef CONFIG_EDAC_ALTERA_SDRAM
2281+ of_device_is_compatible(child, "altr,sdram-edac-s10") ||
2282+#endif
22342283 of_device_is_compatible(child, "altr,socfpga-sdmmc-ecc"))
22352284
22362285 altr_edac_a10_device_add(edac, child);
22372286
22382287 #ifdef CONFIG_EDAC_ALTERA_SDRAM
2239− else if ((of_device_is_compatible(child, "altr,sdram-edac-a10")) ||
2240− (of_device_is_compatible(child, "altr,sdram-edac-s10")))
2288+ else if (of_device_is_compatible(child, "altr,sdram-edac-a10"))
22412289 of_platform_populate(pdev->dev.of_node,
22422290 altr_sdram_ctrl_of_match,
22432291 NULL, &pdev->dev);
drivers/edac/altera_edac.h+24−1
@@ -289,6 +289,29 @@ struct altr_sdram_mc_data { · 288 unmodified lines
289289 #define ALTR_A10_ECC_INIT_WATCHDOG_10US 10000
290290
291291 /************* Stratix10 Defines **************/
292+#define ALTR_S10_ECC_CTRL_SDRAM_OFST 0x00
293+#define ALTR_S10_ECC_EN BIT(0)
294+
295+#define ALTR_S10_ECC_ERRINTEN_OFST 0x10
296+#define ALTR_S10_ECC_ERRINTENS_OFST 0x14
297+#define ALTR_S10_ECC_ERRINTENR_OFST 0x18
298+#define ALTR_S10_ECC_SERRINTEN BIT(0)
299+
300+#define ALTR_S10_ECC_INTMODE_OFST 0x1C
301+#define ALTR_S10_ECC_INTMODE BIT(0)
302+
303+#define ALTR_S10_ECC_INTSTAT_OFST 0x20
304+#define ALTR_S10_ECC_SERRPENA BIT(0)
305+#define ALTR_S10_ECC_DERRPENA BIT(8)
306+#define ALTR_S10_ECC_ERRPENA_MASK (ALTR_S10_ECC_SERRPENA | \
307+ ALTR_S10_ECC_DERRPENA)
308+
309+#define ALTR_S10_ECC_INTTEST_OFST 0x24
310+#define ALTR_S10_ECC_TSERRA BIT(0)
311+#define ALTR_S10_ECC_TDERRA BIT(8)
312+#define ALTR_S10_ECC_TSERRB BIT(16)
313+#define ALTR_S10_ECC_TDERRB BIT(24)
314+
292315 #define ALTR_S10_DERR_ADDRA_OFST 0x2C
293316
294317 /* Stratix10 ECC Manager Defines */
@@ -300,7 +323,7 @@ struct altr_sdram_mc_data { · 5 unmodified lines
300323 #define S10_SYSMGR_UE_ADDR_OFST 0x224
301324
302325 #define S10_DDR0_IRQ_MASK BIT(16)
303−#define S10_DBE_IRQ_MASK 0x3FE
326+#define S10_DBE_IRQ_MASK 0x3FFFE
304327
305328 /* Define ECC Block Offsets for peripherals */
306329 #define ECC_BLK_ADDRESS_OFST 0x40
drivers/edac/amd64_edac.c+249−122
@@ -788,51 +788,45 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan) · 787 unmodified lines
788788 (dclr & BIT(15)) ? "yes" : "no");
789789 }
790790
791−/*
792− * The Address Mask should be a contiguous set of bits in the non-interleaved
793− * case. So to check for CS interleaving, find the most- and least-significant
794− * bits of the mask, generate a contiguous bitmask, and compare the two.
795− */
796−static bool f17_cs_interleaved(struct amd64_pvt *pvt, u8 ctrl, int cs)
791+#define CS_EVEN_PRIMARY BIT(0)
792+#define CS_ODD_PRIMARY BIT(1)
793+#define CS_EVEN_SECONDARY BIT(2)
794+#define CS_ODD_SECONDARY BIT(3)
795+
796+#define CS_EVEN (CS_EVEN_PRIMARY | CS_EVEN_SECONDARY)
797+#define CS_ODD (CS_ODD_PRIMARY | CS_ODD_SECONDARY)
798+
799+static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
797800 {
798− u32 mask = pvt->csels[ctrl].csmasks[cs >> 1];
799− u32 msb = fls(mask) - 1, lsb = ffs(mask) - 1;
800− u32 test_mask = GENMASK(msb, lsb);
801+ int cs_mode = 0;
801802
802− edac_dbg(1, "mask=0x%08x test_mask=0x%08x\n", mask, test_mask);
803+ if (csrow_enabled(2 * dimm, ctrl, pvt))
804+ cs_mode |= CS_EVEN_PRIMARY;
803805
804− return mask ^ test_mask;
806+ if (csrow_enabled(2 * dimm + 1, ctrl, pvt))
807+ cs_mode |= CS_ODD_PRIMARY;
808+
809+ /* Asymmetric dual-rank DIMM support. */
810+ if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt))
811+ cs_mode |= CS_ODD_SECONDARY;
812+
813+ return cs_mode;
805814 }
806815
807816 static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
808817 {
809− int dimm, size0, size1, cs0, cs1;
818+ int dimm, size0, size1, cs0, cs1, cs_mode;
810819
811820 edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl);
812821
813− for (dimm = 0; dimm < 4; dimm++) {
814− size0 = 0;
822+ for (dimm = 0; dimm < 2; dimm++) {
815823 cs0 = dimm * 2;
816−
817− if (csrow_enabled(cs0, ctrl, pvt))
818− size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs0);
819−
820− size1 = 0;
821824 cs1 = dimm * 2 + 1;
822825
823− if (csrow_enabled(cs1, ctrl, pvt)) {
824− /*
825− * CS interleaving is only supported if both CSes have
826− * the same amount of memory. Because they are
827− * interleaved, it will look like both CSes have the
828− * full amount of memory. Save the size for both as
829− * half the amount we found on CS0, if interleaved.
830− */
831− if (f17_cs_interleaved(pvt, ctrl, cs1))
832− size1 = size0 = (size0 >> 1);
833− else
834− size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
835− }
826+ cs_mode = f17_get_cs_mode(dimm, ctrl, pvt);
827+
828+ size0 = pvt->ops->dbam_to_cs(pvt, ctrl, cs_mode, cs0);
829+ size1 = pvt->ops->dbam_to_cs(pvt, ctrl, cs_mode, cs1);
836830
837831 amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
838832 cs0, size0,
@@ -942,89 +936,119 @@ static void prep_chip_selects(struct amd64_pvt *pvt) · 103 unmodified lines
942936 } else if (pvt->fam == 0x15 && pvt->model == 0x30) {
943937 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4;
944938 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2;
939+ } else if (pvt->fam >= 0x17) {
940+ int umc;
941+
942+ for_each_umc(umc) {
943+ pvt->csels[umc].b_cnt = 4;
944+ pvt->csels[umc].m_cnt = 2;
945+ }
946+
945947 } else {
946948 pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8;
947949 pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 4;
948950 }
949951 }
950952
953+static void read_umc_base_mask(struct amd64_pvt *pvt)
954+{
955+ u32 umc_base_reg, umc_base_reg_sec;
956+ u32 umc_mask_reg, umc_mask_reg_sec;
957+ u32 base_reg, base_reg_sec;
958+ u32 mask_reg, mask_reg_sec;
959+ u32 *base, *base_sec;
960+ u32 *mask, *mask_sec;
961+ int cs, umc;
962+
963+ for_each_umc(umc) {
964+ umc_base_reg = get_umc_base(umc) + UMCCH_BASE_ADDR;
965+ umc_base_reg_sec = get_umc_base(umc) + UMCCH_BASE_ADDR_SEC;
966+
967+ for_each_chip_select(cs, umc, pvt) {
968+ base = &pvt->csels[umc].csbases[cs];
969+ base_sec = &pvt->csels[umc].csbases_sec[cs];
970+
971+ base_reg = umc_base_reg + (cs * 4);
972+ base_reg_sec = umc_base_reg_sec + (cs * 4);
973+
974+ if (!amd_smn_read(pvt->mc_node_id, base_reg, base))
975+ edac_dbg(0, " DCSB%d[%d]=0x%08x reg: 0x%x\n",
976+ umc, cs, *base, base_reg);
977+
978+ if (!amd_smn_read(pvt->mc_node_id, base_reg_sec, base_sec))
979+ edac_dbg(0, " DCSB_SEC%d[%d]=0x%08x reg: 0x%x\n",
980+ umc, cs, *base_sec, base_reg_sec);
981+ }
982+
983+ umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK;
984+ umc_mask_reg_sec = get_umc_base(umc) + UMCCH_ADDR_MASK_SEC;
985+
986+ for_each_chip_select_mask(cs, umc, pvt) {
987+ mask = &pvt->csels[umc].csmasks[cs];
988+ mask_sec = &pvt->csels[umc].csmasks_sec[cs];
989+
990+ mask_reg = umc_mask_reg + (cs * 4);
991+ mask_reg_sec = umc_mask_reg_sec + (cs * 4);
992+
993+ if (!amd_smn_read(pvt->mc_node_id, mask_reg, mask))
994+ edac_dbg(0, " DCSM%d[%d]=0x%08x reg: 0x%x\n",
995+ umc, cs, *mask, mask_reg);
996+
997+ if (!amd_smn_read(pvt->mc_node_id, mask_reg_sec, mask_sec))
998+ edac_dbg(0, " DCSM_SEC%d[%d]=0x%08x reg: 0x%x\n",
999+ umc, cs, *mask_sec, mask_reg_sec);
1000+ }
1001+ }
1002+}
1003+
9511004 /*
9521005 * Function 2 Offset F10_DCSB0; read in the DCS Base and DCS Mask registers
9531006 */
9541007 static void read_dct_base_mask(struct amd64_pvt *pvt)
9551008 {
956− int base_reg0, base_reg1, mask_reg0, mask_reg1, cs;
1009+ int cs;
9571010
9581011 prep_chip_selects(pvt);
9591012
960− if (pvt->umc) {
961− base_reg0 = get_umc_base(0) + UMCCH_BASE_ADDR;
962− base_reg1 = get_umc_base(1) + UMCCH_BASE_ADDR;
963− mask_reg0 = get_umc_base(0) + UMCCH_ADDR_MASK;
964− mask_reg1 = get_umc_base(1) + UMCCH_ADDR_MASK;
965− } else {
966− base_reg0 = DCSB0;
967− base_reg1 = DCSB1;
968− mask_reg0 = DCSM0;
969− mask_reg1 = DCSM1;
970− }
1013+ if (pvt->umc)
1014+ return read_umc_base_mask(pvt);
9711015
9721016 for_each_chip_select(cs, 0, pvt) {
973− int reg0 = base_reg0 + (cs * 4);
974− int reg1 = base_reg1 + (cs * 4);
1017+ int reg0 = DCSB0 + (cs * 4);
1018+ int reg1 = DCSB1 + (cs * 4);
9751019 u32 *base0 = &pvt->csels[0].csbases[cs];
9761020 u32 *base1 = &pvt->csels[1].csbases[cs];
9771021
978− if (pvt->umc) {
979− if (!amd_smn_read(pvt->mc_node_id, reg0, base0))
980− edac_dbg(0, " DCSB0[%d]=0x%08x reg: 0x%x\n",
981− cs, *base0, reg0);
1022+ if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0))
1023+ edac_dbg(0, " DCSB0[%d]=0x%08x reg: F2x%x\n",
1024+ cs, *base0, reg0);
9821025
983− if (!amd_smn_read(pvt->mc_node_id, reg1, base1))
984− edac_dbg(0, " DCSB1[%d]=0x%08x reg: 0x%x\n",
985− cs, *base1, reg1);
986− } else {
987− if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0))
988− edac_dbg(0, " DCSB0[%d]=0x%08x reg: F2x%x\n",
989− cs, *base0, reg0);
990−
991− if (pvt->fam == 0xf)
992− continue;
1026+ if (pvt->fam == 0xf)
1027+ continue;
9931028
994− if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1))
995− edac_dbg(0, " DCSB1[%d]=0x%08x reg: F2x%x\n",
996− cs, *base1, (pvt->fam == 0x10) ? reg1
997− : reg0);
998− }
1029+ if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1))
1030+ edac_dbg(0, " DCSB1[%d]=0x%08x reg: F2x%x\n",
1031+ cs, *base1, (pvt->fam == 0x10) ? reg1
1032+ : reg0);
9991033 }
10001034
10011035 for_each_chip_select_mask(cs, 0, pvt) {
1002− int reg0 = mask_reg0 + (cs * 4);
1003− int reg1 = mask_reg1 + (cs * 4);
1036+ int reg0 = DCSM0 + (cs * 4);
1037+ int reg1 = DCSM1 + (cs * 4);
10041038 u32 *mask0 = &pvt->csels[0].csmasks[cs];
10051039 u32 *mask1 = &pvt->csels[1].csmasks[cs];
10061040
1007− if (pvt->umc) {
1008− if (!amd_smn_read(pvt->mc_node_id, reg0, mask0))
1009− edac_dbg(0, " DCSM0[%d]=0x%08x reg: 0x%x\n",
1010− cs, *mask0, reg0);
1011−
1012− if (!amd_smn_read(pvt->mc_node_id, reg1, mask1))
1013− edac_dbg(0, " DCSM1[%d]=0x%08x reg: 0x%x\n",
1014− cs, *mask1, reg1);
1015− } else {
1016− if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0))
1017− edac_dbg(0, " DCSM0[%d]=0x%08x reg: F2x%x\n",
1018− cs, *mask0, reg0);
1041+ if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0))
1042+ edac_dbg(0, " DCSM0[%d]=0x%08x reg: F2x%x\n",
1043+ cs, *mask0, reg0);
10191044
1020− if (pvt->fam == 0xf)
1021− continue;
1045+ if (pvt->fam == 0xf)
1046+ continue;
10221047
1023− if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1))
1024− edac_dbg(0, " DCSM1[%d]=0x%08x reg: F2x%x\n",
1025− cs, *mask1, (pvt->fam == 0x10) ? reg1
1026− : reg0);
1027− }
1048+ if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1))
1049+ edac_dbg(0, " DCSM1[%d]=0x%08x reg: F2x%x\n",
1050+ cs, *mask1, (pvt->fam == 0x10) ? reg1
1051+ : reg0);
10281052 }
10291053 }
10301054
@@ -1556,18 +1580,58 @@ static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct, · 525 unmodified lines
15561580 return ddr3_cs_size(cs_mode, false);
15571581 }
15581582
1559−static int f17_base_addr_to_cs_size(struct amd64_pvt *pvt, u8 umc,
1583+static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
15601584 unsigned int cs_mode, int csrow_nr)
15611585 {
1562− u32 base_addr = pvt->csels[umc].csbases[csrow_nr];
1586+ u32 addr_mask_orig, addr_mask_deinterleaved;
1587+ u32 msb, weight, num_zero_bits;
1588+ int dimm, size = 0;
15631589
1564− /* Each mask is used for every two base addresses. */
1565− u32 addr_mask = pvt->csels[umc].csmasks[csrow_nr >> 1];
1590+ /* No Chip Selects are enabled. */
1591+ if (!cs_mode)
1592+ return size;
15661593
1567− /* Register [31:1] = Address [39:9]. Size is in kBs here. */
1568− u32 size = ((addr_mask >> 1) - (base_addr >> 1) + 1) >> 1;
1594+ /* Requested size of an even CS but none are enabled. */
1595+ if (!(cs_mode & CS_EVEN) && !(csrow_nr & 1))
1596+ return size;
15691597
1570− edac_dbg(1, "BaseAddr: 0x%x, AddrMask: 0x%x\n", base_addr, addr_mask);
1598+ /* Requested size of an odd CS but none are enabled. */
1599+ if (!(cs_mode & CS_ODD) && (csrow_nr & 1))
1600+ return size;
1601+
1602+ /*
1603+ * There is one mask per DIMM, and two Chip Selects per DIMM.
1604+ * CS0 and CS1 -> DIMM0
1605+ * CS2 and CS3 -> DIMM1
1606+ */
1607+ dimm = csrow_nr >> 1;
1608+
1609+ /* Asymmetric dual-rank DIMM support. */
1610+ if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY))
1611+ addr_mask_orig = pvt->csels[umc].csmasks_sec[dimm];
1612+ else
1613+ addr_mask_orig = pvt->csels[umc].csmasks[dimm];
1614+
1615+ /*
1616+ * The number of zero bits in the mask is equal to the number of bits
1617+ * in a full mask minus the number of bits in the current mask.
1618+ *
1619+ * The MSB is the number of bits in the full mask because BIT[0] is
1620+ * always 0.
1621+ */
1622+ msb = fls(addr_mask_orig) - 1;
1623+ weight = hweight_long(addr_mask_orig);
1624+ num_zero_bits = msb - weight;
1625+
1626+ /* Take the number of zero bits off from the top of the mask. */
1627+ addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1);
1628+
1629+ edac_dbg(1, "CS%d DIMM%d AddrMasks:\n", csrow_nr, dimm);
1630+ edac_dbg(1, " Original AddrMask: 0x%x\n", addr_mask_orig);
1631+ edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", addr_mask_deinterleaved);
1632+
1633+ /* Register [31:1] = Address [39:9]. Size is in kBs here. */
1634+ size = (addr_mask_deinterleaved >> 2) + 1;
15711635
15721636 /* Return size in MBs. */
15731637 return size >> 10;
@@ -2232,7 +2296,7 @@ static struct amd64_family_type family_types[] = { · 658 unmodified lines
22322296 .f6_id = PCI_DEVICE_ID_AMD_17H_DF_F6,
22332297 .ops = {
22342298 .early_channel_count = f17_early_channel_count,
2235− .dbam_to_cs = f17_base_addr_to_cs_size,
2299+ .dbam_to_cs = f17_addr_mask_to_cs_size,
22362300 }
22372301 },
22382302 [F17_M10H_CPUS] = {
@@ -2241,7 +2305,7 @@ static struct amd64_family_type family_types[] = { · 2 unmodified lines
22412305 .f6_id = PCI_DEVICE_ID_AMD_17H_M10H_DF_F6,
22422306 .ops = {
22432307 .early_channel_count = f17_early_channel_count,
2244− .dbam_to_cs = f17_base_addr_to_cs_size,
2308+ .dbam_to_cs = f17_addr_mask_to_cs_size,
22452309 }
22462310 },
22472311 [F17_M30H_CPUS] = {
@@ -2250,7 +2314,16 @@ static struct amd64_family_type family_types[] = { · 2 unmodified lines
22502314 .f6_id = PCI_DEVICE_ID_AMD_17H_M30H_DF_F6,
22512315 .ops = {
22522316 .early_channel_count = f17_early_channel_count,
2253− .dbam_to_cs = f17_base_addr_to_cs_size,
2317+ .dbam_to_cs = f17_addr_mask_to_cs_size,
2318+ }
2319+ },
2320+ [F17_M70H_CPUS] = {
2321+ .ctl_name = "F17h_M70h",
2322+ .f0_id = PCI_DEVICE_ID_AMD_17H_M70H_DF_F0,
2323+ .f6_id = PCI_DEVICE_ID_AMD_17H_M70H_DF_F6,
2324+ .ops = {
2325+ .early_channel_count = f17_early_channel_count,
2326+ .dbam_to_cs = f17_addr_mask_to_cs_size,
22542327 }
22552328 },
22562329 };
@@ -2537,13 +2610,6 @@ static void decode_umc_error(int node_id, struct mce *m) · 280 unmodified lines
25372610
25382611 err.channel = find_umc_channel(m);
25392612
2540− if (umc_normaddr_to_sysaddr(m->addr, pvt->mc_node_id, err.channel, &sys_addr)) {
2541− err.err_code = ERR_NORM_ADDR;
2542− goto log_error;
2543− }
2544−
2545− error_address_to_page_and_offset(sys_addr, &err);
2546−
25472613 if (!(m->status & MCI_STATUS_SYNDV)) {
25482614 err.err_code = ERR_SYND;
25492615 goto log_error;
@@ -2560,6 +2626,13 @@ static void decode_umc_error(int node_id, struct mce *m) · 10 unmodified lines
25602626
25612627 err.csrow = m->synd & 0x7;
25622628
2629+ if (umc_normaddr_to_sysaddr(m->addr, pvt->mc_node_id, err.channel, &sys_addr)) {
2630+ err.err_code = ERR_NORM_ADDR;
2631+ goto log_error;
2632+ }
2633+
2634+ error_address_to_page_and_offset(sys_addr, &err);
2635+
25632636 log_error:
25642637 __log_ecc_error(mci, &err, ecc_type);
25652638 }
@@ -2809,10 +2882,12 @@ static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig) · 243 unmodified lines
28092882 int csrow_nr = csrow_nr_orig;
28102883 u32 cs_mode, nr_pages;
28112884
2812− if (!pvt->umc)
2885+ if (!pvt->umc) {
28132886 csrow_nr >>= 1;
2814−
2815− cs_mode = DBAM_DIMM(csrow_nr, dbam);
2887+ cs_mode = DBAM_DIMM(csrow_nr, dbam);
2888+ } else {
2889+ cs_mode = f17_get_cs_mode(csrow_nr >> 1, dct, pvt);
2890+ }
28162891
28172892 nr_pages = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, csrow_nr);
28182893 nr_pages <<= 20 - PAGE_SHIFT;
@@ -2824,6 +2899,49 @@ static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig) · 5 unmodified lines
28242899 return nr_pages;
28252900 }
28262901
2902+static int init_csrows_df(struct mem_ctl_info *mci)
2903+{
2904+ struct amd64_pvt *pvt = mci->pvt_info;
2905+ enum edac_type edac_mode = EDAC_NONE;
2906+ enum dev_type dev_type = DEV_UNKNOWN;
2907+ struct dimm_info *dimm;
2908+ int empty = 1;
2909+ u8 umc, cs;
2910+
2911+ if (mci->edac_ctl_cap & EDAC_FLAG_S16ECD16ED) {
2912+ edac_mode = EDAC_S16ECD16ED;
2913+ dev_type = DEV_X16;
2914+ } else if (mci->edac_ctl_cap & EDAC_FLAG_S8ECD8ED) {
2915+ edac_mode = EDAC_S8ECD8ED;
2916+ dev_type = DEV_X8;
2917+ } else if (mci->edac_ctl_cap & EDAC_FLAG_S4ECD4ED) {
2918+ edac_mode = EDAC_S4ECD4ED;
2919+ dev_type = DEV_X4;
2920+ } else if (mci->edac_ctl_cap & EDAC_FLAG_SECDED) {
2921+ edac_mode = EDAC_SECDED;
2922+ }
2923+
2924+ for_each_umc(umc) {
2925+ for_each_chip_select(cs, umc, pvt) {
2926+ if (!csrow_enabled(cs, umc, pvt))
2927+ continue;
2928+
2929+ empty = 0;
2930+ dimm = mci->csrows[cs]->channels[umc]->dimm;
2931+
2932+ edac_dbg(1, "MC node: %d, csrow: %d\n",
2933+ pvt->mc_node_id, cs);
2934+
2935+ dimm->nr_pages = get_csrow_nr_pages(pvt, umc, cs);
2936+ dimm->mtype = pvt->dram_type;
2937+ dimm->edac_mode = edac_mode;
2938+ dimm->dtype = dev_type;
2939+ }
2940+ }
2941+
2942+ return empty;
2943+}
2944+
28272945 /*
28282946 * Initialize the array of csrow attribute instances, based on the values
28292947 * from pci config hardware registers.
@@ -2838,15 +2956,16 @@ static int init_csrows(struct mem_ctl_info *mci) · 8 unmodified lines
28382956 int nr_pages = 0;
28392957 u32 val;
28402958
2841− if (!pvt->umc) {
2842− amd64_read_pci_cfg(pvt->F3, NBCFG, &val);
2959+ if (pvt->umc)
2960+ return init_csrows_df(mci);
28432961
2844− pvt->nbcfg = val;
2962+ amd64_read_pci_cfg(pvt->F3, NBCFG, &val);
28452963
2846− edac_dbg(0, "node %d, NBCFG=0x%08x[ChipKillEccCap: %d|DramEccEn: %d]\n",
2847− pvt->mc_node_id, val,
2848− !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
2849− }
2964+ pvt->nbcfg = val;
2965+
2966+ edac_dbg(0, "node %d, NBCFG=0x%08x[ChipKillEccCap: %d|DramEccEn: %d]\n",
2967+ pvt->mc_node_id, val,
2968+ !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
28502969
28512970 /*
28522971 * We iterate over DCT0 here but we look at DCT1 in parallel, if needed.
@@ -2883,13 +3002,7 @@ static int init_csrows(struct mem_ctl_info *mci) · 30 unmodified lines
28833002 edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages);
28843003
28853004 /* Determine DIMM ECC mode: */
2886− if (pvt->umc) {
2887− if (mci->edac_ctl_cap & EDAC_FLAG_S4ECD4ED)
2888− edac_mode = EDAC_S4ECD4ED;
2889− else if (mci->edac_ctl_cap & EDAC_FLAG_SECDED)
2890− edac_mode = EDAC_SECDED;
2891−
2892− } else if (pvt->nbcfg & NBCFG_ECC_ENABLE) {
3005+ if (pvt->nbcfg & NBCFG_ECC_ENABLE) {
28933006 edac_mode = (pvt->nbcfg & NBCFG_CHIPKILL)
28943007 ? EDAC_S4ECD4ED
28953008 : EDAC_SECDED;
@@ -3137,12 +3250,15 @@ static bool ecc_enabled(struct pci_dev *F3, u16 nid) · 241 unmodified lines
31373250 static inline void
31383251 f17h_determine_edac_ctl_cap(struct mem_ctl_info *mci, struct amd64_pvt *pvt)
31393252 {
3140− u8 i, ecc_en = 1, cpk_en = 1;
3253+ u8 i, ecc_en = 1, cpk_en = 1, dev_x4 = 1, dev_x16 = 1;
31413254
31423255 for_each_umc(i) {
31433256 if (pvt->umc[i].sdp_ctrl & UMC_SDP_INIT) {
31443257 ecc_en &= !!(pvt->umc[i].umc_cap_hi & UMC_ECC_ENABLED);
31453258 cpk_en &= !!(pvt->umc[i].umc_cap_hi & UMC_ECC_CHIPKILL_CAP);
3259+
3260+ dev_x4 &= !!(pvt->umc[i].dimm_cfg & BIT(6));
3261+ dev_x16 &= !!(pvt->umc[i].dimm_cfg & BIT(7));
31463262 }
31473263 }
31483264
@@ -3150,8 +3266,15 @@ f17h_determine_edac_ctl_cap(struct mem_ctl_info *mci, struct amd64_pvt *pvt) · 1 unmodified line
31503266 if (ecc_en) {
31513267 mci->edac_ctl_cap |= EDAC_FLAG_SECDED;
31523268
3153− if (cpk_en)
3269+ if (!cpk_en)
3270+ return;
3271+
3272+ if (dev_x4)
31543273 mci->edac_ctl_cap |= EDAC_FLAG_S4ECD4ED;
3274+ else if (dev_x16)
3275+ mci->edac_ctl_cap |= EDAC_FLAG_S16ECD16ED;
3276+ else
3277+ mci->edac_ctl_cap |= EDAC_FLAG_S8ECD8ED;
31553278 }
31563279 }
31573280
@@ -3241,6 +3364,10 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt) · 83 unmodified lines
32413364 fam_type = &family_types[F17_M30H_CPUS];
32423365 pvt->ops = &family_types[F17_M30H_CPUS].ops;
32433366 break;
3367+ } else if (pvt->model >= 0x70 && pvt->model <= 0x7f) {
3368+ fam_type = &family_types[F17_M70H_CPUS];
3369+ pvt->ops = &family_types[F17_M70H_CPUS].ops;
3370+ break;
32443371 }
32453372 /* fall through */
32463373 case 0x18:
drivers/edac/amd64_edac.h+12−3
@@ -96,6 +96,7 @@ · 95 unmodified lines
9696 /* Hardware limit on ChipSelect rows per MC and processors per system */
9797 #define NUM_CHIPSELECTS 8
9898 #define DRAM_RANGES 8
99+#define NUM_CONTROLLERS 8
99100
100101 #define ON true
101102 #define OFF false
@@ -119,6 +120,8 @@ · 17 unmodified lines
119120 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F6 0x15ee
120121 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F0 0x1490
121122 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F6 0x1496
123+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F0 0x1440
124+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F6 0x1446
122125
123126 /*
124127 * Function 1 - Address Map
@@ -168,7 +171,8 @@ · 43 unmodified lines
168171 #define DCSM0 0x60
169172 #define DCSM1 0x160
170173
171−#define csrow_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE)
174+#define csrow_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE)
175+#define csrow_sec_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases_sec[(i)] & DCSB_CS_ENABLE)
172176
173177 #define DRAM_CONTROL 0x78
174178
@@ -258,7 +262,9 @@ · 83 unmodified lines
258262
259263 /* UMC CH register offsets */
260264 #define UMCCH_BASE_ADDR 0x0
265+#define UMCCH_BASE_ADDR_SEC 0x10
261266 #define UMCCH_ADDR_MASK 0x20
267+#define UMCCH_ADDR_MASK_SEC 0x28
262268 #define UMCCH_ADDR_CFG 0x30
263269 #define UMCCH_DIMM_CFG 0x80
264270 #define UMCCH_UMC_CFG 0x100
@@ -285,6 +291,7 @@ enum amd_families { · 20 unmodified lines
285291 F17_CPUS,
286292 F17_M10H_CPUS,
287293 F17_M30H_CPUS,
294+ F17_M70H_CPUS,
288295 NUM_FAMILIES,
289296 };
290297
@@ -311,9 +318,11 @@ struct dram_range { · 20 unmodified lines
311318 /* A DCT chip selects collection */
312319 struct chip_select {
313320 u32 csbases[NUM_CHIPSELECTS];
321+ u32 csbases_sec[NUM_CHIPSELECTS];
314322 u8 b_cnt;
315323
316324 u32 csmasks[NUM_CHIPSELECTS];
325+ u32 csmasks_sec[NUM_CHIPSELECTS];
317326 u8 m_cnt;
318327 };
319328
@@ -351,8 +360,8 @@ struct amd64_pvt { · 31 unmodified lines
351360 u32 dbam0; /* DRAM Base Address Mapping reg for DCT0 */
352361 u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */
353362
354− /* one for each DCT */
355− struct chip_select csels[2];
363+ /* one for each DCT/UMC */
364+ struct chip_select csels[NUM_CONTROLLERS];
356365
357366 /* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */
358367 struct dram_range ranges[DRAM_RANGES];
drivers/edac/bluefield_edac.c+356−0
@@ -0,0 +1,356 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Bluefield-specific EDAC driver.
4+ *
5+ * Copyright (c) 2019 Mellanox Technologies.
6+ */
7+
8+#include <linux/acpi.h>
9+#include <linux/arm-smccc.h>
10+#include <linux/bitfield.h>
11+#include <linux/edac.h>
12+#include <linux/io.h>
13+#include <linux/module.h>
14+#include <linux/platform_device.h>
15+
16+#include "edac_module.h"
17+
18+#define DRIVER_NAME "bluefield-edac"
19+
20+/*
21+ * Mellanox BlueField EMI (External Memory Interface) register definitions.
22+ */
23+
24+#define MLXBF_ECC_CNT 0x340
25+#define MLXBF_ECC_CNT__SERR_CNT GENMASK(15, 0)
26+#define MLXBF_ECC_CNT__DERR_CNT GENMASK(31, 16)
27+
28+#define MLXBF_ECC_ERR 0x348
29+#define MLXBF_ECC_ERR__SECC BIT(0)
30+#define MLXBF_ECC_ERR__DECC BIT(16)
31+
32+#define MLXBF_ECC_LATCH_SEL 0x354
33+#define MLXBF_ECC_LATCH_SEL__START BIT(24)
34+
35+#define MLXBF_ERR_ADDR_0 0x358
36+
37+#define MLXBF_ERR_ADDR_1 0x37c
38+
39+#define MLXBF_SYNDROM 0x35c
40+#define MLXBF_SYNDROM__DERR BIT(0)
41+#define MLXBF_SYNDROM__SERR BIT(1)
42+#define MLXBF_SYNDROM__SYN GENMASK(25, 16)
43+
44+#define MLXBF_ADD_INFO 0x364
45+#define MLXBF_ADD_INFO__ERR_PRANK GENMASK(9, 8)
46+
47+#define MLXBF_EDAC_MAX_DIMM_PER_MC 2
48+#define MLXBF_EDAC_ERROR_GRAIN 8
49+
50+/*
51+ * Request MLNX_SIP_GET_DIMM_INFO
52+ *
53+ * Retrieve information about DIMM on a certain slot.
54+ *
55+ * Call register usage:
56+ * a0: MLNX_SIP_GET_DIMM_INFO
57+ * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
58+ * a2-7: not used.
59+ *
60+ * Return status:
61+ * a0: MLXBF_DIMM_INFO defined below describing the DIMM.
62+ * a1-3: not used.
63+ */
64+#define MLNX_SIP_GET_DIMM_INFO 0x82000008
65+
66+/* Format for the SMC response about the memory information */
67+#define MLXBF_DIMM_INFO__SIZE_GB GENMASK_ULL(15, 0)
68+#define MLXBF_DIMM_INFO__IS_RDIMM BIT(16)
69+#define MLXBF_DIMM_INFO__IS_LRDIMM BIT(17)
70+#define MLXBF_DIMM_INFO__IS_NVDIMM BIT(18)
71+#define MLXBF_DIMM_INFO__RANKS GENMASK_ULL(23, 21)
72+#define MLXBF_DIMM_INFO__PACKAGE_X GENMASK_ULL(31, 24)
73+
74+struct bluefield_edac_priv {
75+ int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC];
76+ void __iomem *emi_base;
77+ int dimm_per_mc;
78+};
79+
80+static u64 smc_call1(u64 smc_op, u64 smc_arg)
81+{
82+ struct arm_smccc_res res;
83+
84+ arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res);
85+
86+ return res.a0;
87+}
88+
89+/*
90+ * Gather the ECC information from the External Memory Interface registers
91+ * and report it to the edac handler.
92+ */
93+static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
94+ int error_cnt,
95+ int is_single_ecc)
96+{
97+ struct bluefield_edac_priv *priv = mci->pvt_info;
98+ u32 dram_additional_info, err_prank, edea0, edea1;
99+ u32 ecc_latch_select, dram_syndrom, serr, derr, syndrom;
100+ enum hw_event_mc_err_type ecc_type;
101+ u64 ecc_dimm_addr;
102+ int ecc_dimm;
103+
104+ ecc_type = is_single_ecc ? HW_EVENT_ERR_CORRECTED :
105+ HW_EVENT_ERR_UNCORRECTED;
106+
107+ /*
108+ * Tell the External Memory Interface to populate the relevant
109+ * registers with information about the last ECC error occurrence.
110+ */
111+ ecc_latch_select = MLXBF_ECC_LATCH_SEL__START;
112+ writel(ecc_latch_select, priv->emi_base + MLXBF_ECC_LATCH_SEL);
113+
114+ /*
115+ * Verify that the ECC reported info in the registers is of the
116+ * same type as the one asked to report. If not, just report the
117+ * error without the detailed information.
118+ */
119+ dram_syndrom = readl(priv->emi_base + MLXBF_SYNDROM);
120+ serr = FIELD_GET(MLXBF_SYNDROM__SERR, dram_syndrom);
121+ derr = FIELD_GET(MLXBF_SYNDROM__DERR, dram_syndrom);
122+ syndrom = FIELD_GET(MLXBF_SYNDROM__SYN, dram_syndrom);
123+
124+ if ((is_single_ecc && !serr) || (!is_single_ecc && !derr)) {
125+ edac_mc_handle_error(ecc_type, mci, error_cnt, 0, 0, 0,
126+ 0, 0, -1, mci->ctl_name, "");
127+ return;
128+ }
129+
130+ dram_additional_info = readl(priv->emi_base + MLXBF_ADD_INFO);
131+ err_prank = FIELD_GET(MLXBF_ADD_INFO__ERR_PRANK, dram_additional_info);
132+
133+ ecc_dimm = (err_prank >= 2 && priv->dimm_ranks[0] <= 2) ? 1 : 0;
134+
135+ edea0 = readl(priv->emi_base + MLXBF_ERR_ADDR_0);
136+ edea1 = readl(priv->emi_base + MLXBF_ERR_ADDR_1);
137+
138+ ecc_dimm_addr = ((u64)edea1 << 32) | edea0;
139+
140+ edac_mc_handle_error(ecc_type, mci, error_cnt,
141+ PFN_DOWN(ecc_dimm_addr),
142+ offset_in_page(ecc_dimm_addr),
143+ syndrom, ecc_dimm, 0, 0, mci->ctl_name, "");
144+}
145+
146+static void bluefield_edac_check(struct mem_ctl_info *mci)
147+{
148+ struct bluefield_edac_priv *priv = mci->pvt_info;
149+ u32 ecc_count, single_error_count, double_error_count, ecc_error = 0;
150+
151+ /*
152+ * The memory controller might not be initialized by the firmware
153+ * when there isn't memory, which may lead to bad register readings.
154+ */
155+ if (mci->edac_cap == EDAC_FLAG_NONE)
156+ return;
157+
158+ ecc_count = readl(priv->emi_base + MLXBF_ECC_CNT);
159+ single_error_count = FIELD_GET(MLXBF_ECC_CNT__SERR_CNT, ecc_count);
160+ double_error_count = FIELD_GET(MLXBF_ECC_CNT__DERR_CNT, ecc_count);
161+
162+ if (single_error_count) {
163+ ecc_error |= MLXBF_ECC_ERR__SECC;
164+
165+ bluefield_gather_report_ecc(mci, single_error_count, 1);
166+ }
167+
168+ if (double_error_count) {
169+ ecc_error |= MLXBF_ECC_ERR__DECC;
170+
171+ bluefield_gather_report_ecc(mci, double_error_count, 0);
172+ }
173+
174+ /* Write to clear reported errors. */
175+ if (ecc_count)
176+ writel(ecc_error, priv->emi_base + MLXBF_ECC_ERR);
177+}
178+
179+/* Initialize the DIMMs information for the given memory controller. */
180+static void bluefield_edac_init_dimms(struct mem_ctl_info *mci)
181+{
182+ struct bluefield_edac_priv *priv = mci->pvt_info;
183+ int mem_ctrl_idx = mci->mc_idx;
184+ struct dimm_info *dimm;
185+ u64 smc_info, smc_arg;
186+ int is_empty = 1, i;
187+
188+ for (i = 0; i < priv->dimm_per_mc; i++) {
189+ dimm = mci->dimms[i];
190+
191+ smc_arg = mem_ctrl_idx << 16 | i;
192+ smc_info = smc_call1(MLNX_SIP_GET_DIMM_INFO, smc_arg);
193+
194+ if (!FIELD_GET(MLXBF_DIMM_INFO__SIZE_GB, smc_info)) {
195+ dimm->mtype = MEM_EMPTY;
196+ continue;
197+ }
198+
199+ is_empty = 0;
200+
201+ dimm->edac_mode = EDAC_SECDED;
202+
203+ if (FIELD_GET(MLXBF_DIMM_INFO__IS_NVDIMM, smc_info))
204+ dimm->mtype = MEM_NVDIMM;
205+ else if (FIELD_GET(MLXBF_DIMM_INFO__IS_LRDIMM, smc_info))
206+ dimm->mtype = MEM_LRDDR4;
207+ else if (FIELD_GET(MLXBF_DIMM_INFO__IS_RDIMM, smc_info))
208+ dimm->mtype = MEM_RDDR4;
209+ else
210+ dimm->mtype = MEM_DDR4;
211+
212+ dimm->nr_pages =
213+ FIELD_GET(MLXBF_DIMM_INFO__SIZE_GB, smc_info) *
214+ (SZ_1G / PAGE_SIZE);
215+ dimm->grain = MLXBF_EDAC_ERROR_GRAIN;
216+
217+ /* Mem controller for BlueField only supports x4, x8 and x16 */
218+ switch (FIELD_GET(MLXBF_DIMM_INFO__PACKAGE_X, smc_info)) {
219+ case 4:
220+ dimm->dtype = DEV_X4;
221+ break;
222+ case 8:
223+ dimm->dtype = DEV_X8;
224+ break;
225+ case 16:
226+ dimm->dtype = DEV_X16;
227+ break;
228+ default:
229+ dimm->dtype = DEV_UNKNOWN;
230+ }
231+
232+ priv->dimm_ranks[i] =
233+ FIELD_GET(MLXBF_DIMM_INFO__RANKS, smc_info);
234+ }
235+
236+ if (is_empty)
237+ mci->edac_cap = EDAC_FLAG_NONE;
238+ else
239+ mci->edac_cap = EDAC_FLAG_SECDED;
240+}
241+
242+static int bluefield_edac_mc_probe(struct platform_device *pdev)
243+{
244+ struct bluefield_edac_priv *priv;
245+ struct device *dev = &pdev->dev;
246+ struct edac_mc_layer layers[1];
247+ struct mem_ctl_info *mci;
248+ struct resource *emi_res;
249+ unsigned int mc_idx, dimm_count;
250+ int rc, ret;
251+
252+ /* Read the MSS (Memory SubSystem) index from ACPI table. */
253+ if (device_property_read_u32(dev, "mss_number", &mc_idx)) {
254+ dev_warn(dev, "bf_edac: MSS number unknown\n");
255+ return -EINVAL;
256+ }
257+
258+ /* Read the DIMMs per MC from ACPI table. */
259+ if (device_property_read_u32(dev, "dimm_per_mc", &dimm_count)) {
260+ dev_warn(dev, "bf_edac: DIMMs per MC unknown\n");
261+ return -EINVAL;
262+ }
263+
264+ if (dimm_count > MLXBF_EDAC_MAX_DIMM_PER_MC) {
265+ dev_warn(dev, "bf_edac: DIMMs per MC not valid\n");
266+ return -EINVAL;
267+ }
268+
269+ emi_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
270+ if (!emi_res)
271+ return -EINVAL;
272+
273+ layers[0].type = EDAC_MC_LAYER_SLOT;
274+ layers[0].size = dimm_count;
275+ layers[0].is_virt_csrow = true;
276+
277+ mci = edac_mc_alloc(mc_idx, ARRAY_SIZE(layers), layers, sizeof(*priv));
278+ if (!mci)
279+ return -ENOMEM;
280+
281+ priv = mci->pvt_info;
282+
283+ priv->dimm_per_mc = dimm_count;
284+ priv->emi_base = devm_ioremap_resource(dev, emi_res);
285+ if (IS_ERR(priv->emi_base)) {
286+ dev_err(dev, "failed to map EMI IO resource\n");
287+ ret = PTR_ERR(priv->emi_base);
288+ goto err;
289+ }
290+
291+ mci->pdev = dev;
292+ mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_RDDR4 |
293+ MEM_FLAG_LRDDR4 | MEM_FLAG_NVDIMM;
294+ mci->edac_ctl_cap = EDAC_FLAG_SECDED;
295+
296+ mci->mod_name = DRIVER_NAME;
297+ mci->ctl_name = "BlueField_Memory_Controller";
298+ mci->dev_name = dev_name(dev);
299+ mci->edac_check = bluefield_edac_check;
300+
301+ /* Initialize mci with the actual populated DIMM information. */
302+ bluefield_edac_init_dimms(mci);
303+
304+ platform_set_drvdata(pdev, mci);
305+
306+ /* Register with EDAC core */
307+ rc = edac_mc_add_mc(mci);
308+ if (rc) {
309+ dev_err(dev, "failed to register with EDAC core\n");
310+ ret = rc;
311+ goto err;
312+ }
313+
314+ /* Only POLL mode supported so far. */
315+ edac_op_state = EDAC_OPSTATE_POLL;
316+
317+ return 0;
318+
319+err:
320+ edac_mc_free(mci);
321+
322+ return ret;
323+
324+}
325+
326+static int bluefield_edac_mc_remove(struct platform_device *pdev)
327+{
328+ struct mem_ctl_info *mci = platform_get_drvdata(pdev);
329+
330+ edac_mc_del_mc(&pdev->dev);
331+ edac_mc_free(mci);
332+
333+ return 0;
334+}
335+
336+static const struct acpi_device_id bluefield_mc_acpi_ids[] = {
337+ {"MLNXBF08", 0},
338+ {}
339+};
340+
341+MODULE_DEVICE_TABLE(acpi, bluefield_mc_acpi_ids);
342+
343+static struct platform_driver bluefield_edac_mc_driver = {
344+ .driver = {
345+ .name = DRIVER_NAME,
346+ .acpi_match_table = bluefield_mc_acpi_ids,
347+ },
348+ .probe = bluefield_edac_mc_probe,
349+ .remove = bluefield_edac_mc_remove,
350+};
351+
352+module_platform_driver(bluefield_edac_mc_driver);
353+
354+MODULE_DESCRIPTION("Mellanox BlueField memory edac driver");
355+MODULE_AUTHOR("Mellanox Technologies");
356+MODULE_LICENSE("GPL v2");
drivers/edac/edac_mc.c+28−25
@@ -114,8 +114,8 @@ static const struct kernel_param_ops edac_report_ops = { · 113 unmodified lines
114114
115115 module_param_cb(edac_report, &edac_report_ops, &edac_report, 0644);
116116
117−unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
118− unsigned len)
117+unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
118+ unsigned int len)
119119 {
120120 struct mem_ctl_info *mci = dimm->mci;
121121 int i, n, count = 0;
@@ -236,9 +236,9 @@ EXPORT_SYMBOL_GPL(edac_mem_types); · 114 unmodified lines
236236 * At return, the pointer 'p' will be incremented to be used on a next call
237237 * to this function.
238238 */
239−void *edac_align_ptr(void **p, unsigned size, int n_elems)
239+void *edac_align_ptr(void **p, unsigned int size, int n_elems)
240240 {
241− unsigned align, r;
241+ unsigned int align, r;
242242 void *ptr = *p;
243243
244244 *p += size * n_elems;
@@ -275,38 +275,37 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) · 30 unmodified lines
275275
276276 static void _edac_mc_free(struct mem_ctl_info *mci)
277277 {
278− int i, chn, row;
279278 struct csrow_info *csr;
280− const unsigned int tot_dimms = mci->tot_dimms;
281− const unsigned int tot_channels = mci->num_cschannel;
282− const unsigned int tot_csrows = mci->nr_csrows;
279+ int i, chn, row;
283280
284281 if (mci->dimms) {
285− for (i = 0; i < tot_dimms; i++)
282+ for (i = 0; i < mci->tot_dimms; i++)
286283 kfree(mci->dimms[i]);
287284 kfree(mci->dimms);
288285 }
286+
289287 if (mci->csrows) {
290− for (row = 0; row < tot_csrows; row++) {
288+ for (row = 0; row < mci->nr_csrows; row++) {
291289 csr = mci->csrows[row];
292− if (csr) {
293− if (csr->channels) {
294− for (chn = 0; chn < tot_channels; chn++)
295− kfree(csr->channels[chn]);
296− kfree(csr->channels);
297− }
298− kfree(csr);
290+ if (!csr)
291+ continue;
292+
293+ if (csr->channels) {
294+ for (chn = 0; chn < mci->num_cschannel; chn++)
295+ kfree(csr->channels[chn]);
296+ kfree(csr->channels);
299297 }
298+ kfree(csr);
300299 }
301300 kfree(mci->csrows);
302301 }
303302 kfree(mci);
304303 }
305304
306−struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
307− unsigned n_layers,
305+struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
306+ unsigned int n_layers,
308307 struct edac_mc_layer *layers,
309− unsigned sz_pvt)
308+ unsigned int sz_pvt)
310309 {
311310 struct mem_ctl_info *mci;
312311 struct edac_mc_layer *layer;
@@ -314,9 +313,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, · 1 unmodified line
314313 struct rank_info *chan;
315314 struct dimm_info *dimm;
316315 u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
317− unsigned pos[EDAC_MAX_LAYERS];
318− unsigned size, tot_dimms = 1, count = 1;
319− unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
316+ unsigned int pos[EDAC_MAX_LAYERS];
317+ unsigned int size, tot_dimms = 1, count = 1;
318+ unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
320319 void *pvt, *p, *ptr = NULL;
321320 int i, j, row, chn, n, len, off;
322321 bool per_rank = false;
@@ -1235,9 +1234,13 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, · 912 unmodified lines
12351234 if (p > e->location)
12361235 *(p - 1) = '\0';
12371236
1238− /* Report the error via the trace interface */
1239− grain_bits = fls_long(e->grain) + 1;
1237+ /* Sanity-check driver-supplied grain value. */
1238+ if (WARN_ON_ONCE(!e->grain))
1239+ e->grain = 1;
12401240
1241+ grain_bits = fls_long(e->grain - 1);
1242+
1243+ /* Report the error via the trace interface */
12411244 if (IS_ENABLED(CONFIG_RAS))
12421245 trace_mc_event(type, e->msg, e->label, e->error_count,
12431246 mci->mc_idx, e->top_layer, e->mid_layer,
drivers/edac/edac_mc.h+3−3
@@ -122,10 +122,10 @@ do { \ · 121 unmodified lines
122122 * On success, return a pointer to struct mem_ctl_info pointer;
123123 * %NULL otherwise
124124 */
125−struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
126− unsigned n_layers,
125+struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
126+ unsigned int n_layers,
127127 struct edac_mc_layer *layers,
128− unsigned sz_pvt);
128+ unsigned int sz_pvt);
129129
130130 /**
131131 * edac_get_owner - Return the owner's mod_name of EDAC MC
drivers/edac/edac_mc_sysfs.c+41−51
@@ -131,7 +131,7 @@ static const char * const edac_caps[] = { · 130 unmodified lines
131131
132132 struct dev_ch_attribute {
133133 struct device_attribute attr;
134− int channel;
134+ unsigned int channel;
135135 };
136136
137137 #define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \
@@ -200,7 +200,7 @@ static ssize_t channel_dimm_label_show(struct device *dev, · 62 unmodified lines
200200 char *data)
201201 {
202202 struct csrow_info *csrow = to_csrow(dev);
203− unsigned chan = to_channel(mattr);
203+ unsigned int chan = to_channel(mattr);
204204 struct rank_info *rank = csrow->channels[chan];
205205
206206 /* if field has not been initialized, there is nothing to send */
@@ -216,7 +216,7 @@ static ssize_t channel_dimm_label_store(struct device *dev, · 9 unmodified lines
216216 const char *data, size_t count)
217217 {
218218 struct csrow_info *csrow = to_csrow(dev);
219− unsigned chan = to_channel(mattr);
219+ unsigned int chan = to_channel(mattr);
220220 struct rank_info *rank = csrow->channels[chan];
221221 size_t copy_count = count;
222222
@@ -240,7 +240,7 @@ static ssize_t channel_ce_count_show(struct device *dev, · 17 unmodified lines
240240 struct device_attribute *mattr, char *data)
241241 {
242242 struct csrow_info *csrow = to_csrow(dev);
243− unsigned chan = to_channel(mattr);
243+ unsigned int chan = to_channel(mattr);
244244 struct rank_info *rank = csrow->channels[chan];
245245
246246 return sprintf(data, "%u\n", rank->ce_count);
@@ -278,7 +278,7 @@ static void csrow_attr_release(struct device *dev) · 31 unmodified lines
278278 {
279279 struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
280280
281− edac_dbg(1, "Releasing csrow device %s\n", dev_name(dev));
281+ edac_dbg(1, "device %s released\n", dev_name(dev));
282282 kfree(csrow);
283283 }
284284
@@ -414,14 +414,16 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, · 129 unmodified lines
414414 dev_set_name(&csrow->dev, "csrow%d", index);
415415 dev_set_drvdata(&csrow->dev, csrow);
416416
417− edac_dbg(0, "creating (virtual) csrow node %s\n",
418− dev_name(&csrow->dev));
419−
420417 err = device_add(&csrow->dev);
421− if (err)
418+ if (err) {
419+ edac_dbg(1, "failure: create device %s\n", dev_name(&csrow->dev));
422420 put_device(&csrow->dev);
421+ return err;
422+ }
423423
424− return err;
424+ edac_dbg(0, "device %s created\n", dev_name(&csrow->dev));
425+
426+ return 0;
425427 }
426428
427429 /* Create a CSROW object under specifed edac_mc_device */
@@ -435,12 +437,8 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci) · 7 unmodified lines
435437 if (!nr_pages_per_csrow(csrow))
436438 continue;
437439 err = edac_create_csrow_object(mci, mci->csrows[i], i);
438− if (err < 0) {
439− edac_dbg(1,
440− "failure: create csrow objects for csrow %d\n",
441− i);
440+ if (err < 0)
442441 goto error;
443− }
444442 }
445443 return 0;
446444
@@ -624,7 +622,7 @@ static void dimm_attr_release(struct device *dev) · 177 unmodified lines
624622 {
625623 struct dimm_info *dimm = container_of(dev, struct dimm_info, dev);
626624
627− edac_dbg(1, "Releasing dimm device %s\n", dev_name(dev));
625+ edac_dbg(1, "device %s released\n", dev_name(dev));
628626 kfree(dimm);
629627 }
630628
@@ -653,12 +651,21 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, · 22 unmodified lines
653651 pm_runtime_forbid(&mci->dev);
654652
655653 err = device_add(&dimm->dev);
656− if (err)
654+ if (err) {
655+ edac_dbg(1, "failure: create device %s\n", dev_name(&dimm->dev));
657656 put_device(&dimm->dev);
657+ return err;
658+ }
658659
659− edac_dbg(0, "created rank/dimm device %s\n", dev_name(&dimm->dev));
660+ if (IS_ENABLED(CONFIG_EDAC_DEBUG)) {
661+ char location[80];
660662
661− return err;
663+ edac_dimm_info_location(dimm, location, sizeof(location));
664+ edac_dbg(0, "device %s created at location %s\n",
665+ dev_name(&dimm->dev), location);
666+ }
667+
668+ return 0;
662669 }
663670
664671 /*
@@ -901,7 +908,7 @@ static void mci_attr_release(struct device *dev) · 236 unmodified lines
901908 {
902909 struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
903910
904− edac_dbg(1, "Releasing csrow device %s\n", dev_name(dev));
911+ edac_dbg(1, "device %s released\n", dev_name(dev));
905912 kfree(mci);
906913 }
907914
@@ -933,14 +940,15 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, · 25 unmodified lines
933940 dev_set_drvdata(&mci->dev, mci);
934941 pm_runtime_forbid(&mci->dev);
935942
936− edac_dbg(0, "creating device %s\n", dev_name(&mci->dev));
937943 err = device_add(&mci->dev);
938944 if (err < 0) {
939945 edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
940946 put_device(&mci->dev);
941− goto out;
947+ return err;
942948 }
943949
950+ edac_dbg(0, "device %s created\n", dev_name(&mci->dev));
951+
944952 /*
945953 * Create the dimm/rank devices
946954 */
@@ -950,22 +958,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, · 3 unmodified lines
950958 if (!dimm->nr_pages)
951959 continue;
952960
953−#ifdef CONFIG_EDAC_DEBUG
954− edac_dbg(1, "creating dimm%d, located at ", i);
955− if (edac_debug_level >= 1) {
956− int lay;
957− for (lay = 0; lay < mci->n_layers; lay++)
958− printk(KERN_CONT "%s %d ",
959− edac_layer_name[mci->layers[lay].type],
960− dimm->location[lay]);
961− printk(KERN_CONT "\n");
962− }
963−#endif
964961 err = edac_create_dimm_object(mci, dimm, i);
965− if (err) {
966− edac_dbg(1, "failure: create dimm %d obj\n", i);
962+ if (err)
967963 goto fail_unregister_dimm;
968− }
969964 }
970965
971966 #ifdef CONFIG_EDAC_LEGACY_SYSFS
@@ -987,7 +982,6 @@ fail_unregister_dimm: · 15 unmodified lines
987982 }
988983 device_unregister(&mci->dev);
989984
990−out:
991985 return err;
992986 }
993987
@@ -1011,14 +1005,14 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) · 17 unmodified lines
10111005 struct dimm_info *dimm = mci->dimms[i];
10121006 if (dimm->nr_pages == 0)
10131007 continue;
1014− edac_dbg(0, "removing device %s\n", dev_name(&dimm->dev));
1008+ edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev));
10151009 device_unregister(&dimm->dev);
10161010 }
10171011 }
10181012
10191013 void edac_unregister_sysfs(struct mem_ctl_info *mci)
10201014 {
1021− edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
1015+ edac_dbg(1, "unregistering device %s\n", dev_name(&mci->dev));
10221016 device_unregister(&mci->dev);
10231017 }
10241018
@@ -1029,7 +1023,7 @@ static void mc_attr_release(struct device *dev) · 4 unmodified lines
10291023 * parent device, used to create the /sys/devices/mc sysfs node.
10301024 * So, there are no attributes on it.
10311025 */
1032− edac_dbg(1, "Releasing device %s\n", dev_name(dev));
1026+ edac_dbg(1, "device %s released\n", dev_name(dev));
10331027 kfree(dev);
10341028 }
10351029
@@ -1044,10 +1038,8 @@ int __init edac_mc_sysfs_init(void) · 8 unmodified lines
10441038 int err;
10451039
10461040 mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
1047− if (!mci_pdev) {
1048− err = -ENOMEM;
1049− goto out;
1050− }
1041+ if (!mci_pdev)
1042+ return -ENOMEM;
10511043
10521044 mci_pdev->bus = edac_get_sysfs_subsys();
10531045 mci_pdev->type = &mc_attr_type;
@@ -1055,17 +1047,15 @@ int __init edac_mc_sysfs_init(void) · 1 unmodified line
10551047 dev_set_name(mci_pdev, "mc");
10561048
10571049 err = device_add(mci_pdev);
1058− if (err < 0)
1059− goto out_put_device;
1050+ if (err < 0) {
1051+ edac_dbg(1, "failure: create device %s\n", dev_name(mci_pdev));
1052+ put_device(mci_pdev);
1053+ return err;
1054+ }
10601055
10611056 edac_dbg(0, "device %s created\n", dev_name(mci_pdev));
10621057
10631058 return 0;
1064−
1065− out_put_device:
1066− put_device(mci_pdev);
1067− out:
1068− return err;
10691059 }
10701060
10711061 void edac_mc_sysfs_exit(void)
drivers/edac/ghes_edac.c+1−1
@@ -68,7 +68,7 @@ struct memdev_dmi_entry { · 67 unmodified lines
6868
6969 struct ghes_edac_dimm_fill {
7070 struct mem_ctl_info *mci;
71− unsigned count;
71+ unsigned int count;
7272 };
7373
7474 static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg)
drivers/edac/i5100_edac.c+9−7
@@ -417,7 +417,8 @@ static const char *i5100_err_msg(unsigned err) · 416 unmodified lines
417417 }
418418
419419 /* convert csrow index into a rank (per channel -- 0..5) */
420−static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
420+static unsigned int i5100_csrow_to_rank(const struct mem_ctl_info *mci,
421+ unsigned int csrow)
421422 {
422423 const struct i5100_priv *priv = mci->pvt_info;
423424
@@ -425,7 +426,8 @@ static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow) · 1 unmodified line
425426 }
426427
427428 /* convert csrow index into a channel (0..1) */
428−static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
429+static unsigned int i5100_csrow_to_chan(const struct mem_ctl_info *mci,
430+ unsigned int csrow)
429431 {
430432 const struct i5100_priv *priv = mci->pvt_info;
431433
@@ -653,11 +655,11 @@ static struct pci_dev *pci_get_device_func(unsigned vendor, · 221 unmodified lines
653655 return ret;
654656 }
655657
656−static unsigned long i5100_npages(struct mem_ctl_info *mci, int csrow)
658+static unsigned long i5100_npages(struct mem_ctl_info *mci, unsigned int csrow)
657659 {
658660 struct i5100_priv *priv = mci->pvt_info;
659− const unsigned chan_rank = i5100_csrow_to_rank(mci, csrow);
660− const unsigned chan = i5100_csrow_to_chan(mci, csrow);
661+ const unsigned int chan_rank = i5100_csrow_to_rank(mci, csrow);
662+ const unsigned int chan = i5100_csrow_to_chan(mci, csrow);
661663 unsigned addr_lines;
662664
663665 /* dimm present? */
@@ -852,8 +854,8 @@ static void i5100_init_csrows(struct mem_ctl_info *mci) · 188 unmodified lines
852854 for (i = 0; i < mci->tot_dimms; i++) {
853855 struct dimm_info *dimm;
854856 const unsigned long npages = i5100_npages(mci, i);
855− const unsigned chan = i5100_csrow_to_chan(mci, i);
856− const unsigned rank = i5100_csrow_to_rank(mci, i);
857+ const unsigned int chan = i5100_csrow_to_chan(mci, i);
858+ const unsigned int rank = i5100_csrow_to_rank(mci, i);
857859
858860 if (!npages)
859861 continue;
drivers/edac/pnd2_edac.c+6−1
@@ -260,11 +260,14 @@ static u64 get_sideband_reg_base_addr(void) · 259 unmodified lines
260260 }
261261 }
262262
263+#define DNV_MCHBAR_SIZE 0x8000
264+#define DNV_SB_PORT_SIZE 0x10000
263265 static int dnv_rd_reg(int port, int off, int op, void *data, size_t sz, char *name)
264266 {
265267 struct pci_dev *pdev;
266268 char *base;
267269 u64 addr;
270+ unsigned long size;
268271
269272 if (op == 4) {
270273 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x1980, NULL);
@@ -279,15 +282,17 @@ static int dnv_rd_reg(int port, int off, int op, void *data, size_t sz, char *na · 8 unmodified lines
279282 addr = get_mem_ctrl_hub_base_addr();
280283 if (!addr)
281284 return -ENODEV;
285+ size = DNV_MCHBAR_SIZE;
282286 } else {
283287 /* MMIO via sideband register base address */
284288 addr = get_sideband_reg_base_addr();
285289 if (!addr)
286290 return -ENODEV;
287291 addr += (port << 16);
292+ size = DNV_SB_PORT_SIZE;
288293 }
289294
290− base = ioremap((resource_size_t)addr, 0x10000);
295+ base = ioremap((resource_size_t)addr, size);
291296 if (!base)
292297 return -ENODEV;
293298
include/linux/edac.h+5−5
@@ -440,7 +440,7 @@ struct dimm_info { · 439 unmodified lines
440440 char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */
441441
442442 /* Memory location data */
443− unsigned location[EDAC_MAX_LAYERS];
443+ unsigned int location[EDAC_MAX_LAYERS];
444444
445445 struct mem_ctl_info *mci; /* the parent */
446446
@@ -451,7 +451,7 @@ struct dimm_info { · 4 unmodified lines
451451
452452 u32 nr_pages; /* number of pages on this dimm */
453453
454− unsigned csrow, cschannel; /* Points to the old API data */
454+ unsigned int csrow, cschannel; /* Points to the old API data */
455455
456456 u16 smbios_handle; /* Handle for SMBIOS type 17 */
457457 };
@@ -597,7 +597,7 @@ struct mem_ctl_info { · 139 unmodified lines
597597 unsigned long page);
598598 int mc_idx;
599599 struct csrow_info **csrows;
600− unsigned nr_csrows, num_cschannel;
600+ unsigned int nr_csrows, num_cschannel;
601601
602602 /*
603603 * Memory Controller hierarchy
@@ -608,14 +608,14 @@ struct mem_ctl_info { · 4 unmodified lines
608608 * of the recent drivers enumerate memories per DIMM, instead.
609609 * When the memory controller is per rank, csbased is true.
610610 */
611− unsigned n_layers;
611+ unsigned int n_layers;
612612 struct edac_mc_layer *layers;
613613 bool csbased;
614614
615615 /*
616616 * DIMM info. Will eventually remove the entire csrows_info some day
617617 */
618− unsigned tot_dimms;
618+ unsigned int tot_dimms;
619619 struct dimm_info **dimms;
620620
621621 /*

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t