summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDong Aisheng <b29396@freescale.com>2014-11-07 16:45:14 +0800
committerMarc Kleine-Budde <mkl@pengutronix.de>2014-11-18 21:35:03 +0100
commit962845da54afe2fc7ebf64c2d8bb5aa65a826b2f (patch)
treeed12bbff1d3a12e9861020b5ec7ff3f52ed2d356
parentefe22286e05751e9913a8002fefdb45cdb7361ad (diff)
downloadlinux-stable-962845da54afe2fc7ebf64c2d8bb5aa65a826b2f.tar.gz
linux-stable-962845da54afe2fc7ebf64c2d8bb5aa65a826b2f.tar.bz2
linux-stable-962845da54afe2fc7ebf64c2d8bb5aa65a826b2f.zip
can: m_can: add missing message RAM initialization
The M_CAN message RAM is usually equipped with a parity or ECC functionality. But RAM cells suffer a hardware reset and can therefore hold arbitrary content at startup - including parity and/or ECC bits. To prevent the M_CAN controller detecting checksum errors when reading potentially uninitialized TX message RAM content to transmit CAN frames the TX message RAM has to be written with (any kind of) initial data. Signed-off-by: Dong Aisheng <b29396@freescale.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--drivers/net/can/m_can/m_can.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index e61886bf1bb3..268ad5064c47 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -1010,7 +1010,7 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
struct resource *res;
void __iomem *addr;
u32 out_val[MRAM_CFG_LEN];
- int ret;
+ int i, start, end, ret;
/* message ram could be shared */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
@@ -1061,6 +1061,15 @@ static int m_can_of_parse_mram(struct platform_device *pdev,
priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
+ /* initialize the entire Message RAM in use to avoid possible
+ * ECC/parity checksum errors when reading an uninitialized buffer
+ */
+ start = priv->mcfg[MRAM_SIDF].off;
+ end = priv->mcfg[MRAM_TXB].off +
+ priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
+ for (i = start; i < end; i += 4)
+ writel(0x0, priv->mram_base + i);
+
return 0;
}