]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00265935 net: fec: add pm_qos to avoid cpu enter to wait mode
authorFugang Duan <B38611@freescale.com>
Fri, 11 Oct 2013 08:36:48 +0000 (16:36 +0800)
committerJason Liu <r64343@freescale.com>
Wed, 30 Oct 2013 01:55:55 +0000 (09:55 +0800)
Since imx6q/dl enet cannot wake up wait mode, which cause performance
drops. Add pm_qos to request low cpu latency to avoid enter to wait mode.

Signed-off-by: Fugang Duan <B38611@freescale.com>
drivers/net/ethernet/freescale/fec_main.c

index 93840d4456135ebd78345e97eb81dc1c60748544..a33a58381fda401b0a6156128fada21edf664eb6 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/if_vlan.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
 #include <linux/version.h>
 
 #include <asm/cacheflush.h>
@@ -117,7 +118,13 @@ static void fec_reset_phy(struct platform_device *pdev);
  * frames not being transmitted until there is a 0-to-1 transition on
  * ENET_TDAR[TDAR].
  */
-#define FEC_QUIRK_ERR006358            (1 << 7)
+#define FEC_QUIRK_ERR006358            (1 << 8)
+/*
+ * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx
+ * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter
+ * to wait mode.
+ */
+#define FEC_QUIRK_BUG_WAITMODE         (1 << 9)
 
 static struct platform_device_id fec_devtype[] = {
        {
@@ -137,7 +144,8 @@ static struct platform_device_id fec_devtype[] = {
                .name = "imx6q-fec",
                .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
                                FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
-                               FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358,
+                               FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
+                               FEC_QUIRK_BUG_WAITMODE,
        }, {
                .name = "mvf600-fec",
                .driver_data = FEC_QUIRK_ENET_MAC,
@@ -1796,9 +1804,19 @@ static int
 fec_enet_open(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
+       const struct platform_device_id *id_entry =
+                               platform_get_device_id(fep->pdev);
        int ret;
 
        pm_runtime_get_sync(ndev->dev.parent);
+       if (id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE)
+               pm_qos_add_request(&ndev->pm_qos_req,
+                                  PM_QOS_CPU_DMA_LATENCY,
+                                  0);
+       else
+               pm_qos_add_request(&ndev->pm_qos_req,
+                                  PM_QOS_CPU_DMA_LATENCY,
+                                  PM_QOS_DEFAULT_VALUE);
 
        fec_enet_clk_enable(ndev, true);
 
@@ -1847,6 +1865,7 @@ fec_enet_close(struct net_device *ndev)
 
        fec_enet_clk_enable(ndev, false);
 
+       pm_qos_remove_request(&ndev->pm_qos_req);
        pm_runtime_put_sync_suspend(ndev->dev.parent);
 
        fec_enet_free_buffers(ndev);