drivers: edac: Update the register offsets

Update the register offsets as per the SW interface document. And use
the pvt_info member of edev structure to store the platform device
private data so that the cache error poll function can access the
private data without container_of macro. Update the Kconfig dependency
to make llcc edac driver on llcc core driver.

Change-Id: I66a8dbcfb7bcec98e81a2cb33026d9396f89da63
Signed-off-by: Channagoud Kadabi <ckadabi@codeaurora.org>
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 5ff5679..fb02626 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -462,7 +462,7 @@
 	  APM X-Gene family of SOCs.
 
 config EDAC_QCOM_LLCC
-	depends on EDAC_MM_EDAC
+	depends on EDAC_MM_EDAC && QCOM_LLCC
 	tristate "QCOM LLCC Caches"
 	help
 	  Support for error detection and correction on the
diff --git a/drivers/edac/qcom_llcc_edac.c b/drivers/edac/qcom_llcc_edac.c
index f123868..71f74ad 100644
--- a/drivers/edac/qcom_llcc_edac.c
+++ b/drivers/edac/qcom_llcc_edac.c
@@ -39,27 +39,27 @@
 #define DRP_SYN_REG_CNT	8
 
 /* single & Double Bit syndrome register offsets */
-#define TRP_ECC_SB_ERR_SYN0		0x0002334c
-#define TRP_ECC_DB_ERR_SYN0		0x00023370
-#define DRP_ECC_SB_ERR_SYN0		0x000400A8
-#define DRP_ECC_DB_ERR_SYN0		0x000400D0
+#define TRP_ECC_SB_ERR_SYN0		0x0002304C
+#define TRP_ECC_DB_ERR_SYN0		0x00020370
+#define DRP_ECC_SB_ERR_SYN0		0x0004204C
+#define DRP_ECC_DB_ERR_SYN0		0x00042070
 
 /* Error register offsets */
-#define TRP_ECC_ERROR_STATUS1		0x00023348
-#define TRP_ECC_ERROR_STATUS0		0x00023344
-#define DRP_ECC_ERROR_STATUS1		0x000400A4
-#define DRP_ECC_ERROR_STATUS0		0x000400A0
+#define TRP_ECC_ERROR_STATUS1		0x00020348
+#define TRP_ECC_ERROR_STATUS0		0x00020344
+#define DRP_ECC_ERROR_STATUS1		0x00042048
+#define DRP_ECC_ERROR_STATUS0		0x00042044
 
 /* TRP, DRP interrupt register offsets */
-#define DRP_INTERRUPT_STATUS		0x00040060
-#define TRP_INTERRUPT_0_STATUS		0x00024380
-#define DRP_INTERRUPT_CLEAR		0x00040058
-#define DRP_ECC_ERROR_CNTR_CLEAR	0x00040044
-#define TRP_INTERRUPT_0_CLEAR		0x00024384
-#define TRP_ECC_ERROR_CNTR_CLEAR	0x00023440
+#define DRP_INTERRUPT_STATUS		0x00041000
+#define TRP_INTERRUPT_0_STATUS		0x00020480
+#define DRP_INTERRUPT_CLEAR		0x00041008
+#define DRP_ECC_ERROR_CNTR_CLEAR	0x00040004
+#define TRP_INTERRUPT_0_CLEAR		0x00020484
+#define TRP_ECC_ERROR_CNTR_CLEAR	0x00020440
 
 /* Mask and shift macros */
-#define ECC_DB_ERR_COUNT_MASK	0x0000003f
+#define ECC_DB_ERR_COUNT_MASK	0x0000001f
 #define ECC_DB_ERR_WAYS_MASK	0xffff0000
 #define ECC_DB_ERR_WAYS_SHIFT	16
 
@@ -90,7 +90,6 @@
 };
 
 struct erp_drvdata {
-	struct edac_device_ctl_info *edev_ctl;
 	struct regmap *llcc_map;
 };
 
