From: Marek Majtyka <marekx.majt...@intel.com>

 Added cache L1/L2/L3, SMEM and CMEM drivers.
 Added linux style debug CMEM option.
 Changes:
  - added dtsi/dts definition for XLF board
  - separated configuration between X9 and XLF
  - fix issue with nca ring access
  - added tracepoints for L3 cache
  - other small code adjustments.
  - changed from CMEM debug local define to Kconfig parameter

Signed-off-by: Marek Majtyka <marekx.majt...@intel.com>
---
 .../devicetree/bindings/arm/axxia/edac_l1.txt      |  15 +++
 .../devicetree/bindings/arm/axxia/edac_l2.txt      |   5 +-
 .../devicetree/bindings/arm/axxia/edac_l3.txt      |  11 +-
 arch/arm64/boot/dts/intel/axc6732-waco.dts         |  32 +++++
 arch/arm64/boot/dts/intel/axc67xx.dtsi             |  68 +++++++++++
 drivers/edac/Kconfig                               |  45 ++++++-
 drivers/edac/Makefile                              |   4 +
 drivers/edac/axxia_edac-cmc_56xx.c                 | 135 +++++++++++++++++----
 drivers/edac/axxia_edac-l2_cpu_56xx.c              |  98 ++++++++++-----
 drivers/edac/axxia_edac-l3_56xx.c                  |  94 ++++++++++----
 drivers/edac/axxia_edac-mc_56xx.c                  |  35 +++---
 drivers/edac/edac_core.h                           |   7 ++
 drivers/edac/edac_device.c                         |  97 ++++++++++++++-
 drivers/misc/lsi-ncr.c                             |   4 +-
 include/trace/events/edac.h                        |  77 ++++++++++++
 include/trace/events/edacl3.h                      | 109 +++++++++++++++++
 16 files changed, 740 insertions(+), 96 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/axxia/edac_l1.txt
 create mode 100644 include/trace/events/edac.h
 create mode 100644 include/trace/events/edacl3.h

diff --git a/Documentation/devicetree/bindings/arm/axxia/edac_l1.txt 
b/Documentation/devicetree/bindings/arm/axxia/edac_l1.txt
new file mode 100644
index 0000000..5e0a8dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/axxia/edac_l1.txt
@@ -0,0 +1,15 @@
+Axxia Error Detection & Correction [EDAC]
+The EDAC accesses ARM v7/v8 L2MERRSR_EL1 register data.
+
+Required properties:
+- compatible   : should contain "intel,cortex-a53-cpu" for AXM67xx
+               : should contain "intel,cortex-a57-cpu" for AXM56xx
+               : should contain "lsi,cortex-a15-cpu" for AXM55xx
+- syscon       : should referernce syscon node for both 55xx/56xx/67xx
+
+Example:
+       edac_l2: edac_l2 {
+               compatible = "intel,cortex-a57-cpu";
+               syscon = <&syscon>;
+               status = "disabled";
+       };
diff --git a/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt 
b/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt
index d90629c..b99e77a 100644
--- a/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt
+++ b/Documentation/devicetree/bindings/arm/axxia/edac_l2.txt
@@ -2,9 +2,10 @@ Axxia Error Detection & Correction [EDAC]
 The EDAC accesses ARM v7/v8 L2MERRSR_EL1 register data.
 
 Required properties:
-- compatible   : should contain "intel,cortex-a57-l2-cache" for AXM56xx
+- compatible   : should contain "intel,cortex-a53-l2-cache" for AXM67xx
+               : should contain "intel,cortex-a57-l2-cache" for AXM56xx
                : should contain "lsi,cortex-a15-l2-cache" for AXM55xx
-- syscon       : should referernce syscon node for both 55xx/56xx
+- syscon       : should referernce syscon node for both 55xx/56xx/67xx
 
 Example:
        edac_l2: edac_l2 {
diff --git a/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt 
b/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt
index e37b5b8..5b80f21 100644
--- a/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt
+++ b/Documentation/devicetree/bindings/arm/axxia/edac_l3.txt
@@ -2,7 +2,8 @@ Axxia Error Detection & Correction [EDAC]
 The EDAC accesses a range of registers in the dickens l3 controller
 
 Required properties:
-- compatible : should contain "intel,ccn504-l3-cache"
+- compatible   : should contain "intel,ccn504-l3-cache"
+               : should contain "intel,ccn512-l3-cache"
 - reg : should contain address of ccn first node; its range shall contain
        all ccn nodes registers ( 0x1000000 ).
 - interrupts : if given driver uses interrupts, if not poll mechanism applies
@@ -15,3 +16,11 @@ Example:
                syscon = <&syscon>;
                status = "disabled";
        };
+
+       edac_l3: edac_l3 {
+               compatible = "intel,ccn512-l3-cache";
+               reg = <0x40 0x00000000 0 0x1000000>;
+               interrupts = <0 432 4>;
+               syscon = <&syscon>;
+               status = "disabled";
+       };
diff --git a/arch/arm64/boot/dts/intel/axc6732-waco.dts 
b/arch/arm64/boot/dts/intel/axc6732-waco.dts
index 9208bab..93ef965 100644
--- a/arch/arm64/boot/dts/intel/axc6732-waco.dts
+++ b/arch/arm64/boot/dts/intel/axc6732-waco.dts
@@ -251,6 +251,18 @@
        status = "okay";
 };
 
+&edac_cpu {
+       status = "okay";
+};
+
+&edac_l2 {
+       status = "okay";
+};
+
+&edac_l3 {
+       status = "okay";
+};
+
 &mtc {
        status = "okay";
 };
@@ -258,3 +270,23 @@
 &trng {
        status = "okay";
 };
+
+&sm0 {
+       status = "okay";
+};
+
+&sm1 {
+       status = "okay";
+};
+
+&sm2 {
+       status = "okay";
+};
+
+&sm3 {
+       status = "okay";
+};
+
+&cm0 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/intel/axc67xx.dtsi 
b/arch/arm64/boot/dts/intel/axc67xx.dtsi
index 8370a1c..d4d3171 100644
--- a/arch/arm64/boot/dts/intel/axc67xx.dtsi
+++ b/arch/arm64/boot/dts/intel/axc67xx.dtsi
@@ -49,6 +49,14 @@
                spi2      = &spi2;
                gpdma0    = &gpdma0;
                gpdma1    = &gpdma1;
+               edac_cpu  = &edac_cpu;
+               edac_l2  = &edac_l2;
+               edac_l3  = &edac_l3;
+               sm0       = &sm0;
+               sm1       = &sm1;
+               sm2       = &sm2;
+               sm3       = &sm3;
+               cm0       = &cm0;
        };
 
        clocks {
@@ -104,6 +112,26 @@
                        reg = <0x80 0x02c00000 0 0x40000>;
                };
 
+               edac_cpu: edac_cpu {
+                       compatible = "intel,cortex-a53-cpu";
+                       syscon = <&syscon>;
+                       status = "disabled";
+               };
+
+               edac_l2: edac_l2 {
+                       compatible = "intel,cortex-a53-l2-cache";
+                       syscon = <&syscon>;
+                       status = "disabled";
+               };
+
+               edac_l3: edac_l3 {
+                       compatible = "intel,ccn512-l3-cache";
+                       reg = <0x40 0x00000000 0 0x1000000>;
+                       interrupts = <0 432 4>;
+                       syscon = <&syscon>;
+                       status = "disabled";
+               };
+
                reset: reset@2010031000 {
                        compatible = "intel,axm56xx-reset";
                        syscon = <&syscon>;
@@ -135,6 +163,46 @@
                        status = "disabled";
                };
 
