[PATCH] usb: gadget: pxa25x: mark the watchdog timer IRQ-safe

From: Runyu Xiao

Date: Thu Oct 08 2026 - 23:15:11 EST


The PXA25x UDC reset path runs from its hard-IRQ handler and calls
timer_delete_sync() for the watchdog. The timer is currently initialized
without TIMER_IRQSAFE, so timer_delete_sync() warns and can deadlock when
the reset races with the watchdog callback.

Mark the timer IRQ-safe. Since IRQ-safe callbacks run with interrupts
disabled and remain so on return, remove the callback's local IRQ disable
and enable pair; local_irq_enable() would otherwise re-enable interrupts
before the callback returns.

Fixes: 8fa7292fee5c ("treewide: Switch/rename to timer_delete[_sync]()")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
drivers/usb/gadget/udc/pxa25x_udc.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c
index 594d67193..41076ecca 100644
--- a/drivers/usb/gadget/udc/pxa25x_udc.c
+++ b/drivers/usb/gadget/udc/pxa25x_udc.c
@@ -1563,7 +1563,6 @@ static void udc_watchdog(struct timer_list *t)
{
struct pxa25x_udc *dev = timer_container_of(dev, t, timer);

- local_irq_disable();
if (dev->ep0state == EP0_STALL
&& (udc_ep0_get_UDCCS(dev) & UDCCS0_FST) == 0
&& (udc_ep0_get_UDCCS(dev) & UDCCS0_SST) == 0) {
@@ -1571,7 +1570,6 @@ static void udc_watchdog(struct timer_list *t)
DBG(DBG_VERBOSE, "ep0 re-stall\n");
start_watchdog(dev);
}
- local_irq_enable();
}

static void handle_ep0 (struct pxa25x_udc *dev)
@@ -2343,7 +2341,7 @@ static int pxa25x_udc_probe(struct platform_device *pdev)
goto err;
}

- timer_setup(&dev->timer, udc_watchdog, 0);
+ timer_setup(&dev->timer, udc_watchdog, TIMER_IRQSAFE);

the_controller = dev;
platform_set_drvdata(pdev, dev);
--
2.34.1