ravb: add workaround for clock when resuming with WoL enabled
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Tue, 1 Aug 2017 10:14:37 +0000 (12:14 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Aug 2017 00:54:38 +0000 (17:54 -0700)
The renesas-cpg-mssr clock driver are not yet aware of PSCI sleep where
power is cut to the SoC. When resuming from this state with WoL enabled
the enable count of the ravb clock is 1 and the clock driver thinks the
clock is already on when PM core enables the clock and increments the
enable count to 2. This will result in the ravb driver failing to talk
to the hardware since the module clock is off. Work around this by
forcing the enable count to 0 and then back to 2 when resuming with WoL
enabled.

This workaround should be reverted once the renesas-cpg-mssr clock
driver becomes aware of this PSCI sleep behavior.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/renesas/ravb_main.c

index 6d10db1b51468031b66320cae457811564a902b6..fdf30bfa403bf416572fa45ac3dde48f1e92cded 100644 (file)
@@ -2270,9 +2270,32 @@ static int __maybe_unused ravb_resume(struct device *dev)
        struct ravb_private *priv = netdev_priv(ndev);
        int ret = 0;
 
-       /* If WoL is enabled set reset mode to rearm the WoL logic */
-       if (priv->wol_enabled)
+       if (priv->wol_enabled) {
+               /* Reduce the usecount of the clock to zero and then
+                * restore it to its original value. This is done to force
+                * the clock to be re-enabled which is a workaround
+                * for renesas-cpg-mssr driver which do not enable clocks
+                * when resuming from PSCI suspend/resume.
+                *
+                * Without this workaround the driver fails to communicate
+                * with the hardware if WoL was enabled when the system
+                * entered PSCI suspend. This is due to that if WoL is enabled
+                * we explicitly keep the clock from being turned off when
+                * suspending, but in PSCI sleep power is cut so the clock
+                * is disabled anyhow, the clock driver is not aware of this
+                * so the clock is not turned back on when resuming.
+                *
+                * TODO: once the renesas-cpg-mssr suspend/resume is working
+                *       this clock dance should be removed.
+                */
+               clk_disable(priv->clk);
+               clk_disable(priv->clk);
+               clk_enable(priv->clk);
+               clk_enable(priv->clk);
+
+               /* Set reset mode to rearm the WoL logic */
                ravb_write(ndev, CCC_OPC_RESET, CCC);
+       }
 
        /* All register have been reset to default values.
         * Restore all registers which where setup at probe time and