+               sm0: sm0@00220000 {
+                       compatible = "intel,smmon";
+                       reg = <0 0x00220000 0 0x1000>;
+                       syscon = <&syscon>;
+                       interrupts = <0 451 4>;
+                       status = "disabled";
+               };
+
+               sm1: sm1@000f0000 {
+                       compatible = "intel,smmon";
+                       reg = <0 0x000f0000 0 0x1000>;
+                       syscon = <&syscon>;
+                       interrupts = <0 452 4>;
+                       status = "disabled";
+               };
+
+               sm2: sm2@00230000 {
+                       compatible = "intel,smmon";
+                       reg = <0 0x00230000 0 0x1000>;
+                       syscon = <&syscon>;
+                       interrupts = <0 453 4>;
+                       status = "disabled";
+               };
+
+               sm3: sm3@00240000 {
+                       compatible = "intel,smmon";
+                       reg = <0 0x00240000 0 0x1000>;
+                       syscon = <&syscon>;
+                       interrupts = <0 454 4>;
+                       status = "disabled";
+               };
+
+               cm0: cm0@00080009 {
+                       compatible = "intel,cmmon";
+                       reg = <0 0x00080009 0 0x1000>;
+                       syscon = <&syscon>;
+                       interrupts = <0 386 4>;
+                       status = "disabled";
+               };
+
                usb0: usb@9000000000 {
                        compatible = "intel,axxia-dwc3";
                        dma-coherent;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index fb10774..aa91dda 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -400,6 +400,15 @@ config EDAC_AXXIA_SYSMEM_5500
          the System Memory error detection. System Memory error
          detection is interrupt driven.
 
+config EDAC_AXXIA_SYSMEM_6700
+       depends on ARCH_AXXIA
+       bool "AXXIA EDAC SysMem Controller for 6700"
+       help
+         Support for System Memory Denali controller error
+         detection on the AXXIA AXM67xx devices. This enables
+         the System Memory error detection. System Memory error
+         detection is interrupt driven.
+
 config EDAC_AXXIA_CMEM_5600
        depends on ARCH_AXXIA
        bool "AXXIA EDAC CMem Controller for 5600"
@@ -409,6 +418,24 @@ config EDAC_AXXIA_CMEM_5600
          the Configuration Memory error detection. Configuration Memory error
          detection is interrupt driven.
 
+config EDAC_AXXIA_CMEM_6700
+       depends on ARCH_AXXIA
+       bool "AXXIA EDAC CMem Controller for 6700"
+       help
+         Support for Configuration Memory Denali controller error
+         detection on the AXXIA AXM67xx devices. This enables
+         the Configuration Memory error detection. Configuration Memory error
+         detection is interrupt driven.
+
+config DEBUG_EDAC_AXXIA_CMEM
+       depends on ARCH_AXXIA
+       bool "AXXIA EDAC CMEM error injection interface."
+       help
+         Support for configuration of CMEM edac error injection functionality.
+         It works for both 5600 and 6700 board families.
+         Enables error injection functionality for CMEM over procfs
+         interface (/proc/driver/).
+
 config EDAC_AXXIA_L3_5500
        tristate "AXXIA EDAC L3 Controller for 5500"
        help
@@ -421,10 +448,18 @@ config EDAC_AXXIA_L3_5600
        tristate "AXXIA EDAC L3 Controller for 5600"
        help
          Support for the eight L3 caches error detection
-         on the AXXIA AXM55xx devices. This enables the
+         on the AXXIA AXM56xx devices. This enables the
          L3 cache error detection. L3 cache error detection
          uses polling mechanism.
 
+config EDAC_AXXIA_L3_6700
+       tristate "AXXIA EDAC L3 Controller for 6700"
+       help
+         Support for the eight L3 caches error detection
+         on the AXXIA AXM67xx devices. This enables the
+         L3 cache error detection. L3 cache error detection
+         can use polling mechanism or be interrupt driven.
+
 config EDAC_AXXIA_L2_CPU_5500
        tristate "AXXIA EDAC L2/CPU Controller for 5500"
        help
@@ -441,6 +476,14 @@ config EDAC_AXXIA_L2_CPU_5600
          cache and A57 CPU error detction. L2 cache and A57
          CPU error detection uses polling mechanism.
 
+config EDAC_AXXIA_L2_CPU_6700
+       tristate "AXXIA EDAC L2/CPU Controller for 6700"
+       help
+         Support for L2 cache and A53 CPU error detection
+         on AXXIA AXM67xx devices. This enables the L2
+         cache and A53 CPU error detction. L2 cache and A53
+         CPU error detection uses polling mechanism.
+
 config EDAC_ALTERA
        bool "Altera SOCFPGA ECC"
        depends on EDAC_MM_EDAC=y && ARCH_SOCFPGA
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index c545959..5209c9a 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -20,11 +20,15 @@ endif
 
 obj-$(CONFIG_EDAC_AXXIA_SYSMEM_5500)   += axxia_edac-mc.o
 obj-$(CONFIG_EDAC_AXXIA_SYSMEM_5600)   += axxia_edac-mc_56xx.o
+obj-$(CONFIG_EDAC_AXXIA_SYSMEM_6700)   += axxia_edac-mc_56xx.o
 obj-$(CONFIG_EDAC_AXXIA_CMEM_5600)     += axxia_edac-cmc_56xx.o
+obj-$(CONFIG_EDAC_AXXIA_CMEM_6700)     += axxia_edac-cmc_56xx.o
 obj-$(CONFIG_EDAC_AXXIA_L3_5500)       += axxia_edac-l3.o
 obj-$(CONFIG_EDAC_AXXIA_L3_5600)       += axxia_edac-l3_56xx.o
+obj-$(CONFIG_EDAC_AXXIA_L3_6700)       += axxia_edac-l3_56xx.o
 obj-$(CONFIG_EDAC_AXXIA_L2_CPU_5500)   += axxia_edac-l2_cpu.o
 obj-$(CONFIG_EDAC_AXXIA_L2_CPU_5600)   += axxia_edac-l2_cpu_56xx.o
+obj-$(CONFIG_EDAC_AXXIA_L2_CPU_6700)   += axxia_edac-l2_cpu_56xx.o
 obj-$(CONFIG_EDAC_GHES)                        += ghes_edac.o
 
 edac_mce_amd-y                         := mce_amd.o
diff --git a/drivers/edac/axxia_edac-cmc_56xx.c 
b/drivers/edac/axxia_edac-cmc_56xx.c
index c4bf2d0..11c650af 100644
--- a/drivers/edac/axxia_edac-cmc_56xx.c
+++ b/drivers/edac/axxia_edac-cmc_56xx.c
@@ -39,7 +39,13 @@
 #define MPR_HDR2       "Lp.    dram0      dram1"
 #define MPR_HDR4       "      dram2      dram3"
 
-#define INTEL_EDAC_MOD_STR     "axxia56xx_edac"
+#if defined(CONFIG_EDAC_AXXIA_CMEM_5600)
+#define INTEL_EDAC_MOD_STR     "axxia56xx_edac"
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_CMEM_6700)
+#define INTEL_EDAC_MOD_STR     "axxia67xx_edac"
+#endif
 
 #define AXI2_SER3_PHY_ADDR     0x008002c00000ULL
 #define AXI2_SER3_PHY_SIZE     PAGE_SIZE
