From b7cdc9658ac860f0dff55bf2d6f6fc27ce17a0fa Mon Sep 17 00:00:00 2001 From: Joakim Zhang Date: Thu, 12 Aug 2021 15:09:48 +0800 Subject: [PATCH] net: fec: add WoL support for i.MX8MQ By default FEC driver treat irq[0] (i.e. int0 described in dt-binding) as wakeup interrupt, but this situation changed on i.MX8M serials, SoC integration guys mix wakeup interrupt signal into int2 interrupt line. This patch introduces FEC_QUIRK_WAKEUP_FROM_INT2 to indicate int2 as wakeup interrupt for i.MX8MQ. Signed-off-by: Joakim Zhang Link: https://lore.kernel.org/r/20210812070948.25797-1-qiangqing.zhang@nxp.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/fec.h | 4 ++++ drivers/net/ethernet/freescale/fec_main.c | 24 +++++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index d2e9a6c..7b4961d 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -492,6 +492,9 @@ struct bufdesc_ex { */ #define FEC_QUIRK_DELAYED_CLKS_SUPPORT (1 << 21) +/* i.MX8MQ SoC integration mix wakeup interrupt signal into "int2" interrupt line. */ +#define FEC_QUIRK_WAKEUP_FROM_INT2 (1 << 22) + struct bufdesc_prop { int qid; /* Address of Rx and Tx buffers */ @@ -580,6 +583,7 @@ struct fec_enet_private { bool bufdesc_ex; int pause_flag; int wol_flag; + int wake_irq; u32 quirks; struct napi_struct napi; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index fdff37b..83ab34b 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -142,7 +142,7 @@ static const struct fec_devinfo fec_imx8mq_info = { FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MULTI_QUEUES | - FEC_QUIRK_HAS_EEE, + FEC_QUIRK_HAS_EEE | FEC_QUIRK_WAKEUP_FROM_INT2, }; static const struct fec_devinfo fec_imx8qm_info = { @@ -2878,12 +2878,12 @@ fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol) device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC); if (device_may_wakeup(&ndev->dev)) { fep->wol_flag |= FEC_WOL_FLAG_ENABLE; - if (fep->irq[0] > 0) - enable_irq_wake(fep->irq[0]); + if (fep->wake_irq > 0) + enable_irq_wake(fep->wake_irq); } else { fep->wol_flag &= (~FEC_WOL_FLAG_ENABLE); - if (fep->irq[0] > 0) - disable_irq_wake(fep->irq[0]); + if (fep->wake_irq > 0) + disable_irq_wake(fep->wake_irq); } return 0; @@ -3696,6 +3696,17 @@ static int fec_enet_get_irq_cnt(struct platform_device *pdev) return irq_cnt; } +static void fec_enet_get_wakeup_irq(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct fec_enet_private *fep = netdev_priv(ndev); + + if (fep->quirks & FEC_QUIRK_WAKEUP_FROM_INT2) + fep->wake_irq = fep->irq[2]; + else + fep->wake_irq = fep->irq[0]; +} + static int fec_enet_init_stop_mode(struct fec_enet_private *fep, struct device_node *np) { @@ -3935,6 +3946,9 @@ fec_probe(struct platform_device *pdev) fep->irq[i] = irq; } + /* Decide which interrupt line is wakeup capable */ + fec_enet_get_wakeup_irq(pdev); + ret = fec_enet_mii_init(pdev); if (ret) goto failed_mii_init; -- 2.7.4