On Mon, May 23, 2022 at 02:34:49PM +0200, Andrew Lunn wrote: > > --- a/drivers/net/phy/phy_device.c > > +++ b/drivers/net/phy/phy_device.c > > @@ -283,8 +283,11 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev) > > * may call phy routines that try to grab the same lock, and that may > > * lead to a deadlock. > > */ > > - if (phydev->attached_dev && phydev->adjust_link) > > + if (phydev->attached_dev && phydev->adjust_link) { > > + if (phy_interrupt_is_valid(phydev)) > > + synchronize_irq(phydev->irq); > > phy_stop_machine(phydev); > > + } > > What is this hunk trying to achieve? As far as i know, interrupts have > not been disabled. So as soon as the call to synchronize_irq() > finishes, could well be another interrupt happens. That other interrupt would bail out of phy_interrupt() because the is_prepared flag is set on the PHY's struct device, see first hunk of the patch. The problem is that an interrupt may occur before the system sleep transition commences. phy_interrupt() will notice that is_prepared is not (yet) set, hence invokes drv->handle_interrupt(). Let's say the IRQ thread is preempted at that point, the system sleep transition is started and mdio_bus_phy_suspend() is run. It calls phy_stop_machine(), so the state machine is now stopped. Now phy_interrupt() continues, and the PHY driver's ->handle_interrupt() callback starts the state machine. Boom, that's not what we want. So the synchronize_irq() ensures that any already running phy_interrupt() runs to completion before phy_stop_machine() is called. It doesn't matter if another interrupt occurs because then is_prepared will have been set and therefore phy_interrupt() won't call drv->handle_interrupt(). Let me know if I haven't explained it in sufficient clarity, I'll be happy to try again. :) I'm more concerned about the first hunk of the patch because I'm not sure I got the wakeup stuff right... Thanks, Lukas