Commit 1dee7f50 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'edac_updates_for_v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC updates from Borislav Petkov:

 - The EDAC drivers part of the effort to make the ->remove() platform
   driver callback return void

 - Add support for AMD AI accelerators

 - Add support for a number of Intel SoCs: Alder Lake-N, Raptor Lake-P,
   Meteor Lake-{P,PS}

 - Random fixes and cleanups all over the place

* tag 'edac_updates_for_v6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras: (39 commits)
  EDAC/skx_common: Filter out the invalid address
  EDAC, pnd2: Sort headers alphabetically
  EDAC, pnd2: Correct misleading error message in mk_region_mask()
  EDAC, pnd2: Apply bit macros and helpers where it makes sense
  EDAC, pnd2: Replace custom definition by one from sizes.h
  EDAC/igen6: Add Intel Meteor Lake-P SoCs support
  EDAC/igen6: Add Intel Meteor Lake-PS SoCs support
  EDAC/igen6: Add Intel Raptor Lake-P SoCs support
  EDAC/igen6: Add Intel Alder Lake-N SoCs support
  EDAC/igen6: Make get_mchbar() helper function
  EDAC/amd64: Add support for family 0x19, models 0x90-9f devices
  EDAC/mc: Add support for HBM3 memory type
  EDAC/{sb,i7core}_edac: Do not use a plain integer for a NULL pointer
  EDAC/armada_xp: Explicitly include correct DT includes
  EDAC/pci_sysfs: Use PCI_HEADER_TYPE_MASK instead of literals
  EDAC/thunderx: Fix possible out-of-bounds string access
  EDAC/fsl_ddr: Convert to platform remove callback returning void
  EDAC/zynqmp: Convert to platform remove callback returning void
  EDAC/xgene: Convert to platform remove callback returning void
  EDAC/ti: Convert to platform remove callback returning void
  ...
