linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC
@ 2016-03-07 19:42 tthayer
  2016-03-07 19:42 ` [PATCHv2 01/11] EDAC: Altera L2 Kconfig change from select to depends upon tthayer
                   ` (10 more replies)
  0 siblings, 11 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:42 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

This version splits the larger patch in V1 into smaller,
patches.

 [PATCHv2 01/11] EDAC: Altera L2 Kconfig change from select to
 [PATCHv2 02/11] EDAC, altera: Move Device structs and defines to
 [PATCHv2 03/11] EDAC, altera: Add register offset for ECC Enable
 [PATCHv2 04/11] EDAC, altera: Add register offset for ECC Error
 [PATCHv2 05/11] EDAC, altera: Add register offset for ECC Error
 [PATCHv2 06/11] EDAC, altera: Add IRQ flags to private data struct
 [PATCHv2 07/11] EDAC, altera: Add status offset & masks
 [PATCHv2 08/11] Documentation: dt: socfpga: Add Altera Arria10 L2
 [PATCHv2 09/11] EDAC, altera: Addition of Arria10 L2 Cache ECC
 [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup
 [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCHv2 01/11] EDAC: Altera L2 Kconfig change from select to depends upon.
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
@ 2016-03-07 19:42 ` tthayer
  2016-03-07 19:42 ` [PATCHv2 02/11] EDAC, altera: Move Device structs and defines to header file tthayer
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:42 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

Force L2 cache dependency instead of forcing selection of
L2 cache.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2 No change
---
 drivers/edac/Kconfig |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 37755e6..6ca7474 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -378,12 +378,11 @@ config EDAC_ALTERA
 
 config EDAC_ALTERA_L2C
 	bool "Altera L2 Cache ECC"
-	depends on EDAC_ALTERA=y
-	select CACHE_L2X0
+	depends on EDAC_ALTERA=y && CACHE_L2X0
 	help
 	  Support for error detection and correction on the
 	  Altera L2 cache Memory for Altera SoCs. This option
-	  requires L2 cache so it will force that selection.
+	  requires L2 cache.
 
 config EDAC_ALTERA_OCRAM
 	bool "Altera On-Chip RAM ECC"
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 02/11] EDAC, altera: Move Device structs and defines to header file
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
  2016-03-07 19:42 ` [PATCHv2 01/11] EDAC: Altera L2 Kconfig change from select to depends upon tthayer
@ 2016-03-07 19:42 ` tthayer
  2016-03-07 19:42 ` [PATCHv2 03/11] EDAC, altera: Add register offset for ECC Enable tthayer
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:42 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

Move the device structs and defines to altera_edac.h in preparation
for adding the Arria10 L2 cache ECC.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split original patch into smaller patches. Move private data
    and defines into header file.
---
 drivers/edac/altera_edac.c |   43 -------------------------------------------
 drivers/edac/altera_edac.h |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 63e4209..eee7a39 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -78,27 +78,6 @@ static const struct altr_sdram_prv_data a10_data = {
 	.ue_set_mask        = A10_DIAGINT_TDERRA_MASK,
 };
 
-/************************** EDAC Device Defines **************************/
-
-/* OCRAM ECC Management Group Defines */
-#define ALTR_MAN_GRP_OCRAM_ECC_OFFSET   0x04
-#define ALTR_OCR_ECC_EN                 BIT(0)
-#define ALTR_OCR_ECC_INJS               BIT(1)
-#define ALTR_OCR_ECC_INJD               BIT(2)
-#define ALTR_OCR_ECC_SERR               BIT(3)
-#define ALTR_OCR_ECC_DERR               BIT(4)
-
-/* L2 ECC Management Group Defines */
-#define ALTR_MAN_GRP_L2_ECC_OFFSET      0x00
-#define ALTR_L2_ECC_EN                  BIT(0)
-#define ALTR_L2_ECC_INJS                BIT(1)
-#define ALTR_L2_ECC_INJD                BIT(2)
-
-#define ALTR_UE_TRIGGER_CHAR            'U'   /* Trigger for UE */
-#define ALTR_TRIGGER_READ_WRD_CNT       32    /* Line size x 4 */
-#define ALTR_TRIG_OCRAM_BYTE_SIZE       128   /* Line size x 4 */
-#define ALTR_TRIG_L2C_BYTE_SIZE         4096  /* Full Page */
-
 /*********************** EDAC Memory Controller Functions ****************/
 
 /* The SDRAM controller uses the EDAC Memory Controller framework.       */
@@ -571,28 +550,6 @@ module_platform_driver(altr_edac_driver);
 const struct edac_device_prv_data ocramecc_data;
 const struct edac_device_prv_data l2ecc_data;
 
-struct edac_device_prv_data {
-	int (*setup)(struct platform_device *pdev, void __iomem *base);
-	int ce_clear_mask;
-	int ue_clear_mask;
-	char dbgfs_name[20];
-	void * (*alloc_mem)(size_t size, void **other);
-	void (*free_mem)(void *p, size_t size, void *other);
-	int ecc_enable_mask;
-	int ce_set_mask;
-	int ue_set_mask;
-	int trig_alloc_sz;
-};
-
-struct altr_edac_device_dev {
-	void __iomem *base;
-	int sb_irq;
-	int db_irq;
-	const struct edac_device_prv_data *data;
-	struct dentry *debugfs_dir;
-	char *edac_dev_name;
-};
-
 static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
 {
 	irqreturn_t ret_value = IRQ_NONE;
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index 953077d..e531da4 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -195,4 +195,47 @@ struct altr_sdram_mc_data {
 	const struct altr_sdram_prv_data *data;
 };
 
+/************************** EDAC Device Defines **************************/
+
+#define ALTR_UE_TRIGGER_CHAR            'U'   /* Trigger for UE */
+#define ALTR_TRIGGER_READ_WRD_CNT       32    /* Line size x 4 */
+#define ALTR_TRIG_OCRAM_BYTE_SIZE       128   /* Line size x 4 */
+#define ALTR_TRIG_L2C_BYTE_SIZE         4096  /* Full Page */
+
+/* OCRAM ECC Management Group Defines */
+#define ALTR_MAN_GRP_OCRAM_ECC_OFFSET   0x04
+#define ALTR_OCR_ECC_EN                 BIT(0)
+#define ALTR_OCR_ECC_INJS               BIT(1)
+#define ALTR_OCR_ECC_INJD               BIT(2)
+#define ALTR_OCR_ECC_SERR               BIT(3)
+#define ALTR_OCR_ECC_DERR               BIT(4)
+
+/* L2 ECC Management Group Defines */
+#define ALTR_MAN_GRP_L2_ECC_OFFSET      0x00
+#define ALTR_L2_ECC_EN                  BIT(0)
+#define ALTR_L2_ECC_INJS                BIT(1)
+#define ALTR_L2_ECC_INJD                BIT(2)
+
+struct edac_device_prv_data {
+	int (*setup)(struct platform_device *pdev, void __iomem *base);
+	int ce_clear_mask;
+	int ue_clear_mask;
+	char dbgfs_name[20];
+	void * (*alloc_mem)(size_t size, void **other);
+	void (*free_mem)(void *p, size_t size, void *other);
+	int ecc_enable_mask;
+	int ce_set_mask;
+	int ue_set_mask;
+	int trig_alloc_sz;
+};
+
+struct altr_edac_device_dev {
+	void __iomem *base;
+	int sb_irq;
+	int db_irq;
+	const struct edac_device_prv_data *data;
+	struct dentry *debugfs_dir;
+	char *edac_dev_name;
+};
+
 #endif	/* #ifndef _ALTERA_EDAC_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 03/11] EDAC, altera: Add register offset for ECC Enable
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
  2016-03-07 19:42 ` [PATCHv2 01/11] EDAC: Altera L2 Kconfig change from select to depends upon tthayer
  2016-03-07 19:42 ` [PATCHv2 02/11] EDAC, altera: Move Device structs and defines to header file tthayer
@ 2016-03-07 19:42 ` tthayer
  2016-03-07 19:43 ` [PATCHv2 04/11] EDAC, altera: Add register offset for ECC Error Inject tthayer
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:42 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

In preparation for the Arria10 peripheral ECCs, a register
offset from the ECC base was added to the private data
structure to index into the ECC enable register.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split large patch into smaller patches. Add an ECC
    control offset to support the different register layout
    of Arria10 peripheral ECCs.
---
 drivers/edac/altera_edac.c |   20 +++++++++++++++-----
 drivers/edac/altera_edac.h |    8 +++++++-
 2 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index eee7a39..138446c 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -746,7 +746,7 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 
 	/* Check specific dependencies for the module */
 	if (drvdata->data->setup) {
-		res = drvdata->data->setup(pdev, drvdata->base);
+		res = drvdata->data->setup(pdev, drvdata);
 		if (res)
 			goto fail1;
 	}
@@ -857,9 +857,12 @@ static void ocram_free_mem(void *p, size_t size, void *other)
  *	memory will cause CE/UE errors possibly causing an ABORT.
  */
 static int altr_ocram_check_deps(struct platform_device *pdev,
-				 void __iomem *base)
+				 struct altr_edac_device_dev *drvdata)
 {
-	if (readl(base) & ALTR_OCR_ECC_EN)
+	void __iomem  *base = drvdata->base;
+	const struct edac_device_prv_data *prv = drvdata->data;
+
+	if (readl(base + prv->ecc_en_ofst) & prv->ecc_enable_mask)
 		return 0;
 
 	edac_printk(KERN_ERR, EDAC_DEVICE,
@@ -875,6 +878,7 @@ const struct edac_device_prv_data ocramecc_data = {
 	.alloc_mem = ocram_alloc_mem,
 	.free_mem = ocram_free_mem,
 	.ecc_enable_mask = ALTR_OCR_ECC_EN,
+	.ecc_en_ofst = ALTR_OCR_ECC_REG_OFFSET,
 	.ce_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJS),
 	.ue_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJD),
 	.trig_alloc_sz = ALTR_TRIG_OCRAM_BYTE_SIZE,
@@ -924,10 +928,15 @@ static void l2_free_mem(void *p, size_t size, void *other)
  *	Note that L2 Cache Enable is forced at build time.
  */
 static int altr_l2_check_deps(struct platform_device *pdev,
-			      void __iomem *base)
+			      struct altr_edac_device_dev *drvdata)
 {
-	if (readl(base) & ALTR_L2_ECC_EN)
+	void __iomem  *base = drvdata->base;
+	const struct edac_device_prv_data *prv = drvdata->data;
+
+	if ((readl(base + prv->ecc_en_ofst) & prv->ecc_enable_mask) ==
+	     prv->ecc_enable_mask) {
 		return 0;
+	}
 
 	edac_printk(KERN_ERR, EDAC_DEVICE,
 		    "L2: No ECC present, or ECC disabled\n");
@@ -942,6 +951,7 @@ const struct edac_device_prv_data l2ecc_data = {
 	.alloc_mem = l2_alloc_mem,
 	.free_mem = l2_free_mem,
 	.ecc_enable_mask = ALTR_L2_ECC_EN,
+	.ecc_en_ofst = ALTR_L2_ECC_REG_OFFSET,
 	.ce_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJS),
 	.ue_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJD),
 	.trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index e531da4..54e2742 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -204,6 +204,7 @@ struct altr_sdram_mc_data {
 
 /* OCRAM ECC Management Group Defines */
 #define ALTR_MAN_GRP_OCRAM_ECC_OFFSET   0x04
+#define ALTR_OCR_ECC_REG_OFFSET         0x00
 #define ALTR_OCR_ECC_EN                 BIT(0)
 #define ALTR_OCR_ECC_INJS               BIT(1)
 #define ALTR_OCR_ECC_INJD               BIT(2)
@@ -212,18 +213,23 @@ struct altr_sdram_mc_data {
 
 /* L2 ECC Management Group Defines */
 #define ALTR_MAN_GRP_L2_ECC_OFFSET      0x00
+#define ALTR_L2_ECC_REG_OFFSET          0x00
 #define ALTR_L2_ECC_EN                  BIT(0)
 #define ALTR_L2_ECC_INJS                BIT(1)
 #define ALTR_L2_ECC_INJD                BIT(2)
 
+struct altr_edac_device_dev;
+
 struct edac_device_prv_data {
-	int (*setup)(struct platform_device *pdev, void __iomem *base);
+	int (*setup)(struct platform_device *pdev,
+		     struct altr_edac_device_dev *drvdata);
 	int ce_clear_mask;
 	int ue_clear_mask;
 	char dbgfs_name[20];
 	void * (*alloc_mem)(size_t size, void **other);
 	void (*free_mem)(void *p, size_t size, void *other);
 	int ecc_enable_mask;
+	int ecc_en_ofst;
 	int ce_set_mask;
 	int ue_set_mask;
 	int trig_alloc_sz;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 04/11] EDAC, altera: Add register offset for ECC Error Inject
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (2 preceding siblings ...)
  2016-03-07 19:42 ` [PATCHv2 03/11] EDAC, altera: Add register offset for ECC Enable tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-07 19:43 ` [PATCHv2 05/11] EDAC, altera: Add register offset for ECC Error Clear tthayer
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

In preparation for the Arria10 peripheral ECCs, a register
offset from the ECC base was added to the private data
structure to index to the error injection register.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split large patch into smaller patches. Add an ECC
    error inject offset to support the different register
    layout of Arria10 peripheral ECCs.
---
 drivers/edac/altera_edac.c |    7 +++++--
 drivers/edac/altera_edac.h |    1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 138446c..9e62a49 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -622,8 +622,9 @@ static ssize_t altr_edac_device_trig(struct file *file,
 		if (ACCESS_ONCE(ptemp[i]))
 			result = -1;
 		/* Toggle Error bit (it is latched), leave ECC enabled */
-		writel(error_mask, drvdata->base);
-		writel(priv->ecc_enable_mask, drvdata->base);
+		writel(error_mask, (drvdata->base + priv->set_err_ofst));
+		writel(priv->ecc_enable_mask, (drvdata->base +
+					       priv->set_err_ofst));
 		ptemp[i] = i;
 	}
 	/* Ensure it has been written out */
@@ -881,6 +882,7 @@ const struct edac_device_prv_data ocramecc_data = {
 	.ecc_en_ofst = ALTR_OCR_ECC_REG_OFFSET,
 	.ce_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJS),
 	.ue_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJD),
+	.set_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
 	.trig_alloc_sz = ALTR_TRIG_OCRAM_BYTE_SIZE,
 };
 
@@ -954,6 +956,7 @@ const struct edac_device_prv_data l2ecc_data = {
 	.ecc_en_ofst = ALTR_L2_ECC_REG_OFFSET,
 	.ce_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJS),
 	.ue_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJD),
+	.set_err_ofst = ALTR_L2_ECC_REG_OFFSET,
 	.trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
 };
 
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index 54e2742..d4105b0 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -232,6 +232,7 @@ struct edac_device_prv_data {
 	int ecc_en_ofst;
 	int ce_set_mask;
 	int ue_set_mask;
+	int set_err_ofst;
 	int trig_alloc_sz;
 };
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 05/11] EDAC, altera: Add register offset for ECC Error Clear
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (3 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 04/11] EDAC, altera: Add register offset for ECC Error Inject tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-07 19:43 ` [PATCHv2 06/11] EDAC, altera: Add IRQ flags to private data struct tthayer
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

