diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index a776cab1a5a4..ddff615ccad4 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -307,6 +307,14 @@ enum m_can_reg {
 #define TX_EVENT_MM_MASK	GENMASK(31, 24)
 #define TX_EVENT_TXTS_MASK	GENMASK(15, 0)
 
+/* ECC Config Bits */
+#define MCAN_ECC_CFG_VALID    BIT(5)
+#define MCAN_ECC_ENABLE       BIT(3)
+#define MCAN_ECC_INIT_ENABLE  BIT(1)
+#define MCAN_ECC_INIT_DONE    BIT(0)
+#define MCAN_ECC_REG_MASK     GENMASK(5, 0)
+#define MCAN_ECC_INIT_TIMEOUT 100
+
 /* The ID and DLC registers are adjacent in M_CAN FIFO memory,
  * and we can save a (potentially slow) bus round trip by combining
  * reads and writes to them.
@@ -1516,9 +1524,9 @@ static int m_can_dev_setup(struct m_can_classdev *cdev)
 	}
 
 	if (cdev->ops->init)
-		cdev->ops->init(cdev);
+		err = cdev->ops->init(cdev);
 
-	return 0;
+	return err;
 }
 
 static void m_can_stop(struct net_device *dev)
@@ -1535,6 +1543,39 @@ static void m_can_stop(struct net_device *dev)
 	cdev->can.state = CAN_STATE_STOPPED;
 }
 
+int m_can_config_mram_ecc_check(struct m_can_classdev *cdev, bool enable)
+{
+	struct  m_can_ecc_regmap *ecc_cfg = &cdev->ecc_cfg_sys;
+	int val, ret;
+
+	val = FIELD_PREP(MCAN_ECC_REG_MASK, MCAN_ECC_ENABLE |
+			 MCAN_ECC_CFG_VALID | MCAN_ECC_INIT_ENABLE);
+	regmap_clear_bits(ecc_cfg->syscon, ecc_cfg->reg, val);
+
+	if (enable) {
+		val = FIELD_PREP(MCAN_ECC_REG_MASK, MCAN_ECC_ENABLE |
+				 MCAN_ECC_INIT_ENABLE);
+		regmap_set_bits(ecc_cfg->syscon, ecc_cfg->reg, val);
+	}
+
+	/* after enable or disable, valid flag need to be set*/
+	val = FIELD_PREP(MCAN_ECC_REG_MASK, MCAN_ECC_CFG_VALID);
+	regmap_set_bits(ecc_cfg->syscon, ecc_cfg->reg, val);
+
+	if (enable) {
+		/* Poll for completion */
+		ret = regmap_read_poll_timeout(ecc_cfg->syscon, ecc_cfg->reg,
+					       val,
+					       (val & MCAN_ECC_INIT_DONE), 5,
+					       MCAN_ECC_INIT_TIMEOUT);
+
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int m_can_close(struct net_device *dev)
 {
 	struct m_can_classdev *cdev = netdev_priv(dev);
@@ -1557,6 +1598,9 @@ static int m_can_close(struct net_device *dev)
 	if (cdev->is_peripheral)
 		can_rx_offload_disable(&cdev->offload);
 
+	if (cdev->ops->deinit)
+		cdev->ops->deinit(cdev);
+
 	close_candev(dev);
 
 	phy_power_off(cdev->transceiver);
diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h
index 401410022823..9821b135a2be 100644
--- a/drivers/net/can/m_can/m_can.h
+++ b/drivers/net/can/m_can/m_can.h
@@ -19,6 +19,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/of.h>
@@ -26,6 +27,7 @@
 #include <linux/phy/phy.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pm_runtime.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 
@@ -52,12 +54,23 @@ enum m_can_mram_cfg {
 	MRAM_CFG_NUM,
 };
 
+enum m_can_ecc_cfg {
+	ECC_DISABLE = 0,
+	ECC_ENABLE,
+};
+
 /* address offset and element number for each FIFO/Buffer in the Message RAM */
 struct mram_cfg {
 	u16 off;
 	u8  num;
 };
 
+struct m_can_ecc_regmap {
+	struct regmap *syscon;  /* for mram ecc ctrl. reg. access */
+	unsigned int reg;       /* register index within syscon */
+	u8 ecc_cfg_flag;
+};
+
 struct m_can_classdev;
 struct m_can_ops {
 	/* Device specific call backs */
@@ -68,6 +81,7 @@ struct m_can_ops {
 	int (*write_fifo)(struct m_can_classdev *cdev, int addr_offset,
 			  const void *val, size_t val_count);
 	int (*init)(struct m_can_classdev *cdev);
+	int (*deinit)(struct m_can_classdev *cdev);
 };
 
 struct m_can_classdev {
@@ -92,7 +106,9 @@ struct m_can_classdev {
 	int pm_clock_support;
 	int is_peripheral;
 
+	struct m_can_ecc_regmap ecc_cfg_sys; /* ecc config via syscon regmap */
 	struct mram_cfg mcfg[MRAM_CFG_NUM];
+	u8 mram_cfg_flag;
 };
 
 struct m_can_classdev *m_can_class_allocate_dev(struct device *dev, int sizeof_priv);
@@ -104,4 +120,5 @@ int m_can_init_ram(struct m_can_classdev *priv);
 
 int m_can_class_suspend(struct device *dev);
 int m_can_class_resume(struct device *dev);
+int m_can_config_mram_ecc_check(struct m_can_classdev *cdev, bool enable);
 #endif	/* _CAN_M_H_ */
diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
index b5a5bedb3116..1281214a3f43 100644
--- a/drivers/net/can/m_can/m_can_platform.c
+++ b/drivers/net/can/m_can/m_can_platform.c
@@ -67,11 +67,83 @@ static int iomap_write_fifo(struct m_can_classdev *cdev, int offset,
 	return 0;
 }
 
+static int m_can_plat_init(struct m_can_classdev *cdev)
+{
+	struct  m_can_ecc_regmap *ecc_cfg = &cdev->ecc_cfg_sys;
+	struct device_node *np = cdev->dev->of_node;
+	int ret = 0;
+
+	if (cdev->mram_cfg_flag != ECC_ENABLE) {
+		/* Initialize mcan message ram */
+		ret = m_can_init_ram(cdev);
+
+		if (ret)
+			return ret;
+
+		cdev->mram_cfg_flag = ECC_ENABLE;
+	}
+
+	if (ecc_cfg->ecc_cfg_flag != ECC_ENABLE) {
+		/* configure error code check for mram */
+		if (!ecc_cfg->syscon) {
+			ecc_cfg->syscon =
+			syscon_regmap_lookup_by_phandle_args(np,
+							     "tesla,mram-ecc-cfg"
+							     , 1,
+							     &ecc_cfg->reg);
+		}
+
+		if (IS_ERR(ecc_cfg->syscon)) {
+			dev_err(cdev->dev, "couldn't get the syscon reg!\n");
+			goto ecc_failed;
+		}
+
+		if (!ecc_cfg->reg) {
+			dev_err(cdev->dev,
+				"couldn't get the ecc init reg. offset!\n");
+			goto ecc_failed;
+		}
+
+		/* Enable error code check functionality for message ram */
+		if (m_can_config_mram_ecc_check(cdev, ECC_ENABLE))
+			goto ecc_failed;
+
+		ecc_cfg->ecc_cfg_flag = ECC_ENABLE;
+	}
+
+	return 0;
+
+ecc_failed:
+	dev_err(cdev->dev, "Message ram ecc enable config failed\n");
+
+	return 0;
+}
+
+static int m_can_plat_deinit(struct m_can_classdev *cdev)
+{
+	struct  m_can_ecc_regmap *ecc_cfg = &cdev->ecc_cfg_sys;
+
+	if (ecc_cfg->ecc_cfg_flag == ECC_ENABLE) {
+		/* Disable error code check functionality for message ram */
+		if (m_can_config_mram_ecc_check(cdev, ECC_DISABLE)) {
+			dev_err(cdev->dev,
+				"Message ram ecc disable config failed\n");
+			return 0;
+		}
+
+		ecc_cfg->ecc_cfg_flag = ECC_DISABLE;
+	}
+
+	return 0;
+}
+
 static struct m_can_ops m_can_plat_ops = {
 	.read_reg = iomap_read_reg,
 	.write_reg = iomap_write_reg,
 	.write_fifo = iomap_write_fifo,
 	.read_fifo = iomap_read_fifo,
+	.init = m_can_plat_init,
+	.deinit = m_can_plat_deinit,
 };
 
 static int m_can_plat_probe(struct platform_device *pdev)
@@ -140,10 +212,6 @@ static int m_can_plat_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, mcan_class);
 
-	ret = m_can_init_ram(mcan_class);
-	if (ret)
-		goto probe_fail;
-
 	pm_runtime_enable(mcan_class->dev);
 	ret = m_can_class_register(mcan_class);
 	if (ret)
