mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
- 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmWZRIAACgkQEsHwGGHe VUpesxAAux/mgyqJ4lfzpP4I3LkDA7X9uU3Iv6j9NtS64TGvulT4ZMiSL/U/nqTY /jsJYNJE4yIXm2Bf/T3zx+Dxh6MmUZNEYzSgZyyNx9NPEkHi4gX+b9F2nUx9i66s D0Pn9IVbM1liNfGr2RSSsKwFa/5UBg+58nGF1DSUz+rOaQ0KOoeta9WE98ne4n81 fC0o4RCzcPswy3NVhi3wPoBiAfyMYmrtvBcSezIbV6CaVJB8aFkvZK4xGKkEBFoJ ApVrSr6bEjJ7I7DdudisfIhLfU6iji7ZGfkwiouN2TIfVCaOZdAVan/OETpPLC6b IPNac1iIIl6v2OfxQp6s6b/Vq+dL+vVa4SW5tNj242s9eHunuevEcly37x4W254m vt91K9dvZI3I5DzAbVagw3Z9tFHbIH7uiSYyjMoyYw11EvwY+bZPXfZExvEUuPQK 2f+VL4ELlBj0imrWSCur5hF1g8R2ejTjb+kYlTcULyaXB4ANeBVzeShff3qc/21g 3QojVA7v+7xkPwURKxRwlqkwE113cz0Rr/kKjXhXnBOuPulX0T5eSzX8WExZzSCT 4FsEvAwZPFt7iCTxB+cspykNxyxLqzMb8GZFG+Ji8szGNbVgiidn/QEQzohs8yBu aFenuLEM7XwvpPCjmLGGnRkFV9mBDfPATLegTFvMpPQVYhjPdp4= =Bptq -----END PGP SIGNATURE----- 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 ...
This commit is contained in:
commit
1dee7f509d
@ -22,6 +22,7 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/panic_notifier.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
@ -279,7 +280,6 @@ release:
|
||||
|
||||
static int altr_sdram_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *id;
|
||||
struct edac_mc_layer layers[2];
|
||||
struct mem_ctl_info *mci;
|
||||
struct altr_sdram_mc_data *drvdata;
|
||||
@ -290,10 +290,6 @@ static int altr_sdram_probe(struct platform_device *pdev)
|
||||
int irq, irq2, res = 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 */
|
||||
mc_vbase = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
|
||||
"altr,sdr-syscon");
|
||||
@ -304,8 +300,7 @@ static int altr_sdram_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Check specific dependencies for the module */
|
||||
priv = of_match_node(altr_sdram_ctrl_of_match,
|
||||
pdev->dev.of_node)->data;
|
||||
priv = device_get_match_data(&pdev->dev);
|
||||
|
||||
/* Validate the SDRAM controller has ECC enabled */
|
||||
if (regmap_read(mc_vbase, priv->ecc_ctrl_offset, &read_reg) ||
|
||||
@ -459,15 +454,13 @@ free:
|
||||
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);
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -489,7 +482,7 @@ static const struct dev_pm_ops altr_sdram_pm_ops = {
|
||||
|
||||
static struct platform_driver altr_sdram_edac_driver = {
|
||||
.probe = altr_sdram_probe,
|
||||
.remove = altr_sdram_remove,
|
||||
.remove_new = altr_sdram_remove,
|
||||
.driver = {
|
||||
.name = "altr_sdram_edac",
|
||||
#ifdef CONFIG_PM
|
||||
@ -812,7 +805,7 @@ fail:
|
||||
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 altr_edac_device_dev *drvdata = dci->pvt_info;
|
||||
@ -820,13 +813,11 @@ static int altr_edac_device_remove(struct platform_device *pdev)
|
||||
debugfs_remove_recursive(drvdata->debugfs_dir);
|
||||
edac_device_del_device(&pdev->dev);
|
||||
edac_device_free_ctl_info(dci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver altr_edac_device_driver = {
|
||||
.probe = altr_edac_device_probe,
|
||||
.remove = altr_edac_device_remove,
|
||||
.remove_new = altr_edac_device_remove,
|
||||
.driver = {
|
||||
.name = "altr_edac_device",
|
||||
.of_match_table = altr_edac_device_of_match,
|
||||
|
@ -996,15 +996,23 @@ static struct local_node_map {
|
||||
#define LNTM_NODE_COUNT GENMASK(27, 16)
|
||||
#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;
|
||||
int ret;
|
||||
u32 tmp;
|
||||
|
||||
/*
|
||||
* Node ID 0 is reserved for CPUs.
|
||||
* Therefore, a non-zero Node ID means we've already cached the values.
|
||||
* Mapping of nodes from hardware-provided AMD Node ID to a
|
||||
* 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)
|
||||
return 0;
|
||||
@ -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->edac_mode = EDAC_SECDED;
|
||||
dimm->mtype = MEM_HBM2;
|
||||
dimm->mtype = pvt->dram_type;
|
||||
dimm->dtype = DEV_X16;
|
||||
dimm->grain = 64;
|
||||
}
|
||||
@ -3880,7 +3888,7 @@ static bool gpu_ecc_enabled(struct amd64_pvt *pvt)
|
||||
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
|
||||
@ -3893,13 +3901,16 @@ static inline u32 gpu_get_umc_base(u8 umc, u8 channel)
|
||||
* On GPU nodes channels are selected in 3rd nibble
|
||||
* HBM chX[3:0]= [Y ]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;
|
||||
|
||||
if (channel >= 4)
|
||||
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)
|
||||
@ -3910,7 +3921,7 @@ static void gpu_read_mc_regs(struct amd64_pvt *pvt)
|
||||
|
||||
/* Read registers from each UMC */
|
||||
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];
|
||||
|
||||
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)
|
||||
|
||||
for_each_umc(umc) {
|
||||
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];
|
||||
|
||||
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)
|
||||
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];
|
||||
|
||||
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)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = gpu_get_node_map();
|
||||
ret = gpu_get_node_map(pvt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -4125,6 +4136,8 @@ static int per_family_init(struct amd64_pvt *pvt)
|
||||
if (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) {
|
||||
pvt->ctl_name = "MI200";
|
||||
pvt->max_mcs = 4;
|
||||
pvt->dram_type = MEM_HBM2;
|
||||
pvt->gpu_umc_base = 0x50000;
|
||||
pvt->ops = &gpu_ops;
|
||||
} else {
|
||||
pvt->ctl_name = "F19h_M30h";
|
||||
@ -4142,6 +4155,13 @@ static int per_family_init(struct amd64_pvt *pvt)
|
||||
pvt->ctl_name = "F19h_M70h";
|
||||
pvt->flags.zn_regs_v2 = 1;
|
||||
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:
|
||||
pvt->ctl_name = "F19h_MA0h";
|
||||
pvt->max_mcs = 12;
|
||||
@ -4180,23 +4200,33 @@ static const struct attribute_group *amd64_edac_attr_groups[] = {
|
||||
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)
|
||||
{
|
||||
struct mem_ctl_info *mci = NULL;
|
||||
struct edac_mc_layer layers[2];
|
||||
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].size = (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) ?
|
||||
pvt->max_mcs : pvt->csels[0].b_cnt;
|
||||
layers[0].size = get_layer_size(pvt, 0);
|
||||
layers[0].is_virt_csrow = true;
|
||||
layers[1].type = EDAC_MC_LAYER_CHANNEL;
|
||||
layers[1].size = (pvt->F3->device == PCI_DEVICE_ID_AMD_MI200_DF_F3) ?
|
||||
pvt->csels[0].b_cnt : pvt->max_mcs;
|
||||
layers[1].size = get_layer_size(pvt, 1);
|
||||
layers[1].is_virt_csrow = false;
|
||||
|
||||
mci = edac_mc_alloc(pvt->mc_node_id, ARRAY_SIZE(layers), layers, 0);
|
||||
|
@ -362,6 +362,7 @@ struct amd64_pvt {
|
||||
u32 dct_sel_lo; /* DRAM Controller Select Low */
|
||||
u32 dct_sel_hi; /* DRAM Controller Select High */
|
||||
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 */
|
||||
u8 ecc_sym_sz;
|
||||
|
@ -5,7 +5,9 @@
|
||||
|
||||
#include <linux/kernel.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-aurora-l2.h>
|
||||
@ -351,20 +353,18 @@ static int axp_mc_probe(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver axp_mc_driver = {
|
||||
.probe = axp_mc_probe,
|
||||
.remove = axp_mc_remove,
|
||||
.remove_new = axp_mc_remove,
|
||||
.driver = {
|
||||
.name = "armada_xp_mc_edac",
|
||||
.of_match_table = of_match_ptr(axp_mc_of_match),
|
||||
@ -564,7 +564,7 @@ static int aurora_l2_probe(struct platform_device *pdev)
|
||||
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);
|
||||
#ifdef CONFIG_EDAC_DEBUG
|
||||
@ -575,13 +575,11 @@ static int aurora_l2_remove(struct platform_device *pdev)
|
||||
edac_device_del_device(&pdev->dev);
|
||||
edac_device_free_ctl_info(dci);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver aurora_l2_driver = {
|
||||
.probe = aurora_l2_probe,
|
||||
.remove = aurora_l2_remove,
|
||||
.remove_new = aurora_l2_remove,
|
||||
.driver = {
|
||||
.name = "aurora_l2_edac",
|
||||
.of_match_table = of_match_ptr(aurora_l2_of_match),
|
||||
|
@ -357,7 +357,7 @@ probe_exit02:
|
||||
}
|
||||
|
||||
|
||||
static int aspeed_remove(struct platform_device *pdev)
|
||||
static void aspeed_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mem_ctl_info *mci;
|
||||
|
||||
@ -369,8 +369,6 @@ static int aspeed_remove(struct platform_device *pdev)
|
||||
mci = edac_mc_del_mc(&pdev->dev);
|
||||
if (mci)
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -389,7 +387,7 @@ static struct platform_driver aspeed_driver = {
|
||||
.of_match_table = aspeed_of_match
|
||||
},
|
||||
.probe = aspeed_probe,
|
||||
.remove = aspeed_remove
|
||||
.remove_new = aspeed_remove
|
||||
};
|
||||
module_platform_driver(aspeed_driver);
|
||||
|
||||
|
@ -323,14 +323,12 @@ err:
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id bluefield_mc_acpi_ids[] = {
|
||||
@ -346,7 +344,7 @@ static struct platform_driver bluefield_edac_mc_driver = {
|
||||
.acpi_match_table = bluefield_mc_acpi_ids,
|
||||
},
|
||||
.probe = bluefield_edac_mc_probe,
|
||||
.remove = bluefield_edac_mc_remove,
|
||||
.remove_new = bluefield_edac_mc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(bluefield_edac_mc_driver);
|
||||
|
@ -234,12 +234,11 @@ static int cell_edac_probe(struct platform_device *pdev)
|
||||
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);
|
||||
if (mci)
|
||||
edac_mc_free(mci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cell_edac_driver = {
|
||||
@ -247,7 +246,7 @@ static struct platform_driver cell_edac_driver = {
|
||||
.name = "cbe-mic",
|
||||
},
|
||||
.probe = cell_edac_probe,
|
||||
.remove = cell_edac_remove,
|
||||
.remove_new = cell_edac_remove,
|
||||
};
|
||||
|
||||
static int __init cell_edac_init(void)
|
||||
|
@ -1010,7 +1010,7 @@ out:
|
||||
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);
|
||||
|
||||
@ -1023,13 +1023,11 @@ static int cpc925_remove(struct platform_device *pdev)
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cpc925_edac_driver = {
|
||||
.probe = cpc925_probe,
|
||||
.remove = cpc925_remove,
|
||||
.remove_new = cpc925_remove,
|
||||
.driver = {
|
||||
.name = "cpc925_edac",
|
||||
}
|
||||
|
@ -602,7 +602,7 @@ err:
|
||||
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;
|
||||
struct mem_ctl_info *mci;
|
||||
@ -626,8 +626,6 @@ static int dmc520_edac_remove(struct platform_device *pdev)
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id dmc520_edac_driver_id[] = {
|
||||
@ -644,7 +642,7 @@ static struct platform_driver dmc520_edac_driver = {
|
||||
},
|
||||
|
||||
.probe = dmc520_edac_probe,
|
||||
.remove = dmc520_edac_remove
|
||||
.remove_new = dmc520_edac_remove
|
||||
};
|
||||
|
||||
module_platform_driver(dmc520_edac_driver);
|
||||
|
@ -166,6 +166,7 @@ const char * const edac_mem_types[] = {
|
||||
[MEM_NVDIMM] = "Non-volatile-RAM",
|
||||
[MEM_WIO2] = "Wide-IO-2",
|
||||
[MEM_HBM2] = "High-bandwidth-memory-Gen2",
|
||||
[MEM_HBM3] = "High-bandwidth-memory-Gen3",
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(edac_mem_types);
|
||||
|
||||
|
@ -521,7 +521,7 @@ static void edac_pci_dev_parity_clear(struct pci_dev *dev)
|
||||
/* read the device TYPE, looking for bridges */
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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",
|
||||
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 */
|
||||
status = get_pci_parity_status(dev, 1);
|
||||
|
||||
|
@ -612,7 +612,7 @@ err:
|
||||
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 fsl_mc_pdata *pdata = mci->pvt_info;
|
||||
@ -629,5 +629,4 @@ int fsl_mc_err_remove(struct platform_device *op)
|
||||
|
||||
edac_mc_del_mc(&op->dev);
|
||||
edac_mc_free(mci);
|
||||
return 0;
|
||||
}
|
||||
|
@ -72,5 +72,5 @@ struct fsl_mc_pdata {
|
||||
int irq;
|
||||
};
|
||||
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
|
||||
|
@ -118,18 +118,17 @@ err:
|
||||
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);
|
||||
|
||||
edac_device_del_device(&pdev->dev);
|
||||
edac_device_free_ctl_info(dci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver highbank_l2_edac_driver = {
|
||||
.probe = highbank_l2_err_probe,
|
||||
.remove = highbank_l2_err_remove,
|
||||
.remove_new = highbank_l2_err_remove,
|
||||
.driver = {
|
||||
.name = "hb_l2_edac",
|
||||
.of_match_table = hb_l2_err_of_match,
|
||||
|
@ -251,18 +251,17 @@ free:
|
||||
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);
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver highbank_mc_edac_driver = {
|
||||
.probe = highbank_mc_probe,
|
||||
.remove = highbank_mc_remove,
|
||||
.remove_new = highbank_mc_remove,
|
||||
.driver = {
|
||||
.name = "hb_mc_edac",
|
||||
.of_match_table = hb_ddr_ctrl_of_match,
|
||||
|
@ -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_lynnfield),
|
||||
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[] = {
|
||||
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_LYNNFIELD_QPI_LINK0)},
|
||||
{0,} /* 0 terminated list. */
|
||||
{ 0, }
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -58,6 +58,7 @@
|
||||
/* Capability register E */
|
||||
#define CAPID_E_OFFSET 0xf0
|
||||
#define CAPID_E_IBECC BIT(12)
|
||||
#define CAPID_E_IBECC_BIT18 BIT(18)
|
||||
|
||||
/* Error Status */
|
||||
#define ERRSTS_OFFSET 0xc8
|
||||
@ -80,6 +81,7 @@
|
||||
#define ECC_ERROR_LOG_UE BIT_ULL(63)
|
||||
#define ECC_ERROR_LOG_ADDR_SHIFT 5
|
||||
#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)
|
||||
|
||||
/* Host MMIO base address */
|
||||
@ -133,6 +135,8 @@ static struct res_config {
|
||||
u32 ibecc_base;
|
||||
u32 ibecc_error_log_offset;
|
||||
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 */
|
||||
u64 (*err_addr_to_sys_addr)(u64 eaddr, int mc);
|
||||
/* Convert error address logged in IBECC to integrated memory controller address */
|
||||
@ -222,6 +226,67 @@ static struct work_struct ecclog_work;
|
||||
#define DID_ADL_SKU3 0x4621
|
||||
#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)
|
||||
{
|
||||
u32 v;
|
||||
@ -272,6 +337,39 @@ static bool tgl_ibecc_available(struct pci_dev *pdev)
|
||||
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)
|
||||
{
|
||||
if (maddr < igen6_tolud)
|
||||
@ -358,6 +456,11 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc)
|
||||
return imc_addr;
|
||||
}
|
||||
|
||||
static u64 rpl_p_err_addr(u64 ecclog)
|
||||
{
|
||||
return ECC_ERROR_LOG_ADDR45(ecclog);
|
||||
}
|
||||
|
||||
static struct res_config ehl_cfg = {
|
||||
.num_imc = 1,
|
||||
.imc_base = 0x5000,
|
||||
@ -403,6 +506,51 @@ static struct res_config adl_cfg = {
|
||||
.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[] = {
|
||||
{ PCI_VDEVICE(INTEL, DID_EHL_SKU5), (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[] = {
|
||||
{ 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_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);
|
||||
@ -679,8 +850,11 @@ static void ecclog_work_cb(struct work_struct *work)
|
||||
|
||||
llist_for_each_entry_safe(node, tmp, head, llnode) {
|
||||
memset(&res, 0, sizeof(res));
|
||||
eaddr = ECC_ERROR_LOG_ADDR(node->ecclog) <<
|
||||
ECC_ERROR_LOG_ADDR_SHIFT;
|
||||
if (res_cfg->err_addr)
|
||||
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.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);
|
||||
@ -969,22 +1143,8 @@ static int igen6_pci_setup(struct pci_dev *pdev, u64 *mchbar)
|
||||
|
||||
igen6_tom = u.v & GENMASK_ULL(38, 20);
|
||||
|
||||
if (pci_read_config_dword(pdev, MCHBAR_OFFSET, &u.v_lo)) {
|
||||
igen6_printk(KERN_ERR, "Failed to read lower MCHBAR\n");
|
||||
if (get_mchbar(pdev, mchbar))
|
||||
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
|
||||
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);
|
||||
|
||||
static struct platform_driver fsl_ddr_mc_err_driver = {
|
||||
.probe = fsl_mc_err_probe,
|
||||
.remove = fsl_mc_err_remove,
|
||||
.remove_new = fsl_mc_err_remove,
|
||||
.driver = {
|
||||
.name = "fsl_ddr_mc_err",
|
||||
.of_match_table = fsl_ddr_mc_err_of_match,
|
||||
|
@ -300,7 +300,7 @@ err:
|
||||
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 mpc85xx_pci_pdata *pdata = pci->pvt_info;
|
||||
@ -312,8 +312,6 @@ static int mpc85xx_pci_err_remove(struct platform_device *op)
|
||||
|
||||
edac_pci_del_device(&op->dev);
|
||||
edac_pci_free_ctl_info(pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 = {
|
||||
.probe = mpc85xx_pci_err_probe,
|
||||
.remove = mpc85xx_pci_err_remove,
|
||||
.remove_new = mpc85xx_pci_err_remove,
|
||||
.id_table = mpc85xx_pci_err_match,
|
||||
.driver = {
|
||||
.name = "mpc85xx_pci_err",
|
||||
@ -591,7 +589,7 @@ err:
|
||||
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 mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;
|
||||
@ -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);
|
||||
edac_device_del_device(&op->dev);
|
||||
edac_device_free_ctl_info(edac_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id 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 = {
|
||||
.probe = mpc85xx_l2_err_probe,
|
||||
.remove = mpc85xx_l2_err_remove,
|
||||
.remove_new = mpc85xx_l2_err_remove,
|
||||
.driver = {
|
||||
.name = "mpc85xx_l2_err",
|
||||
.of_match_table = mpc85xx_l2_err_of_match,
|
||||
@ -659,7 +656,7 @@ MODULE_DEVICE_TABLE(of, mpc85xx_mc_err_of_match);
|
||||
|
||||
static struct platform_driver mpc85xx_mc_err_driver = {
|
||||
.probe = fsl_mc_err_probe,
|
||||
.remove = fsl_mc_err_remove,
|
||||
.remove_new = fsl_mc_err_remove,
|
||||
.driver = {
|
||||
.name = "mpc85xx_mc_err",
|
||||
.of_match_table = mpc85xx_mc_err_of_match,
|
||||
|
@ -410,7 +410,7 @@ free_edac_mc:
|
||||
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 priv_data *priv = mci->pvt_info;
|
||||
@ -426,8 +426,6 @@ static int edac_remove(struct platform_device *pdev)
|
||||
regmap_write(npcm_regmap, pdata->ctl_int_mask_master,
|
||||
pdata->int_mask_master_global_mask);
|
||||
regmap_update_bits(npcm_regmap, pdata->ctl_ecc_en, pdata->ecc_en_mask, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct npcm_platform_data npcm750_edac = {
|
||||
@ -533,7 +531,7 @@ static struct platform_driver npcm_edac_driver = {
|
||||
.of_match_table = npcm_edac_of_match,
|
||||
},
|
||||
.probe = edac_probe,
|
||||
.remove = edac_remove,
|
||||
.remove_new = edac_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(npcm_edac_driver);
|
||||
|
@ -184,19 +184,17 @@ err:
|
||||
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);
|
||||
|
||||
edac_device_del_device(&pdev->dev);
|
||||
edac_device_free_ctl_info(l2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver octeon_l2c_driver = {
|
||||
.probe = octeon_l2c_probe,
|
||||
.remove = octeon_l2c_remove,
|
||||
.remove_new = octeon_l2c_remove,
|
||||
.driver = {
|
||||
.name = "octeon_l2c_edac",
|
||||
}
|
||||
|
@ -302,18 +302,17 @@ static int octeon_lmc_edac_probe(struct platform_device *pdev)
|
||||
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);
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver octeon_lmc_edac_driver = {
|
||||
.probe = octeon_lmc_edac_probe,
|
||||
.remove = octeon_lmc_edac_remove,
|
||||
.remove_new = octeon_lmc_edac_remove,
|
||||
.driver = {
|
||||
.name = "octeon_lmc_edac",
|
||||
}
|
||||
|
@ -119,19 +119,18 @@ err:
|
||||
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);
|
||||
|
||||
unregister_co_cache_error_notifier(&p->notifier);
|
||||
edac_device_del_device(&pdev->dev);
|
||||
edac_device_free_ctl_info(p->ed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver co_cache_error_driver = {
|
||||
.probe = co_cache_error_probe,
|
||||
.remove = co_cache_error_remove,
|
||||
.remove_new = co_cache_error_remove,
|
||||
.driver = {
|
||||
.name = "octeon_pc_edac",
|
||||
}
|
||||
|
@ -87,19 +87,17 @@ err:
|
||||
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);
|
||||
|
||||
edac_pci_del_device(&pdev->dev);
|
||||
edac_pci_free_ctl_info(pci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver octeon_pci_driver = {
|
||||
.probe = octeon_pci_probe,
|
||||
.remove = octeon_pci_remove,
|
||||
.remove_new = octeon_pci_remove,
|
||||
.driver = {
|
||||
.name = "octeon_pci_edac",
|
||||
}
|
||||
|
@ -16,18 +16,20 @@
|
||||
* rank, bank, row and column using the appropriate "dunit_ops" functions/parameters.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/edac.h>
|
||||
#include <linux/mmzone.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/bitmap.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_ids.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include <linux/platform_data/x86/p2sb.h>
|
||||
|
||||
#include <asm/cpu_device_id.h>
|
||||
@ -109,7 +111,6 @@ static struct mem_ctl_info *pnd2_mci;
|
||||
#define MOT_CHAN_INTLV_BIT_1SLC_2CH 12
|
||||
#define MOT_CHAN_INTLV_BIT_2SLC_2CH 13
|
||||
#define SELECTOR_DISABLED (-1)
|
||||
#define _4GB (1ul << 32)
|
||||
|
||||
#define PMI_ADDRESS_WIDTH 31
|
||||
#define PND_MAX_PHYS_BIT 39
|
||||
@ -183,7 +184,7 @@ static int _apl_rd_reg(int port, int off, int op, u32 *data)
|
||||
}
|
||||
|
||||
P2SB_READ(dword, P2SB_DATA_OFF, data);
|
||||
ret = (status >> 1) & 0x3;
|
||||
ret = (status >> 1) & GENMASK(1, 0);
|
||||
out:
|
||||
/* Hide the P2SB device, if it was hidden before */
|
||||
if (hidden)
|
||||
@ -307,7 +308,7 @@ static bool two_channels; /* Both PMI channels in one slice enabled */
|
||||
|
||||
static u8 sym_chan_mask;
|
||||
static u8 asym_chan_mask;
|
||||
static u8 chan_mask;
|
||||
static unsigned long chan_mask;
|
||||
|
||||
static int slice_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)
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (base & ~mask) {
|
||||
@ -587,7 +588,7 @@ static int get_registers(void)
|
||||
/* Get a contiguous memory address (remove the MMIO gap) */
|
||||
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 */
|
||||
@ -598,7 +599,7 @@ static void remove_addr_bit(u64 *addr, int bitidx)
|
||||
if (bitidx == -1)
|
||||
return;
|
||||
|
||||
mask = (1ull << bitidx) - 1;
|
||||
mask = BIT_ULL(bitidx) - 1;
|
||||
*addr = ((*addr >> 1) & ~mask) | (*addr & mask);
|
||||
}
|
||||
|
||||
@ -642,8 +643,8 @@ static int sys2pmi(const u64 addr, u32 *pmiidx, u64 *pmiaddr, char *msg)
|
||||
int sym_chan_shift = sym_channels >> 1;
|
||||
|
||||
/* Give up if address is out of range, or in MMIO gap */
|
||||
if (addr >= (1ul << PND_MAX_PHYS_BIT) ||
|
||||
(addr >= top_lm && addr < _4GB) || addr >= top_hm) {
|
||||
if (addr >= BIT(PND_MAX_PHYS_BIT) ||
|
||||
(addr >= top_lm && addr < SZ_4G) || addr >= top_hm) {
|
||||
snprintf(msg, PND2_MSG_SIZE, "Error address 0x%llx is not DRAM", addr);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -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) */
|
||||
#define C(n) (0x10 | (n)) /* column */
|
||||
#define B(n) (0x20 | (n)) /* bank */
|
||||
#define R(n) (0x40 | (n)) /* row */
|
||||
#define RS (0x80) /* rank */
|
||||
#define C(n) (BIT(4) | (n)) /* column */
|
||||
#define B(n) (BIT(5) | (n)) /* bank */
|
||||
#define R(n) (BIT(6) | (n)) /* row */
|
||||
#define RS (BIT(7)) /* rank */
|
||||
|
||||
/* addrdec values */
|
||||
#define AMAP_1KB 0
|
||||
@ -1064,9 +1065,9 @@ static int apl_check_ecc_active(void)
|
||||
int i, ret = 0;
|
||||
|
||||
/* Check dramtype and ECC mode for each present DIMM */
|
||||
for (i = 0; i < APL_NUM_CHANNELS; i++)
|
||||
if (chan_mask & BIT(i))
|
||||
ret += check_channel(i);
|
||||
for_each_set_bit(i, &chan_mask, APL_NUM_CHANNELS)
|
||||
ret += check_channel(i);
|
||||
|
||||
return ret ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
@ -1205,10 +1206,7 @@ static void apl_get_dimm_config(struct mem_ctl_info *mci)
|
||||
u64 capacity;
|
||||
int i, g;
|
||||
|
||||
for (i = 0; i < APL_NUM_CHANNELS; i++) {
|
||||
if (!(chan_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
for_each_set_bit(i, &chan_mask, APL_NUM_CHANNELS) {
|
||||
dimm = edac_get_dimm(mci, i, 0, 0);
|
||||
if (!dimm) {
|
||||
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)
|
||||
}
|
||||
|
||||
pvt->dimm_geom[i] = g;
|
||||
capacity = (d->rken0 + d->rken1) * 8 * (1ul << dimms[g].rowbits) *
|
||||
(1ul << dimms[g].colbits);
|
||||
capacity = (d->rken0 + d->rken1) * 8 * BIT(dimms[g].rowbits + dimms[g].colbits);
|
||||
edac_dbg(0, "Channel %d: %lld MByte DIMM\n", i, capacity >> (20 - 3));
|
||||
dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3));
|
||||
dimm->grain = 32;
|
||||
@ -1295,7 +1292,7 @@ static void dnv_get_dimm_config(struct mem_ctl_info *mci)
|
||||
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));
|
||||
dimm->nr_pages = MiB_TO_PAGES(capacity >> (20 - 3));
|
||||
dimm->grain = 32;
|
||||
|
@ -1329,8 +1329,7 @@ static int ppc4xx_edac_probe(struct platform_device *op)
|
||||
*
|
||||
* Unconditionally returns 0.
|
||||
*/
|
||||
static int
|
||||
ppc4xx_edac_remove(struct platform_device *op)
|
||||
static void ppc4xx_edac_remove(struct platform_device *op)
|
||||
{
|
||||
struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
|
||||
struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
|
||||
@ -1344,8 +1343,6 @@ ppc4xx_edac_remove(struct platform_device *op)
|
||||
|
||||
edac_mc_del_mc(mci->pdev);
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1379,7 +1376,7 @@ ppc4xx_edac_opstate_init(void)
|
||||
|
||||
static struct platform_driver ppc4xx_edac_driver = {
|
||||
.probe = ppc4xx_edac_probe,
|
||||
.remove = ppc4xx_edac_remove,
|
||||
.remove_new = ppc4xx_edac_remove,
|
||||
.driver = {
|
||||
.name = PPC4XX_EDAC_MODULE_NAME,
|
||||
.of_match_table = ppc4xx_edac_match,
|
||||
|
@ -390,14 +390,12 @@ irq_done:
|
||||
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);
|
||||
|
||||
edac_device_del_device(edev_ctl->dev);
|
||||
edac_device_free_ctl_info(edev_ctl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id 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 = {
|
||||
.probe = qcom_llcc_edac_probe,
|
||||
.remove = qcom_llcc_edac_remove,
|
||||
.remove_new = qcom_llcc_edac_remove,
|
||||
.driver = {
|
||||
.name = "qcom_llcc_edac",
|
||||
},
|
||||
|
@ -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[] = {
|
||||
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:
|
||||
@ -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[] = {
|
||||
PCI_ID_TABLE_ENTRY(pci_dev_descr_ibridge, 12, 2, IVY_BRIDGE),
|
||||
{0,} /* 0 terminated list. */
|
||||
{ NULL, }
|
||||
};
|
||||
|
||||
/* Haswell support */
|
||||
@ -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[] = {
|
||||
PCI_ID_TABLE_ENTRY(pci_dev_descr_haswell, 13, 2, HASWELL),
|
||||
{0,} /* 0 terminated list. */
|
||||
{ NULL, }
|
||||
};
|
||||
|
||||
/* Knight's Landing Support */
|
||||
@ -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[] = {
|
||||
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[] = {
|
||||
|
||||
static const struct pci_id_table pci_dev_descr_broadwell_table[] = {
|
||||
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,
|
||||
memset(&res, 0, sizeof(res));
|
||||
res.mce = mce;
|
||||
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 */
|
||||
if (!(driver_decode && driver_decode(&res))) {
|
||||
|
@ -1410,7 +1410,7 @@ free_edac_mc:
|
||||
*
|
||||
* 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 synps_edac_priv *priv = mci->pvt_info;
|
||||
@ -1425,8 +1425,6 @@ static int mc_remove(struct platform_device *pdev)
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
.probe = mc_probe,
|
||||
.remove = mc_remove,
|
||||
.remove_new = mc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(synps_edac_mc_driver);
|
||||
|
@ -1133,7 +1133,7 @@ static irqreturn_t thunderx_ocx_com_threaded_isr(int irq, void *irq_id)
|
||||
decode_register(other, OCX_OTHER_SIZE,
|
||||
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++)
|
||||
if (ctx->reg_com_int & BIT(lane)) {
|
||||
@ -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_stat11[lane]);
|
||||
|
||||
strncat(msg, other, OCX_MESSAGE_SIZE);
|
||||
strlcat(msg, other, OCX_MESSAGE_SIZE);
|
||||
|
||||
decode_register(other, OCX_OTHER_SIZE,
|
||||
ocx_lane_errors,
|
||||
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)
|
||||
@ -1217,7 +1217,7 @@ static irqreturn_t thunderx_ocx_lnk_threaded_isr(int irq, void *irq_id)
|
||||
decode_register(other, OCX_OTHER_SIZE,
|
||||
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)
|
||||
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)
|
||||
|
||||
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)
|
||||
edac_device_handle_ue(l2c->edac_dev, 0, 0, msg);
|
||||
|
@ -312,19 +312,17 @@ err:
|
||||
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);
|
||||
|
||||
edac_mc_del_mc(&pdev->dev);
|
||||
edac_mc_free(mci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ti_edac_driver = {
|
||||
.probe = ti_edac_probe,
|
||||
.remove = ti_edac_remove,
|
||||
.remove_new = ti_edac_remove,
|
||||
.driver = {
|
||||
.name = EDAC_MOD_NAME,
|
||||
.of_match_table = ti_edac_of_match,
|
||||
|
@ -1960,7 +1960,7 @@ out_err:
|
||||
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_mc_ctx *mcu;
|
||||
@ -1981,8 +1981,6 @@ static int xgene_edac_remove(struct platform_device *pdev)
|
||||
|
||||
list_for_each_entry_safe(node, temp_node, &edac->socs, next)
|
||||
xgene_edac_soc_remove(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id xgene_edac_of_match[] = {
|
||||
@ -1993,7 +1991,7 @@ MODULE_DEVICE_TABLE(of, xgene_edac_of_match);
|
||||
|
||||
static struct platform_driver xgene_edac_driver = {
|
||||
.probe = xgene_edac_probe,
|
||||
.remove = xgene_edac_remove,
|
||||
.remove_new = xgene_edac_remove,
|
||||
.driver = {
|
||||
.name = "xgene-edac",
|
||||
.of_match_table = xgene_edac_of_match,
|
||||
|
@ -426,7 +426,7 @@ free_dev_ctl:
|
||||
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_priv *priv = dci->pvt_info;
|
||||
@ -440,8 +440,6 @@ static int edac_remove(struct platform_device *pdev)
|
||||
|
||||
edac_device_del_device(&pdev->dev);
|
||||
edac_device_free_ctl_info(dci);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id zynqmp_ocm_edac_match[] = {
|
||||
@ -457,7 +455,7 @@ static struct platform_driver zynqmp_ocm_edac_driver = {
|
||||
.of_match_table = zynqmp_ocm_edac_match,
|
||||
},
|
||||
.probe = edac_probe,
|
||||
.remove = edac_remove,
|
||||
.remove_new = edac_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(zynqmp_ocm_edac_driver);
|
||||
|
@ -187,6 +187,7 @@ static inline char *mc_event_error_type(const unsigned int err_type)
|
||||
* @MEM_NVDIMM: Non-volatile RAM
|
||||
* @MEM_WIO2: Wide I/O 2.
|
||||
* @MEM_HBM2: High bandwidth Memory Gen 2.
|
||||
* @MEM_HBM3: High bandwidth Memory Gen 3.
|
||||
*/
|
||||
enum mem_type {
|
||||
MEM_EMPTY = 0,
|
||||
@ -218,6 +219,7 @@ enum mem_type {
|
||||
MEM_NVDIMM,
|
||||
MEM_WIO2,
|
||||
MEM_HBM2,
|
||||
MEM_HBM3,
|
||||
};
|
||||
|
||||
#define MEM_FLAG_EMPTY BIT(MEM_EMPTY)
|
||||
@ -248,6 +250,7 @@ enum mem_type {
|
||||
#define MEM_FLAG_NVDIMM BIT(MEM_NVDIMM)
|
||||
#define MEM_FLAG_WIO2 BIT(MEM_WIO2)
|
||||
#define MEM_FLAG_HBM2 BIT(MEM_HBM2)
|
||||
#define MEM_FLAG_HBM3 BIT(MEM_HBM3)
|
||||
|
||||
/**
|
||||
* enum edac_type - Error Detection and Correction capabilities and mode
|
||||
|
Loading…
Reference in New Issue
Block a user