From 1a905ec734cfe924f72252f3cf36c3d00c52af06 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 17 Jan 2014 21:24:41 +0800 Subject: [PATCH] net: stmmac: Add support for optional reset control The DWMAC has a reset assert line, which is used on some SoCs. Add an optional reset control to stmmac driver core. To support reset control deferred probing, this patch changes the driver probe function to return the actual error, instead of just -EINVAL. Signed-off-by: Chen-Yu Tsai Signed-off-by: David S. Miller --- .../devicetree/bindings/net/stmmac.txt | 3 +++ drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 + drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 ++ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 19 ++++++++++++++++++- .../net/ethernet/stmicro/stmmac/stmmac_pci.c | 4 ++-- .../ethernet/stmicro/stmmac/stmmac_platform.c | 4 ++-- 6 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index eba0e5e59ebe2..d132513e8fac4 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -30,6 +30,9 @@ Required properties: Optional properties: - mac-address: 6 bytes, mac address +- resets: Should contain a phandle to the STMMAC reset signal, if any +- reset-names: Should contain the reset signal name "stmmaceth", if a + reset phandle is given Examples: diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 6e52c0f74cd9d..b59d1ef5f6d45 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -5,6 +5,7 @@ config STMMAC_ETH select PHYLIB select CRC32 select PTP_1588_CLOCK + select RESET_CONTROLLER ---help--- This is the driver for the Ethernet IPs are built around a Synopsys IP Core and only tested on the STMicroelectronics diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 73709e9ddcd11..c1c141fe15e70 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -32,6 +32,7 @@ #include #include "common.h" #include +#include struct stmmac_priv { /* Frequently used values are kept adjacent for cache effect */ @@ -91,6 +92,7 @@ struct stmmac_priv { int wolopts; int wol_irq; struct clk *stmmac_clk; + struct reset_control *stmmac_rst; int clk_csr; struct timer_list eee_ctrl_timer; int lpi_irq; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 0d2c4cb0996b3..0c5c1208900e5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -51,6 +51,7 @@ #include #include "stmmac_ptp.h" #include "stmmac.h" +#include #define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x) #define JUMBO_LEN 9000 @@ -2728,10 +2729,24 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, if (IS_ERR(priv->stmmac_clk)) { dev_warn(priv->device, "%s: warning: cannot get CSR clock\n", __func__); + ret = PTR_ERR(priv->stmmac_clk); goto error_clk_get; } clk_prepare_enable(priv->stmmac_clk); + priv->stmmac_rst = devm_reset_control_get(priv->device, + STMMAC_RESOURCE_NAME); + if (IS_ERR(priv->stmmac_rst)) { + if (PTR_ERR(priv->stmmac_rst) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto error_hw_init; + } + dev_info(priv->device, "no reset control found\n"); + priv->stmmac_rst = NULL; + } + if (priv->stmmac_rst) + reset_control_deassert(priv->stmmac_rst); + /* Init MAC and get the capabilities */ ret = stmmac_hw_init(priv); if (ret) @@ -2808,7 +2823,7 @@ error_hw_init: error_clk_get: free_netdev(ndev); - return NULL; + return ERR_PTR(ret); } /** @@ -2832,6 +2847,8 @@ int stmmac_dvr_remove(struct net_device *ndev) stmmac_mdio_unregister(ndev); netif_carrier_off(ndev); unregister_netdev(ndev); + if (priv->stmmac_rst) + reset_control_assert(priv->stmmac_rst); clk_disable_unprepare(priv->stmmac_clk); free_netdev(ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 37ba2e0808255..2916089248494 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -100,9 +100,9 @@ static int stmmac_pci_probe(struct pci_dev *pdev, stmmac_default_data(); priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat, addr); - if (!priv) { + if (IS_ERR(priv)) { pr_err("%s: main driver probe failed", __func__); - ret = -ENODEV; + ret = PTR_ERR(priv); goto err_out; } priv->dev->irq = pdev->irq; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 6d0bf222623a5..cc6b89a75f994 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -152,9 +152,9 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) } priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr); - if (!priv) { + if (IS_ERR(priv)) { pr_err("%s: main driver probe failed", __func__); - return -ENODEV; + return PTR_ERR(priv); } /* Get MAC address if available (DT) */ -- 2.39.5