ARM: imx6: disable deeper idle states when FEC is active w/o HW workaround

The i.MX6 Q/DL has an erratum (ERR006687) that prevents the FEC from
waking the CPUs when they are in wait(unclocked) state. As the hardware
workaround isn't applicable to all boards, disable the deeper idle state
when the workaround isn't present and the FEC is in use.

This allows to safely run a kernel with CPUidle enabled on all i.MX6
boards.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Acked-by: David S. Miller <davem@davemloft.net> (for network changes)
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
This commit is contained in:
Lucas Stach
2016-06-03 18:31:19 +02:00
committed by Shawn Guo
parent ac4bbb45e9
commit 2938090556
5 changed files with 58 additions and 0 deletions

View File

@@ -60,6 +60,7 @@
#include <linux/if_vlan.h>
#include <linux/pinctrl/consumer.h>
#include <linux/prefetch.h>
#include <soc/imx/cpuidle.h>
#include <asm/cacheflush.h>
@@ -2820,6 +2821,9 @@ fec_enet_open(struct net_device *ndev)
if (ret)
goto err_enet_mii_probe;
if (fep->quirks & FEC_QUIRK_ERR006687)
imx6q_cpuidle_fec_irqs_used();
napi_enable(&fep->napi);
phy_start(ndev->phydev);
netif_tx_start_all_queues(ndev);
@@ -2855,6 +2859,9 @@ fec_enet_close(struct net_device *ndev)
phy_disconnect(ndev->phydev);
if (fep->quirks & FEC_QUIRK_ERR006687)
imx6q_cpuidle_fec_irqs_unused();
fec_enet_clk_enable(ndev, false);
pinctrl_pm_select_sleep_state(&fep->pdev->dev);
pm_runtime_mark_last_busy(&fep->pdev->dev);
@@ -3294,6 +3301,11 @@ fec_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ndev);
if ((of_machine_is_compatible("fsl,imx6q") ||
of_machine_is_compatible("fsl,imx6dl")) &&
!of_property_read_bool(np, "fsl,err006687-workaround-present"))
fep->quirks |= FEC_QUIRK_ERR006687;
if (of_get_property(np, "fsl,magic-packet", NULL))
fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;