@@ -286,6 +292,31 @@ struct __packed cm_56xx_denali_ctl_34
 #endif
 };
 
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
+
+#define CM_56XX_DENALI_CTL_62 0xf8
+
+struct __packed cm_56xx_denali_ctl_62
+{
+#ifdef CPU_BIG_ENDIAN
+       unsigned        reserved0                               : 2;
+       unsigned        xor_check_bits                          : 14;
+       unsigned        reserved1                               : 7;
+       unsigned        fwc                                     : 1;
+       unsigned        reserved2                               : 7;
+       unsigned        ecc_en                                  : 1;
+#else  /* Little Endian */
+       unsigned        ecc_en                                  : 1;
+       unsigned        reserved2                               : 7;
+       unsigned        fwc                                     : 1;
+       unsigned        reserved1                               : 7;
+       unsigned        xor_check_bits                          : 14;
+       unsigned        reserved0                               : 2;
+#endif
+};
+
+#endif
+
 struct __packed cm_56xx_denali_ctl_74
 {
 #ifdef CPU_BIG_ENDIAN
@@ -455,7 +486,7 @@ struct intel_edac_dev_info {
        char *ctl_name;
        char *blk_name;
        char *proc_name;
-#ifdef CONFIG_DEBUG_CMEM
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
        struct proc_dir_entry *dir_entry;
 #endif
        struct mutex state_machine_lock;
@@ -475,7 +506,48 @@ struct intel_edac_dev_info {
        void (*check)(struct edac_device_ctl_info *edac_dev);
 };
 
-#ifdef CONFIG_DEBUG_CMEM
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
+static int setup_fault_injection(struct intel_edac_dev_info *dev_info,
+                                       int fault, int enable)
+{
+       struct cm_56xx_denali_ctl_62 denali_ctl_62;
+
+       if (ncr_read(dev_info->cm_region,
+               CM_56XX_DENALI_CTL_62,
+               4, &denali_ctl_62))
+               goto error_read;
+
+       denali_ctl_62.xor_check_bits = fault;
+
+       if (ncr_write(dev_info->cm_region,
+               CM_56XX_DENALI_CTL_62,
+               4, (u32 *) &denali_ctl_62))
+               goto error_write;
+
+       if (ncr_read(dev_info->cm_region,
+               CM_56XX_DENALI_CTL_62,
+               4, &denali_ctl_62))
+               goto error_read;
+
+       denali_ctl_62.fwc = (enable > 0 ? 0x1 : 0x0);
+
+       if (ncr_write(dev_info->cm_region,
+               CM_56XX_DENALI_CTL_62,
+               4, (u32 *) &denali_ctl_62))
+               goto error_write;
+       return 0;
+
+error_read:
+       printk_ratelimited("%s: Error reading denali_ctl_62\n",
+                      dev_name(&dev_info->pdev->dev));
+       return 1;
+
+error_write:
+       printk_ratelimited("%s: Error writing denali_ctl_62\n",
+                      dev_name(&dev_info->pdev->dev));
+       return 1;
+}
+
 static ssize_t mpr1_dump_show(struct edac_device_ctl_info
                                 *edac_dev, char *data)
 {
@@ -832,7 +904,7 @@ static void intel_cm_alerts_error_check(struct 
edac_device_ctl_info *edac_dev)
        struct event_counter (*alerts)[MAX_DQ][MPR_ERRORS] =
                        dev_info->data->alerts;
        struct cm_56xx_denali_ctl_34 denali_ctl_34;
-       int i, j, k, l, ret;
+       int i, j, k, ret;
        u32 counter;
 
 start:
@@ -894,10 +966,10 @@ static void intel_cm_alerts_error_check(struct 
edac_device_ctl_info *edac_dev)
                                 */
                                counter = atomic_xchg(&alerts[i][j][k].counter,
                                                        0);
-                               for (l = 0; l < counter; ++l)
-                                       edac_device_handle_ce(edac_dev, 0,
+                               if (counter)
+                                       edac_device_handle_multi_ce(edac_dev, 0,
                                                alerts[i][j][k].edac_block_idx,
-                                               edac_dev->ctl_name);
+                                               counter, edac_dev->ctl_name);
                        }
                }
        }
@@ -927,7 +999,7 @@ static void intel_cm_events_error_check(struct 
edac_device_ctl_info *edac_dev)
        struct intel_edac_dev_info *dev_info =
                        (struct intel_edac_dev_info *) edac_dev->pvt_info;
        struct event_counter *events = dev_info->data->events;
