add idle wakelock for vmac
authorlyx <lyx@rock-chips.com>
Wed, 2 Mar 2011 06:37:58 +0000 (22:37 -0800)
committerlyx <lyx@rock-chips.com>
Wed, 2 Mar 2011 06:37:58 +0000 (22:37 -0800)
drivers/net/rk29_vmac.c

index 2548cffbb0b0de80f8c2dede7e556ee9e3f52825..5f3c6e6c4e2531a9568c28044a8b42536134dccd 100755 (executable)
 #include <linux/platform_device.h>\r
 #include <linux/slab.h>\r
 #include <linux/types.h>\r
+#include <linux/wakelock.h>\r
 \r
 #include <mach/iomux.h>\r
 #include <mach/gpio.h>\r
 #include <mach/cru.h>\r
 #include <mach/board.h>\r
+\r
 #include "rk29_vmac.h"\r
 \r
+static struct wake_lock idlelock; /* add by lyx @ 20110302 */\r
+\r
 /* Register access macros */\r
 #define vmac_writel(port, value, reg)  \\r
        writel((value), (port)->regs + reg##_OFFSET)\r
@@ -1020,6 +1024,9 @@ int vmac_open(struct net_device *dev)
        struct phy_device *phydev;\r
        unsigned int temp;\r
        int err = 0;\r
+       struct clk *mac_clk = NULL;\r
+       struct clk *mac_parent = NULL;\r
+       struct clk *arm_clk = NULL;\r
        struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
 \r
        if (ap == NULL)\r
@@ -1028,7 +1035,13 @@ int vmac_open(struct net_device *dev)
        ap->shutdown = 0;\r
                \r
        //set rmii ref clock 50MHz\r
-       clk_set_rate(clk_get(NULL, "mac_ref_div"), 50000000);\r
+       mac_clk = clk_get(NULL, "mac_ref_div");\r
+       arm_clk = clk_get(NULL, "arm_pll");\r
+       mac_parent = clk_get_parent(mac_clk);\r
+       if (arm_clk && mac_parent && (arm_clk == mac_parent))\r
+               wake_lock(&idlelock);\r
+       \r
+       clk_set_rate(mac_clk, 50000000);\r
        clk_enable(clk_get(NULL,"mii_rx"));\r
        clk_enable(clk_get(NULL,"mii_tx"));\r
        clk_enable(clk_get(NULL,"hclk_mac"));\r
@@ -1102,7 +1115,10 @@ err_free_irq:
        free_irq(dev->irq, dev);\r
 err_free_buffers:\r
        free_buffers(dev);\r
-err_out:\r
+err_out:       \r
+       if (arm_clk && mac_parent && (arm_clk == mac_parent))\r
+               wake_unlock(&idlelock);\r
+\r
        return err;\r
 }\r
 \r
@@ -1110,6 +1126,9 @@ int vmac_close(struct net_device *dev)
 {\r
        struct vmac_priv *ap = netdev_priv(dev);\r
        unsigned int temp;\r
+       struct clk *mac_clk = NULL;\r
+       struct clk *arm_clk = NULL;\r
+       struct clk *mac_parent = NULL;\r
        struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
 \r
        netif_stop_queue(dev);\r
@@ -1140,16 +1159,23 @@ int vmac_close(struct net_device *dev)
 \r
        free_buffers(dev);\r
 \r
-       //set rmii ref clock 50MHz\r
+       //phy power off\r
+       if (pdata && pdata->rmii_power_control)\r
+               pdata->rmii_power_control(0);\r
+\r
+       //clock close\r
+       mac_clk = clk_get(NULL, "mac_ref_div");\r
+       mac_parent = clk_get_parent(mac_clk);   \r
+       arm_clk = clk_get(NULL, "arm_pll");\r
+\r
+       if (arm_clk && mac_parent && (arm_clk == mac_parent))\r
+               wake_unlock(&idlelock);\r
+       \r
        clk_disable(clk_get(NULL,"mii_rx"));\r
        clk_disable(clk_get(NULL,"mii_tx"));\r
        clk_disable(clk_get(NULL,"hclk_mac"));\r
        clk_disable(clk_get(NULL,"mac_ref"));\r
 \r
-       //phy power off\r
-       if (pdata && pdata->rmii_power_control)\r
-               pdata->rmii_power_control(0);\r
-       \r
        return 0;\r
 }\r
 \r
@@ -1255,7 +1281,7 @@ static void create_multicast_filter(struct net_device *dev,
        char *addrs;\r
        struct netdev_hw_addr_list *list = &dev->dev_addrs;\r
        \r
-       printk("-----------------func %s-------------------\n", __func__);\r
+       //printk("-----------------func %s-------------------\n", __func__);\r
 \r
        WARN_ON(dev->mc_count == 0);\r
        WARN_ON(dev->flags & IFF_ALLMULTI);\r
@@ -1302,7 +1328,7 @@ static void vmac_set_multicast_list(struct net_device *dev)
        unsigned long flags, bitmask[2];\r
        int promisc, reg;\r
 \r
-       printk("-----------------func %s-------------------\n", __func__);\r
+       //printk("-----------------func %s-------------------\n", __func__);\r
 \r
        spin_lock_irqsave(&ap->lock, flags);\r
 \r
@@ -1458,6 +1484,8 @@ static int __devinit vmac_probe(struct platform_device *pdev)
            dev->irq, dev->dev_addr);\r
        platform_set_drvdata(pdev, dev);\r
 \r
+       wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "vmac");\r
+\r
        //config rk29 vmac as rmii, 100MHz \r
        if (pdata && pdata->vmac_register_set)\r
                pdata->vmac_register_set();\r
@@ -1484,6 +1512,8 @@ static int __devexit vmac_remove(struct platform_device *pdev)
        struct resource *res;\r
        struct rk29_vmac_platform_data *pdata = pdev->dev.platform_data;\r
 \r
+       wake_lock_destroy(&idlelock);\r
+\r
        //power gpio deinit, phy power off\r
        if (pdata && pdata->rmii_io_deinit)\r
                pdata->rmii_io_deinit();\r