In preparation for the Arria10 peripheral ECCs, a register
offset from the ECC base was added to the private data
structure to index to the error clear register. Since
the Arria10 L2 cache ECC registers are not contiguous,
a status base address was added.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split large patch into smaller patches. Add an ECC
    error clear offset to support the different register
    layout of Arria10 peripheral ECCs.
---
 drivers/edac/altera_edac.c |   10 ++++++++--
 drivers/edac/altera_edac.h |    2 ++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 9e62a49..c28cd78 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -556,15 +556,16 @@ static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
 	struct edac_device_ctl_info *dci = dev_id;
 	struct altr_edac_device_dev *drvdata = dci->pvt_info;
 	const struct edac_device_prv_data *priv = drvdata->data;
+	void __iomem *clear_addr = drvdata->status + priv->clear_err_ofst;
 
 	if (irq == drvdata->sb_irq) {
 		if (priv->ce_clear_mask)
-			writel(priv->ce_clear_mask, drvdata->base);
+			writel(priv->ce_clear_mask, clear_addr);
 		edac_device_handle_ce(dci, 0, 0, drvdata->edac_dev_name);
 		ret_value = IRQ_HANDLED;
 	} else if (irq == drvdata->db_irq) {
 		if (priv->ue_clear_mask)
-			writel(priv->ue_clear_mask, drvdata->base);
+			writel(priv->ue_clear_mask, clear_addr);
 		edac_device_handle_ue(dci, 0, 0, drvdata->edac_dev_name);
 		panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
 		ret_value = IRQ_HANDLED;
@@ -742,6 +743,9 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 	if (!drvdata->base)
 		goto fail1;
 
+	/* Except for A10 L2 cache, status reg is within alloced base mem */
+	drvdata->status = drvdata->base;
+
 	/* Get driver specific data for this EDAC device */
 	drvdata->data = of_match_node(altr_edac_device_of_match, np)->data;
 
@@ -875,6 +879,7 @@ const struct edac_device_prv_data ocramecc_data = {
 	.setup = altr_ocram_check_deps,
 	.ce_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_SERR),
 	.ue_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_DERR),
