Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0d7ffd4 authored by Felipe Balbi's avatar Felipe Balbi
Browse files

usb: dwc3: gadget: don't request IRQs in atomic



We cannot request an IRQ with spinlocks held
as that would trigger a sleeping inside
spinlock warning.

Cc: <stable@vger.kernel.org> # v3.10
Reported-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 2b0c4953
Loading
Loading
Loading
Loading
+22 −17
Original line number Diff line number Diff line
@@ -1508,6 +1508,15 @@ static int dwc3_gadget_start(struct usb_gadget *g,
	int			irq;
	u32			reg;

	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
	ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
			IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc);
	if (ret) {
		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
				irq, ret);
		goto err0;
	}

	spin_lock_irqsave(&dwc->lock, flags);

	if (dwc->gadget_driver) {
@@ -1515,7 +1524,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
				dwc->gadget.name,
				dwc->gadget_driver->driver.name);
		ret = -EBUSY;
		goto err0;
		goto err1;
	}

	dwc->gadget_driver	= driver;
@@ -1551,42 +1560,38 @@ static int dwc3_gadget_start(struct usb_gadget *g,
	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false);
	if (ret) {
		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
		goto err0;
		goto err2;
	}

	dep = dwc->eps[1];
	ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false);
	if (ret) {
		dev_err(dwc->dev, "failed to enable %s\n", dep->name);
		goto err1;
		goto err3;
	}

	/* begin to receive SETUP packets */
	dwc->ep0state = EP0_SETUP_PHASE;
	dwc3_ep0_out_start(dwc);

	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
	ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
			IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc);
	if (ret) {
		dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
				irq, ret);
		goto err1;
	}

	dwc3_gadget_enable_irq(dwc);

	spin_unlock_irqrestore(&dwc->lock, flags);

	return 0;

err1:
err3:
	__dwc3_gadget_ep_disable(dwc->eps[0]);

err0:
err2:
	dwc->gadget_driver = NULL;

err1:
	spin_unlock_irqrestore(&dwc->lock, flags);

	free_irq(irq, dwc);

err0:
	return ret;
}

@@ -1600,9 +1605,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g,
	spin_lock_irqsave(&dwc->lock, flags);

	dwc3_gadget_disable_irq(dwc);
	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
	free_irq(irq, dwc);

	__dwc3_gadget_ep_disable(dwc->eps[0]);
	__dwc3_gadget_ep_disable(dwc->eps[1]);

@@ -1610,6 +1612,9 @@ static int dwc3_gadget_stop(struct usb_gadget *g,

	spin_unlock_irqrestore(&dwc->lock, flags);

	irq = platform_get_irq(to_platform_device(dwc->dev), 0);
	free_irq(irq, dwc);

	return 0;
}