net: systemport: Manage Wake-on-LAN clock
authorFlorian Fainelli <f.fainelli@gmail.com>
Tue, 1 Sep 2020 21:43:48 +0000 (14:43 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Sep 2020 22:06:03 +0000 (15:06 -0700)
It is necessary to manage the Wake-on-LAN clock to turn on the
appropriate blocks for MPD or CFP-based packet matching to work
otherwise we will not be able to reliably match packets during suspend.

Reported-by: Blair Prescott <blair.prescott@broadcom.com>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bcmsysport.h

index 91eadba..b25c70b 100644 (file)
@@ -2583,6 +2583,10 @@ static int bcm_sysport_probe(struct platform_device *pdev)
        if (!ret)
                device_set_wakeup_capable(&pdev->dev, 1);
 
+       priv->wol_clk = devm_clk_get_optional(&pdev->dev, "sw_sysportwol");
+       if (IS_ERR(priv->wol_clk))
+               return PTR_ERR(priv->wol_clk);
+
        /* Set the needed headroom once and for all */
        BUILD_BUG_ON(sizeof(struct bcm_tsb) != 8);
        dev->needed_headroom += sizeof(struct bcm_tsb);
@@ -2772,8 +2776,10 @@ static int __maybe_unused bcm_sysport_suspend(struct device *d)
        bcm_sysport_fini_rx_ring(priv);
 
        /* Get prepared for Wake-on-LAN */
-       if (device_may_wakeup(d) && priv->wolopts)
+       if (device_may_wakeup(d) && priv->wolopts) {
+               clk_prepare_enable(priv->wol_clk);
                ret = bcm_sysport_suspend_to_wol(priv);
+       }
 
        clk_disable_unprepare(priv->clk);
 
@@ -2791,6 +2797,8 @@ static int __maybe_unused bcm_sysport_resume(struct device *d)
                return 0;
 
        clk_prepare_enable(priv->clk);
+       if (priv->wolopts)
+               clk_disable_unprepare(priv->wol_clk);
 
        umac_reset(priv);
 
index 5180005..3a5cb6f 100644 (file)
@@ -771,6 +771,7 @@ struct bcm_sysport_priv {
        u8                      sopass[SOPASS_MAX];
        unsigned int            wol_irq_disabled:1;
        struct clk              *clk;
+       struct clk              *wol_clk;
 
        /* MIB related fields */
        struct bcm_sysport_mib  mib;