summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/freescale/fec.h2
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c45
2 files changed, 39 insertions, 8 deletions
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index ae236009f1a8..ea5c60d84889 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -318,6 +318,8 @@ struct fec_enet_private {
struct napi_struct napi;
int csum_flags;
+ int phy_reset_gpio;
+
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
unsigned long last_overflow_check;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 8f296d71eecb..995abce9ea70 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -18,7 +18,7 @@
* Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
* Copyright (c) 2004-2006 Macq Electronique SA.
*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
*/
#include <linux/module.h>
@@ -61,6 +61,8 @@
#include "fec.h"
static void set_multicast_list(struct net_device *ndev);
+static void fec_reset_phy(struct platform_device *pdev);
+static void fec_free_reset_gpio(struct platform_device *pdev);
#if defined(CONFIG_ARM)
#define FEC_ALIGNMENT 0xf
@@ -1760,6 +1762,10 @@ fec_enet_open(struct net_device *ndev)
phy_start(fep->phy_dev);
netif_start_queue(ndev);
fep->opened = 1;
+
+ /* reset phy */
+ fec_reset_phy(fep->pdev);
+
return 0;
}
@@ -1780,6 +1786,7 @@ fec_enet_close(struct net_device *ndev)
}
fec_enet_free_buffers(ndev);
+ fec_free_reset_gpio(fep->pdev);
return 0;
}
@@ -2008,9 +2015,11 @@ static int fec_enet_init(struct net_device *ndev)
#ifdef CONFIG_OF
static void fec_reset_phy(struct platform_device *pdev)
{
- int err, phy_reset;
+ int err;
int msec = 1;
struct device_node *np = pdev->dev.of_node;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct fec_enet_private *fep = netdev_priv(ndev);
if (!np)
return;
@@ -2020,18 +2029,33 @@ static void fec_reset_phy(struct platform_device *pdev)
if (msec > 1000)
msec = 1;
- phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
- if (!gpio_is_valid(phy_reset))
+ fep->phy_reset_gpio = of_get_named_gpio(np, "phy-reset-gpios", 0);
+ if (!gpio_is_valid(fep->phy_reset_gpio))
return;
- err = devm_gpio_request_one(&pdev->dev, phy_reset,
+ err = devm_gpio_request_one(&pdev->dev, fep->phy_reset_gpio,
GPIOF_OUT_INIT_LOW, "phy-reset");
if (err) {
dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", err);
return;
}
msleep(msec);
- gpio_set_value(phy_reset, 1);
+ gpio_set_value(fep->phy_reset_gpio, 1);
+}
+
+static void fec_free_reset_gpio(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ struct device_node *np = pdev->dev.of_node;
+ if (!np)
+ return;
+
+ fep->phy_reset_gpio = of_get_named_gpio(np, "phy-reset-gpios", 0);
+ if (!gpio_is_valid(fep->phy_reset_gpio))
+ return;
+
+ devm_gpio_free(&pdev->dev, fep->phy_reset_gpio);
}
#else /* CONFIG_OF */
static void fec_reset_phy(struct platform_device *pdev)
@@ -2041,6 +2065,13 @@ static void fec_reset_phy(struct platform_device *pdev)
* by machine code.
*/
}
+
+static void fec_free_reset_gpio(struct platform_device *pdev)
+{
+ /*
+ * make pair as api "fec_reset_phy()"
+ */
+}
#endif /* CONFIG_OF */
static int
@@ -2145,8 +2176,6 @@ fec_probe(struct platform_device *pdev)
fep->reg_phy = NULL;
}
- fec_reset_phy(pdev);
-
if (fep->bufdesc_ex)
fec_ptp_init(pdev);