[PATCH 4/4] powerpc/mpc8548: Add workaround for erratum NMG_SRIO135

Zhao Chenhui chenhui.zhao at freescale.com
Tue Mar 6 20:10:56 EST 2012


From: chenhui zhao <chenhui.zhao at freescale.com>

Issue:
Applications using lwarx/stwcx instructions in the core to
compete for a software lock or semaphore with a device on
RapidIO using read atomic set, clr, inc, or dec in a similar
manner may falsely result in both masters seeing the lock
as "available". This could result in data corruption as
both masters try to modify the same piece of data protected
by the lock.

Workaround:
Set bits 13 and 29 of CCSR offset 0x01010 (EEBPCR register
of the ECM) during initialization and leave them set
indefinitely. This may slightly degrade overall system
performance.

Refer to SRIO39 in MPC8548 errata document.

Signed-off-by: Gong Chen <g.chen at freescale.com>
Signed-off-by: Zhao Chenhui <chenhui.zhao at freescale.com>
Signed-off-by: Li Yang <leoli at freescale.com>
---
 arch/powerpc/sysdev/fsl_rio.c |   44 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c
index a4c4f4a..78a0c3d 100644
--- a/arch/powerpc/sysdev/fsl_rio.c
+++ b/arch/powerpc/sysdev/fsl_rio.c
@@ -35,6 +35,8 @@
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <asm/machdep.h>
+#include <asm/mpc85xx.h>
+#include <sysdev/fsl_soc.h>
 
 #include "fsl_rio.h"
 
@@ -321,6 +323,37 @@ static inline void fsl_rio_info(struct device *dev, u32 ccsr)
 	}
 }
 
+#define CCSR_ECM_EEBPCR_OFF 0x10
+/*
+ * fixup_erratum_srio135 - Fix Serial RapidIO atomic operation erratum
+ */
+static int fixup_erratum_srio135(struct device *dev)
+{
+	struct device_node *np;
+	void __iomem *ecm;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,mpc8548-ecm");
+	if (!np) {
+		dev_err(dev, "no ECM node found.\n");
+		return -ENODEV;
+	}
+
+	ecm = of_iomap(np, 0);
+	of_node_put(np);
+	if (!ecm) {
+		dev_err(dev, "failed to map ECM register base.\n");
+		return -ENODEV;
+	}
+	/*
+	 * Set bits 13 and 29 of the EEBPCR register in the ECM
+	 * during initialization and leave them set indefinitely.
+	 */
+	setbits32(ecm + CCSR_ECM_EEBPCR_OFF, 0x00040004);
+	iounmap(ecm);
+
+	return 0;
+}
+
 /**
  * fsl_rio_setup - Setup Freescale PowerPC RapidIO interface
  * @dev: platform_device pointer
@@ -358,6 +391,17 @@ int fsl_rio_setup(struct platform_device *dev)
 				dev->dev.of_node->full_name);
 		return -EFAULT;
 	}
+
+	/* Fix erratum NMG_SRIO135 */
+	if (fsl_svr_is(SVR_8548) || fsl_svr_is(SVR_8548_E)) {
+		rc = fixup_erratum_srio135(&dev->dev);
+		if (rc) {
+			dev_err(&dev->dev,
+				"Failed to fix the erratum NMG_SRIO135.");
+			return rc;
+		}
+	}
+
 	dev_info(&dev->dev, "Of-device full name %s\n",
 			dev->dev.of_node->full_name);
 	dev_info(&dev->dev, "Regs: %pR\n", &regs);
-- 
1.6.4.1




More information about the Linuxppc-dev mailing list