diff mbox series

[jammy,xilinx-zynqmp,v2,2/2] can: xilinx_can: Add support for controller reset

Message ID 20240103235646.36605-3-portia.stephens@canonical.com
State New
Headers show
Series Add support for KD240 platform | expand

Commit Message

Portia Stephens Jan. 3, 2024, 11:56 p.m. UTC
From: Srinivas Neeli <srinivas.neeli@amd.com>

Add support for an optional reset for the CAN controller using the reset
driver. If the CAN node contains the "resets" property, then this logic
will perform CAN controller reset.

BugLink: https://bugs.launchpad.net/bugs/2046280

Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>
State: pending
(cherry-picked from commit 433d2843762819d2601f44bfef02e72c9f710063 https://github.com/Xilinx/linux-xlnx.git)
Signed-off-by: Portia Stephens <portia.stephens@canonical.com>
---
 drivers/net/can/xilinx_can.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 622d71058fc9..5ce99fb7ef22 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -28,6 +28,7 @@ 
 #include <linux/can/error.h>
 #include <linux/can/led.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 
 #define DRIVER_NAME	"xilinx_can"
 
@@ -225,6 +226,7 @@  struct xcan_priv {
 	struct clk *bus_clk;
 	struct clk *can_clk;
 	struct xcan_devtype_data devtype;
+	struct reset_control *rstc;
 };
 
 /* CAN Bittiming constants as per Xilinx CAN specs */
@@ -1762,6 +1764,17 @@  static int xcan_probe(struct platform_device *pdev)
 	priv->can.do_get_berr_counter = xcan_get_berr_counter;
 	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
 					CAN_CTRLMODE_BERR_REPORTING;
+	priv->rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(priv->rstc)) {
+		dev_err(&pdev->dev, "Cannot get CAN reset.\n");
+		ret = PTR_ERR(priv->rstc);
+		goto err_free;
+	}
+
+	ret = reset_control_reset(priv->rstc);
+	if (ret)
+		goto err_free;
+
 
 	if (devtype->cantype == XAXI_CANFD)
 		priv->can.data_bittiming_const =
@@ -1783,7 +1796,7 @@  static int xcan_probe(struct platform_device *pdev)
 	/* Get IRQ for the device */
 	ret = platform_get_irq(pdev, 0);
 	if (ret < 0)
-		goto err_free;
+		goto err_reset;
 
 	ndev->irq = ret;
 
@@ -1798,14 +1811,14 @@  static int xcan_probe(struct platform_device *pdev)
 	if (IS_ERR(priv->can_clk)) {
 		ret = dev_err_probe(&pdev->dev, PTR_ERR(priv->can_clk),
 				    "device clock not found\n");
-		goto err_free;
+		goto err_reset;
 	}
 
 	priv->bus_clk = devm_clk_get(&pdev->dev, devtype->bus_clk_name);
 	if (IS_ERR(priv->bus_clk)) {
 		ret = dev_err_probe(&pdev->dev, PTR_ERR(priv->bus_clk),
 				    "bus clock not found\n");
-		goto err_free;
+		goto err_reset;
 	}
 
 	priv->write_reg = xcan_write_reg_le;
@@ -1854,6 +1867,8 @@  static int xcan_probe(struct platform_device *pdev)
 err_disableclks:
 	pm_runtime_put(priv->dev);
 	pm_runtime_disable(&pdev->dev);
+err_reset:
+	reset_control_assert(priv->rstc);
 err_free:
 	free_candev(ndev);
 err:
@@ -1876,6 +1891,7 @@  static int xcan_remove(struct platform_device *pdev)
 	pm_runtime_disable(&pdev->dev);
 	netif_napi_del(&priv->napi);
 	free_candev(ndev);
+	reset_control_assert(priv->rstc);
 
 	return 0;
 }