| From 2ffe7b230b60257a1e29ac1b76226edd121c1cb9 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 12 Feb 2021 18:17:48 -0600 |
| Subject: net: axienet: Handle deferred probe on clock properly |
| |
| From: Robert Hancock <robert.hancock@calian.com> |
| |
| [ Upstream commit 57baf8cc70ea4cf5503c9d42f31f6a86d7f5ff1a ] |
| |
| This driver is set up to use a clock mapping in the device tree if it is |
| present, but still work without one for backward compatibility. However, |
| if getting the clock returns -EPROBE_DEFER, then we need to abort and |
| return that error from our driver initialization so that the probe can |
| be retried later after the clock is set up. |
| |
| Move clock initialization to earlier in the process so we do not waste as |
| much effort if the clock is not yet available. Switch to use |
| devm_clk_get_optional and abort initialization on any error reported. |
| Also enable the clock regardless of whether the controller is using an MDIO |
| bus, as the clock is required in any case. |
| |
| Fixes: 09a0354cadec267be7f ("net: axienet: Use clock framework to get device clock rate") |
| Signed-off-by: Robert Hancock <robert.hancock@calian.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| .../net/ethernet/xilinx/xilinx_axienet_main.c | 26 +++++++++---------- |
| 1 file changed, 12 insertions(+), 14 deletions(-) |
| |
| diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c |
| index 9aafd3ecdaa4d..eea0bb7c23ede 100644 |
| --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c |
| +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c |
| @@ -1805,6 +1805,18 @@ static int axienet_probe(struct platform_device *pdev) |
| lp->options = XAE_OPTION_DEFAULTS; |
| lp->rx_bd_num = RX_BD_NUM_DEFAULT; |
| lp->tx_bd_num = TX_BD_NUM_DEFAULT; |
| + |
| + lp->clk = devm_clk_get_optional(&pdev->dev, NULL); |
| + if (IS_ERR(lp->clk)) { |
| + ret = PTR_ERR(lp->clk); |
| + goto free_netdev; |
| + } |
| + ret = clk_prepare_enable(lp->clk); |
| + if (ret) { |
| + dev_err(&pdev->dev, "Unable to enable clock: %d\n", ret); |
| + goto free_netdev; |
| + } |
| + |
| /* Map device registers */ |
| ethres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| lp->regs = devm_ioremap_resource(&pdev->dev, ethres); |
| @@ -1980,20 +1992,6 @@ static int axienet_probe(struct platform_device *pdev) |
| |
| lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); |
| if (lp->phy_node) { |
| - lp->clk = devm_clk_get(&pdev->dev, NULL); |
| - if (IS_ERR(lp->clk)) { |
| - dev_warn(&pdev->dev, "Failed to get clock: %ld\n", |
| - PTR_ERR(lp->clk)); |
| - lp->clk = NULL; |
| - } else { |
| - ret = clk_prepare_enable(lp->clk); |
| - if (ret) { |
| - dev_err(&pdev->dev, "Unable to enable clock: %d\n", |
| - ret); |
| - goto free_netdev; |
| - } |
| - } |
| - |
| ret = axienet_mdio_setup(lp); |
| if (ret) |
| dev_warn(&pdev->dev, |
| -- |
| 2.27.0 |
| |