-       int i, j;
+       int i;
        u32 counter;
 
        while (1) {
@@ -944,7 +1016,7 @@ static void intel_cm_events_error_check(struct 
edac_device_ctl_info *edac_dev)
                mutex_lock(&dev_info->data->edac_sysfs_data_lock);
                for (i = 0; i < NR_EVENTS; ++i) {
                        counter = atomic_xchg(&events[i].counter, 0);
-                       for (j = 0; j < counter; ++j) {
+                       if (counter)
                                switch (i) {
                                /*
                                 * TODO - How can one determine event type?
@@ -954,22 +1026,23 @@ static void intel_cm_events_error_check(struct 
edac_device_ctl_info *edac_dev)
                                case EV_MULT_ILLEGAL:
                                case EV_UNCORR_ECC:
                                case EV_MULT_UNCORR_ECC:
-                                       edac_device_handle_ue(edac_dev, 0, i,
-                                                       edac_dev->ctl_name);
+                                       edac_device_handle_multi_ue(edac_dev,
+                                               0, i, counter,
+                                               edac_dev->ctl_name);
                                        break;
                                case EV_CORR_ECC:
                                case EV_MULT_CORR_ECC:
                                case EV_PORT_ERROR:
                                case EV_WRAP_ERROR:
                                case EV_PARITY_ERROR:
-                                       edac_device_handle_ce(edac_dev, 0, i,
-                                                       edac_dev->ctl_name);
+                                       edac_device_handle_multi_ce(edac_dev,
+                                               0, i, counter,
+                                               edac_dev->ctl_name);
                                        break;
                                default:
                                        printk_ratelimited(
                                                "ERROR EVENT MISSING.\n");
                                }
-                       }
                }
                mutex_unlock(&dev_info->data->edac_sysfs_data_lock);
        }
@@ -1209,7 +1282,7 @@ static int initialize(struct intel_edac_dev_info 
*dev_info)
        dev_info->edac_dev->dev_name = dev_name(&dev_info->pdev->dev);
        dev_info->edac_dev->edac_check = NULL;
 
-#ifdef CONFIG_DEBUG_CMEM
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
        if (dev_info->is_ddr4)
                axxia_mc_sysfs_attributes(dev_info->edac_dev);
 #endif
@@ -1311,7 +1384,7 @@ static int enable_driver_irq(struct intel_edac_dev_info 
*dev_info)
 }
 
 
-#ifdef CONFIG_DEBUG_CMEM
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
 static ssize_t
 axxia_cmem_read(struct file *filp, char *buffer, size_t length, loff_t *offset)
 {
@@ -1323,7 +1396,7 @@ axxia_cmem_read(struct file *filp, char *buffer, size_t 
length, loff_t *offset)
        if (*offset > 0)
                return 0;
 
-       buf = kmalloc(PAGE_SIZE, __GFP_WAIT);
+       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
        if (buf == NULL)
                goto no_mem_buffer;
 
@@ -1335,7 +1408,15 @@ axxia_cmem_read(struct file *filp, char *buffer, size_t 
length, loff_t *offset)
         */
        len = snprintf(buf, PAGE_SIZE-1, "Node: 0x%x\n"
                "Command available:\n"
-               "          dump - triggers mpr_page1 dump.\n",
+               "          dump - triggers mpr_page1 dump.\n"
+               "          cerror - enable correctable error injection.\n"
+               "          uerror - enable uncorrectable error injection.\n"
+               "          disable - disable errors injection\n"
+               " When error is enabled run a sequence:\n"
+               "  ncpWrite -w 32 0x%x.0x0.0x4 0x11223344\n"
+               "  ncpRead 0x%x.0x0.0x4\n",
+               (int) dev_info->cm_region >> 16,
+               (int) dev_info->cm_region >> 16,
                (int) dev_info->cm_region >> 16);
 
        mutex_unlock(&dev_info->state_machine_lock);
@@ -1361,7 +1442,7 @@ axxia_cmem_write(struct file *file, const char __user 
*buffer,
        struct intel_edac_dev_info *dev_info =
                (struct intel_edac_dev_info *) file->private_data;
 
-       buf = kmalloc(count + 1, __GFP_WAIT);
+       buf = kmalloc(count + 1, GFP_KERNEL);
        if (buf == NULL)
                goto no_mem_buffer;
 
@@ -1376,6 +1457,18 @@ axxia_cmem_write(struct file *file, const char __user 
*buffer,
                atomic_inc(&dev_info->data->dump_in_progress);
                wake_up(&dev_info->data->dump_wq);
        }
+       if (!strncmp(buf, "cerror", 6)) {
+               /* 0x75 0x75 */
+               setup_fault_injection(dev_info, 0x3af5, 1);
+       }
+       if (!strncmp(buf, "uerror", 6)) {
+               /* 0x3 0x3 */
+               setup_fault_injection(dev_info, 0x183, 1);
+       }
+       if (!strncmp(buf, "disable", 7)) {
+               /* disable injection */
+               setup_fault_injection(dev_info, 0x0, 0);
+       }
 
        kfree(buf);
        return count;
@@ -1548,7 +1641,7 @@ static int intel_edac_mc_probe(struct platform_device 
*pdev)
                        dev_name(&dev_info->pdev->dev));
        }
 
-#ifdef CONFIG_DEBUG_CMEM
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
        /* in this case create procfs file to be used by rte */
        dev_info->proc_name =
                devm_kzalloc(&pdev->dev, 32*sizeof(char),
@@ -1599,7 +1692,7 @@ static int intel_edac_mc_remove(struct platform_device 
*pdev)
                (struct intel_edac_dev_info *) &pdev->dev;
 
        if (dev_info) {
-#ifdef CONFIG_DEBUG_CMEM
+#ifdef CONFIG_DEBUG_EDAC_AXXIA_CMEM
                remove_procfs_entry(dev_info);
 #endif
 
diff --git a/drivers/edac/axxia_edac-l2_cpu_56xx.c 
b/drivers/edac/axxia_edac-l2_cpu_56xx.c
index 4b5f6bf..3248384 100644
--- a/drivers/edac/axxia_edac-l2_cpu_56xx.c
+++ b/drivers/edac/axxia_edac-l2_cpu_56xx.c
@@ -9,6 +9,8 @@
  * GNU General Public License.
  */
 
+#define CREATE_TRACE_POINTS
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -22,12 +24,20 @@
 #include <linux/reboot.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <trace/events/edac.h>
 #include "edac_core.h"
 #include "edac_module.h"
 #include "axxia_l2_56xx.h"
 
 
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600)
 #define INTEL_EDAC_MOD_STR     "axxia56xx_edac"
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700)
+#define INTEL_EDAC_MOD_STR     "axxia67xx_edac"
+#endif
+
 #define CORES_PER_CLUSTER 4
 
 #define SYSCON_PERSIST_SCRATCH 0xdc
@@ -50,38 +60,41 @@ void log_cpumerrsr(void *edac)
        struct edac_device_ctl_info *edac_dev = edac;
        u64 val, clear_val;
        u32 count0, count1;
-       int i;
        struct intel_edac_dev_info *dev_info;
 
        dev_info = edac_dev->pvt_info;
 
        /* Read S3_1_c15_c2_2 for CPUMERRSR_EL1 counts */
        val = read_cpumerrsr();
+       trace_edac_l1cache_syndrome(val);
+
+       if (val & 0x8000000000000000) {
+               regmap_update_bits(dev_info->syscon,
+                                  SYSCON_PERSIST_SCRATCH,
+                                  CPU_PERSIST_SCRATCH_BIT,
+                                  CPU_PERSIST_SCRATCH_BIT);
+               pr_emerg("CPU uncorrectable error\n");
+               machine_restart(NULL);
+       }
+
        if (val & 0x80000000) {
                int cpu = get_cpu();
 
-               count0 = ((val) & 0x000000ff00000000) >> 31;
-               count1 = ((val) & 0x0000ff0000000000) >> 39;
+               count0 = ((val) & 0x000000ff00000000) >> 32;
+               count1 = ((val) & 0x0000ff0000000000) >> 40;
 
                /* increment correctable error counts */
-               for (i = 0; i < count0+count1; i++) {
-                       edac_device_handle_ce(edac_dev, 0,
-                               cpu, edac_dev->ctl_name);
-               }
+               trace_edac_l1cache_counter(count0 + count1);
+
+               if (count0 || count1)
+                       edac_device_handle_multi_ce(edac_dev, 0, cpu,
+                               count0 + count1, edac_dev->ctl_name);
 
                /* Clear the valid bit */
                clear_val = 0x80000000;
                write_cpumerrsr(clear_val);
                put_cpu();
        }
-       if (val & 0x8000000000000000) {
-               regmap_update_bits(dev_info->syscon,
-                                  SYSCON_PERSIST_SCRATCH,
-                                  CPU_PERSIST_SCRATCH_BIT,
-                                  CPU_PERSIST_SCRATCH_BIT);
-               pr_emerg("CPU uncorrectable error\n");
-               machine_restart(NULL);
-       }
 }
 
 
@@ -101,38 +114,38 @@ void log_l2merrsr(void *edac)
        struct edac_device_ctl_info *edac_dev = edac;
        u64 val, clear_val;
        u32 count0, count1;
-       int i;
        struct intel_edac_dev_info *dev_info;
 
        dev_info = edac_dev->pvt_info;
 
        val = read_l2merrsr();
+       trace_edac_l2cache_syndrome(val);
+       if (val & 0x8000000000000000) {
+               regmap_update_bits(dev_info->syscon,
+                                  SYSCON_PERSIST_SCRATCH,
+                                  L2_PERSIST_SCRATCH_BIT,
+                                  L2_PERSIST_SCRATCH_BIT);
+               pr_emerg("L2 uncorrectable error\n");
+               machine_restart(NULL);
+       }
        if (val & 0x80000000) {
                int cpu = get_cpu();
 
-               count0 = ((val) & 0x000000ff00000000) >> 31;
-               count1 = ((val) & 0x0000ff0000000000) >> 39;
+               count0 = ((val) & 0x000000ff00000000) >> 32;
+               count1 = ((val) & 0x0000ff0000000000) >> 40;
 
                /* increment correctable error counts */
-               for (i = 0; i < count0+count1; i++) {
-                       edac_device_handle_ce(edac_dev, 0,
+               trace_edac_l2cache_counter(count0 + count1);
+               if (count0 || count1)
+                       edac_device_handle_multi_ce(edac_dev, 0,
                                cpu/CORES_PER_CLUSTER,
-                               edac_dev->ctl_name);
-               }
+                               count0 + count1, edac_dev->ctl_name);
 
                /* Clear the valid bit */
                clear_val = 0x80000000;
                write_l2merrsr(clear_val);
                put_cpu();
        }
-       if (val & 0x8000000000000000) {
-               regmap_update_bits(dev_info->syscon,
-                                  SYSCON_PERSIST_SCRATCH,
-                                  L2_PERSIST_SCRATCH_BIT,
-                                  L2_PERSIST_SCRATCH_BIT);
-               pr_emerg("L2 uncorrectable error\n");
-               machine_restart(NULL);
-       }
 }
 
 /* Check for L2 Errors */
@@ -262,9 +275,22 @@ static int intel_edac_l2_remove(struct platform_device 
*pdev)
 }
 
 static const struct of_device_id intel_edac_l2_match[] = {
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600)
+
        {
        .compatible = "intel,cortex-a57-l2-cache",
        },
