diff options
-rw-r--r-- | drivers/net/ethernet/freescale/fec.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 45 |
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); |