[jammy xilinx-zynqmp 2/2] can: xilinx_can: Add support for controller reset
Portia Stephens
portia.stephens at canonical.com
Thu Jan 4 00:04:30 UTC 2024
From: Srinivas Neeli <srinivas.neeli at 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 at amd.com>
State: pending
(cherry-picked from commit 433d2843762819d2601f44bfef02e72c9f710063 https://github.com/Xilinx/linux-xlnx.git)
Signed-off-by: Portia Stephens <portia.stephens at canonical.com>
---
drivers/net/can/xilinx_can.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
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;
}
--
2.34.1
More information about the kernel-team
mailing list