parents 5db8752c 1e92af09
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/panic_notifier.h> #include <linux/panic_notifier.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
...@@ -279,7 +280,6 @@ static int a10_unmask_irq(struct platform_device *pdev, u32 mask) ...@@ -279,7 +280,6 @@ static int a10_unmask_irq(struct platform_device *pdev, u32 mask)
static int altr_sdram_probe(struct platform_device *pdev) static int altr_sdram_probe(struct platform_device *pdev)
{ {
const struct of_device_id *id;
struct edac_mc_layer layers[2]; struct edac_mc_layer layers[2];
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
struct altr_sdram_mc_data *drvdata; struct altr_sdram_mc_data *drvdata;
...@@ -290,10 +290,6 @@ static int altr_sdram_probe(struct platform_device *pdev) ...@@ -290,10 +290,6 @@ static int altr_sdram_probe(struct platform_device *pdev)
int irq, irq2, res = 0; int irq, irq2, res = 0;
unsigned long mem_size, irqflags = 0; unsigned long mem_size, irqflags = 0;
id = of_match_device(altr_sdram_ctrl_of_match, &pdev->dev);
if (!id)
return -ENODEV;
/* Grab the register range from the sdr controller in device tree */ /* Grab the register range from the sdr controller in device tree */
mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"altr,sdr-syscon"); "altr,sdr-syscon");
...@@ -304,8 +300,7 @@ static int altr_sdram_probe(struct platform_device *pdev) ...@@ -304,8 +300,7 @@ static int altr_sdram_probe(struct platform_device *pdev)
} }
/* Check specific dependencies for the module */ /* Check specific dependencies for the module */
priv = of_match_node(altr_sdram_ctrl_of_match, priv = device_get_match_data(&pdev->dev);
pdev->dev.of_node)->data;
/* Validate the SDRAM controller has ECC enabled */ /* Validate the SDRAM controller has ECC enabled */
if (regmap_read(mc_vbase, priv->ecc_ctrl_offset, &read_reg) || if (regmap_read(mc_vbase, priv->ecc_ctrl_offset, &read_reg) ||
...@@ -459,15 +454,13 @@ static int altr_sdram_probe(struct platform_device *pdev) ...@@ -459,15 +454,13 @@ static int altr_sdram_probe(struct platform_device *pdev)
return res; return res;
} }
static int altr_sdram_remove(struct platform_device *pdev) static void altr_sdram_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return 0;
} }
/* /*
...@@ -489,7 +482,7 @@ static const struct dev_pm_ops altr_sdram_pm_ops = { ...@@ -489,7 +482,7 @@ static const struct dev_pm_ops altr_sdram_pm_ops = {
static struct platform_driver altr_sdram_edac_driver = { static struct platform_driver altr_sdram_edac_driver = {
.probe = altr_sdram_probe, .probe = altr_sdram_probe,
.remove = altr_sdram_remove, .remove_new = altr_sdram_remove,
.driver = { .driver = {
.name = "altr_sdram_edac", .name = "altr_sdram_edac",
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -812,7 +805,7 @@ static int altr_edac_device_probe(struct platform_device *pdev) ...@@ -812,7 +805,7 @@ static int altr_edac_device_probe(struct platform_device *pdev)
return res; return res;
} }
static int altr_edac_device_remove(struct platform_device *pdev) static void altr_edac_device_remove(struct platform_device *pdev)
{ {
struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
struct altr_edac_device_dev *drvdata = dci->pvt_info; struct altr_edac_device_dev *drvdata = dci->pvt_info;
...@@ -820,13 +813,11 @@ static int altr_edac_device_remove(struct platform_device *pdev) ...@@ -820,13 +813,11 @@ static int altr_edac_device_remove(struct platform_device *pdev)
debugfs_remove_recursive(drvdata->debugfs_dir); debugfs_remove_recursive(drvdata->debugfs_dir);
edac_device_del_device(&pdev->dev); edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(dci); edac_device_free_ctl_info(dci);
return 0;
} }
static struct platform_driver altr_edac_device_driver = { static struct platform_driver altr_edac_device_driver = {
.probe = altr_edac_device_probe, .probe = altr_edac_device_probe,
.remove = altr_edac_device_remove, .remove_new = altr_edac_device_remove,
.driver = { .driver = {
.name = "altr_edac_device", .name = "altr_edac_device",
.of_match_table = altr_edac_device_of_match, .of_match_table = altr_edac_device_of_match,
......
...@@ -996,15 +996,23 @@ static struct local_node_map { ...@@ -996,15 +996,23 @@ static struct local_node_map {
#define LNTM_NODE_COUNT GENMASK(27, 16) #define LNTM_NODE_COUNT GENMASK(27, 16)
#define LNTM_BASE_NODE_ID GENMASK(11, 0) #define LNTM_BASE_NODE_ID GENMASK(11, 0)
static int gpu_get_node_map(void) static int gpu_get_node_map(struct amd64_pvt *pvt)
{ {
struct pci_dev *pdev; struct pci_dev *pdev;
int ret; int ret;
u32 tmp; u32 tmp;
/* /*
* Node ID 0 is reserved for CPUs. * Mapping of nodes from hardware-provided AMD Node ID to a
* Therefore, a non-zero Node ID means we've already cached the values. * Linux logical one is applicable for MI200 models. Therefore,
* return early for other heterogeneous systems.
*/
if (pvt->F3->device != PCI_DEVICE_ID_AMD_MI200_DF_F3)
return 0;
/*
* Node ID 0 is reserved for CPUs. Therefore, a non-zero Node ID
* means the values have been already cached.
*/ */
if (gpu_node_map.base_node_id) if (gpu_node_map.base_node_id)
return 0; return 0;
...@@ -3851,7 +3859,7 @@ static void gpu_init_csrows(struct mem_ctl_info *mci) ...@@ -3851,7 +3859,7 @@ static void gpu_init_csrows(struct mem_ctl_info *mci)
dimm->nr_pages = gpu_get_csrow_nr_pages(pvt, umc, cs); dimm->nr_pages = gpu_get_csrow_nr_pages(pvt, umc, cs);
dimm->edac_mode = EDAC_SECDED; dimm->edac_mode = EDAC_SECDED;
dimm->mtype = MEM_HBM2; dimm->mtype = pvt->dram_type;
dimm->dtype = DEV_X16; dimm->dtype = DEV_X16;
dimm->grain = 64; dimm->grain = 64;
} }
...@@ -3880,7 +3888,7 @@ static bool gpu_ecc_enabled(struct amd64_pvt *pvt) ...@@ -3880,7 +3888,7 @@ static bool gpu_ecc_enabled(struct amd64_pvt *pvt)
return true; return true;
} }
static inline u32 gpu_get_umc_base(u8 umc, u8 channel) static inline u32 gpu_get_umc_base(struct amd64_pvt *pvt, u8 umc, u8 channel)
{ {
/* /*
* On CPUs, there is one channel per UMC, so UMC numbering equals * On CPUs, there is one channel per UMC, so UMC numbering equals
...@@ -3893,13 +3901,16 @@ static inline u32 gpu_get_umc_base(u8 umc, u8 channel) ...@@ -3893,13 +3901,16 @@ static inline u32 gpu_get_umc_base(u8 umc, u8 channel)
* On GPU nodes channels are selected in 3rd nibble * On GPU nodes channels are selected in 3rd nibble
* HBM chX[3:0]= [Y ]5X[3:0]000; * HBM chX[3:0]= [Y ]5X[3:0]000;
* HBM chX[7:4]= [Y+1]5X[3:0]000 * HBM chX[7:4]= [Y+1]5X[3:0]000
*
* On MI300 APU nodes, same as GPU nodes but channels are selected
* in the base address of 0x90000
*/ */
umc *= 2; umc *= 2;
if (channel >= 4) if (channel >= 4)
umc++; umc++;
return 0x50000 + (umc << 20) + ((channel % 4) << 12); return pvt->gpu_umc_base + (umc << 20) + ((channel % 4) << 12);
} }
static void gpu_read_mc_regs(struct amd64_pvt *pvt) static void gpu_read_mc_regs(struct amd64_pvt *pvt)
...@@ -3910,7 +3921,7 @@ static void gpu_read_mc_regs(struct amd64_pvt *pvt) ...@@ -3910,7 +3921,7 @@ static void gpu_read_mc_regs(struct amd64_pvt *pvt)
/* Read registers from each UMC */ /* Read registers from each UMC */
for_each_umc(i) { for_each_umc(i) {
umc_base = gpu_get_umc_base(i, 0); umc_base = gpu_get_umc_base(pvt, i, 0);
umc = &pvt->umc[i]; umc = &pvt->umc[i];
amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg); amd_smn_read(nid, umc_base + UMCCH_UMC_CFG, &umc->umc_cfg);
...@@ -3927,7 +3938,7 @@ static void gpu_read_base_mask(struct amd64_pvt *pvt) ...@@ -3927,7 +3938,7 @@ static void gpu_read_base_mask(struct amd64_pvt *pvt)
for_each_umc(umc) { for_each_umc(umc) {
for_each_chip_select(cs, umc, pvt) { for_each_chip_select(cs, umc, pvt) {
base_reg = gpu_get_umc_base(umc, cs) + UMCCH_BASE_ADDR; base_reg = gpu_get_umc_base(pvt, umc, cs) + UMCCH_BASE_ADDR;
base = &pvt->csels[umc].csbases[cs]; base = &pvt->csels[umc].csbases[cs];
if (!amd_smn_read(pvt->mc_node_id, base_reg, base)) { if (!amd_smn_read(pvt->mc_node_id, base_reg, base)) {
...@@ -3935,7 +3946,7 @@ static void gpu_read_base_mask(struct amd64_pvt *pvt) ...@@ -3935,7 +3946,7 @@ static void gpu_read_base_mask(struct amd64_pvt *pvt)
umc, cs, *base, base_reg); umc, cs, *base, base_reg);
} }
mask_reg = gpu_get_umc_base(umc, cs) + UMCCH_ADDR_MASK; mask_reg = gpu_get_umc_base(pvt, umc, cs) + UMCCH_ADDR_MASK;
mask = &pvt->csels[umc].csmasks[cs]; mask = &pvt->csels[umc].csmasks[cs];
if (!amd_smn_read(pvt->mc_node_id, mask_reg, mask)) { if (!amd_smn_read(pvt->mc_node_id, mask_reg, mask)) {
...@@ -3960,7 +3971,7 @@ static int gpu_hw_info_get(struct amd64_pvt *pvt) ...@@ -3960,7 +3971,7 @@ static int gpu_hw_info_get(struct amd64_pvt *pvt)
{ {
int ret; int ret;
ret = gpu_get_node_map(); ret = gpu_get_node_map(pvt);
if (ret) if (ret)
return ret; return ret;
...@@ -4125,6 +4136,8 @@ static int per_family_init(struct amd64_pvt *pvt) ...@@ -4125,6 +4136,8 @@ static int per_family_init(struct amd64_pvt *pvt)
if (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) { if (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) {
pvt->ctl_name = "MI200"; pvt->ctl_name = "MI200";
pvt->max_mcs = 4; pvt->max_mcs = 4;
pvt->dram_type = MEM_HBM2;
pvt->gpu_umc_base = 0x50000;
pvt->ops = &gpu_ops; pvt->ops = &gpu_ops;
} else { } else {
pvt->ctl_name = "F19h_M30h"; pvt->ctl_name = "F19h_M30h";
...@@ -4142,6 +4155,13 @@ static int per_family_init(struct amd64_pvt *pvt) ...@@ -4142,6 +4155,13 @@ static int per_family_init(struct amd64_pvt *pvt)
pvt->ctl_name = "F19h_M70h"; pvt->ctl_name = "F19h_M70h";
pvt->flags.zn_regs_v2 = 1; pvt->flags.zn_regs_v2 = 1;
break; break;
case 0x90 ... 0x9f:
pvt->ctl_name = "F19h_M90h";
pvt->max_mcs = 4;
pvt->dram_type = MEM_HBM3;
pvt->gpu_umc_base = 0x90000;
pvt->ops = &gpu_ops;
break;
case 0xa0 ... 0xaf: case 0xa0 ... 0xaf:
pvt->ctl_name = "F19h_MA0h"; pvt->ctl_name = "F19h_MA0h";
pvt->max_mcs = 12; pvt->max_mcs = 12;
...@@ -4180,23 +4200,33 @@ static const struct attribute_group *amd64_edac_attr_groups[] = { ...@@ -4180,23 +4200,33 @@ static const struct attribute_group *amd64_edac_attr_groups[] = {
NULL NULL
}; };
/*
* For heterogeneous and APU models EDAC CHIP_SELECT and CHANNEL layers
* should be swapped to fit into the layers.
*/
static unsigned int get_layer_size(struct amd64_pvt *pvt, u8 layer)
{
bool is_gpu = (pvt->ops == &gpu_ops);
if (!layer)
return is_gpu ? pvt->max_mcs
: pvt->csels[0].b_cnt;
else
return is_gpu ? pvt->csels[0].b_cnt
: pvt->max_mcs;
}
static int init_one_instance(struct amd64_pvt *pvt) static int init_one_instance(struct amd64_pvt *pvt)
{ {
struct mem_ctl_info *mci = NULL; struct mem_ctl_info *mci = NULL;
struct edac_mc_layer layers[2]; struct edac_mc_layer layers[2];
int ret = -ENOMEM; int ret = -ENOMEM;
/*
* For Heterogeneous family EDAC CHIP_SELECT and CHANNEL layers should
* be swapped to fit into the layers.
*/
layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
layers[0].size = (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) ? layers[0].size = get_layer_size(pvt, 0);
pvt->max_mcs : pvt->csels[0].b_cnt;
layers[0].is_virt_csrow = true; layers[0].is_virt_csrow = true;
layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].type = EDAC_MC_LAYER_CHANNEL;
layers[1].size = (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) ? layers[1].size = get_layer_size(pvt, 1);
pvt->csels[0].b_cnt : pvt->max_mcs;
layers[1].is_virt_csrow = false; layers[1].is_virt_csrow = false;
mci = edac_mc_alloc(pvt->mc_node_id, ARRAY_SIZE(layers), layers, 0); mci = edac_mc_alloc(pvt->mc_node_id, ARRAY_SIZE(layers), layers, 0);
......
...@@ -362,6 +362,7 @@ struct amd64_pvt { ...@@ -362,6 +362,7 @@ struct amd64_pvt {
u32 dct_sel_lo; /* DRAM Controller Select Low */ u32 dct_sel_lo; /* DRAM Controller Select Low */
u32 dct_sel_hi; /* DRAM Controller Select High */ u32 dct_sel_hi; /* DRAM Controller Select High */
u32 online_spare; /* On-Line spare Reg */ u32 online_spare; /* On-Line spare Reg */
u32 gpu_umc_base; /* Base address used for channel selection on GPUs */
/* x4, x8, or x16 syndromes in use */ /* x4, x8, or x16 syndromes in use */
u8 ecc_sym_sz; u8 ecc_sym_sz;
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/edac.h> #include <linux/edac.h>
#include <linux/of_platform.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <asm/hardware/cache-l2x0.h> #include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/cache-aurora-l2.h> #include <asm/hardware/cache-aurora-l2.h>
...@@ -351,20 +353,18 @@ static int axp_mc_probe(struct platform_device *pdev) ...@@ -351,20 +353,18 @@ static int axp_mc_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int axp_mc_remove(struct platform_device *pdev) static void axp_mc_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return 0;
} }
static struct platform_driver axp_mc_driver = { static struct platform_driver axp_mc_driver = {
.probe = axp_mc_probe, .probe = axp_mc_probe,
.remove = axp_mc_remove, .remove_new = axp_mc_remove,
.driver = { .driver = {
.name = "armada_xp_mc_edac", .name = "armada_xp_mc_edac",
.of_match_table = of_match_ptr(axp_mc_of_match), .of_match_table = of_match_ptr(axp_mc_of_match),
...@@ -564,7 +564,7 @@ static int aurora_l2_probe(struct platform_device *pdev) ...@@ -564,7 +564,7 @@ static int aurora_l2_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int aurora_l2_remove(struct platform_device *pdev) static void aurora_l2_remove(struct platform_device *pdev)
{ {
struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
...@@ -575,13 +575,11 @@ static int aurora_l2_remove(struct platform_device *pdev) ...@@ -575,13 +575,11 @@ static int aurora_l2_remove(struct platform_device *pdev)
edac_device_del_device(&pdev->dev); edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(dci); edac_device_free_ctl_info(dci);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return 0;
} }
static struct platform_driver aurora_l2_driver = { static struct platform_driver aurora_l2_driver = {
.probe = aurora_l2_probe, .probe = aurora_l2_probe,
.remove = aurora_l2_remove, .remove_new = aurora_l2_remove,
.driver = { .driver = {
.name = "aurora_l2_edac", .name = "aurora_l2_edac",
.of_match_table = of_match_ptr(aurora_l2_of_match), .of_match_table = of_match_ptr(aurora_l2_of_match),
......
...@@ -357,7 +357,7 @@ static int aspeed_probe(struct platform_device *pdev) ...@@ -357,7 +357,7 @@ static int aspeed_probe(struct platform_device *pdev)
} }
static int aspeed_remove(struct platform_device *pdev) static void aspeed_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -369,8 +369,6 @@ static int aspeed_remove(struct platform_device *pdev) ...@@ -369,8 +369,6 @@ static int aspeed_remove(struct platform_device *pdev)
mci = edac_mc_del_mc(&pdev->dev); mci = edac_mc_del_mc(&pdev->dev);
if (mci) if (mci)
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
...@@ -389,7 +387,7 @@ static struct platform_driver aspeed_driver = { ...@@ -389,7 +387,7 @@ static struct platform_driver aspeed_driver = {
.of_match_table = aspeed_of_match .of_match_table = aspeed_of_match
}, },
.probe = aspeed_probe, .probe = aspeed_probe,
.remove = aspeed_remove .remove_new = aspeed_remove
}; };
module_platform_driver(aspeed_driver); module_platform_driver(aspeed_driver);
......
...@@ -323,14 +323,12 @@ static int bluefield_edac_mc_probe(struct platform_device *pdev) ...@@ -323,14 +323,12 @@ static int bluefield_edac_mc_probe(struct platform_device *pdev)
} }
static int bluefield_edac_mc_remove(struct platform_device *pdev) static void bluefield_edac_mc_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static const struct acpi_device_id bluefield_mc_acpi_ids[] = { static const struct acpi_device_id bluefield_mc_acpi_ids[] = {
...@@ -346,7 +344,7 @@ static struct platform_driver bluefield_edac_mc_driver = { ...@@ -346,7 +344,7 @@ static struct platform_driver bluefield_edac_mc_driver = {
.acpi_match_table = bluefield_mc_acpi_ids, .acpi_match_table = bluefield_mc_acpi_ids,
}, },
.probe = bluefield_edac_mc_probe, .probe = bluefield_edac_mc_probe,
.remove = bluefield_edac_mc_remove, .remove_new = bluefield_edac_mc_remove,
}; };
module_platform_driver(bluefield_edac_mc_driver); module_platform_driver(bluefield_edac_mc_driver);
......
...@@ -234,12 +234,11 @@ static int cell_edac_probe(struct platform_device *pdev) ...@@ -234,12 +234,11 @@ static int cell_edac_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int cell_edac_remove(struct platform_device *pdev) static void cell_edac_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = edac_mc_del_mc(&pdev->dev); struct mem_ctl_info *mci = edac_mc_del_mc(&pdev->dev);
if (mci) if (mci)
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static struct platform_driver cell_edac_driver = { static struct platform_driver cell_edac_driver = {
...@@ -247,7 +246,7 @@ static struct platform_driver cell_edac_driver = { ...@@ -247,7 +246,7 @@ static struct platform_driver cell_edac_driver = {
.name = "cbe-mic", .name = "cbe-mic",
}, },
.probe = cell_edac_probe, .probe = cell_edac_probe,
.remove = cell_edac_remove, .remove_new = cell_edac_remove,
}; };
static int __init cell_edac_init(void) static int __init cell_edac_init(void)
......
...@@ -1010,7 +1010,7 @@ static int cpc925_probe(struct platform_device *pdev) ...@@ -1010,7 +1010,7 @@ static int cpc925_probe(struct platform_device *pdev)
return res; return res;
} }
static int cpc925_remove(struct platform_device *pdev) static void cpc925_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
...@@ -1023,13 +1023,11 @@ static int cpc925_remove(struct platform_device *pdev) ...@@ -1023,13 +1023,11 @@ static int cpc925_remove(struct platform_device *pdev)
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static struct platform_driver cpc925_edac_driver = { static struct platform_driver cpc925_edac_driver = {
.probe = cpc925_probe, .probe = cpc925_probe,
.remove = cpc925_remove, .remove_new = cpc925_remove,
.driver = { .driver = {
.name = "cpc925_edac", .name = "cpc925_edac",
} }
......
...@@ -602,7 +602,7 @@ static int dmc520_edac_probe(struct platform_device *pdev) ...@@ -602,7 +602,7 @@ static int dmc520_edac_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int dmc520_edac_remove(struct platform_device *pdev) static void dmc520_edac_remove(struct platform_device *pdev)
{ {
u32 reg_val, idx, irq_mask_all = 0; u32 reg_val, idx, irq_mask_all = 0;
struct mem_ctl_info *mci; struct mem_ctl_info *mci;
...@@ -626,8 +626,6 @@ static int dmc520_edac_remove(struct platform_device *pdev) ...@@ -626,8 +626,6 @@ static int dmc520_edac_remove(struct platform_device *pdev)
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static const struct of_device_id dmc520_edac_driver_id[] = { static const struct of_device_id dmc520_edac_driver_id[] = {
...@@ -644,7 +642,7 @@ static struct platform_driver dmc520_edac_driver = { ...@@ -644,7 +642,7 @@ static struct platform_driver dmc520_edac_driver = {
}, },
.probe = dmc520_edac_probe, .probe = dmc520_edac_probe,
.remove = dmc520_edac_remove .remove_new = dmc520_edac_remove
}; };
module_platform_driver(dmc520_edac_driver); module_platform_driver(dmc520_edac_driver);
......
...@@ -166,6 +166,7 @@ const char * const edac_mem_types[] = { ...@@ -166,6 +166,7 @@ const char * const edac_mem_types[] = {
[MEM_NVDIMM] = "Non-volatile-RAM", [MEM_NVDIMM] = "Non-volatile-RAM",
[MEM_WIO2] = "Wide-IO-2", [MEM_WIO2] = "Wide-IO-2",
[MEM_HBM2] = "High-bandwidth-memory-Gen2", [MEM_HBM2] = "High-bandwidth-memory-Gen2",
[MEM_HBM3] = "High-bandwidth-memory-Gen3",
}; };
EXPORT_SYMBOL_GPL(edac_mem_types); EXPORT_SYMBOL_GPL(edac_mem_types);
......
...@@ -521,7 +521,7 @@ static void edac_pci_dev_parity_clear(struct pci_dev *dev) ...@@ -521,7 +521,7 @@ static void edac_pci_dev_parity_clear(struct pci_dev *dev)
/* read the device TYPE, looking for bridges */ /* read the device TYPE, looking for bridges */
pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE)
get_pci_parity_status(dev, 1); get_pci_parity_status(dev, 1);
} }
...@@ -583,7 +583,7 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) ...@@ -583,7 +583,7 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev)
edac_dbg(4, "PCI HEADER TYPE= 0x%02x %s\n", edac_dbg(4, "PCI HEADER TYPE= 0x%02x %s\n",
header_type, dev_name(&dev->dev)); header_type, dev_name(&dev->dev));
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
/* On bridges, need to examine secondary status register */ /* On bridges, need to examine secondary status register */
status = get_pci_parity_status(dev, 1); status = get_pci_parity_status(dev, 1);
......
...@@ -612,7 +612,7 @@ int fsl_mc_err_probe(struct platform_device *op) ...@@ -612,7 +612,7 @@ int fsl_mc_err_probe(struct platform_device *op)
return res; return res;
} }
int fsl_mc_err_remove(struct platform_device *op) void fsl_mc_err_remove(struct platform_device *op)
{ {
struct mem_ctl_info *mci = dev_get_drvdata(&op->dev); struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
struct fsl_mc_pdata *pdata = mci->pvt_info; struct fsl_mc_pdata *pdata = mci->pvt_info;
...@@ -629,5 +629,4 @@ int fsl_mc_err_remove(struct platform_device *op) ...@@ -629,5 +629,4 @@ int fsl_mc_err_remove(struct platform_device *op)
edac_mc_del_mc(&op->dev); edac_mc_del_mc(&op->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
...@@ -72,5 +72,5 @@ struct fsl_mc_pdata { ...@@ -72,5 +72,5 @@ struct fsl_mc_pdata {
int irq; int irq;
}; };
int fsl_mc_err_probe(struct platform_device *op); int fsl_mc_err_probe(struct platform_device *op);
int fsl_mc_err_remove(struct platform_device *op); void fsl_mc_err_remove(struct platform_device *op);
#endif #endif
...@@ -118,18 +118,17 @@ static int highbank_l2_err_probe(struct platform_device *pdev) ...@@ -118,18 +118,17 @@ static int highbank_l2_err_probe(struct platform_device *pdev)
return res; return res;
} }
static int highbank_l2_err_remove(struct platform_device *pdev) static void highbank_l2_err_remove(struct platform_device *pdev)
{ {
struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
edac_device_del_device(&pdev->dev); edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(dci); edac_device_free_ctl_info(dci);
return 0;
} }
static struct platform_driver highbank_l2_edac_driver = { static struct platform_driver highbank_l2_edac_driver = {
.probe = highbank_l2_err_probe, .probe = highbank_l2_err_probe,
.remove = highbank_l2_err_remove, .remove_new = highbank_l2_err_remove,
.driver = { .driver = {
.name = "hb_l2_edac", .name = "hb_l2_edac",
.of_match_table = hb_l2_err_of_match, .of_match_table = hb_l2_err_of_match,
......
...@@ -251,18 +251,17 @@ static int highbank_mc_probe(struct platform_device *pdev) ...@@ -251,18 +251,17 @@ static int highbank_mc_probe(struct platform_device *pdev)
return res; return res;
} }
static int highbank_mc_remove(struct platform_device *pdev) static void highbank_mc_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static struct platform_driver highbank_mc_edac_driver = { static struct platform_driver highbank_mc_edac_driver = {
.probe = highbank_mc_probe, .probe = highbank_mc_probe,
.remove = highbank_mc_remove, .remove_new = highbank_mc_remove,
.driver = { .driver = {
.name = "hb_mc_edac", .name = "hb_mc_edac",
.of_match_table = hb_ddr_ctrl_of_match, .of_match_table = hb_ddr_ctrl_of_match,
......
...@@ -376,7 +376,7 @@ static const struct pci_id_table pci_dev_table[] = { ...@@ -376,7 +376,7 @@ static const struct pci_id_table pci_dev_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem), PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_nehalem),
PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield), PCI_ID_TABLE_ENTRY(pci_dev_descr_lynnfield),
PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere), PCI_ID_TABLE_ENTRY(pci_dev_descr_i7core_westmere),
{0,} /* 0 terminated list. */ { NULL, }
}; };
/* /*
...@@ -385,7 +385,7 @@ static const struct pci_id_table pci_dev_table[] = { ...@@ -385,7 +385,7 @@ static const struct pci_id_table pci_dev_table[] = {
static const struct pci_device_id i7core_pci_tbl[] = { static const struct pci_device_id i7core_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_X58_HUB_MGMT)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNNFIELD_QPI_LINK0)},
{0,} /* 0 terminated list. */ { 0, }
}; };
/**************************************************************************** /****************************************************************************
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
/* Capability register E */ /* Capability register E */
#define CAPID_E_OFFSET 0xf0 #define CAPID_E_OFFSET 0xf0
#define CAPID_E_IBECC BIT(12) #define CAPID_E_IBECC BIT(12)
#define CAPID_E_IBECC_BIT18 BIT(18)
/* Error Status */ /* Error Status */
#define ERRSTS_OFFSET 0xc8 #define ERRSTS_OFFSET 0xc8
...@@ -80,6 +81,7 @@ ...@@ -80,6 +81,7 @@
#define ECC_ERROR_LOG_UE BIT_ULL(63) #define ECC_ERROR_LOG_UE BIT_ULL(63)
#define ECC_ERROR_LOG_ADDR_SHIFT 5 #define ECC_ERROR_LOG_ADDR_SHIFT 5
#define ECC_ERROR_LOG_ADDR(v) GET_BITFIELD(v, 5, 38) #define ECC_ERROR_LOG_ADDR(v) GET_BITFIELD(v, 5, 38)
#define ECC_ERROR_LOG_ADDR45(v) GET_BITFIELD(v, 5, 45)
#define ECC_ERROR_LOG_SYND(v) GET_BITFIELD(v, 46, 61) #define ECC_ERROR_LOG_SYND(v) GET_BITFIELD(v, 46, 61)
/* Host MMIO base address */ /* Host MMIO base address */
...@@ -133,6 +135,8 @@ static struct res_config { ...@@ -133,6 +135,8 @@ static struct res_config {
u32 ibecc_base; u32 ibecc_base;
u32 ibecc_error_log_offset; u32 ibecc_error_log_offset;
bool (*ibecc_available)(struct pci_dev *pdev); bool (*ibecc_available)(struct pci_dev *pdev);
/* Extract error address logged in IBECC */
u64 (*err_addr)(u64 ecclog);
/* Convert error address logged in IBECC to system physical address */ /* Convert error address logged in IBECC to system physical address */
u64 (*err_addr_to_sys_addr)(u64 eaddr, int mc); u64 (*err_addr_to_sys_addr)(u64 eaddr, int mc);
/* Convert error address logged in IBECC to integrated memory controller address */ /* Convert error address logged in IBECC to integrated memory controller address */
...@@ -222,6 +226,67 @@ static struct work_struct ecclog_work; ...@@ -222,6 +226,67 @@ static struct work_struct ecclog_work;
#define DID_ADL_SKU3 0x4621 #define DID_ADL_SKU3 0x4621
#define DID_ADL_SKU4 0x4641 #define DID_ADL_SKU4 0x4641
/* Compute die IDs for Alder Lake-N with IBECC */
#define DID_ADL_N_SKU1 0x4614
#define DID_ADL_N_SKU2 0x4617
#define DID_ADL_N_SKU3 0x461b
#define DID_ADL_N_SKU4 0x461c
#define DID_ADL_N_SKU5 0x4673
#define DID_ADL_N_SKU6 0x4674
#define DID_ADL_N_SKU7 0x4675
#define DID_ADL_N_SKU8 0x4677
#define DID_ADL_N_SKU9 0x4678
#define DID_ADL_N_SKU10 0x4679
#define DID_ADL_N_SKU11 0x467c
/* Compute die IDs for Raptor Lake-P with IBECC */
#define DID_RPL_P_SKU1 0xa706
#define DID_RPL_P_SKU2 0xa707
#define DID_RPL_P_SKU3 0xa708
#define DID_RPL_P_SKU4 0xa716
#define DID_RPL_P_SKU5 0xa718
/* Compute die IDs for Meteor Lake-PS with IBECC */
#define DID_MTL_PS_SKU1 0x7d21
#define DID_MTL_PS_SKU2 0x7d22
#define DID_MTL_PS_SKU3 0x7d23
#define DID_MTL_PS_SKU4 0x7d24
/* Compute die IDs for Meteor Lake-P with IBECC */
#define DID_MTL_P_SKU1 0x7d01
#define DID_MTL_P_SKU2 0x7d02
#define DID_MTL_P_SKU3 0x7d14
static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
{
union {
u64 v;
struct {
u32 v_lo;
u32 v_hi;
};
} u;
if (pci_read_config_dword(pdev, MCHBAR_OFFSET, &u.v_lo)) {
igen6_printk(KERN_ERR, "Failed to read lower MCHBAR\n");
return -ENODEV;
}
if (pci_read_config_dword(pdev, MCHBAR_OFFSET + 4, &u.v_hi)) {
igen6_printk(KERN_ERR, "Failed to read upper MCHBAR\n");
return -ENODEV;
}
if (!(u.v & MCHBAR_EN)) {
igen6_printk(KERN_ERR, "MCHBAR is disabled\n");
return -ENODEV;
}
*mchbar = MCHBAR_BASE(u.v);
return 0;
}
static bool ehl_ibecc_available(struct pci_dev *pdev) static bool ehl_ibecc_available(struct pci_dev *pdev)
{ {
u32 v; u32 v;
...@@ -272,6 +337,39 @@ static bool tgl_ibecc_available(struct pci_dev *pdev) ...@@ -272,6 +337,39 @@ static bool tgl_ibecc_available(struct pci_dev *pdev)
return !(CAPID_E_IBECC & v); return !(CAPID_E_IBECC & v);
} }
static bool mtl_p_ibecc_available(struct pci_dev *pdev)
{
u32 v;
if (pci_read_config_dword(pdev, CAPID_E_OFFSET, &v))
return false;
return !(CAPID_E_IBECC_BIT18 & v);
}
static bool mtl_ps_ibecc_available(struct pci_dev *pdev)
{
#define MCHBAR_MEMSS_IBECCDIS 0x13c00
void __iomem *window;
u64 mchbar;
u32 val;
if (get_mchbar(pdev, &mchbar))
return false;
window = ioremap(mchbar, MCHBAR_SIZE * 2);
if (!window) {
igen6_printk(KERN_ERR, "Failed to ioremap 0x%llx\n", mchbar);
return false;
}
val = readl(window + MCHBAR_MEMSS_IBECCDIS);
iounmap(window);
/* Bit6: 1 - IBECC is disabled, 0 - IBECC isn't disabled */
return !GET_BITFIELD(val, 6, 6);
}
static u64 mem_addr_to_sys_addr(u64 maddr) static u64 mem_addr_to_sys_addr(u64 maddr)
{ {
if (maddr < igen6_tolud) if (maddr < igen6_tolud)
...@@ -358,6 +456,11 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc) ...@@ -358,6 +456,11 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc)
return imc_addr; return imc_addr;
} }
static u64 rpl_p_err_addr(u64 ecclog)
{
return ECC_ERROR_LOG_ADDR45(ecclog);
}
static struct res_config ehl_cfg = { static struct res_config ehl_cfg = {
.num_imc = 1, .num_imc = 1,
.imc_base = 0x5000, .imc_base = 0x5000,
...@@ -403,6 +506,51 @@ static struct res_config adl_cfg = { ...@@ -403,6 +506,51 @@ static struct res_config adl_cfg = {
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr, .err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
}; };
static struct res_config adl_n_cfg = {
.machine_check = true,
.num_imc = 1,
.imc_base = 0xd800,
.ibecc_base = 0xd400,
.ibecc_error_log_offset = 0x68,
.ibecc_available = tgl_ibecc_available,
.err_addr_to_sys_addr = adl_err_addr_to_sys_addr,
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
};
static struct res_config rpl_p_cfg = {
.machine_check = true,
.num_imc = 2,
.imc_base = 0xd800,
.ibecc_base = 0xd400,
.ibecc_error_log_offset = 0x68,
.ibecc_available = tgl_ibecc_available,
.err_addr = rpl_p_err_addr,
.err_addr_to_sys_addr = adl_err_addr_to_sys_addr,
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
};
static struct res_config mtl_ps_cfg = {
.machine_check = true,
.num_imc = 2,
.imc_base = 0xd800,
.ibecc_base = 0xd400,
.ibecc_error_log_offset = 0x170,
.ibecc_available = mtl_ps_ibecc_available,
.err_addr_to_sys_addr = adl_err_addr_to_sys_addr,
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
};
static struct res_config mtl_p_cfg = {
.machine_check = true,
.num_imc = 2,
.imc_base = 0xd800,
.ibecc_base = 0xd400,
.ibecc_error_log_offset = 0x170,
.ibecc_available = mtl_p_ibecc_available,
.err_addr_to_sys_addr = adl_err_addr_to_sys_addr,
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
};
static const struct pci_device_id igen6_pci_tbl[] = { static const struct pci_device_id igen6_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg }, { PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg },
{ PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg }, { PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg },
...@@ -424,6 +572,29 @@ static const struct pci_device_id igen6_pci_tbl[] = { ...@@ -424,6 +572,29 @@ static const struct pci_device_id igen6_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, DID_ADL_SKU2), (kernel_ulong_t)&adl_cfg }, { PCI_VDEVICE(INTEL, DID_ADL_SKU2), (kernel_ulong_t)&adl_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_SKU3), (kernel_ulong_t)&adl_cfg }, { PCI_VDEVICE(INTEL, DID_ADL_SKU3), (kernel_ulong_t)&adl_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_SKU4), (kernel_ulong_t)&adl_cfg }, { PCI_VDEVICE(INTEL, DID_ADL_SKU4), (kernel_ulong_t)&adl_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU1), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU2), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU3), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU4), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU5), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU6), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU7), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU8), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU9), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU10), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ADL_N_SKU11), (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), (kernel_ulong_t)&rpl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), (kernel_ulong_t)&rpl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), (kernel_ulong_t)&rpl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_RPL_P_SKU4), (kernel_ulong_t)&rpl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_RPL_P_SKU5), (kernel_ulong_t)&rpl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU1), (kernel_ulong_t)&mtl_ps_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU2), (kernel_ulong_t)&mtl_ps_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU3), (kernel_ulong_t)&mtl_ps_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU4), (kernel_ulong_t)&mtl_ps_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_P_SKU1), (kernel_ulong_t)&mtl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_P_SKU2), (kernel_ulong_t)&mtl_p_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_P_SKU3), (kernel_ulong_t)&mtl_p_cfg },
{ }, { },
}; };
MODULE_DEVICE_TABLE(pci, igen6_pci_tbl); MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
...@@ -679,8 +850,11 @@ static void ecclog_work_cb(struct work_struct *work) ...@@ -679,8 +850,11 @@ static void ecclog_work_cb(struct work_struct *work)
llist_for_each_entry_safe(node, tmp, head, llnode) { llist_for_each_entry_safe(node, tmp, head, llnode) {
memset(&res, 0, sizeof(res)); memset(&res, 0, sizeof(res));
eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) << if (res_cfg->err_addr)
ECC_ERROR_LOG_ADDR_SHIFT; eaddr = res_cfg->err_addr(node->ecclog);
else
eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) <<
ECC_ERROR_LOG_ADDR_SHIFT;
res.mc = node->mc; res.mc = node->mc;
res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc); res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc);
res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc); res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc);
...@@ -969,22 +1143,8 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar) ...@@ -969,22 +1143,8 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar)
igen6_tom = u.v & GENMASK_ULL(38, 20); igen6_tom = u.v & GENMASK_ULL(38, 20);
if (pci_read_config_dword(pdev, MCHBAR_OFFSET, &u.v_lo)) { if (get_mchbar(pdev, mchbar))
igen6_printk(KERN_ERR, "Failed to read lower MCHBAR\n");
goto fail; goto fail;
}
if (pci_read_config_dword(pdev, MCHBAR_OFFSET + 4, &u.v_hi)) {
igen6_printk(KERN_ERR, "Failed to read upper MCHBAR\n");
goto fail;
}
if (!(u.v & MCHBAR_EN)) {
igen6_printk(KERN_ERR, "MCHBAR is disabled\n");
goto fail;
}
*mchbar = MCHBAR_BASE(u.v);
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
if (pci_read_config_dword(pdev, TOUUD_OFFSET, &u.v_lo)) if (pci_read_config_dword(pdev, TOUUD_OFFSET, &u.v_lo))
......
...@@ -27,7 +27,7 @@ MODULE_DEVICE_TABLE(of, fsl_ddr_mc_err_of_match); ...@@ -27,7 +27,7 @@ MODULE_DEVICE_TABLE(of, fsl_ddr_mc_err_of_match);
static struct platform_driver fsl_ddr_mc_err_driver = { static struct platform_driver fsl_ddr_mc_err_driver = {
.probe = fsl_mc_err_probe, .probe = fsl_mc_err_probe,
.remove = fsl_mc_err_remove, .remove_new = fsl_mc_err_remove,
.driver = { .driver = {
.name = "fsl_ddr_mc_err", .name = "fsl_ddr_mc_err",
.of_match_table = fsl_ddr_mc_err_of_match, .of_match_table = fsl_ddr_mc_err_of_match,
......
...@@ -300,7 +300,7 @@ static int mpc85xx_pci_err_probe(struct platform_device *op) ...@@ -300,7 +300,7 @@ static int mpc85xx_pci_err_probe(struct platform_device *op)
return res; return res;
} }
static int mpc85xx_pci_err_remove(struct platform_device *op) static void mpc85xx_pci_err_remove(struct platform_device *op)
{ {
struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev); struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
struct mpc85xx_pci_pdata *pdata = pci->pvt_info; struct mpc85xx_pci_pdata *pdata = pci->pvt_info;
...@@ -312,8 +312,6 @@ static int mpc85xx_pci_err_remove(struct platform_device *op) ...@@ -312,8 +312,6 @@ static int mpc85xx_pci_err_remove(struct platform_device *op)
edac_pci_del_device(&op->dev); edac_pci_del_device(&op->dev);
edac_pci_free_ctl_info(pci); edac_pci_free_ctl_info(pci);
return 0;
} }
static const struct platform_device_id mpc85xx_pci_err_match[] = { static const struct platform_device_id mpc85xx_pci_err_match[] = {
...@@ -325,7 +323,7 @@ static const struct platform_device_id mpc85xx_pci_err_match[] = { ...@@ -325,7 +323,7 @@ static const struct platform_device_id mpc85xx_pci_err_match[] = {
static struct platform_driver mpc85xx_pci_err_driver = { static struct platform_driver mpc85xx_pci_err_driver = {
.probe = mpc85xx_pci_err_probe, .probe = mpc85xx_pci_err_probe,
.remove = mpc85xx_pci_err_remove, .remove_new = mpc85xx_pci_err_remove,
.id_table = mpc85xx_pci_err_match, .id_table = mpc85xx_pci_err_match,
.driver = { .driver = {
.name = "mpc85xx_pci_err", .name = "mpc85xx_pci_err",
...@@ -591,7 +589,7 @@ static int mpc85xx_l2_err_probe(struct platform_device *op) ...@@ -591,7 +589,7 @@ static int mpc85xx_l2_err_probe(struct platform_device *op)
return res; return res;
} }
static int mpc85xx_l2_err_remove(struct platform_device *op) static void mpc85xx_l2_err_remove(struct platform_device *op)
{ {
struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev); struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info; struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
...@@ -606,7 +604,6 @@ static int mpc85xx_l2_err_remove(struct platform_device *op) ...@@ -606,7 +604,6 @@ static int mpc85xx_l2_err_remove(struct platform_device *op)
out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable); out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable);
edac_device_del_device(&op->dev); edac_device_del_device(&op->dev);
edac_device_free_ctl_info(edac_dev); edac_device_free_ctl_info(edac_dev);
return 0;
} }
static const struct of_device_id mpc85xx_l2_err_of_match[] = { static const struct of_device_id mpc85xx_l2_err_of_match[] = {
...@@ -630,7 +627,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match); ...@@ -630,7 +627,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_l2_err_of_match);
static struct platform_driver mpc85xx_l2_err_driver = { static struct platform_driver mpc85xx_l2_err_driver = {
.probe = mpc85xx_l2_err_probe, .probe = mpc85xx_l2_err_probe,
.remove = mpc85xx_l2_err_remove, .remove_new = mpc85xx_l2_err_remove,
.driver = { .driver = {
.name = "mpc85xx_l2_err", .name = "mpc85xx_l2_err",
.of_match_table = mpc85xx_l2_err_of_match, .of_match_table = mpc85xx_l2_err_of_match,
...@@ -659,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match); ...@@ -659,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
static struct platform_driver mpc85xx_mc_err_driver = { static struct platform_driver mpc85xx_mc_err_driver = {
.probe = fsl_mc_err_probe, .probe = fsl_mc_err_probe,
.remove = fsl_mc_err_remove, .remove_new = fsl_mc_err_remove,
.driver = { .driver = {
.name = "mpc85xx_mc_err", .name = "mpc85xx_mc_err",
.of_match_table = mpc85xx_mc_err_of_match, .of_match_table = mpc85xx_mc_err_of_match,
......
...@@ -410,7 +410,7 @@ static int edac_probe(struct platform_device *pdev) ...@@ -410,7 +410,7 @@ static int edac_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int edac_remove(struct platform_device *pdev) static void edac_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
struct priv_data *priv = mci->pvt_info; struct priv_data *priv = mci->pvt_info;
...@@ -426,8 +426,6 @@ static int edac_remove(struct platform_device *pdev) ...@@ -426,8 +426,6 @@ static int edac_remove(struct platform_device *pdev)
regmap_write(npcm_regmap, pdata->ctl_int_mask_master, regmap_write(npcm_regmap, pdata->ctl_int_mask_master,
pdata->int_mask_master_global_mask); pdata->int_mask_master_global_mask);
regmap_update_bits(npcm_regmap, pdata->ctl_ecc_en, pdata->ecc_en_mask, 0); regmap_update_bits(npcm_regmap, pdata->ctl_ecc_en, pdata->ecc_en_mask, 0);
return 0;
} }
static const struct npcm_platform_data npcm750_edac = { static const struct npcm_platform_data npcm750_edac = {
...@@ -533,7 +531,7 @@ static struct platform_driver npcm_edac_driver = { ...@@ -533,7 +531,7 @@ static struct platform_driver npcm_edac_driver = {
.of_match_table = npcm_edac_of_match, .of_match_table = npcm_edac_of_match,
}, },
.probe = edac_probe, .probe = edac_probe,
.remove = edac_remove, .remove_new = edac_remove,
}; };
module_platform_driver(npcm_edac_driver); module_platform_driver(npcm_edac_driver);
......
...@@ -184,19 +184,17 @@ static int octeon_l2c_probe(struct platform_device *pdev) ...@@ -184,19 +184,17 @@ static int octeon_l2c_probe(struct platform_device *pdev)
return -ENXIO; return -ENXIO;
} }
static int octeon_l2c_remove(struct platform_device *pdev) static void octeon_l2c_remove(struct platform_device *pdev)
{ {
struct edac_device_ctl_info *l2c = platform_get_drvdata(pdev); struct edac_device_ctl_info *l2c = platform_get_drvdata(pdev);
edac_device_del_device(&pdev->dev); edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(l2c); edac_device_free_ctl_info(l2c);
return 0;
} }
static struct platform_driver octeon_l2c_driver = { static struct platform_driver octeon_l2c_driver = {
.probe = octeon_l2c_probe, .probe = octeon_l2c_probe,
.remove = octeon_l2c_remove, .remove_new = octeon_l2c_remove,
.driver = { .driver = {
.name = "octeon_l2c_edac", .name = "octeon_l2c_edac",
} }
......
...@@ -302,18 +302,17 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev) ...@@ -302,18 +302,17 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int octeon_lmc_edac_remove(struct platform_device *pdev) static void octeon_lmc_edac_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static struct platform_driver octeon_lmc_edac_driver = { static struct platform_driver octeon_lmc_edac_driver = {
.probe = octeon_lmc_edac_probe, .probe = octeon_lmc_edac_probe,
.remove = octeon_lmc_edac_remove, .remove_new = octeon_lmc_edac_remove,
.driver = { .driver = {
.name = "octeon_lmc_edac", .name = "octeon_lmc_edac",
} }
......
...@@ -119,19 +119,18 @@ static int co_cache_error_probe(struct platform_device *pdev) ...@@ -119,19 +119,18 @@ static int co_cache_error_probe(struct platform_device *pdev)
return -ENXIO; return -ENXIO;
} }
static int co_cache_error_remove(struct platform_device *pdev) static void co_cache_error_remove(struct platform_device *pdev)
{ {
struct co_cache_error *p = platform_get_drvdata(pdev); struct co_cache_error *p = platform_get_drvdata(pdev);
unregister_co_cache_error_notifier(&p->notifier); unregister_co_cache_error_notifier(&p->notifier);
edac_device_del_device(&pdev->dev); edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(p->ed); edac_device_free_ctl_info(p->ed);
return 0;
} }
static struct platform_driver co_cache_error_driver = { static struct platform_driver co_cache_error_driver = {
.probe = co_cache_error_probe, .probe = co_cache_error_probe,
.remove = co_cache_error_remove, .remove_new = co_cache_error_remove,
.driver = { .driver = {
.name = "octeon_pc_edac", .name = "octeon_pc_edac",
} }
......
...@@ -87,19 +87,17 @@ static int octeon_pci_probe(struct platform_device *pdev) ...@@ -87,19 +87,17 @@ static int octeon_pci_probe(struct platform_device *pdev)
return res; return res;
} }
static int octeon_pci_remove(struct platform_device *pdev) static void octeon_pci_remove(struct platform_device *pdev)
{ {
struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev); struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev);
edac_pci_del_device(&pdev->dev); edac_pci_del_device(&pdev->dev);
edac_pci_free_ctl_info(pci); edac_pci_free_ctl_info(pci);
return 0;
} }
static struct platform_driver octeon_pci_driver = { static struct platform_driver octeon_pci_driver = {
.probe = octeon_pci_probe, .probe = octeon_pci_probe,
.remove = octeon_pci_remove, .remove_new = octeon_pci_remove,
.driver = { .driver = {
.name = "octeon_pci_edac", .name = "octeon_pci_edac",
} }
......
...@@ -16,18 +16,20 @@ ...@@ -16,18 +16,20 @@
* rank, bank, row and column using the appropriate "dunit_ops" functions/parameters. * rank, bank, row and column using the appropriate "dunit_ops" functions/parameters.
*/ */
#include <linux/module.h> #include <linux/bitmap.h>
#include <linux/delay.h>
#include <linux/edac.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/math64.h>
#include <linux/mmzone.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <linux/sizes.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h>
#include <linux/edac.h>
#include <linux/mmzone.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/bitmap.h>
#include <linux/math64.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_data/x86/p2sb.h> #include <linux/platform_data/x86/p2sb.h>
#include <asm/cpu_device_id.h> #include <asm/cpu_device_id.h>
...@@ -109,7 +111,6 @@ static struct mem_ctl_info *pnd2_mci; ...@@ -109,7 +111,6 @@ static struct mem_ctl_info *pnd2_mci;
#define MOT_CHAN_INTLV_BIT_1SLC_2CH 12 #define MOT_CHAN_INTLV_BIT_1SLC_2CH 12
#define MOT_CHAN_INTLV_BIT_2SLC_2CH 13 #define MOT_CHAN_INTLV_BIT_2SLC_2CH 13
#define SELECTOR_DISABLED (-1) #define SELECTOR_DISABLED (-1)
#define _4GB (1ul << 32)
#define PMI_ADDRESS_WIDTH 31 #define PMI_ADDRESS_WIDTH 31
#define PND_MAX_PHYS_BIT 39 #define PND_MAX_PHYS_BIT 39
...@@ -183,7 +184,7 @@ static int _apl_rd_reg(int port, int off, int op, u32 *data) ...@@ -183,7 +184,7 @@ static int _apl_rd_reg(int port, int off, int op, u32 *data)
} }
P2SB_READ(dword, P2SB_DATA_OFF, data); P2SB_READ(dword, P2SB_DATA_OFF, data);
ret = (status >> 1) & 0x3; ret = (status >> 1) & GENMASK(1, 0);
out: out:
/* Hide the P2SB device, if it was hidden before */ /* Hide the P2SB device, if it was hidden before */
if (hidden) if (hidden)
...@@ -307,7 +308,7 @@ static bool two_channels; /* Both PMI channels in one slice enabled */ ...@@ -307,7 +308,7 @@ static bool two_channels; /* Both PMI channels in one slice enabled */
static u8 sym_chan_mask; static u8 sym_chan_mask;
static u8 asym_chan_mask; static u8 asym_chan_mask;
static u8 chan_mask; static unsigned long chan_mask;
static int slice_selector = -1; static int slice_selector = -1;
static int chan_selector = -1; static int chan_selector = -1;
...@@ -329,7 +330,7 @@ static void mk_region_mask(char *name, struct region *rp, u64 base, u64 mask) ...@@ -329,7 +330,7 @@ static void mk_region_mask(char *name, struct region *rp, u64 base, u64 mask)
return; return;
} }
if (mask != GENMASK_ULL(PND_MAX_PHYS_BIT, __ffs(mask))) { if (mask != GENMASK_ULL(PND_MAX_PHYS_BIT, __ffs(mask))) {
pr_info(FW_BUG "MOT mask not power of two\n"); pr_info(FW_BUG "MOT mask is invalid\n");
return; return;
} }
if (base & ~mask) { if (base & ~mask) {
...@@ -587,7 +588,7 @@ static int get_registers(void) ...@@ -587,7 +588,7 @@ static int get_registers(void)
/* Get a contiguous memory address (remove the MMIO gap) */ /* Get a contiguous memory address (remove the MMIO gap) */
static u64 remove_mmio_gap(u64 sys) static u64 remove_mmio_gap(u64 sys)
{ {
return (sys < _4GB) ? sys : sys - (_4GB - top_lm); return (sys < SZ_4G) ? sys : sys - (SZ_4G - top_lm);
} }
/* Squeeze out one address bit, shift upper part down to fill gap */ /* Squeeze out one address bit, shift upper part down to fill gap */
...@@ -598,7 +599,7 @@ static void remove_addr_bit(u64 *addr, int bitidx) ...@@ -598,7 +599,7 @@ static void remove_addr_bit(u64 *addr, int bitidx)
if (bitidx == -1) if (bitidx == -1)
return; return;
mask = (1ull << bitidx) - 1; mask = BIT_ULL(bitidx) - 1;
*addr = ((*addr >> 1) & ~mask) | (*addr & mask); *addr = ((*addr >> 1) & ~mask) | (*addr & mask);
} }
...@@ -642,8 +643,8 @@ static int sys2pmi(const u64 addr, u32 *pmiidx, u64 *pmiaddr, char *msg) ...@@ -642,8 +643,8 @@ static int sys2pmi(const u64 addr, u32 *pmiidx, u64 *pmiaddr, char *msg)
int sym_chan_shift = sym_channels >> 1; int sym_chan_shift = sym_channels >> 1;
/* Give up if address is out of range, or in MMIO gap */ /* Give up if address is out of range, or in MMIO gap */
if (addr >= (1ul << PND_MAX_PHYS_BIT) || if (addr >= BIT(PND_MAX_PHYS_BIT) ||
(addr >= top_lm && addr < _4GB) || addr >= top_hm) { (addr >= top_lm && addr < SZ_4G) || addr >= top_hm) {
snprintf(msg, PND2_MSG_SIZE, "Error address 0x%llx is not DRAM", addr); snprintf(msg, PND2_MSG_SIZE, "Error address 0x%llx is not DRAM", addr);
return -EINVAL; return -EINVAL;
} }
...@@ -727,10 +728,10 @@ static int sys2pmi(const u64 addr, u32 *pmiidx, u64 *pmiaddr, char *msg) ...@@ -727,10 +728,10 @@ static int sys2pmi(const u64 addr, u32 *pmiidx, u64 *pmiaddr, char *msg)
} }
/* Translate PMI address to memory (rank, row, bank, column) */ /* Translate PMI address to memory (rank, row, bank, column) */
#define C(n) (0x10 | (n)) /* column */ #define C(n) (BIT(4) | (n)) /* column */
#define B(n) (0x20 | (n)) /* bank */ #define B(n) (BIT(5) | (n)) /* bank */
#define R(n) (0x40 | (n)) /* row */ #define R(n) (BIT(6) | (n)) /* row */
#define RS (0x80) /* rank */ #define RS (BIT(7)) /* rank */
/* addrdec values */ /* addrdec values */
#define AMAP_1KB 0 #define AMAP_1KB 0
...@@ -1064,9 +1065,9 @@ static int apl_check_ecc_active(void) ...@@ -1064,9 +1065,9 @@ static int apl_check_ecc_active(void)
int i, ret = 0; int i, ret = 0;
/* Check dramtype and ECC mode for each present DIMM */ /* Check dramtype and ECC mode for each present DIMM */
for (i = 0; i < APL_NUM_CHANNELS; i++) for_each_set_bit(i, &chan_mask, APL_NUM_CHANNELS)
if (chan_mask & BIT(i)) ret += check_channel(i);
ret += check_channel(i);
return ret ? -EINVAL : 0; return ret ? -EINVAL : 0;
} }
...@@ -1205,10 +1206,7 @@ static void apl_get_dimm_config(struct mem_ctl_info *mci) ...@@ -1205,10 +1206,7 @@ static void apl_get_dimm_config(struct mem_ctl_info *mci)
u64 capacity; u64 capacity;
int i, g; int i, g;
for (i = 0; i < APL_NUM_CHANNELS; i++) { for_each_set_bit(i, &chan_mask, APL_NUM_CHANNELS) {
if (!(chan_mask & BIT(i)))
continue;
dimm = edac_get_dimm(mci, i, 0, 0); dimm = edac_get_dimm(mci, i, 0, 0);
if (!dimm) { if (!dimm) {
edac_dbg(0, "No allocated DIMM for channel %d\n", i); edac_dbg(0, "No allocated DIMM for channel %d\n", i);
...@@ -1228,8 +1226,7 @@ static void apl_get_dimm_config(struct mem_ctl_info *mci) ...@@ -1228,8 +1226,7 @@ static void apl_get_dimm_config(struct mem_ctl_info *mci)
} }
pvt->dimm_geom[i] = g; pvt->dimm_geom[i] = g;
capacity = (d->rken0 + d->rken1) * 8 * (1ul << dimms[g].rowbits) * capacity = (d->rken0 + d->rken1) * 8 * BIT(dimms[g].rowbits + dimms[g].colbits);
(1ul << dimms[g].colbits);
edac_dbg(0, "Channel %d: %lld MByte DIMM\n", i, capacity >> (20 - 3)); edac_dbg(0, "Channel %d: %lld MByte DIMM\n", i, capacity >> (20 - 3));
dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3)); dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3));
dimm->grain = 32; dimm->grain = 32;
...@@ -1295,7 +1292,7 @@ static void dnv_get_dimm_config(struct mem_ctl_info *mci) ...@@ -1295,7 +1292,7 @@ static void dnv_get_dimm_config(struct mem_ctl_info *mci)
continue; continue;
} }
capacity = ranks_of_dimm[j] * banks * (1ul << rowbits) * (1ul << colbits); capacity = ranks_of_dimm[j] * banks * BIT(rowbits + colbits);
edac_dbg(0, "Channel %d DIMM %d: %lld MByte DIMM\n", i, j, capacity >> (20 - 3)); edac_dbg(0, "Channel %d DIMM %d: %lld MByte DIMM\n", i, j, capacity >> (20 - 3));
dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3)); dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3));
dimm->grain = 32; dimm->grain = 32;
......
...@@ -1329,8 +1329,7 @@ static int ppc4xx_edac_probe(struct platform_device *op) ...@@ -1329,8 +1329,7 @@ static int ppc4xx_edac_probe(struct platform_device *op)
* *
* Unconditionally returns 0. * Unconditionally returns 0.
*/ */
static int static void ppc4xx_edac_remove(struct platform_device *op)
ppc4xx_edac_remove(struct platform_device *op)
{ {
struct mem_ctl_info *mci = dev_get_drvdata(&op->dev); struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
struct ppc4xx_edac_pdata *pdata = mci->pvt_info; struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
...@@ -1344,8 +1343,6 @@ ppc4xx_edac_remove(struct platform_device *op) ...@@ -1344,8 +1343,6 @@ ppc4xx_edac_remove(struct platform_device *op)
edac_mc_del_mc(mci->pdev); edac_mc_del_mc(mci->pdev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
/** /**
...@@ -1379,7 +1376,7 @@ ppc4xx_edac_opstate_init(void) ...@@ -1379,7 +1376,7 @@ ppc4xx_edac_opstate_init(void)
static struct platform_driver ppc4xx_edac_driver = { static struct platform_driver ppc4xx_edac_driver = {
.probe = ppc4xx_edac_probe, .probe = ppc4xx_edac_probe,
.remove = ppc4xx_edac_remove, .remove_new = ppc4xx_edac_remove,
.driver = { .driver = {
.name = PPC4XX_EDAC_MODULE_NAME, .name = PPC4XX_EDAC_MODULE_NAME,
.of_match_table = ppc4xx_edac_match, .of_match_table = ppc4xx_edac_match,
......
...@@ -390,14 +390,12 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev) ...@@ -390,14 +390,12 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int qcom_llcc_edac_remove(struct platform_device *pdev) static void qcom_llcc_edac_remove(struct platform_device *pdev)
{ {
struct edac_device_ctl_info *edev_ctl = dev_get_drvdata(&pdev->dev); struct edac_device_ctl_info *edev_ctl = dev_get_drvdata(&pdev->dev);
edac_device_del_device(edev_ctl->dev); edac_device_del_device(edev_ctl->dev);
edac_device_free_ctl_info(edev_ctl); edac_device_free_ctl_info(edev_ctl);
return 0;
} }
static const struct platform_device_id qcom_llcc_edac_id_table[] = { static const struct platform_device_id qcom_llcc_edac_id_table[] = {
...@@ -408,7 +406,7 @@ MODULE_DEVICE_TABLE(platform, qcom_llcc_edac_id_table); ...@@ -408,7 +406,7 @@ MODULE_DEVICE_TABLE(platform, qcom_llcc_edac_id_table);
static struct platform_driver qcom_llcc_edac_driver = { static struct platform_driver qcom_llcc_edac_driver = {
.probe = qcom_llcc_edac_probe, .probe = qcom_llcc_edac_probe,
.remove = qcom_llcc_edac_remove, .remove_new = qcom_llcc_edac_remove,
.driver = { .driver = {
.name = "qcom_llcc_edac", .name = "qcom_llcc_edac",
}, },
......
...@@ -439,7 +439,7 @@ static const struct pci_id_descr pci_dev_descr_sbridge[] = { ...@@ -439,7 +439,7 @@ static const struct pci_id_descr pci_dev_descr_sbridge[] = {
static const struct pci_id_table pci_dev_descr_sbridge_table[] = { static const struct pci_id_table pci_dev_descr_sbridge_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_sbridge, ARRAY_SIZE(pci_dev_descr_sbridge), 1, SANDY_BRIDGE), PCI_ID_TABLE_ENTRY(pci_dev_descr_sbridge, ARRAY_SIZE(pci_dev_descr_sbridge), 1, SANDY_BRIDGE),
{0,} /* 0 terminated list. */ { NULL, }
}; };
/* This changes depending if 1HA or 2HA: /* This changes depending if 1HA or 2HA:
...@@ -505,7 +505,7 @@ static const struct pci_id_descr pci_dev_descr_ibridge[] = { ...@@ -505,7 +505,7 @@ static const struct pci_id_descr pci_dev_descr_ibridge[] = {
static const struct pci_id_table pci_dev_descr_ibridge_table[] = { static const struct pci_id_table pci_dev_descr_ibridge_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_ibridge, 12, 2, IVY_BRIDGE), PCI_ID_TABLE_ENTRY(pci_dev_descr_ibridge, 12, 2, IVY_BRIDGE),
{0,} /* 0 terminated list. */ { NULL, }
}; };
/* Haswell support */ /* Haswell support */
...@@ -576,7 +576,7 @@ static const struct pci_id_descr pci_dev_descr_haswell[] = { ...@@ -576,7 +576,7 @@ static const struct pci_id_descr pci_dev_descr_haswell[] = {
static const struct pci_id_table pci_dev_descr_haswell_table[] = { static const struct pci_id_table pci_dev_descr_haswell_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_haswell, 13, 2, HASWELL), PCI_ID_TABLE_ENTRY(pci_dev_descr_haswell, 13, 2, HASWELL),
{0,} /* 0 terminated list. */ { NULL, }
}; };
/* Knight's Landing Support */ /* Knight's Landing Support */
...@@ -620,7 +620,7 @@ static const struct pci_id_descr pci_dev_descr_knl[] = { ...@@ -620,7 +620,7 @@ static const struct pci_id_descr pci_dev_descr_knl[] = {
static const struct pci_id_table pci_dev_descr_knl_table[] = { static const struct pci_id_table pci_dev_descr_knl_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_knl, ARRAY_SIZE(pci_dev_descr_knl), 1, KNIGHTS_LANDING), PCI_ID_TABLE_ENTRY(pci_dev_descr_knl, ARRAY_SIZE(pci_dev_descr_knl), 1, KNIGHTS_LANDING),
{0,} { NULL, }
}; };
/* /*
...@@ -686,7 +686,7 @@ static const struct pci_id_descr pci_dev_descr_broadwell[] = { ...@@ -686,7 +686,7 @@ static const struct pci_id_descr pci_dev_descr_broadwell[] = {
static const struct pci_id_table pci_dev_descr_broadwell_table[] = { static const struct pci_id_table pci_dev_descr_broadwell_table[] = {
PCI_ID_TABLE_ENTRY(pci_dev_descr_broadwell, 10, 2, BROADWELL), PCI_ID_TABLE_ENTRY(pci_dev_descr_broadwell, 10, 2, BROADWELL),
{0,} /* 0 terminated list. */ { NULL, }
}; };
......
...@@ -648,6 +648,10 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val, ...@@ -648,6 +648,10 @@ int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
memset(&res, 0, sizeof(res)); memset(&res, 0, sizeof(res));
res.mce = mce; res.mce = mce;
res.addr = mce->addr & MCI_ADDR_PHYSADDR; res.addr = mce->addr & MCI_ADDR_PHYSADDR;
if (!pfn_to_online_page(res.addr >> PAGE_SHIFT)) {
pr_err("Invalid address 0x%llx in IA32_MC%d_ADDR\n", mce->addr, mce->bank);
return NOTIFY_DONE;
}
/* Try driver decoder first */ /* Try driver decoder first */
if (!(driver_decode && driver_decode(&res))) { if (!(driver_decode && driver_decode(&res))) {
......
...@@ -1410,7 +1410,7 @@ static int mc_probe(struct platform_device *pdev) ...@@ -1410,7 +1410,7 @@ static int mc_probe(struct platform_device *pdev)
* *
* Return: Unconditionally 0 * Return: Unconditionally 0
*/ */
static int mc_remove(struct platform_device *pdev) static void mc_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
struct synps_edac_priv *priv = mci->pvt_info; struct synps_edac_priv *priv = mci->pvt_info;
...@@ -1425,8 +1425,6 @@ static int mc_remove(struct platform_device *pdev) ...@@ -1425,8 +1425,6 @@ static int mc_remove(struct platform_device *pdev)
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static struct platform_driver synps_edac_mc_driver = { static struct platform_driver synps_edac_mc_driver = {
...@@ -1435,7 +1433,7 @@ static struct platform_driver synps_edac_mc_driver = { ...@@ -1435,7 +1433,7 @@ static struct platform_driver synps_edac_mc_driver = {
.of_match_table = synps_edac_match, .of_match_table = synps_edac_match,
}, },
.probe = mc_probe, .probe = mc_probe,
.remove = mc_remove, .remove_new = mc_remove,
}; };
module_platform_driver(synps_edac_mc_driver); module_platform_driver(synps_edac_mc_driver);
......
...@@ -1133,7 +1133,7 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) ...@@ -1133,7 +1133,7 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id)
decode_register(other, OCX_OTHER_SIZE, decode_register(other, OCX_OTHER_SIZE,
ocx_com_errors, ctx->reg_com_int); ocx_com_errors, ctx->reg_com_int);
strncat(msg, other, OCX_MESSAGE_SIZE); strlcat(msg, other, OCX_MESSAGE_SIZE);
for (lane = 0; lane < OCX_RX_LANES; lane++) for (lane = 0; lane < OCX_RX_LANES; lane++)
if (ctx->reg_com_int & BIT(lane)) { if (ctx->reg_com_int & BIT(lane)) {
...@@ -1142,12 +1142,12 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id) ...@@ -1142,12 +1142,12 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id)
lane, ctx->reg_lane_int[lane], lane, ctx->reg_lane_int[lane],
lane, ctx->reg_lane_stat11[lane]); lane, ctx->reg_lane_stat11[lane]);
strncat(msg, other, OCX_MESSAGE_SIZE); strlcat(msg, other, OCX_MESSAGE_SIZE);
decode_register(other, OCX_OTHER_SIZE, decode_register(other, OCX_OTHER_SIZE,
ocx_lane_errors, ocx_lane_errors,
ctx->reg_lane_int[lane]); ctx->reg_lane_int[lane]);
strncat(msg, other, OCX_MESSAGE_SIZE); strlcat(msg, other, OCX_MESSAGE_SIZE);
} }
if (ctx->reg_com_int & OCX_COM_INT_CE) if (ctx->reg_com_int & OCX_COM_INT_CE)
...@@ -1217,7 +1217,7 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id) ...@@ -1217,7 +1217,7 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id)
decode_register(other, OCX_OTHER_SIZE, decode_register(other, OCX_OTHER_SIZE,
ocx_com_link_errors, ctx->reg_com_link_int); ocx_com_link_errors, ctx->reg_com_link_int);
strncat(msg, other, OCX_MESSAGE_SIZE); strlcat(msg, other, OCX_MESSAGE_SIZE);
if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE)
edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); edac_device_handle_ue(ocx->edac_dev, 0, 0, msg);
...@@ -1896,7 +1896,7 @@ static irqreturn_t thunderx_l2c_threaded_isr(int irq, void *irq_id) ...@@ -1896,7 +1896,7 @@ static irqreturn_t thunderx_l2c_threaded_isr(int irq, void *irq_id)
decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int);
strncat(msg, other, L2C_MESSAGE_SIZE); strlcat(msg, other, L2C_MESSAGE_SIZE);
if (ctx->reg_int & mask_ue) if (ctx->reg_int & mask_ue)
edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); edac_device_handle_ue(l2c->edac_dev, 0, 0, msg);
......
...@@ -312,19 +312,17 @@ static int ti_edac_probe(struct platform_device *pdev) ...@@ -312,19 +312,17 @@ static int ti_edac_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int ti_edac_remove(struct platform_device *pdev) static void ti_edac_remove(struct platform_device *pdev)
{ {
struct mem_ctl_info *mci = platform_get_drvdata(pdev); struct mem_ctl_info *mci = platform_get_drvdata(pdev);
edac_mc_del_mc(&pdev->dev); edac_mc_del_mc(&pdev->dev);
edac_mc_free(mci); edac_mc_free(mci);
return 0;
} }
static struct platform_driver ti_edac_driver = { static struct platform_driver ti_edac_driver = {
.probe = ti_edac_probe, .probe = ti_edac_probe,
.remove = ti_edac_remove, .remove_new = ti_edac_remove,
.driver = { .driver = {
.name = EDAC_MOD_NAME, .name = EDAC_MOD_NAME,
.of_match_table = ti_edac_of_match, .of_match_table = ti_edac_of_match,
......
...@@ -1960,7 +1960,7 @@ static int xgene_edac_probe(struct platform_device *pdev) ...@@ -1960,7 +1960,7 @@ static int xgene_edac_probe(struct platform_device *pdev)
return rc; return rc;
} }
static int xgene_edac_remove(struct platform_device *pdev) static void xgene_edac_remove(struct platform_device *pdev)
{ {
struct xgene_edac *edac = dev_get_drvdata(&pdev->dev); struct xgene_edac *edac = dev_get_drvdata(&pdev->dev);
struct xgene_edac_mc_ctx *mcu; struct xgene_edac_mc_ctx *mcu;
...@@ -1981,8 +1981,6 @@ static int xgene_edac_remove(struct platform_device *pdev) ...@@ -1981,8 +1981,6 @@ static int xgene_edac_remove(struct platform_device *pdev)
list_for_each_entry_safe(node, temp_node, &edac->socs, next) list_for_each_entry_safe(node, temp_node, &edac->socs, next)
xgene_edac_soc_remove(node); xgene_edac_soc_remove(node);
return 0;
} }
static const struct of_device_id xgene_edac_of_match[] = { static const struct of_device_id xgene_edac_of_match[] = {
...@@ -1993,7 +1991,7 @@ MODULE_DEVICE_TABLE(of, xgene_edac_of_match); ...@@ -1993,7 +1991,7 @@ MODULE_DEVICE_TABLE(of, xgene_edac_of_match);
static struct platform_driver xgene_edac_driver = { static struct platform_driver xgene_edac_driver = {
.probe = xgene_edac_probe, .probe = xgene_edac_probe,
.remove = xgene_edac_remove, .remove_new = xgene_edac_remove,
.driver = { .driver = {
.name = "xgene-edac", .name = "xgene-edac",
.of_match_table = xgene_edac_of_match, .of_match_table = xgene_edac_of_match,
......
...@@ -426,7 +426,7 @@ static int edac_probe(struct platform_device *pdev) ...@@ -426,7 +426,7 @@ static int edac_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int edac_remove(struct platform_device *pdev) static void edac_remove(struct platform_device *pdev)
{ {
struct edac_device_ctl_info *dci = platform_get_drvdata(pdev); struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
struct edac_priv *priv = dci->pvt_info; struct edac_priv *priv = dci->pvt_info;
...@@ -440,8 +440,6 @@ static int edac_remove(struct platform_device *pdev) ...@@ -440,8 +440,6 @@ static int edac_remove(struct platform_device *pdev)
edac_device_del_device(&pdev->dev); edac_device_del_device(&pdev->dev);
edac_device_free_ctl_info(dci); edac_device_free_ctl_info(dci);
return 0;
} }
static const struct of_device_id zynqmp_ocm_edac_match[] = { static const struct of_device_id zynqmp_ocm_edac_match[] = {
...@@ -457,7 +455,7 @@ static struct platform_driver zynqmp_ocm_edac_driver = { ...@@ -457,7 +455,7 @@ static struct platform_driver zynqmp_ocm_edac_driver = {
.of_match_table = zynqmp_ocm_edac_match, .of_match_table = zynqmp_ocm_edac_match,
}, },
.probe = edac_probe, .probe = edac_probe,
.remove = edac_remove, .remove_new = edac_remove,
}; };
module_platform_driver(zynqmp_ocm_edac_driver); module_platform_driver(zynqmp_ocm_edac_driver);
......
...@@ -187,6 +187,7 @@ static inline char *mc_event_error_type(const unsigned int err_type) ...@@ -187,6 +187,7 @@ static inline char *mc_event_error_type(const unsigned int err_type)
* @MEM_NVDIMM: Non-volatile RAM * @MEM_NVDIMM: Non-volatile RAM
* @MEM_WIO2: Wide I/O 2. * @MEM_WIO2: Wide I/O 2.
* @MEM_HBM2: High bandwidth Memory Gen 2. * @MEM_HBM2: High bandwidth Memory Gen 2.
* @MEM_HBM3: High bandwidth Memory Gen 3.
*/ */
enum mem_type { enum mem_type {
MEM_EMPTY = 0, MEM_EMPTY = 0,
...@@ -218,6 +219,7 @@ enum mem_type { ...@@ -218,6 +219,7 @@ enum mem_type {
MEM_NVDIMM, MEM_NVDIMM,
MEM_WIO2, MEM_WIO2,
MEM_HBM2, MEM_HBM2,
MEM_HBM3,
}; };
#define MEM_FLAG_EMPTY BIT(MEM_EMPTY) #define MEM_FLAG_EMPTY BIT(MEM_EMPTY)
...@@ -248,6 +250,7 @@ enum mem_type { ...@@ -248,6 +250,7 @@ enum mem_type {
#define MEM_FLAG_NVDIMM BIT(MEM_NVDIMM) #define MEM_FLAG_NVDIMM BIT(MEM_NVDIMM)
#define MEM_FLAG_WIO2 BIT(MEM_WIO2) #define MEM_FLAG_WIO2 BIT(MEM_WIO2)
#define MEM_FLAG_HBM2 BIT(MEM_HBM2) #define MEM_FLAG_HBM2 BIT(MEM_HBM2)
#define MEM_FLAG_HBM3 BIT(MEM_HBM3)
/** /**
* enum edac_type - Error Detection and Correction capabilities and mode * enum edac_type - Error Detection and Correction capabilities and mode
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment