@@ -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;
}