+
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700)
+
+       {
+       .compatible = "intel,cortex-a53-l2-cache",
+       },
+
+#endif
+
        {},
 };
 
@@ -277,9 +303,21 @@ static struct platform_driver intel_edac_l2_driver = {
        }
 };
 static const struct of_device_id intel_edac_cpu_match[] = {
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600)
+
        {
        .compatible = "intel,cortex-a57-cpu",
        },
+
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700)
+
+       {
+       .compatible = "intel,cortex-a53-cpu",
+       },
+
+#endif
        {},
 };
 
diff --git a/drivers/edac/axxia_edac-l3_56xx.c 
b/drivers/edac/axxia_edac-l3_56xx.c
index fa9548b..af4ff16 100644
--- a/drivers/edac/axxia_edac-l3_56xx.c
+++ b/drivers/edac/axxia_edac-l3_56xx.c
@@ -2,12 +2,14 @@
  * drivers/edac/axxia_edac-l3_56xx.c
  *
  * EDAC Driver for Intel's Axxia 5600 L3 (DICKENS)
+ * EDAC Driver for Intel's Axxia 6700 L3 (SHELLEY)
  *
  * Copyright (C) 2017 Intel Inc.
  *
  * This file may be distributed under the terms of the
  * GNU General Public License.
  */
+#define CREATE_TRACE_POINTS
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -24,10 +26,21 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 #include <linux/arm-smccc.h>
+#include <trace/events/edacl3.h>
 #include "edac_core.h"
 #include "edac_module.h"
 
+#if defined(CONFIG_EDAC_AXXIA_L3_5600)
 #define INTEL_EDAC_MOD_STR     "axxia56xx_edac"
+#define CCN_XP_NODES                   11
+#define        CCN_HNI_NODES                   1
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_L3_6700)
+#define INTEL_EDAC_MOD_STR     "axxia67xx_edac"
+#define CCN_XP_NODES                   18
+#define        CCN_HNI_NODES                   2
+#endif
 
 #define SYSCON_PERSIST_SCRATCH 0xdc
 #define L3_PERSIST_SCRATCH_BIT (0x1 << 4)
@@ -55,7 +68,6 @@
 
 #define CCN_HNI_NODE_BIT               8
 #define CCN_HNF_NODES                  8
-#define CCN_XP_NODES                   11
 #define CCN_DT_NODE_BASE_ADDR          (1 * CCN_REGION_SIZE)
 #define CCN_HNI_NODE_BASE_ADDR(i)      (0x80000 + (i) * CCN_REGION_SIZE)
 #define CCN_HNF_NODE_BASE_ADDR(i)      (0x200000 + (i) * CCN_REGION_SIZE)
@@ -151,7 +163,7 @@ struct intel_edac_dev_info {
        int irq_used;
        struct event_data data[CCN_HNF_NODES];
        struct event_data data_xp[CCN_XP_NODES];
-       struct event_data data_hni;
+       struct event_data data_hni[CCN_HNI_NODES];
        struct regmap *syscon;
        void __iomem *dickens_L3;
        struct edac_device_ctl_info *edac_dev;
@@ -198,7 +210,7 @@ static irqreturn_t ccn_irq_thread(int irq, void *device)
        union dickens_hnf_err_syndrome_reg1 err_syndrome_reg1;
        struct arm_smccc_res r;
        unsigned int count = 0;
-       int i, j;
+       int i;
 
        /* only HNF nodes are of our interest */
        for (i = 0; i < CCN_HNF_NODES; ++i) {
@@ -222,10 +234,10 @@ static irqreturn_t ccn_irq_thread(int irq, void *device)
                                machine_restart(NULL);
                        }
                        count = err_syndrome_reg0.reg0.err_count;
-                       for (j = 0; j < count; j++)
-                               edac_device_handle_ce(edac_dev, 0,
+                       if (count)
+                               edac_device_handle_multi_ce(edac_dev, 0,
                                        dev_info->data[i].idx,
-                                       edac_dev->ctl_name);
+                                       count, edac_dev->ctl_name);
                }
        }
 
@@ -233,6 +245,8 @@ static irqreturn_t ccn_irq_thread(int irq, void *device)
        arm_smccc_smc(0xc4000027, CCN_MN_ERRINT_STATUS__INTREQ__DESSERT,
                        0, 0, 0, 0, 0, 0, &r);
 
+       trace_edacl3_smc_results(&r);
+
        return IRQ_HANDLED;
 }
 
@@ -262,24 +276,37 @@ static irqreturn_t ccn_irq_handler(int irq, void *device)
                err_or |= err_sig_val[i];
        }
 
-       err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE);
-       err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x8);
-       err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x10);
-       err_type_value[i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x20);
+       trace_edacl3_sig_vals(err_sig_val[0], err_sig_val[1],
+                               err_sig_val[2]);
+
+       i = 0;
+       err_type_value[i]   = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE);
+       err_type_value[++i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x8);
+       err_type_value[++i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x10);
+       err_type_value[++i] = readq(ccn_base + CCN_MN_ERROR_TYPE_VALUE + 0x20);
+
+       trace_edacl3_error_types(err_type_value[0], err_type_value[1],
+                                       err_type_value[2], err_type_value[3]);
 
        /* check hni node */
