}
 }
 
+static void fec_irqs_disable(struct net_device *ndev)
+{
+       struct fec_enet_private *fep = netdev_priv(ndev);
+
+       writel(0, fep->hwp + FEC_IMASK);
+}
+
+static void fec_irqs_disable_except_wakeup(struct net_device *ndev)
+{
+       struct fec_enet_private *fep = netdev_priv(ndev);
+
+       writel(0, fep->hwp + FEC_IMASK);
+       writel(FEC_ENET_WAKEUP, fep->hwp + FEC_IMASK);
+}
+
 static void
 fec_stop(struct net_device *ndev)
 {
                        writel(1, fep->hwp + FEC_ECNTRL);
                        udelay(10);
                }
-               writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
        } else {
-               writel(FEC_DEFAULT_IMASK | FEC_ENET_WAKEUP, fep->hwp + FEC_IMASK);
                val = readl(fep->hwp + FEC_ECNTRL);
                val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP);
                writel(val, fep->hwp + FEC_ECNTRL);
-               fec_enet_stop_mode(fep, true);
        }
        writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
+       writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK);
 
        /* We have to keep ENET enabled to have MII interrupt stay working */
        if (fep->quirks & FEC_QUIRK_ENET_MAC &&
                return -EINVAL;
 
        device_set_wakeup_enable(&ndev->dev, wol->wolopts & WAKE_MAGIC);
-       if (device_may_wakeup(&ndev->dev)) {
+       if (device_may_wakeup(&ndev->dev))
                fep->wol_flag |= FEC_WOL_FLAG_ENABLE;
-               if (fep->wake_irq > 0)
-                       enable_irq_wake(fep->wake_irq);
-       } else {
+       else
                fep->wol_flag &= (~FEC_WOL_FLAG_ENABLE);
-               if (fep->wake_irq > 0)
-                       disable_irq_wake(fep->wake_irq);
-       }
 
        return 0;
 }
                netif_device_detach(ndev);
                netif_tx_unlock_bh(ndev);
                fec_stop(ndev);
-               fec_enet_clk_enable(ndev, false);
-               if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE))
+               if (!(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
+                       fec_irqs_disable(ndev);
                        pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+               } else {
+                       fec_irqs_disable_except_wakeup(ndev);
+                       if (fep->wake_irq > 0) {
+                               disable_irq(fep->wake_irq);
+                               enable_irq_wake(fep->wake_irq);
+                       }
+                       fec_enet_stop_mode(fep, true);
+               }
+               /* It's safe to disable clocks since interrupts are masked */
+               fec_enet_clk_enable(ndev, false);
        }
        rtnl_unlock();
 
                }
                if (fep->wol_flag & FEC_WOL_FLAG_ENABLE) {
                        fec_enet_stop_mode(fep, false);
+                       if (fep->wake_irq) {
+                               disable_irq_wake(fep->wake_irq);
+                               enable_irq(fep->wake_irq);
+                       }
 
                        val = readl(fep->hwp + FEC_ECNTRL);
                        val &= ~(FEC_ECR_MAGICEN | FEC_ECR_SLEEP);