Skip to content

Commit d7588f0

Browse files
hellow554marckleinebudde
authored andcommitted
can: dev: add transceiver capabilities to xilinx_can
Currently the xilinx_can driver does not support adding a phy like the "ti,tcan1043" to its devicetree. This code makes it possible to add such phy, so that the kernel makes sure that the PHY is in operational state, when the link is set to an "up" state. Signed-off-by: Marcel Hellwig <[email protected]> Link: https://lore.kernel.org/r/[email protected] [mkl: call phy_power_off() after pm_runtime_put()] [mkl: remove error message for phy_power_on() failure] [mkl: update kernel-doc for struct xcan_priv] Signed-off-by: Marc Kleine-Budde <[email protected]>
1 parent 843b846 commit d7588f0

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

drivers/net/can/xilinx_can.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <linux/types.h>
2929
#include <linux/can/dev.h>
3030
#include <linux/can/error.h>
31+
#include <linux/phy/phy.h>
3132
#include <linux/pm_runtime.h>
3233

3334
#define DRIVER_NAME "xilinx_can"
@@ -198,6 +199,7 @@ struct xcan_devtype_data {
198199
* @bus_clk: Pointer to struct clk
199200
* @can_clk: Pointer to struct clk
200201
* @devtype: Device type specific constants
202+
* @transceiver: Optional pointer to associated CAN transceiver
201203
*/
202204
struct xcan_priv {
203205
struct can_priv can;
@@ -215,6 +217,7 @@ struct xcan_priv {
215217
struct clk *bus_clk;
216218
struct clk *can_clk;
217219
struct xcan_devtype_data devtype;
220+
struct phy *transceiver;
218221
};
219222

220223
/* CAN Bittiming constants as per Xilinx CAN specs */
@@ -1419,6 +1422,10 @@ static int xcan_open(struct net_device *ndev)
14191422
struct xcan_priv *priv = netdev_priv(ndev);
14201423
int ret;
14211424

1425+
ret = phy_power_on(priv->transceiver);
1426+
if (ret)
1427+
return ret;
1428+
14221429
ret = pm_runtime_get_sync(priv->dev);
14231430
if (ret < 0) {
14241431
netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
@@ -1462,6 +1469,7 @@ static int xcan_open(struct net_device *ndev)
14621469
free_irq(ndev->irq, ndev);
14631470
err:
14641471
pm_runtime_put(priv->dev);
1472+
phy_power_off(priv->transceiver);
14651473

14661474
return ret;
14671475
}
@@ -1483,6 +1491,7 @@ static int xcan_close(struct net_device *ndev)
14831491
close_candev(ndev);
14841492

14851493
pm_runtime_put(priv->dev);
1494+
phy_power_off(priv->transceiver);
14861495

14871496
return 0;
14881497
}
@@ -1713,6 +1722,7 @@ static int xcan_probe(struct platform_device *pdev)
17131722
{
17141723
struct net_device *ndev;
17151724
struct xcan_priv *priv;
1725+
struct phy *transceiver;
17161726
const struct of_device_id *of_id;
17171727
const struct xcan_devtype_data *devtype = &xcan_axi_data;
17181728
void __iomem *addr;
@@ -1843,6 +1853,14 @@ static int xcan_probe(struct platform_device *pdev)
18431853
goto err_free;
18441854
}
18451855

1856+
transceiver = devm_phy_optional_get(&pdev->dev, NULL);
1857+
if (IS_ERR(transceiver)) {
1858+
ret = PTR_ERR(transceiver);
1859+
dev_err_probe(&pdev->dev, ret, "failed to get phy\n");
1860+
goto err_free;
1861+
}
1862+
priv->transceiver = transceiver;
1863+
18461864
priv->write_reg = xcan_write_reg_le;
18471865
priv->read_reg = xcan_read_reg_le;
18481866

@@ -1869,6 +1887,7 @@ static int xcan_probe(struct platform_device *pdev)
18691887
goto err_disableclks;
18701888
}
18711889

1890+
of_can_transceiver(ndev);
18721891
pm_runtime_put(&pdev->dev);
18731892

18741893
if (priv->devtype.flags & XCAN_FLAG_CANFD_2) {

0 commit comments

Comments
 (0)