-       if ((0x1 << CCN_HNI_NODE_BIT) & err_sig_val[0]) {
-               err_synd_reg0 = readq(ccn_base + CCN_HNI_NODE_BASE_ADDR(0) +
+       for (i = 0; i < CCN_HNI_NODES; ++i) {
+               if ((0x1 << (CCN_HNI_NODE_BIT + i)) & err_sig_val[0]) {
+                       err_synd_reg0 = readq(ccn_base +
+                                       CCN_HNI_NODE_BASE_ADDR(i) +
                                        CCN_NODE_ERR_SYND_REG0);
-               err_synd_reg1 = readq(ccn_base + CCN_HNI_NODE_BASE_ADDR(0) +
+                       err_synd_reg1 = readq(ccn_base +
+                                       CCN_HNI_NODE_BASE_ADDR(i) +
                                        CCN_NODE_ERR_SYND_REG1);
 
-               dev_info->data_hni.err_synd_reg0 = err_synd_reg0;
-               dev_info->data_hni.err_synd_reg1 = err_synd_reg1;
-               dev_info->data_hni.idx = 0;
+                       trace_edacl3_syndromes(err_synd_reg0,
+                                                       err_synd_reg1);
+                       dev_info->data_hni[i].err_synd_reg0 = err_synd_reg0;
+                       dev_info->data_hni[i].err_synd_reg1 = err_synd_reg1;
+                       dev_info->data_hni[i].idx = 0;
 
-               clear_node_error(ccn_base + CCN_HNI_NODE_BASE_ADDR(0) +
-                                       CCN_NODE_ERR_SYND_CLR);
+                       clear_node_error(ccn_base + CCN_HNI_NODE_BASE_ADDR(i) +
+                                               CCN_NODE_ERR_SYND_CLR);
+               }
        }
 
        /* go through all hnf nodes */
@@ -293,6 +320,9 @@ static irqreturn_t ccn_irq_handler(int irq, void *device)
                                                CCN_HNF_NODE_BASE_ADDR(i) +
                                                CCN_NODE_ERR_SYND_REG1);
 
+                       trace_edacl3_syndromes(err_synd_reg0,
+                                                       err_synd_reg1);
+
                        dev_info->data[i].err_synd_reg0 = err_synd_reg0;
                        dev_info->data[i].err_synd_reg1 = err_synd_reg1;
                        dev_info->data[i].idx = i;
@@ -313,6 +343,9 @@ static irqreturn_t ccn_irq_handler(int irq, void *device)
                        dev_info->data_xp[i].err_synd_reg0 = err_synd_reg0;
                        dev_info->data_xp[i].err_synd_reg1 = 0;
 
+                       trace_edacl3_syndromes(err_synd_reg0,
+                                               err_synd_reg1);
+
                        clear_node_error(ccn_base + CCN_XP_NODE_BASE_ADDR(i) +
                                CCN_NODE_ERR_SYND_CLR);
                }
@@ -335,7 +368,7 @@ static void intel_l3_error_check(struct 
edac_device_ctl_info *edac_dev)
        union dickens_hnf_err_syndrome_reg0 err_syndrome_reg0;
        union dickens_hnf_err_syndrome_clr err_syndrome_clr;
        unsigned int count = 0;
-       int i, instance;
+       int instance;
        struct intel_edac_dev_info *dev_info;
 
        err_syndrome_clr.value = 0x0;
@@ -351,6 +384,9 @@ static void intel_l3_error_check(struct 
edac_device_ctl_info *edac_dev)
 
                err_syndrome_reg0.value =
                        readq(addr + CCN_NODE_ERR_SYND_REG0);
+
+               trace_edacl3_syndromes(err_syndrome_reg0.value,
+                                               (u64) 0);
                /* First error valid */
                if (err_syndrome_reg0.reg0.first_err_vld) {
                        if (err_syndrome_reg0.reg0.err_class & 0x3) {
@@ -363,9 +399,9 @@ static void intel_l3_error_check(struct 
edac_device_ctl_info *edac_dev)
                                machine_restart(NULL);
                        }
                        count = err_syndrome_reg0.reg0.err_count;
-                       for (i = 0; i < count; i++)
-                               edac_device_handle_ce(edac_dev, 0,
-                                       instance, edac_dev->ctl_name);
+                       if (count)
+                               edac_device_handle_multi_ce(edac_dev, 0,
+                                       instance, count, edac_dev->ctl_name);
 
                        /* clear the valid bit */
                        clear_node_error(addr + CCN_NODE_ERR_SYND_CLR);
@@ -413,7 +449,7 @@ static int intel_edac_l3_probe(struct platform_device *pdev)
        dev_info->edac_dev =
                edac_device_alloc_ctl_info(0, dev_info->ctl_name,
                                           1, dev_info->blk_name,
-                                          8, 0, NULL, 0,
+                                          CCN_HNI_NODES, 0, NULL, 0,
                                           dev_info->edac_idx);
        if (!dev_info->edac_dev) {
                pr_info("No memory for edac device\n");
@@ -478,9 +514,21 @@ static int intel_edac_l3_remove(struct platform_device 
*pdev)
 }
 
 static const struct of_device_id intel_edac_l3_match[] = {
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_5600)
+
        {
        .compatible = "intel,ccn504-l3-cache",
        },
+
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_L2_CPU_6700)
+
+       {
+       .compatible = "intel,ccn512-l3-cache",
+       },
+
+#endif
        {},
 };
 
diff --git a/drivers/edac/axxia_edac-mc_56xx.c 
b/drivers/edac/axxia_edac-mc_56xx.c
index fb1e742..fcc53bd 100644
--- a/drivers/edac/axxia_edac-mc_56xx.c
+++ b/drivers/edac/axxia_edac-mc_56xx.c
@@ -43,7 +43,13 @@
 #define MPR_HDR18      "      dram9     dram10     dram11     dram12"\
                "     dram13     dram14     dram15     dram16     dram17"
 
-#define INTEL_EDAC_MOD_STR     "axxia56xx_edac"
+#if defined(CONFIG_EDAC_AXXIA_SYSMEM_5600)
+#define INTEL_EDAC_MOD_STR     "axxia56xx_edac"
+#endif
+
+#if defined(CONFIG_EDAC_AXXIA_SYSMEM_6700)
+#define INTEL_EDAC_MOD_STR     "axxia67xx_edac"
+#endif
 
 #define AXI2_SER3_PHY_ADDR     0x008002c00000ULL
 #define AXI2_SER3_PHY_SIZE     PAGE_SIZE
@@ -995,7 +1001,7 @@ static void intel_sm_alerts_error_check(struct 
edac_device_ctl_info *edac_dev)
        struct event_counter (*alerts)[MAX_DQ][MPR_ERRORS] =
                        dev_info->data->alerts;
        struct sm_56xx_denali_ctl_57 denali_ctl_57;
-       int i, j, k, l;
+       int i, j, k;
        u32 counter;
 
 start:
@@ -1052,12 +1058,12 @@ static void intel_sm_alerts_error_check(struct 
edac_device_ctl_info *edac_dev)
                                 * TODO - How can one determine event type?
                                 *      recoverable/unrecoverable
                                 */
-                               counter = atomic_xchg(&alerts[i][j][k].counter,
-                                                       0);
-                               for (l = 0; l < counter; ++l)
-                                       edac_device_handle_ce(edac_dev, 0,
+                               counter = atomic_xchg(
+                                               &alerts[i][j][k].counter, 0);
+                               if (counter)
+                                       edac_device_handle_multi_ce(edac_dev, 0,
                                                alerts[i][j][k].edac_block_idx,
-                                               edac_dev->ctl_name);
+                                               counter, edac_dev->ctl_name);
                        }
                }
        }
