net: stmmac: Add support for optional reset control
authorChen-Yu Tsai <wens@csie.org>
Fri, 17 Jan 2014 13:24:41 +0000 (21:24 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Jan 2014 04:02:02 +0000 (20:02 -0800)
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 <wens@csie.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/devicetree/bindings/net/stmmac.txt
drivers/net/ethernet/stmicro/stmmac/Kconfig
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c

index eba0e5e59ebe226aff38db501fd736aa6047f367..d132513e8fac447fb8920eefbca55793feb58f42 100644 (file)
@@ -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:
 
index 6e52c0f74cd9daad4ac5f80e1db98eec04958d55..b59d1ef5f6d45c5816a459d8948a84965f6801da 100644 (file)
@@ -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
index 73709e9ddcd119e1bc5dc6a4763c0cb2405e3c1a..c1c141fe15e7084cb3b0a7ff6d9cdc0bfd89e192 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/pci.h>
 #include "common.h"
 #include <linux/ptp_clock_kernel.h>
+#include <linux/reset.h>
 
 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;
index 0d2c4cb0996b3155a59586fe4fa855cdfc70fa3a..0c5c1208900e5c3f9f1f39a275282cea98468676 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/net_tstamp.h>
 #include "stmmac_ptp.h"
 #include "stmmac.h"
+#include <linux/reset.h>
 
 #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);
 
index 37ba2e0808255659e9e71c0b397aeebc9695fe55..2916089248494ed72a944b3cfd9a7ac6e1bba418 100644 (file)
@@ -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;
index 6d0bf222623a56a174c35e8a06ed8e5d6d6d3074..cc6b89a75f994538a800c67034d7ed26121eaf7a 100644 (file)
@@ -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) */