+	.clear_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
 	.dbgfs_name = "altr_ocram_trigger",
 	.alloc_mem = ocram_alloc_mem,
 	.free_mem = ocram_free_mem,
@@ -949,6 +954,7 @@ const struct edac_device_prv_data l2ecc_data = {
 	.setup = altr_l2_check_deps,
 	.ce_clear_mask = 0,
 	.ue_clear_mask = 0,
+	.clear_err_ofst = ALTR_L2_ECC_REG_OFFSET,
 	.dbgfs_name = "altr_l2_trigger",
 	.alloc_mem = l2_alloc_mem,
 	.free_mem = l2_free_mem,
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index d4105b0..f15b4ad 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -225,6 +225,7 @@ struct edac_device_prv_data {
 		     struct altr_edac_device_dev *drvdata);
 	int ce_clear_mask;
 	int ue_clear_mask;
+	int clear_err_ofst;
 	char dbgfs_name[20];
 	void * (*alloc_mem)(size_t size, void **other);
 	void (*free_mem)(void *p, size_t size, void *other);
@@ -238,6 +239,7 @@ struct edac_device_prv_data {
 
 struct altr_edac_device_dev {
 	void __iomem *base;
+	void __iomem *status;
 	int sb_irq;
 	int db_irq;
 	const struct edac_device_prv_data *data;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 06/11] EDAC, altera: Add IRQ flags to private data struct
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (4 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 05/11] EDAC, altera: Add register offset for ECC Error Clear tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-07 19:43 ` [PATCHv2 07/11] EDAC, altera: Add status offset & masks tthayer
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

In preparation for the Arria10 peripheral ECCs, irq_flags
was added to the private data structure because Arria10
uses shared IRQs while Cyclone5/Arria5 have exclusive IRQs.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split large patch into smaller patches. Add irq_flags
    to the private data structure.
---
 drivers/edac/altera_edac.c |    8 ++++++--
 drivers/edac/altera_edac.h |    1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index c28cd78..fd73a77 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -759,14 +759,16 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 	drvdata->sb_irq = platform_get_irq(pdev, 0);
 	res = devm_request_irq(&pdev->dev, drvdata->sb_irq,
 			       altr_edac_device_handler,
-			       0, dev_name(&pdev->dev), dci);
+			       drvdata->data->irq_flags,
+			       dev_name(&pdev->dev), dci);
 	if (res)
 		goto fail1;
 
 	drvdata->db_irq = platform_get_irq(pdev, 1);
 	res = devm_request_irq(&pdev->dev, drvdata->db_irq,
 			       altr_edac_device_handler,
-			       0, dev_name(&pdev->dev), dci);
+			       drvdata->data->irq_flags,
+			       dev_name(&pdev->dev), dci);
 	if (res)
 		goto fail1;
 
@@ -889,6 +891,7 @@ const struct edac_device_prv_data ocramecc_data = {
 	.ue_set_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_INJD),
 	.set_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
 	.trig_alloc_sz = ALTR_TRIG_OCRAM_BYTE_SIZE,
+	.irq_flags = 0,
 };
 
 #endif	/* CONFIG_EDAC_ALTERA_OCRAM */
@@ -964,6 +967,7 @@ const struct edac_device_prv_data l2ecc_data = {
 	.ue_set_mask = (ALTR_L2_ECC_EN | ALTR_L2_ECC_INJD),
 	.set_err_ofst = ALTR_L2_ECC_REG_OFFSET,
 	.trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
+	.irq_flags = 0,
 };
 
 #endif	/* CONFIG_EDAC_ALTERA_L2C */
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index f15b4ad..b262f74 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -235,6 +235,7 @@ struct edac_device_prv_data {
 	int ue_set_mask;
 	int set_err_ofst;
 	int trig_alloc_sz;
+	int irq_flags;
 };
 
 struct altr_edac_device_dev {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 07/11] EDAC, altera: Add status offset & masks
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (5 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 06/11] EDAC, altera: Add IRQ flags to private data struct tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-08 15:52   ` Thor Thayer
  2016-03-07 19:43 ` [PATCHv2 08/11] Documentation: dt: socfpga: Add Altera Arria10 L2 cache binding tthayer
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

In preparation for the Arria10 peripheral ECCs, the IRQ
status needs to be determined because the IRQs are shared.
The IRQ status register is read to determine if the IRQ
was for this ECC peripheral. Cyclone5 and Arria5 have
dedicated IRQs so the confirmation mechanism is not
required and the mask is set to 0.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split large patch into smaller patches. Determine
    if IRQ matches this ECC peripheral before handling it.
---
 drivers/edac/altera_edac.c |   41 +++++++++++++++++++++++++++++++----------
 drivers/edac/altera_edac.h |    3 +++
 2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index fd73a77..11b7291 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -556,19 +556,32 @@ static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
 	struct edac_device_ctl_info *dci = dev_id;
 	struct altr_edac_device_dev *drvdata = dci->pvt_info;
 	const struct edac_device_prv_data *priv = drvdata->data;
+	void __iomem *status_addr = drvdata->status + priv->err_status_ofst;
 	void __iomem *clear_addr = drvdata->status + priv->clear_err_ofst;
 
+	/*
+	 * CycloneV is directly mapped to a specific IRQ. Arria10
+	 * shares the IRQ with other ECCs so we must match first.
+	 */
 	if (irq == drvdata->sb_irq) {
-		if (priv->ce_clear_mask)
-			writel(priv->ce_clear_mask, clear_addr);
-		edac_device_handle_ce(dci, 0, 0, drvdata->edac_dev_name);
-		ret_value = IRQ_HANDLED;
+		if (!priv->ce_status_mask ||
+		    (priv->ce_status_mask & readl(status_addr))) {
+			if (priv->ce_clear_mask)
+				writel(priv->ce_clear_mask, clear_addr);
+			edac_device_handle_ce(dci, 0, 0,
+					      drvdata->edac_dev_name);
+			ret_value = IRQ_HANDLED;
+		}
 	} else if (irq == drvdata->db_irq) {
-		if (priv->ue_clear_mask)
-			writel(priv->ue_clear_mask, clear_addr);
-		edac_device_handle_ue(dci, 0, 0, drvdata->edac_dev_name);
-		panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
-		ret_value = IRQ_HANDLED;
+		if (!priv->ue_status_mask ||
+		    (priv->ue_status_mask & readl(status_addr))) {
+			if (priv->ue_clear_mask)
+				writel(priv->ue_clear_mask, clear_addr);
+			edac_device_handle_ue(dci, 0, 0,
+					      drvdata->edac_dev_name);
+			panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
+			ret_value = IRQ_HANDLED;
+		}
 	} else {
 		WARN_ON(1);
 	}
@@ -882,6 +895,10 @@ const struct edac_device_prv_data ocramecc_data = {
 	.ce_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_SERR),
 	.ue_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_DERR),
 	.clear_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
+	/* Cyclone5 & Arria5 have separate IRQs so status = 0 */
+	.ce_status_mask = 0,
+	.ue_status_mask = 0,
+	.err_status_ofst = 0,
 	.dbgfs_name = "altr_ocram_trigger",
 	.alloc_mem = ocram_alloc_mem,
 	.free_mem = ocram_free_mem,
@@ -957,7 +974,11 @@ const struct edac_device_prv_data l2ecc_data = {
 	.setup = altr_l2_check_deps,
 	.ce_clear_mask = 0,
 	.ue_clear_mask = 0,
-	.clear_err_ofst = ALTR_L2_ECC_REG_OFFSET,
+	.clear_err_ofst = ALTR_MAN_GRP_L2_ECC_OFFSET,
+	/* Cyclone5 & Arria5 have separate IRQs so status = 0 */
+	.ce_status_mask = 0,
+	.ue_status_mask = 0,
+	.err_status_ofst = 0,
 	.dbgfs_name = "altr_l2_trigger",
 	.alloc_mem = l2_alloc_mem,
 	.free_mem = l2_free_mem,
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index b262f74..43e0dae 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -226,6 +226,9 @@ struct edac_device_prv_data {
 	int ce_clear_mask;
 	int ue_clear_mask;
 	int clear_err_ofst;
+	int ce_status_mask;
+	int ue_status_mask;
+	int err_status_ofst;
 	char dbgfs_name[20];
 	void * (*alloc_mem)(size_t size, void **other);
 	void (*free_mem)(void *p, size_t size, void *other);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 08/11] Documentation: dt: socfpga: Add Altera Arria10 L2 cache binding
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (6 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 07/11] EDAC, altera: Add status offset & masks tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-07 19:43 ` [PATCHv2 09/11] EDAC, altera: Addition of Arria10 L2 Cache ECC tthayer
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

Add the device tree binding string needed to support the Altera L2
cache on the Arria10 chip.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
Acked-by: Rob Herring <robh@kernel.org>
---
v2 Correct spelling of Arria10 in patch title.
---
 .../bindings/arm/altera/socfpga-eccmgr.txt         |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt
index 885f93d..4cea386 100644
--- a/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt
+++ b/Documentation/devicetree/bindings/arm/altera/socfpga-eccmgr.txt
@@ -13,7 +13,8 @@ Subcomponents:
 
 L2 Cache ECC
 Required Properties:
-- compatible : Should be "altr,socfpga-l2-ecc"
+- compatible : Should be "altr,socfpga-l2-ecc" or
+	       "altr,socfpga-a10-l2-ecc"
 - reg : Address and size for ECC error interrupt clear registers.
 - interrupts : Should be single bit error interrupt, then double bit error
 	interrupt. Note the rising edge type.
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 09/11] EDAC, altera: Addition of Arria10 L2 Cache ECC
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (7 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 08/11] Documentation: dt: socfpga: Add Altera Arria10 L2 cache binding tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-07 19:43 ` [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup tthayer
  2016-03-07 19:43 ` [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry tthayer
  10 siblings, 0 replies; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

Addition of the Arria10 L2 Cache ECC handling. Addition
of private data structure for Arria10 L2 cache ECC and
the initialization function for it.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split large patch into smaller patches. Addition of
    Arria10 L2 cache dependency check and private data.
---
 drivers/edac/altera_edac.c |   57 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/edac/altera_edac.h |   21 +++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 11b7291..8afdf8b 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -549,6 +549,7 @@ module_platform_driver(altr_edac_driver);
 
 const struct edac_device_prv_data ocramecc_data;
 const struct edac_device_prv_data l2ecc_data;
+const struct edac_device_prv_data a10_l2ecc_data;
 
 static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
 {
@@ -687,6 +688,8 @@ static void altr_create_edacdev_dbgfs(struct edac_device_ctl_info *edac_dci,
 static const struct of_device_id altr_edac_device_of_match[] = {
 #ifdef CONFIG_EDAC_ALTERA_L2C
 	{ .compatible = "altr,socfpga-l2-ecc", .data = (void *)&l2ecc_data },
+	{ .compatible = "altr,socfpga-a10-l2-ecc",
+	  .data = (void *)&a10_l2ecc_data },
 #endif
 #ifdef CONFIG_EDAC_ALTERA_OCRAM
 	{ .compatible = "altr,socfpga-ocram-ecc",
@@ -970,6 +973,40 @@ static int altr_l2_check_deps(struct platform_device *pdev,
 	return -ENODEV;
 }
 
+static int altr_a10_l2_check_deps(struct platform_device *pdev,
+				  struct altr_edac_device_dev *drvdata)
+{
+	void __iomem  *status_base, *base = drvdata->base;
+	const struct edac_device_prv_data *prv = drvdata->data;
+
+	if ((readl(base + prv->ecc_en_ofst) & prv->ecc_enable_mask) !=
+	     prv->ecc_enable_mask) {
+		edac_printk(KERN_ERR, EDAC_DEVICE,
+			    "L2: No ECC present, or ECC disabled\n");
+		return -ENODEV;
+	}
+
+	/* A10 L2 cache status registers are not contiguous with base */
+	if (!devm_request_mem_region(&pdev->dev, ALTR_A10_L2_ECC_STATUS,
+				     2 * sizeof(u32), dev_name(&pdev->dev))) {
+		edac_printk(KERN_ERR, EDAC_DEVICE,
+			    "Unable to request mem region\n");
+		return -EBUSY;
+	}
+
+	status_base = devm_ioremap(&pdev->dev, ALTR_A10_L2_ECC_STATUS,
+				   2 * sizeof(u32));
+	if (!status_base) {
+		edac_printk(KERN_ERR, EDAC_DEVICE,
+			    "Unable to ioremap L2 status\n");
+		return -ENOMEM;
+	}
+
+	drvdata->status = status_base;
+
+	return 0;
+}
+
 const struct edac_device_prv_data l2ecc_data = {
 	.setup = altr_l2_check_deps,
 	.ce_clear_mask = 0,
@@ -991,6 +1028,26 @@ const struct edac_device_prv_data l2ecc_data = {
 	.irq_flags = 0,
 };
 
+const struct edac_device_prv_data a10_l2ecc_data = {
+	.setup = altr_a10_l2_check_deps,
+	.ce_clear_mask = ALTR_A10_L2_ECC_SERR_CLR,
+	.ue_clear_mask = ALTR_A10_L2_ECC_MERR_CLR,
+	.clear_err_ofst = ALTR_A10_L2_ECC_CLR_OFST,
+	.ce_status_mask = ALTR_A10_L2_ECC_SERR_PEND,
+	.ue_status_mask = ALTR_A10_L2_ECC_MERR_PEND,
+	.err_status_ofst = ALTR_A10_L2_ECC_STAT_OFST,
+	.dbgfs_name = "altr_l2_trigger",
+	.alloc_mem = l2_alloc_mem,
+	.free_mem = l2_free_mem,
+	.ecc_enable_mask = ALTR_A10_L2_ECC_EN_CTL,
+	.ecc_en_ofst = ALTR_A10_L2_ECC_CTL_OFST,
+	.ce_set_mask = ALTR_A10_L2_ECC_CE_INJ_MASK,
+	.ue_set_mask = ALTR_A10_L2_ECC_UE_INJ_MASK,
+	.set_err_ofst = ALTR_A10_L2_ECC_INJ_OFST,
+	.trig_alloc_sz = ALTR_TRIG_L2C_BYTE_SIZE,
+	.irq_flags = IRQF_SHARED,
+};
+
 #endif	/* CONFIG_EDAC_ALTERA_L2C */
 
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
index 43e0dae..a9177c8 100644
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -196,12 +196,13 @@ struct altr_sdram_mc_data {
 };
 
 /************************** EDAC Device Defines **************************/
-
+/***** General Device Trigger Defines *****/
 #define ALTR_UE_TRIGGER_CHAR            'U'   /* Trigger for UE */
 #define ALTR_TRIGGER_READ_WRD_CNT       32    /* Line size x 4 */
 #define ALTR_TRIG_OCRAM_BYTE_SIZE       128   /* Line size x 4 */
 #define ALTR_TRIG_L2C_BYTE_SIZE         4096  /* Full Page */
 
+/******* Cyclone5 and Arria5 Defines *******/
 /* OCRAM ECC Management Group Defines */
 #define ALTR_MAN_GRP_OCRAM_ECC_OFFSET   0x04
 #define ALTR_OCR_ECC_REG_OFFSET         0x00
@@ -218,6 +219,24 @@ struct altr_sdram_mc_data {
 #define ALTR_L2_ECC_INJS                BIT(1)
 #define ALTR_L2_ECC_INJD                BIT(2)
 
+/************* Arria10 Defines *************/
+/* Arria 10 L2 ECC Management Group Defines */
+#define ALTR_A10_L2_ECC_CTL_OFST        0x0
+#define ALTR_A10_L2_ECC_EN_CTL          BIT(0)
+
+#define ALTR_A10_L2_ECC_STATUS          0xFFD060A4
+#define ALTR_A10_L2_ECC_STAT_OFST       0x0
+#define ALTR_A10_L2_ECC_SERR_PEND       BIT(15)
+#define ALTR_A10_L2_ECC_MERR_PEND       BIT(31)
+
+#define ALTR_A10_L2_ECC_CLR_OFST        0x4
+#define ALTR_A10_L2_ECC_SERR_CLR        BIT(15)
+#define ALTR_A10_L2_ECC_MERR_CLR        BIT(31)
+
+#define ALTR_A10_L2_ECC_INJ_OFST        ALTR_A10_L2_ECC_CTL_OFST
+#define ALTR_A10_L2_ECC_CE_INJ_MASK     0x00000101
+#define ALTR_A10_L2_ECC_UE_INJ_MASK     0x00010101
+
 struct altr_edac_device_dev;
 
 struct edac_device_prv_data {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (8 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 09/11] EDAC, altera: Addition of Arria10 L2 Cache ECC tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-08 14:45   ` Dinh Nguyen
  2016-03-07 19:43 ` [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry tthayer
  10 siblings, 1 reply; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

Enable ECC for Arria10 L2 cache on machine startup. The ECC has to be
enabled before data is stored in memory otherwise the ECC will fail
on reads.
Use DT_MACHINE to select Arria10 L2 cache function.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2: Split into 2 separate functions selected with DT_MACHINE.
---
 arch/arm/mach-socfpga/core.h     |    1 +
 arch/arm/mach-socfpga/l2_cache.c |   49 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-socfpga/socfpga.c  |   10 +++++++-
 3 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
index 575195b..bfbc78d 100644
--- a/arch/arm/mach-socfpga/core.h
+++ b/arch/arm/mach-socfpga/core.h
@@ -38,6 +38,7 @@ extern void socfpga_init_clocks(void);
 extern void socfpga_sysmgr_init(void);
 void socfpga_init_l2_ecc(void);
 void socfpga_init_ocram_ecc(void);
+void socfpga_init_arria10_l2_ecc(void);
 
 extern void __iomem *sys_manager_base_addr;
 extern void __iomem *rst_manager_base_addr;
diff --git a/arch/arm/mach-socfpga/l2_cache.c b/arch/arm/mach-socfpga/l2_cache.c
index e3907ab..4267c95f 100644
--- a/arch/arm/mach-socfpga/l2_cache.c
+++ b/arch/arm/mach-socfpga/l2_cache.c
@@ -17,6 +17,20 @@
 #include <linux/of_platform.h>
 #include <linux/of_address.h>
 
+#include "core.h"
+
+/* A10 System Manager L2 ECC Control register */
+#define A10_MPU_CTRL_L2_ECC_OFST          0x0
+#define A10_MPU_CTRL_L2_ECC_EN            BIT(0)
+
+/* A10 System Manager Global IRQ Mask register */
+#define A10_SYSMGR_ECC_INTMASK_CLR_OFST   0x98
+#define A10_SYSMGR_ECC_INTMASK_CLR_L2     BIT(0)
+
+/* A10 System Manager L2 ECC IRQ Clear register */
+#define A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST  0xA8
+#define A10_SYSMGR_MPU_CLEAR_L2_ECC       (BIT(31) | BIT(15))
+
 void socfpga_init_l2_ecc(void)
 {
 	struct device_node *np;
@@ -39,3 +53,38 @@ void socfpga_init_l2_ecc(void)
 	writel(0x01, mapped_l2_edac_addr);
 	iounmap(mapped_l2_edac_addr);
 }
+
+void socfpga_init_arria10_l2_ecc(void)
+{
+	struct device_node *np;
+	void __iomem *mapped_l2_edac_addr;
+
+	/* Find the L2 EDAC device tree node */
+	np = of_find_compatible_node(NULL, NULL, "altr,socfpga-a10-l2-ecc");
+	if (!np) {
+		pr_err("Unable to find socfpga-a10-l2-ecc in dtb\n");
+		return;
+	}
+
+	mapped_l2_edac_addr = of_iomap(np, 0);
+	of_node_put(np);
+	if (!mapped_l2_edac_addr) {
+		pr_err("Unable to find L2 ECC mapping in dtb\n");
+		return;
+	}
+
+	if (!sys_manager_base_addr) {
+		pr_err("System Mananger not mapped for L2 ECC\n");
+		goto exit;
+	}
+	/* Clear any pending IRQs */
+	writel(A10_SYSMGR_MPU_CLEAR_L2_ECC, (sys_manager_base_addr +
+	       A10_SYSMGR_MPU_CLEAR_L2_ECC_OFST));
+	/* Enable ECC */
+	writel(A10_SYSMGR_ECC_INTMASK_CLR_L2, sys_manager_base_addr +
+	       A10_SYSMGR_ECC_INTMASK_CLR_OFST);
+	writel(A10_MPU_CTRL_L2_ECC_EN, mapped_l2_edac_addr +
+	       A10_MPU_CTRL_L2_ECC_OFST);
+exit:
+	iounmap(mapped_l2_edac_addr);
+}
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 7e0aad2..e9b5b60 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -66,6 +66,14 @@ static void __init socfpga_init_irq(void)
 		socfpga_init_ocram_ecc();
 }
 
+static void __init socfpga_arria10_init_irq(void)
+{
+	irqchip_init();
+	socfpga_sysmgr_init();
+	if (IS_ENABLED(CONFIG_EDAC_ALTERA_L2C))
+		socfpga_init_arria10_l2_ecc();
+}
+
 static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
 {
 	u32 temp;
@@ -113,7 +121,7 @@ static const char *altera_a10_dt_match[] = {
 DT_MACHINE_START(SOCFPGA_A10, "Altera SOCFPGA Arria10")
 	.l2c_aux_val	= 0,
 	.l2c_aux_mask	= ~0,
-	.init_irq	= socfpga_init_irq,
+	.init_irq	= socfpga_arria10_init_irq,
 	.restart	= socfpga_arria10_restart,
 	.dt_compat	= altera_a10_dt_match,
 MACHINE_END
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry
  2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
                   ` (9 preceding siblings ...)
  2016-03-07 19:43 ` [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup tthayer
@ 2016-03-07 19:43 ` tthayer
  2016-03-08 14:50   ` Dinh Nguyen
  10 siblings, 1 reply; 16+ messages in thread
From: tthayer @ 2016-03-07 19:43 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux, tthayer

From: Thor Thayer <tthayer@opensource.altera.com>

Add the device tree entries needed to support the Altera L2
cache EDAC on the Arria10 chip.

Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
---
v2 Match register value (l2-ecc@ffd06010)
---
 arch/arm/boot/dts/socfpga_arria10.dtsi |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
index cce9e50..44aeb3f 100644
--- a/arch/arm/boot/dts/socfpga_arria10.dtsi
+++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
@@ -599,6 +599,20 @@
 			reg = <0xffe00000 0x40000>;
 		};
 
+		eccmgr: eccmgr@ffd06090 {
+			compatible = "altr,socfpga-ecc-manager";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			l2-ecc@ffd06010 {
+				compatible = "altr,socfpga-a10-l2-ecc";
+				reg = <0xffd06010 0x4>;
+				interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>,
+					     <0 0 IRQ_TYPE_LEVEL_HIGH>;
+			};
+		};
+
 		rst: rstmgr@ffd05000 {
 			#reset-cells = <1>;
 			compatible = "altr,rst-mgr";
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup
  2016-03-07 19:43 ` [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup tthayer
@ 2016-03-08 14:45   ` Dinh Nguyen
  0 siblings, 0 replies; 16+ messages in thread
From: Dinh Nguyen @ 2016-03-08 14:45 UTC (permalink / raw)
  To: tthayer, bp, dougthompson, m.chehab, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, linux, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux



On 03/07/2016 01:43 PM, tthayer@opensource.altera.com wrote:
> From: Thor Thayer <tthayer@opensource.altera.com>
> 
> Enable ECC for Arria10 L2 cache on machine startup. The ECC has to be
> enabled before data is stored in memory otherwise the ECC will fail
> on reads.
> Use DT_MACHINE to select Arria10 L2 cache function.
> 
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> v2: Split into 2 separate functions selected with DT_MACHINE.
> ---
>  arch/arm/mach-socfpga/core.h     |    1 +
>  arch/arm/mach-socfpga/l2_cache.c |   49 ++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-socfpga/socfpga.c  |   10 +++++++-
>  3 files changed, 59 insertions(+), 1 deletion(-)
> 

Acked-by: Dinh Nguyen <dinguyen@opensource.altera.com>

Thanks,
Dinh

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry
  2016-03-07 19:43 ` [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry tthayer
@ 2016-03-08 14:50   ` Dinh Nguyen
  2016-03-08 15:59     ` Thor Thayer
  0 siblings, 1 reply; 16+ messages in thread
From: Dinh Nguyen @ 2016-03-08 14:50 UTC (permalink / raw)
  To: tthayer, bp, dougthompson, m.chehab, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, linux, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux



On 03/07/2016 01:43 PM, tthayer@opensource.altera.com wrote:
> From: Thor Thayer <tthayer@opensource.altera.com>
> 
> Add the device tree entries needed to support the Altera L2
> cache EDAC on the Arria10 chip.
> 
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> v2 Match register value (l2-ecc@ffd06010)
> ---
>  arch/arm/boot/dts/socfpga_arria10.dtsi |   14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
> index cce9e50..44aeb3f 100644
> --- a/arch/arm/boot/dts/socfpga_arria10.dtsi
> +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
> @@ -599,6 +599,20 @@
>  			reg = <0xffe00000 0x40000>;
>  		};
>  
> +		eccmgr: eccmgr@ffd06090 {
> +			compatible = "altr,socfpga-ecc-manager";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges;
> +
> +			l2-ecc@ffd06010 {
> +				compatible = "altr,socfpga-a10-l2-ecc";
> +				reg = <0xffd06010 0x4>;
> +				interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>,
> +					     <0 0 IRQ_TYPE_LEVEL_HIGH>;
> +			};
> +		};
> +

Just checking if these addresses are correct. The eccmgr is at
0xffd06090, but the l2-ecc is at 0xffd06010? I would have thought from
the placement the l2-ecc address would be inside the eccmgr's address?

Dinh

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv2 07/11] EDAC, altera: Add status offset & masks
  2016-03-07 19:43 ` [PATCHv2 07/11] EDAC, altera: Add status offset & masks tthayer
@ 2016-03-08 15:52   ` Thor Thayer
  0 siblings, 0 replies; 16+ messages in thread
From: Thor Thayer @ 2016-03-08 15:52 UTC (permalink / raw)
  To: bp, dougthompson, m.chehab, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, linux, dinguyen, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux

Hi Boris,

On 03/07/2016 01:43 PM, tthayer@opensource.altera.com wrote:
> From: Thor Thayer <tthayer@opensource.altera.com>
>
> In preparation for the Arria10 peripheral ECCs, the IRQ
> status needs to be determined because the IRQs are shared.
> The IRQ status register is read to determine if the IRQ
> was for this ECC peripheral. Cyclone5 and Arria5 have
> dedicated IRQs so the confirmation mechanism is not
> required and the mask is set to 0.
>
> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
> ---
> v2: Split large patch into smaller patches. Determine
>      if IRQ matches this ECC peripheral before handling it.
> ---
>   drivers/edac/altera_edac.c |   41 +++++++++++++++++++++++++++++++----------
>   drivers/edac/altera_edac.h |    3 +++
>   2 files changed, 34 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
> index fd73a77..11b7291 100644
> --- a/drivers/edac/altera_edac.c
> +++ b/drivers/edac/altera_edac.c
> @@ -556,19 +556,32 @@ static irqreturn_t altr_edac_device_handler(int irq, void *dev_id)
>   	struct edac_device_ctl_info *dci = dev_id;
>   	struct altr_edac_device_dev *drvdata = dci->pvt_info;
>   	const struct edac_device_prv_data *priv = drvdata->data;
> +	void __iomem *status_addr = drvdata->status + priv->err_status_ofst;
>   	void __iomem *clear_addr = drvdata->status + priv->clear_err_ofst;
>
> +	/*
> +	 * CycloneV is directly mapped to a specific IRQ. Arria10
> +	 * shares the IRQ with other ECCs so we must match first.
> +	 */
>   	if (irq == drvdata->sb_irq) {
> -		if (priv->ce_clear_mask)
> -			writel(priv->ce_clear_mask, clear_addr);
> -		edac_device_handle_ce(dci, 0, 0, drvdata->edac_dev_name);
> -		ret_value = IRQ_HANDLED;
> +		if (!priv->ce_status_mask ||
> +		    (priv->ce_status_mask & readl(status_addr))) {
> +			if (priv->ce_clear_mask)
> +				writel(priv->ce_clear_mask, clear_addr);
> +			edac_device_handle_ce(dci, 0, 0,
> +					      drvdata->edac_dev_name);
> +			ret_value = IRQ_HANDLED;
> +		}
>   	} else if (irq == drvdata->db_irq) {
> -		if (priv->ue_clear_mask)
> -			writel(priv->ue_clear_mask, clear_addr);
> -		edac_device_handle_ue(dci, 0, 0, drvdata->edac_dev_name);
> -		panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
> -		ret_value = IRQ_HANDLED;
> +		if (!priv->ue_status_mask ||
> +		    (priv->ue_status_mask & readl(status_addr))) {
> +			if (priv->ue_clear_mask)
> +				writel(priv->ue_clear_mask, clear_addr);
> +			edac_device_handle_ue(dci, 0, 0,
> +					      drvdata->edac_dev_name);
> +			panic("\nEDAC:ECC_DEVICE[Uncorrectable errors]\n");
> +			ret_value = IRQ_HANDLED;
> +		}
>   	} else {
>   		WARN_ON(1);
>   	}


While working on subsequent ECC components to upstream, I realized that 
the above is not an optimal solution for Arria10.

The Arria10 is significantly different from the Cyclone5/Arria5 and 
therefore should be it's own implementation.

Please disregard this patch series. I'll redo the series with a 
different IRQ implementation that is cleaner - it will be closer to the 
Xgene driver.

Sorry for the noise.

Thor


> @@ -882,6 +895,10 @@ const struct edac_device_prv_data ocramecc_data = {
>   	.ce_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_SERR),
>   	.ue_clear_mask = (ALTR_OCR_ECC_EN | ALTR_OCR_ECC_DERR),
>   	.clear_err_ofst = ALTR_OCR_ECC_REG_OFFSET,
> +	/* Cyclone5 & Arria5 have separate IRQs so status = 0 */
> +	.ce_status_mask = 0,
> +	.ue_status_mask = 0,
> +	.err_status_ofst = 0,
>   	.dbgfs_name = "altr_ocram_trigger",
>   	.alloc_mem = ocram_alloc_mem,
>   	.free_mem = ocram_free_mem,
> @@ -957,7 +974,11 @@ const struct edac_device_prv_data l2ecc_data = {
>   	.setup = altr_l2_check_deps,
>   	.ce_clear_mask = 0,
>   	.ue_clear_mask = 0,
> -	.clear_err_ofst = ALTR_L2_ECC_REG_OFFSET,
> +	.clear_err_ofst = ALTR_MAN_GRP_L2_ECC_OFFSET,
> +	/* Cyclone5 & Arria5 have separate IRQs so status = 0 */
> +	.ce_status_mask = 0,
> +	.ue_status_mask = 0,
> +	.err_status_ofst = 0,
>   	.dbgfs_name = "altr_l2_trigger",
>   	.alloc_mem = l2_alloc_mem,
>   	.free_mem = l2_free_mem,
> diff --git a/drivers/edac/altera_edac.h b/drivers/edac/altera_edac.h
> index b262f74..43e0dae 100644
> --- a/drivers/edac/altera_edac.h
> +++ b/drivers/edac/altera_edac.h
> @@ -226,6 +226,9 @@ struct edac_device_prv_data {
>   	int ce_clear_mask;
>   	int ue_clear_mask;
>   	int clear_err_ofst;
> +	int ce_status_mask;
> +	int ue_status_mask;
> +	int err_status_ofst;
>   	char dbgfs_name[20];
>   	void * (*alloc_mem)(size_t size, void **other);
>   	void (*free_mem)(void *p, size_t size, void *other);
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry
  2016-03-08 14:50   ` Dinh Nguyen
@ 2016-03-08 15:59     ` Thor Thayer
  0 siblings, 0 replies; 16+ messages in thread
From: Thor Thayer @ 2016-03-08 15:59 UTC (permalink / raw)
  To: Dinh Nguyen, bp, dougthompson, m.chehab, robh+dt, pawel.moll,
	mark.rutland, ijc+devicetree, galak, linux, grant.likely
  Cc: devicetree, linux-doc, linux-edac, linux-kernel,
	linux-arm-kernel, tthayer.linux

Hi Dinh,

On 03/08/2016 08:50 AM, Dinh Nguyen wrote:
>
>
> On 03/07/2016 01:43 PM, tthayer@opensource.altera.com wrote:
>> From: Thor Thayer <tthayer@opensource.altera.com>
>>
>> Add the device tree entries needed to support the Altera L2
>> cache EDAC on the Arria10 chip.
>>
>> Signed-off-by: Thor Thayer <tthayer@opensource.altera.com>
>> ---
>> v2 Match register value (l2-ecc@ffd06010)
>> ---
>>   arch/arm/boot/dts/socfpga_arria10.dtsi |   14 ++++++++++++++
>>   1 file changed, 14 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi
>> index cce9e50..44aeb3f 100644
>> --- a/arch/arm/boot/dts/socfpga_arria10.dtsi
>> +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi
>> @@ -599,6 +599,20 @@
>>   			reg = <0xffe00000 0x40000>;
>>   		};
>>
>> +		eccmgr: eccmgr@ffd06090 {
>> +			compatible = "altr,socfpga-ecc-manager";
>> +			#address-cells = <1>;
>> +			#size-cells = <1>;
>> +			ranges;
>> +
>> +			l2-ecc@ffd06010 {
>> +				compatible = "altr,socfpga-a10-l2-ecc";
>> +				reg = <0xffd06010 0x4>;
>> +				interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>,
>> +					     <0 0 IRQ_TYPE_LEVEL_HIGH>;
>> +			};
>> +		};
>> +
>
> Just checking if these addresses are correct. The eccmgr is at
> 0xffd06090, but the l2-ecc is at 0xffd06010? I would have thought from
> the placement the l2-ecc address would be inside the eccmgr's address?
>
> Dinh
>

Yes, this is confusing and I'll clarify/reorganize in the next series. 
The eccmgr is pointing to the ECC IRQ mask bits. These registers and the 
L2 ECC registers are organized in different areas within the system manager.

I'm actually redoing the series since the Arria10 IRQ handling is 
significantly different.

Since this change will affect the bindings and dti (the eccmgr will have 
the IRQs), please disregard this series.

Sorry for the noise.

Thor

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-03-08 15:55 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-07 19:42 [PATCHv2 0/11] Series adding Altera Arria10 L2 Cache EDAC tthayer
2016-03-07 19:42 ` [PATCHv2 01/11] EDAC: Altera L2 Kconfig change from select to depends upon tthayer
2016-03-07 19:42 ` [PATCHv2 02/11] EDAC, altera: Move Device structs and defines to header file tthayer
2016-03-07 19:42 ` [PATCHv2 03/11] EDAC, altera: Add register offset for ECC Enable tthayer
2016-03-07 19:43 ` [PATCHv2 04/11] EDAC, altera: Add register offset for ECC Error Inject tthayer
2016-03-07 19:43 ` [PATCHv2 05/11] EDAC, altera: Add register offset for ECC Error Clear tthayer
2016-03-07 19:43 ` [PATCHv2 06/11] EDAC, altera: Add IRQ flags to private data struct tthayer
2016-03-07 19:43 ` [PATCHv2 07/11] EDAC, altera: Add status offset & masks tthayer
2016-03-08 15:52   ` Thor Thayer
2016-03-07 19:43 ` [PATCHv2 08/11] Documentation: dt: socfpga: Add Altera Arria10 L2 cache binding tthayer
2016-03-07 19:43 ` [PATCHv2 09/11] EDAC, altera: Addition of Arria10 L2 Cache ECC tthayer
2016-03-07 19:43 ` [PATCHv2 10/11] ARM: socfpga: Enable Arria10 L2 cache ECC on startup tthayer
2016-03-08 14:45   ` Dinh Nguyen
2016-03-07 19:43 ` [PATCHv2 11/11] ARM: dts: Add Altera Arria10 L2 Cache EDAC devicetree entry tthayer
2016-03-08 14:50   ` Dinh Nguyen
2016-03-08 15:59     ` Thor Thayer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).