]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00159982 - FEC: low power mode when FEC is no use.
authorFugang Duan <B38611@freescale.com>
Fri, 4 Nov 2011 08:13:43 +0000 (16:13 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:24 +0000 (08:33 +0200)
- 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>
drivers/net/fec.c
include/linux/fec.h

index 710824044abcd34bbf84900a42d79892948511bc..f9f73505891e5f2d669c46f04d736589edf0fbef 100644 (file)
@@ -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>
@@ -684,6 +685,7 @@ static void fec_enet_adjust_link(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
        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;
@@ -698,6 +700,8 @@ static void fec_enet_adjust_link(struct net_device *ndev)
 
        /* 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(ndev, phy_dev->duplex);
                        status_change = 1;
@@ -717,8 +721,11 @@ static void fec_enet_adjust_link(struct net_device *ndev)
 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)
@@ -1071,7 +1078,9 @@ fec_enet_open(struct net_device *ndev)
         * a simple way to do that.
         */
 
-       ret = fec_enet_alloc_buffers(ndev);
+       if (!clk_get_usecount(fep->clk))
+               clk_enable(fep->clk);
+       ret = fec_enet_alloc_buffers(dev);
        if (ret)
                return ret;
 
@@ -1110,6 +1119,10 @@ fec_enet_close(struct net_device *ndev)
 
        fec_enet_free_buffers(ndev);
 
+       /* Clock gate close for saving power */
+       if (clk_get_usecount(fep->clk))
+               clk_disable(fep->clk);
+
        return 0;
 }
 
index d6a07048f84282f836aa00a5a0d4e91c6d85485a..8f69cb58d458ed5f3d7698503f86c7f247934967 100644 (file)
@@ -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];
 };