[PATCH 06/19] usb: gadget: snps_udc_plat: lock out the interrupt
From: Greg Kroah-Hartman
Date: Tue Oct 27 2026 - 11:06:30 EST
From: Josef Bacik <josef@xxxxxxxxxxxxxx>
stop_udc() is called from a work item, when the extcon device reports
that the cable has been unplugged. It takes udc->lock with interrupts
enabled. udc_irq(), the hard interrupt handler of the controller, takes
the same lock. If the controller raises an interrupt on the CPU which
is in stop_udc(), and it is likely to have something to report when the
cable is pulled, the handler spins on a lock which the interrupted work
holds: the CPU is stuck.
Disable interrupts while the lock is held. They are enabled again for
the ->disconnect() callback of the gadget driver, for which the lock is
dropped as before.
Fixes: 1b9f35adb0ff ("usb: gadget: udc: Add Synopsys UDC Platform driver")
Cc: stable <stable@xxxxxxxxxx>
Cc: Neill Kapron <nkapron@xxxxxxxxxx>
Cc: Ijae Kim <ae878000@xxxxxxxxx>
Cc: Herve Codina <herve.codina@xxxxxxxxxxx>
Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/usb/gadget/udc/snps_udc_plat.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/gadget/udc/snps_udc_plat.c b/drivers/usb/gadget/udc/snps_udc_plat.c
index 8ce43c4f8fba..e2e71cc947dc 100644
--- a/drivers/usb/gadget/udc/snps_udc_plat.c
+++ b/drivers/usb/gadget/udc/snps_udc_plat.c
@@ -34,7 +34,7 @@ static void stop_udc(struct udc *udc)
int tmp;
u32 reg;
- spin_lock(&udc->lock);
+ spin_lock_irq(&udc->lock);
/* Flush the receieve fifo */
reg = readl(&udc->regs->ctl);
@@ -53,9 +53,9 @@ static void stop_udc(struct udc *udc)
/* Disconnect gadget driver */
if (udc->driver) {
- spin_unlock(&udc->lock);
+ spin_unlock_irq(&udc->lock);
udc->driver->disconnect(&udc->gadget);
- spin_lock(&udc->lock);
+ spin_lock_irq(&udc->lock);
/* empty queues */
for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
@@ -63,7 +63,7 @@ static void stop_udc(struct udc *udc)
}
udc->connected = 0;
- spin_unlock(&udc->lock);
+ spin_unlock_irq(&udc->lock);
dev_info(udc->dev, "Device disconnected\n");
}
--
2.56.0