[PATCH] usb: phy: gpio-vbus: disable VBUS work during removal
From: Myeonghun Pak
Date: Sat Oct 17 2026 - 23:17:24 EST
Legacy users such as PXA UDC obtain this PHY through usb_get_phy(),
which does not create a supplier device link. A sysfs unbind of the PHY
can therefore run while the gadget consumer remains bound.
The VBUS IRQ remains registered until devres cleanup, after
gpio_vbus_remove() returns. With the gadget still registered, an IRQ
after cancel_delayed_work_sync() returns can queue another instance of
the delayed work. The 100 ms delay lets devres release the GPIO, OTG and
driver state before that instance runs.
Disable and drain the delayed work during removal so late IRQs cannot
queue it again. This also rejects work queued by set_peripheral(), which
calls the IRQ handler directly. The managed IRQ is released before the
GPIO and driver state accessed by its handler are freed.
This issue was identified as part of our ongoing research while
reviewing kernel code.
Fixes: c2344f13b59e ("USB: gpio_vbus: add delayed vbus_session calls")
Co-developed-by: Ijae Kim <ae878000@xxxxxxxxx>
Signed-off-by: Ijae Kim <ae878000@xxxxxxxxx>
Signed-off-by: Myeonghun Pak <mhun512@xxxxxxxxx>
---
Compile-tested with Clang, W=1. No hardware runtime testing.
Based on mainline 0fcb05b72344f40806cbe810de8872f1698bf053.
diff --git a/drivers/usb/phy/phy-gpio-vbus-usb.c b/drivers/usb/phy/phy-gpio-vbus-usb.c
index ce09e78..80216af 100644
--- a/drivers/usb/phy/phy-gpio-vbus-usb.c
+++ b/drivers/usb/phy/phy-gpio-vbus-usb.c
@@ -330,7 +330,7 @@ static void gpio_vbus_remove(struct platform_device *pdev)
struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev);
device_init_wakeup(&pdev->dev, 0);
- cancel_delayed_work_sync(&gpio_vbus->work);
+ disable_delayed_work_sync(&gpio_vbus->work);
usb_remove_phy(&gpio_vbus->phy);
}