diff options
author | Alexandre Belloni <alexandre.belloni@bootlin.com> | 2019-04-09 14:09:05 +0200 |
---|---|---|
committer | Felipe Balbi <felipe.balbi@linux.intel.com> | 2019-05-03 09:13:48 +0300 |
commit | 59a9901ec7ef320a82cd6d8983937aed739c9e94 (patch) | |
tree | ad79c7c51ef9bb8d17575cba444340f4a3c80b9a /drivers/usb | |
parent | 408b56ca5c8eea1e46d2094818de8acc7215cf58 (diff) | |
download | linux-59a9901ec7ef320a82cd6d8983937aed739c9e94.tar.gz linux-59a9901ec7ef320a82cd6d8983937aed739c9e94.tar.bz2 linux-59a9901ec7ef320a82cd6d8983937aed739c9e94.zip |
usb: gadget: udc: lpc32xx: simplify vbus handling
Use a threaded IRQ to handle vbus_work instead of using the global
worqueue.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/udc/lpc32xx_udc.c | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 5546cb509085..777279fa4637 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -152,7 +152,6 @@ struct lpc32xx_udc { /* Work queues related to I2C support */ struct work_struct pullup_job; - struct work_struct vbus_job; struct work_struct power_job; /* USB device peripheral - various */ @@ -2828,11 +2827,9 @@ static irqreturn_t lpc32xx_usb_devdma_irq(int irq, void *_udc) * VBUS detection, pullup handler, and Gadget cable state notification * */ -static void vbus_work(struct work_struct *work) +static void vbus_work(struct lpc32xx_udc *udc) { u8 value; - struct lpc32xx_udc *udc = container_of(work, struct lpc32xx_udc, - vbus_job); if (udc->enabled != 0) { /* Discharge VBUS real quick */ @@ -2877,9 +2874,7 @@ static irqreturn_t lpc32xx_usb_vbus_irq(int irq, void *_udc) { struct lpc32xx_udc *udc = _udc; - /* Defer handling of VBUS IRQ to work queue */ - disable_irq_nosync(udc->udp_irq[IRQ_USB_ATX]); - schedule_work(&udc->vbus_job); + vbus_work(udc); return IRQ_HANDLED; } @@ -2908,7 +2903,7 @@ static int lpc32xx_start(struct usb_gadget *gadget, /* Force VBUS process once to check for cable insertion */ udc->last_vbus = udc->vbus = 0; - schedule_work(&udc->vbus_job); + vbus_work(udc); /* Do not re-enable ATX IRQ (3) */ for (i = IRQ_USB_LP; i < IRQ_USB_ATX; i++) @@ -3080,7 +3075,6 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) /* Setup deferred workqueue data */ udc->poweron = udc->pullup = 0; INIT_WORK(&udc->pullup_job, pullup_work); - INIT_WORK(&udc->vbus_job, vbus_work); #ifdef CONFIG_PM INIT_WORK(&udc->power_job, power_work); #endif @@ -3143,8 +3137,9 @@ static int lpc32xx_udc_probe(struct platform_device *pdev) /* The transceiver interrupt is used for VBUS detection and will kick off the VBUS handler function */ - retval = devm_request_irq(dev, udc->udp_irq[IRQ_USB_ATX], - lpc32xx_usb_vbus_irq, 0, "udc_otg", udc); + retval = devm_request_threaded_irq(dev, udc->udp_irq[IRQ_USB_ATX], NULL, + lpc32xx_usb_vbus_irq, IRQF_ONESHOT, + "udc_otg", udc); if (retval < 0) { dev_err(udc->dev, "VBUS request irq %d failed\n", udc->udp_irq[IRQ_USB_ATX]); |