Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

EDAC, layerscape: Add Layerscape EDAC support

Add DDR EDAC driver for ARM-based compatible controllers. Both
big-endian and little-endian are supported, as specified in device tree.

Signed-off-by: York Sun <york.sun@nxp.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: http://lkml.kernel.org/r/1471990465-27443-1-git-send-email-york.sun@nxp.com
Signed-off-by: Borislav Petkov <bp@suse.de>

authored by

York Sun and committed by
Borislav Petkov
eeb3d68b 55764ed3

+85 -1
+1
arch/arm64/Kconfig.platforms
··· 55 55 56 56 config ARCH_LAYERSCAPE 57 57 bool "ARMv8 based Freescale Layerscape SoC family" 58 + select EDAC_SUPPORT 58 59 help 59 60 This enables support for the Freescale Layerscape SoC family. 60 61
+7
drivers/edac/Kconfig
··· 258 258 Support for error detection and correction on the Freescale 259 259 MPC8349, MPC8560, MPC8540, MPC8548, T4240 260 260 261 + config EDAC_LAYERSCAPE 262 + tristate "Freescale Layerscape DDR" 263 + depends on EDAC_MM_EDAC && ARCH_LAYERSCAPE 264 + help 265 + Support for error detection and correction on Freescale memory 266 + controllers on Layerscape SoCs. 267 + 261 268 config EDAC_MV64X60 262 269 tristate "Marvell MV64x60" 263 270 depends on EDAC_MM_EDAC && MV64X60
+3
drivers/edac/Makefile
··· 54 54 mpc85xx_edac_mod-y := fsl_ddr_edac.o mpc85xx_edac.o 55 55 obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac_mod.o 56 56 57 + layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o 58 + obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o 59 + 57 60 obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o 58 61 obj-$(CONFIG_EDAC_CELL) += cell_edac.o 59 62 obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o
+1 -1
drivers/edac/fsl_ddr_edac.c
··· 26 26 27 27 #include <linux/of_platform.h> 28 28 #include <linux/of_device.h> 29 + #include <linux/of_address.h> 29 30 #include "edac_module.h" 30 31 #include "edac_core.h" 31 32 #include "fsl_ddr_edac.h" ··· 479 478 480 479 pdata = mci->pvt_info; 481 480 pdata->name = "fsl_mc_err"; 482 - pdata->irq = NO_IRQ; 483 481 mci->pdev = &op->dev; 484 482 pdata->edac_idx = edac_mc_idx++; 485 483 dev_set_drvdata(mci->pdev, mci);
+73
drivers/edac/layerscape_edac.c
··· 1 + /* 2 + * Freescale Memory Controller kernel module 3 + * 4 + * Author: York Sun <york.sun@nxp.com> 5 + * 6 + * Copyright 2016 NXP Semiconductor 7 + * 8 + * Derived from mpc85xx_edac.c 9 + * Author: Dave Jiang <djiang@mvista.com> 10 + * 11 + * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under 12 + * the terms of the GNU General Public License version 2. This program 13 + * is licensed "as is" without any warranty of any kind, whether express 14 + * or implied. 15 + */ 16 + 17 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 + 19 + #include "edac_core.h" 20 + #include "fsl_ddr_edac.h" 21 + 22 + static const struct of_device_id fsl_ddr_mc_err_of_match[] = { 23 + { .compatible = "fsl,qoriq-memory-controller", }, 24 + {}, 25 + }; 26 + MODULE_DEVICE_TABLE(of, fsl_ddr_mc_err_of_match); 27 + 28 + static struct platform_driver fsl_ddr_mc_err_driver = { 29 + .probe = fsl_mc_err_probe, 30 + .remove = fsl_mc_err_remove, 31 + .driver = { 32 + .name = "fsl_ddr_mc_err", 33 + .of_match_table = fsl_ddr_mc_err_of_match, 34 + }, 35 + }; 36 + 37 + static int __init fsl_ddr_mc_init(void) 38 + { 39 + int res; 40 + 41 + /* make sure error reporting method is sane */ 42 + switch (edac_op_state) { 43 + case EDAC_OPSTATE_POLL: 44 + case EDAC_OPSTATE_INT: 45 + break; 46 + default: 47 + edac_op_state = EDAC_OPSTATE_INT; 48 + break; 49 + } 50 + 51 + res = platform_driver_register(&fsl_ddr_mc_err_driver); 52 + if (res) { 53 + pr_err("MC fails to register\n"); 54 + return res; 55 + } 56 + 57 + return 0; 58 + } 59 + 60 + module_init(fsl_ddr_mc_init); 61 + 62 + static void __exit fsl_ddr_mc_exit(void) 63 + { 64 + platform_driver_unregister(&fsl_ddr_mc_err_driver); 65 + } 66 + 67 + module_exit(fsl_ddr_mc_exit); 68 + 69 + MODULE_LICENSE("GPL"); 70 + MODULE_AUTHOR("NXP Semiconductor"); 71 + module_param(edac_op_state, int, 0444); 72 + MODULE_PARM_DESC(edac_op_state, 73 + "EDAC Error Reporting state: 0=Poll, 2=Interrupt");