aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFugang Duan <B38611@freescale.com>2011-11-04 16:13:43 +0800
committerEric Miao <eric.miao@canonical.com>2011-11-10 07:39:06 +0800
commita01c210b8f6a2209c2f791768527b465c70c1dfc (patch)
treef22e616e6cb5ee251384d3147b5dc9a1f20426d4
parent8350f22a27affd4c14e62331cdbea3c349a17cf4 (diff)
downloadlinux-linaro-a01c210b8f6a2209c2f791768527b465c70c1dfc.tar.gz
ENGR00159982 - FEC: low power mode when FEC is no use.
- Set phy AR8031 to save power mode when no cable connect. - Close enet clock gate when FEC is no use. Signed-off-by: Fugang Duan <B38611@freescale.com>
-rw-r--r--drivers/net/fec.c15
-rw-r--r--include/linux/fec.h1
2 files changed, 15 insertions, 1 deletions
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index fd519571cbb..2022af73e19 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -42,6 +42,7 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/clk.h>
+#include <mach/clock.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/fec.h>
@@ -697,6 +698,7 @@ static void fec_enet_adjust_link(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
struct phy_device *phy_dev = fep->phy_dev;
+ struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
unsigned long flags;
int status_change = 0;
@@ -711,6 +713,8 @@ static void fec_enet_adjust_link(struct net_device *dev)
/* Duplex link change */
if (phy_dev->link) {
+ if (!clk_get_usecount(fep->clk))
+ clk_enable(fep->clk);
if (fep->full_duplex != phy_dev->duplex) {
fec_restart(dev, phy_dev->duplex);
status_change = 1;
@@ -730,8 +734,11 @@ static void fec_enet_adjust_link(struct net_device *dev)
spin_unlock:
spin_unlock_irqrestore(&fep->hw_lock, flags);
- if (status_change)
+ if (status_change) {
+ if (!phy_dev->link && phy_dev && pdata && pdata->power_hibernate)
+ pdata->power_hibernate(phy_dev);
phy_print_status(phy_dev);
+ }
}
static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
@@ -1086,6 +1093,8 @@ fec_enet_open(struct net_device *dev)
* a simple way to do that.
*/
+ if (!clk_get_usecount(fep->clk))
+ clk_enable(fep->clk);
ret = fec_enet_alloc_buffers(dev);
if (ret)
return ret;
@@ -1123,6 +1132,10 @@ fec_enet_close(struct net_device *dev)
fec_enet_free_buffers(dev);
+ /* Clock gate close for saving power */
+ if (clk_get_usecount(fep->clk))
+ clk_disable(fep->clk);
+
return 0;
}
diff --git a/include/linux/fec.h b/include/linux/fec.h
index d6a07048f84..8f69cb58d45 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -18,6 +18,7 @@
struct fec_platform_data {
int (*init) (struct phy_device *);
+ int (*power_hibernate) (struct phy_device *);
phy_interface_t phy;
unsigned char mac[ETH_ALEN];
};