@@ -1081,7 +1087,7 @@ static void intel_sm_events_error_check(struct 
edac_device_ctl_info *edac_dev)
        struct intel_edac_dev_info *dev_info =
                        (struct intel_edac_dev_info *) edac_dev->pvt_info;
        struct event_counter *events = dev_info->data->events;
-       int i, j;
+       int i;
        u32 counter;
 
        while (1) {
@@ -1098,7 +1104,7 @@ static void intel_sm_events_error_check(struct 
edac_device_ctl_info *edac_dev)
                mutex_lock(&dev_info->data->edac_sysfs_data_lock);
                for (i = 0; i < NR_EVENTS; ++i) {
                        counter = atomic_xchg(&events[i].counter, 0);
-                       for (j = 0; j < counter; ++j) {
+                       if (counter)
                                switch (i) {
                                /*
                                 * TODO - How can one determine event type?
@@ -1108,22 +1114,23 @@ static void intel_sm_events_error_check(struct 
edac_device_ctl_info *edac_dev)
                                case EV_MULT_ILLEGAL:
                                case EV_UNCORR_ECC:
                                case EV_MULT_UNCORR_ECC:
-                                       edac_device_handle_ue(edac_dev, 0, i,
-                                                       edac_dev->ctl_name);
+                                       edac_device_handle_multi_ue(edac_dev,
+                                               0, i, counter,
+                                               edac_dev->ctl_name);
                                        break;
                                case EV_CORR_ECC:
                                case EV_MULT_CORR_ECC:
                                case EV_PORT_ERROR:
                                case EV_WRAP_ERROR:
                                case EV_PARITY_ERROR:
-                                       edac_device_handle_ce(edac_dev, 0, i,
-                                                       edac_dev->ctl_name);
+                                       edac_device_handle_multi_ce(edac_dev,
+                                               0, i, counter,
+                                               edac_dev->ctl_name);
                                        break;
                                default:
                                        printk_ratelimited(
                                                "ERROR EVENT MISSING.\n");
                                }
-                       }
                }
                mutex_unlock(&dev_info->data->edac_sysfs_data_lock);
        }
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 4861542..e2d64e1 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -481,8 +481,15 @@ extern int edac_device_add_device(struct 
edac_device_ctl_info *edac_dev);
 extern struct edac_device_ctl_info *edac_device_del_device(struct device *dev);
 extern void edac_device_handle_ue(struct edac_device_ctl_info *edac_dev,
                                int inst_nr, int block_nr, const char *msg);
+extern void edac_device_handle_multi_ue(struct edac_device_ctl_info *edac_dev,
+                               int inst_nr, int block_nr, int events,
+                               const char *msg);
 extern void edac_device_handle_ce(struct edac_device_ctl_info *edac_dev,
                                int inst_nr, int block_nr, const char *msg);
+extern void edac_device_handle_multi_ce(struct edac_device_ctl_info *edac_dev,
+                               int inst_nr, int block_nr, int events,
+                               const char *msg);
+
 extern int edac_device_alloc_index(void);
 extern const char *edac_layer_name[];
 
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c
index a979003..0f735ce 100644
--- a/drivers/edac/edac_device.c
+++ b/drivers/edac/edac_device.c
@@ -25,7 +25,7 @@
 #include <linux/list.h>
 #include <linux/ctype.h>
 #include <linux/workqueue.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/page.h>
 
 #include "edac_core.h"
@@ -154,7 +154,7 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
        dev_ctl->log_ue = 1;
 
        /* Name of this edac device */
-       snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name);
+       snprintf(dev_ctl->name, sizeof(dev_ctl->name), "%s", edac_device_name);
 
        edac_dbg(4, "edac_dev=%p next after end=%p\n",
                 dev_ctl, pvt + sz_private);
@@ -655,6 +655,50 @@ void edac_device_handle_ce(struct edac_device_ctl_info 
*edac_dev,
 EXPORT_SYMBOL_GPL(edac_device_handle_ce);
 
 /*
+ * edac_device_handle_multi_ce
+ *     perform a common output and handling of an 'edac_dev' CE multiple events
+ */
+void edac_device_handle_multi_ce(struct edac_device_ctl_info *edac_dev,
+                       int inst_nr, int block_nr, int events, const char *msg)
+{
+       struct edac_device_instance *instance;
+       struct edac_device_block *block = NULL;
+
+       if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) {
+               edac_device_printk(edac_dev, KERN_ERR,
+                               "INTERNAL ERROR: 'instance' out of range (%d >= 
%d)\n",
+                               inst_nr, edac_dev->nr_instances);
+               return;
+       }
+
+       instance = edac_dev->instances + inst_nr;
+
+       if ((block_nr >= instance->nr_blocks) || (block_nr < 0)) {
+               edac_device_printk(edac_dev, KERN_ERR,
+                               "INTERNAL ERROR: instance %d 'block' out of 
range (%d >= %d)\n",
+                               inst_nr, block_nr,
+                               instance->nr_blocks);
+               return;
+       }
+
+       if (instance->nr_blocks > 0) {
+               block = instance->blocks + block_nr;
+               block->counters.ce_count += events;
+       }
+
+       /* Propagate the count up the 'totals' tree */
+       instance->counters.ce_count += events;
+       edac_dev->counters.ce_count += events;
+
+       if (edac_device_get_log_ce(edac_dev))
+               edac_device_printk(edac_dev, KERN_WARNING,
+                       "CE: %s instance: %s block: %s events: %d '%s'\n",
+                       edac_dev->ctl_name, instance->name,
+                       block ? block->name : "N/A", events, msg);
+}
+EXPORT_SYMBOL_GPL(edac_device_handle_multi_ce);
+
+/*
  * edac_device_handle_ue
  *     perform a common output and handling of an 'edac_dev' UE event
  */
@@ -704,3 +748,52 @@ void edac_device_handle_ue(struct edac_device_ctl_info 
*edac_dev,
                        block ? block->name : "N/A", msg);
 }
 EXPORT_SYMBOL_GPL(edac_device_handle_ue);
+
+/*
+ * edac_device_handle_multi_ue
+ *     perform a common output and handling of an 'edac_dev' UE event
+ */
+void edac_device_handle_multi_ue(struct edac_device_ctl_info *edac_dev,
+                       int inst_nr, int block_nr, int events, const char *msg)
+{
+       struct edac_device_instance *instance;
+       struct edac_device_block *block = NULL;
+
+       if ((inst_nr >= edac_dev->nr_instances) || (inst_nr < 0)) {
+               edac_device_printk(edac_dev, KERN_ERR,
+                               "INTERNAL ERROR: 'instance' out of range (%d >= 
%d)\n",
+                               inst_nr, edac_dev->nr_instances);
+               return;
+       }
+
+       instance = edac_dev->instances + inst_nr;
+
+       if ((block_nr >= instance->nr_blocks) || (block_nr < 0)) {
+               edac_device_printk(edac_dev, KERN_ERR,
+                               "INTERNAL ERROR: instance %d 'block' out of 
range (%d >= %d)\n",
+                               inst_nr, block_nr,
+                               instance->nr_blocks);
+               return;
+       }
+
+       if (instance->nr_blocks > 0) {
+               block = instance->blocks + block_nr;
+               block->counters.ue_count += events;
+       }
+
+       /* Propagate the count up the 'totals' tree */
+       instance->counters.ue_count += events;
+       edac_dev->counters.ue_count += events;
+
+       if (edac_device_get_log_ue(edac_dev))
+               edac_device_printk(edac_dev, KERN_EMERG,
+                       "UE: %s instance: %s block: %s events: %d '%s'\n",
+                       edac_dev->ctl_name, instance->name,
+                       block ? block->name : "N/A", events, msg);
+
+       if (edac_device_get_panic_on_ue(edac_dev))
+               panic("EDAC %s: UE instance: %s block %s events: %d '%s'\n",
+                       edac_dev->ctl_name, instance->name,
+                       block ? block->name : "N/A", events, msg);
+}
+EXPORT_SYMBOL_GPL(edac_device_handle_multi_ue);
diff --git a/drivers/misc/lsi-ncr.c b/drivers/misc/lsi-ncr.c
index d918ccb..a5fd0f3 100644
--- a/drivers/misc/lsi-ncr.c
+++ b/drivers/misc/lsi-ncr.c
@@ -172,8 +172,8 @@ ncr_register_write(const unsigned int value, unsigned int 
*address)
 
        if (0 == nca_big_endian)
                __raw_writel(value, address);