@@ -107,9 +106,11 @@
 	switch (err_type) {
 	case LLCC_DRAM_CE:
 	case LLCC_DRAM_UE:
+		/* Clear the interrupt */
 		regmap_write(llcc_map, DRP_INTERRUPT_CLEAR, DRP_TRP_INT_CLEAR);
-		regmap_write(llcc_map, TRP_INTERRUPT_CLEAR,
-			     DRP_ECC_ERROR_CNTR_CLEAR);
+		/* Clear the counters */
+		regmap_write(llcc_map, DRP_ECC_ERROR_CNTR_CLEAR,
+			DRP_TRP_CNT_CLEAR);
 		break;
 	case LLCC_TRAM_CE:
 	case LLCC_TRAM_UE:
@@ -190,7 +191,7 @@
 
 	for (i = 0; i < DRP_SYN_REG_CNT; i++) {
 		synd_reg = DRP_ECC_DB_ERR_SYN0 + (i * 4);
-		regmap_read(llcc_map, synd_red, &synd_val);
+		regmap_read(llcc_map, synd_reg, &synd_val);
 		edac_printk(KERN_CRIT, EDAC_LLCC, "DRP_ECC_SYN%d: 0x%8x\n",
 			i, synd_val);
 	}
@@ -215,6 +216,7 @@
 	int sb_err_ways;
 	u32 synd_reg;
 	u32 synd_val;
+	u32 synd_reg_offset;
 
 	for (i = 0; i < DRP_SYN_REG_CNT; i++) {
 		synd_reg_offset = DRP_ECC_SB_ERR_SYN0 + (i * 4);
@@ -237,7 +239,8 @@
 }
 
 
-static void dump_syn_reg(int err_type, struct regmap *llcc_map)
+static void dump_syn_reg(struct edac_device_ctl_info *edev_ctl,
+			 int err_type, struct regmap *llcc_map)
 {
 	switch (err_type) {
 	case LLCC_DRAM_CE:
@@ -256,7 +259,7 @@
 
 	qcom_llcc_clear_errors(err_type, llcc_map);
 
-	errors[err_type].func(edev_ctl, 1, 0, errors[err_type].msg);
+	errors[err_type].func(edev_ctl, 0, 0, errors[err_type].msg);
 }
 
 static void qcom_llcc_poll_cache_errors
@@ -264,9 +267,7 @@
 {
 	u32 drp_error;
 	u32 trp_error;
-	struct erp_drvdata *drv;
-
-	drv = container_of(edev_ctl, struct erp_drvdata, edev_ctl);
+	struct erp_drvdata *drv = edev_ctl->pvt_info;
 
 	/* Look for Data RAM errors */
 	regmap_read(drv->llcc_map, DRP_INTERRUPT_STATUS, &drp_error);
@@ -274,11 +275,11 @@
 	if (drp_error & SB_ECC_ERROR) {
 		edac_printk(KERN_CRIT, EDAC_LLCC,
 			"Single Bit Error detected in Data Ram\n");
-		dump_syn_reg(LLCC_DRAM_CE, drv->llcc_map);
+		dump_syn_reg(edev_ctl, LLCC_DRAM_CE, drv->llcc_map);
 	} else if (drp_error & DB_ECC_ERROR) {
 		edac_printk(KERN_CRIT, EDAC_LLCC,
 			"Double Bit Error detected in Data Ram\n");
-		dump_syn_reg(LLCC_DRAM_UE, drv->llcc_map);
+		dump_syn_reg(edev_ctl, LLCC_DRAM_UE, drv->llcc_map);
 	}
 
 	/* Look for Tag RAM errors */
@@ -286,11 +287,11 @@
 	if (trp_error & SB_ECC_ERROR) {
 		edac_printk(KERN_CRIT, EDAC_LLCC,
 			"Single Bit Error detected in Tag Ram\n");
-		dump_syn_reg(LLCC_TRAM_CE, drv->llcc_map);
+		dump_syn_reg(edev_ctl, LLCC_TRAM_CE, drv->llcc_map);
 	} else if (trp_error & DB_ECC_ERROR) {
 		edac_printk(KERN_CRIT, EDAC_LLCC,
 			"Double Bit Error detected in Tag Ram\n");
-		dump_syn_reg(LLCC_TRAM_UE, drv->llcc_map);
+		dump_syn_reg(edev_ctl, LLCC_TRAM_UE, drv->llcc_map);
 	}
 }
 
@@ -298,11 +299,24 @@
 {
 	int rc = 0;
 	struct erp_drvdata *drv;
+	struct edac_device_ctl_info *edev_ctl;
 	struct device *dev = &pdev->dev;
 
-	drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
-	if (!drv)
-		return -ENOMEM;
+	/* Allocate edac control info */
+	edev_ctl = edac_device_alloc_ctl_info(sizeof(*drv), "qcom-llcc", 1,
+			NULL, 1, 1, NULL, 0, edac_device_alloc_index());
+
+	edev_ctl->dev = dev;
+	edev_ctl->mod_name = dev_name(dev);
+	edev_ctl->dev_name = dev_name(dev);
+	edev_ctl->ctl_name = "llcc";
+	edev_ctl->poll_msec = poll_msec;
+	edev_ctl->edac_check = qcom_llcc_poll_cache_errors;
+	edev_ctl->defer_work = 1;
+	edev_ctl->panic_on_ce = LLCC_ERP_PANIC_ON_CE;
+	edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
+
+	drv = edev_ctl->pvt_info;
 
 	drv->llcc_map = syscon_node_to_regmap(dev->parent->of_node);
 	if (IS_ERR(drv->llcc_map)) {
@@ -310,32 +324,18 @@
 		return -ENOMEM;
 	}
 
-	/* Allocate edac control info */
-	drv->edev_ctl = edac_device_alloc_ctl_info(0, "qcom-llcc", 1, NULL, 1,
-				1, NULL, 0, edac_device_alloc_index());
+	platform_set_drvdata(pdev, edev_ctl);
 
-	drv->edev_ctl->dev = dev;
-	drv->edev_ctl->mod_name = dev_name(dev);
-	drv->edev_ctl->dev_name = dev_name(dev);
-	drv->edev_ctl->ctl_name = "llcc";
-	drv->edev_ctl->poll_msec = poll_msec;
-	drv->edev_ctl->edac_check = qcom_llcc_poll_cache_errors;
-	drv->edev_ctl->defer_work = 1;
-	drv->edev_ctl->panic_on_ce = LLCC_ERP_PANIC_ON_CE;
-	drv->edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE;
-	platform_set_drvdata(pdev, drv);
-
-	rc = edac_device_add_device(drv->edev_ctl);
+	rc = edac_device_add_device(edev_ctl);
 	if (rc)
-		edac_device_free_ctl_info(drv->edev_ctl);
+		edac_device_free_ctl_info(edev_ctl);
 
 	return rc;
 }
 
 static int qcom_llcc_erp_remove(struct platform_device *pdev)
 {
-	struct erp_drvdata *drv = dev_get_drvdata(&pdev->dev);
-	struct edac_device_ctl_info *edev_ctl = drv->edev_ctl;
+	struct edac_device_ctl_info *edev_ctl = dev_get_drvdata(&pdev->dev);
 
 	edac_device_del_device(edev_ctl->dev);
 	edac_device_free_ctl_info(edev_ctl);