Hi, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> writes: >> > Hence, the reason if there was already a pending IRQ triggered, the >> > dwc3_gadget_disable_irq() won't ensure the IRQ is handled. We can do >> > something like: >> > if (!is_on) >> > dwc3_gadget_disable_irq() >> > synchronize_irq() >> > spin_lock_irqsave() >> > if(!is_on) { >> > ... >> > >> > But the logic to only apply this on the pullup removal case is a little >> > messy. Also, from my understanding, the spin_lock_irqsave() will only >> > disable the local CPU IRQs, but not the interrupt line on the GIC, which >> > means other CPUs can handle it, unless we explicitly set the IRQ >> > affinity to CPUX. >> >> Yeah, the way I understand this can't really happen. But I'm open to >> being educated. Maybe Alan can explain if this is really possibility? > > It depends on the details of the hardware, but yes, it is possible in > general for an interrupt handler to run after you have turned off the > device's interrupt-request line. For example: > > CPU A CPU B > --------------------------- ---------------------- > Gets an IRQ from the device > Calls handler routine spin_lock_irq > spin_lock_irq Turns off the IRQ line > ...spins... spin_unlock_irq > Rest of handler runs > spin_unlock_irq > > That's why we have synchronize_irq(). The usual pattern is something > like this: > > spin_lock_irq(&priv->lock); > priv->disconnected = true; > my_disable_irq(priv); > spin_unlock_irq(&priv->lock); > synchronize_irq(priv->irq); > > And of course this has to be done in a context that can sleep. > > Does this answer your question? It does, thank you Alan. It seems like we don't need a call to disable_irq(), only synchronize_irq() is enough, however it should be called with spinlocks released, not held. Thanks -- balbi
Attachment:
signature.asc
Description: PGP signature