-
-       __raw_writel(cpu_to_be32(value), address);
+       else
+               __raw_writel(cpu_to_be32(value), address);
 }
 
 /*
diff --git a/include/trace/events/edac.h b/include/trace/events/edac.h
new file mode 100644
index 0000000..29da0d1
--- /dev/null
+++ b/include/trace/events/edac.h
@@ -0,0 +1,77 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM edac
+
+#if !defined(_TRACE_EDAC_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EDAC_H
+
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+
+TRACE_EVENT(edac_l2cache_syndrome,
+       TP_PROTO(u64 syndrome),
+
+       TP_ARGS(syndrome),
+
+       TP_STRUCT__entry(
+               __field(u64, syndrome)
+       ),
+
+       TP_fast_assign(
+               __entry->syndrome = syndrome;
+       ),
+
+       TP_printk("L2MERRSR_EL1=0x%016llx", (u64) __entry->syndrome)
+);
+
+TRACE_EVENT(edac_l2cache_counter,
+       TP_PROTO(int counter),
+
+       TP_ARGS(counter),
+
+       TP_STRUCT__entry(
+               __field(int, counter)
+       ),
+
+       TP_fast_assign(
+               __entry->counter = counter;
+       ),
+
+       TP_printk("l2 counter =%d",  __entry->counter)
+);
+
+TRACE_EVENT(edac_l1cache_syndrome,
+       TP_PROTO(u64 syndrome),
+
+       TP_ARGS(syndrome),
+
+       TP_STRUCT__entry(
+               __field(u64, syndrome)
+       ),
+
+       TP_fast_assign(
+               __entry->syndrome = syndrome;
+       ),
+
+       TP_printk("CPUMERRSR_EL1=0x%016llx", (u64) __entry->syndrome)
+);
+
+TRACE_EVENT(edac_l1cache_counter,
+       TP_PROTO(int counter),
+
+       TP_ARGS(counter),
+
+       TP_STRUCT__entry(
+               __field(int, counter)
+       ),
+
+       TP_fast_assign(
+               __entry->counter = counter;
+       ),
+
+       TP_printk("l1 counter =%d",  __entry->counter)
+);
+#endif /* _TRACE_EDAC_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/edacl3.h b/include/trace/events/edacl3.h
new file mode 100644
index 0000000..5b63278
--- /dev/null
+++ b/include/trace/events/edacl3.h
@@ -0,0 +1,109 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM edacl3
+
+#if !defined(_TRACE_EDACL3_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EDACL3_H
+
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+
+TRACE_EVENT(edacl3_error_types,
+       TP_PROTO(u64 error_31_0, u64 error_63_32,
+               u64 error_95_64, u64 error_159_128),
+
+       TP_ARGS(error_31_0, error_63_32, error_95_64, error_159_128),
+
+       TP_STRUCT__entry(
+               __field(u64, error_31_0)
+               __field(u64, error_63_32)
+               __field(u64, error_95_64)
+               __field(u64, error_159_128)
+       ),
+
+       TP_fast_assign(
+               __entry->error_31_0 = error_31_0;
+               __entry->error_63_32 = error_63_32;
+               __entry->error_95_64 = error_95_64;
+               __entry->error_159_128 = error_159_128;
+       ),
+
+       TP_printk("Err types(0-3):(0x%016llx, 0x%016llx, 0x%016llx, 0x%016llx)",
+               (u64) __entry->error_31_0, (u64) __entry->error_63_32,
+               (u64) __entry->error_95_64, (u64) __entry->error_159_128
+       )
+);
+
+TRACE_EVENT(edacl3_sig_vals,
+       TP_PROTO(u64 sig_val_63_0, u64 sig_val_127_64, u64 sig_val_191_128),
+
+       TP_ARGS(sig_val_63_0, sig_val_127_64, sig_val_191_128),
+
+       TP_STRUCT__entry(
+               __field(u64, sig_val_63_0)
+               __field(u64, sig_val_127_64)
+               __field(u64, sig_val_191_128)
+       ),
+
+       TP_fast_assign(
+               __entry->sig_val_63_0 = sig_val_63_0;
+               __entry->sig_val_127_64 = sig_val_127_64;
+               __entry->sig_val_191_128 = sig_val_191_128;
+       ),
+
+       TP_printk("Sig_val_regs(0-3):(0x%016llx, 0x%016llx, 0x%016llx)",
+               (u64) __entry->sig_val_63_0, (u64) __entry->sig_val_127_64,
+               (u64) __entry->sig_val_191_128
+       )
+);
+
+TRACE_EVENT(edacl3_syndromes,
+       TP_PROTO(u64 syndrome0, u64 syndrome1),
+
+       TP_ARGS(syndrome0, syndrome1),
+
+       TP_STRUCT__entry(
+               __field(u64, syndrome0)
+               __field(u64, syndrome1)
+       ),
+
+       TP_fast_assign(
+               __entry->syndrome0 = syndrome0;
+               __entry->syndrome1 = syndrome1;
+       ),
+
+       TP_printk("Syndromes(0-1):(0x%016llx, 0x%016llx)",
+               (u64) __entry->syndrome0, (u64) __entry->syndrome1
+       )
+);
+
+
+TRACE_EVENT(edacl3_smc_results,
+       TP_PROTO(struct arm_smccc_res *ptr),
+
+       TP_ARGS(ptr),
+
+       TP_STRUCT__entry(
+               __field(u64, a0)
+               __field(u64, a1)
+               __field(u64, a2)
+               __field(u64, a3)
+       ),
+
+       TP_fast_assign(
+               __entry->a0 = ptr->a0;
+               __entry->a1 = ptr->a1;
+               __entry->a2 = ptr->a2;
+               __entry->a3 = ptr->a3;
+       ),
+
+       TP_printk("Smc(a0-a3):(0x%llx, 0x%llx, 0x%llx, 0x%llx)",
+               (u64) __entry->a0, (u64) __entry->a1,
+               (u64) __entry->a2, (u64) __entry->a3
+       )
+);
+
+#endif /* _TRACE_EDACL3_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
2.7.4

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to