tegra_xudc_probe() requests the IRQ before initializing the state used by tegra_xudc_irq(). The handler may run immediately and access the event ring or lock before they are ready. Request the IRQ after initializing all handler-visible state and before usb_add_gadget_udc() publishes the UDC. That call may bind a gadget driver. If UDC registration fails, release the managed IRQ before freeing state. Fixes: 49db427232fe ("usb: gadget: Add UDC driver for tegra XUSB device mode controller") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Runyu Xiao --- drivers/usb/gadget/udc/tegra-xudc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index e9d33be028664..5b133b9d65631 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -3801,14 +3801,6 @@ static int tegra_xudc_probe(struct platform_device *pdev) if (xudc->irq < 0) return xudc->irq; - err = devm_request_irq(&pdev->dev, xudc->irq, tegra_xudc_irq, 0, - dev_name(&pdev->dev), xudc); - if (err < 0) { - dev_err(xudc->dev, "failed to claim IRQ#%u: %d\n", xudc->irq, - err); - return err; - } - xudc->clks = devm_kcalloc(&pdev->dev, xudc->soc->num_clks, sizeof(*xudc->clks), GFP_KERNEL); if (!xudc->clks) @@ -3886,9 +3878,18 @@ static int tegra_xudc_probe(struct platform_device *pdev) xudc->gadget.name = "tegra-xudc"; xudc->gadget.max_speed = USB_SPEED_SUPER; + err = devm_request_irq(&pdev->dev, xudc->irq, tegra_xudc_irq, 0, + dev_name(&pdev->dev), xudc); + if (err < 0) { + dev_err(xudc->dev, "failed to claim IRQ#%u: %d\n", xudc->irq, + err); + goto free_eps; + } + err = usb_add_gadget_udc(&pdev->dev, &xudc->gadget); if (err) { dev_err(&pdev->dev, "failed to add USB gadget: %d\n", err); + devm_free_irq(&pdev->dev, xudc->irq, xudc); goto free_eps; } -- 2.34.1