can: m_can: Call the RAM init directly from m_can_chip_config
authorVivek Yadav <vivek.2311@samsung.com>
Wed, 7 Dec 2022 10:06:31 +0000 (15:36 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:14:20 +0000 (13:14 +0100)
[ Upstream commit eaacfeaca7ad0804b9a6eff7afeba93a87db7638 ]

When we try to access the mcan message ram addresses during the probe,
hclk is gated by any other drivers or disabled, because of that probe
gets failed.

Move the mram init functionality to mcan chip config called by
m_can_start from mcan open function, by that time clocks are
enabled.

Suggested-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Vivek Yadav <vivek.2311@samsung.com>
Link: https://lore.kernel.org/all/20221207100632.96200-2-vivek.2311@samsung.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Stable-dep-of: 67727a17a6b3 ("can: tcan4x5x: Fix use of register error status mask")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/can/m_can/m_can.c
drivers/net/can/m_can/m_can_platform.c
drivers/net/can/m_can/tcan4x5x-core.c

index 46ab6155795c0f3376996b3617fbf94f2732b1e0..e027229c1955bddcf873efe7e3d9c6d92de829ea 100644 (file)
@@ -1248,10 +1248,17 @@ static int m_can_set_bittiming(struct net_device *dev)
  * - setup bittiming
  * - configure timestamp generation
  */
-static void m_can_chip_config(struct net_device *dev)
+static int m_can_chip_config(struct net_device *dev)
 {
        struct m_can_classdev *cdev = netdev_priv(dev);
        u32 cccr, test;
+       int err;
+
+       err = m_can_init_ram(cdev);
+       if (err) {
+               dev_err(cdev->dev, "Message RAM configuration failed\n");
+               return err;
+       }
 
        m_can_config_endisable(cdev, true);
 
@@ -1375,18 +1382,25 @@ static void m_can_chip_config(struct net_device *dev)
 
        if (cdev->ops->init)
                cdev->ops->init(cdev);
+
+       return 0;
 }
 
-static void m_can_start(struct net_device *dev)
+static int m_can_start(struct net_device *dev)
 {
        struct m_can_classdev *cdev = netdev_priv(dev);
+       int ret;
 
        /* basic m_can configuration */
-       m_can_chip_config(dev);
+       ret = m_can_chip_config(dev);
+       if (ret)
+               return ret;
 
        cdev->can.state = CAN_STATE_ERROR_ACTIVE;
 
        m_can_enable_all_interrupts(cdev);
+
+       return 0;
 }
 
 static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
@@ -1824,7 +1838,9 @@ static int m_can_open(struct net_device *dev)
        }
 
        /* start the m_can controller */
-       m_can_start(dev);
+       err = m_can_start(dev);
+       if (err)
+               goto exit_irq_fail;
 
        can_led_event(dev, CAN_LED_EVENT_OPEN);
 
@@ -2082,9 +2098,13 @@ int m_can_class_resume(struct device *dev)
                ret = m_can_clk_start(cdev);
                if (ret)
                        return ret;
+               ret  = m_can_start(ndev);
+               if (ret) {
+                       m_can_clk_stop(cdev);
+
+                       return ret;
+               }
 
-               m_can_init_ram(cdev);
-               m_can_start(ndev);
                netif_device_attach(ndev);
                netif_start_queue(ndev);
        }
index eee47bad0592007c6bce70def5e015d2fab4cdaf..de6d8e01bf2e81e97d61d222bc3afc031d7264fc 100644 (file)
@@ -140,10 +140,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)
index 9b735eccec8af1f6d070e454f3fc348f287de763..a0eee69e52eacff550114dc0e2766a4786576b1a 100644 (file)
@@ -229,11 +229,6 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
        if (ret)
                return ret;
 
-       /* Zero out the MCAN buffers */
-       ret = m_can_init_ram(cdev);
-       if (ret)
-               return ret;
-
        ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
                                 TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL);
        if (ret)