From 908f6e2b8a7987ae761d80ea05738aa2a42c4474 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Mon, 18 Jan 2021 16:16:53 -0800 Subject: USB: gadget: udc: Process disconnect synchronously As the comment in usb_disconnect() hints, do not defer the disconnect processing, and instead just do it directly in the irq handler. This allows the driver to avoid using a nowadays deprecated tasklet. Acked-by: Felipe Balbi Signed-off-by: Davidlohr Bueso Link: https://lore.kernel.org/r/20210119001653.127975-1-dave@stgolabs.net Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/snps_udc_core.c | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index 6c726d2e1788..d046c09fa566 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -36,7 +36,6 @@ #include #include "amd5536udc.h" -static void udc_tasklet_disconnect(unsigned long); static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); @@ -95,9 +94,6 @@ static struct timer_list udc_pollstall_timer; static int stop_pollstall_timer; static DECLARE_COMPLETION(on_pollstall_exit); -/* tasklet for usb disconnect */ -static DECLARE_TASKLET_OLD(disconnect_tasklet, udc_tasklet_disconnect); - /* endpoint names used for print */ static const char ep0_string[] = "ep0in"; static const struct { @@ -1637,6 +1633,8 @@ static void usb_connect(struct udc *dev) */ static void usb_disconnect(struct udc *dev) { + u32 tmp; + /* Return if already disconnected */ if (!dev->connected) return; @@ -1648,23 +1646,6 @@ static void usb_disconnect(struct udc *dev) /* mask interrupts */ udc_mask_unused_interrupts(dev); - /* REVISIT there doesn't seem to be a point to having this - * talk to a tasklet ... do it directly, we already hold - * the spinlock needed to process the disconnect. - */ - - tasklet_schedule(&disconnect_tasklet); -} - -/* Tasklet for disconnect to be outside of interrupt context */ -static void udc_tasklet_disconnect(unsigned long par) -{ - struct udc *dev = udc; - u32 tmp; - - DBG(dev, "Tasklet disconnect\n"); - spin_lock_irq(&dev->lock); - if (dev->driver) { spin_unlock(&dev->lock); dev->driver->disconnect(&dev->gadget); @@ -1673,13 +1654,10 @@ static void udc_tasklet_disconnect(unsigned long par) /* empty queues */ for (tmp = 0; tmp < UDC_EP_NUM; tmp++) empty_req_queue(&dev->ep[tmp]); - } /* disable ep0 */ - ep_init(dev->regs, - &dev->ep[UDC_EP0IN_IX]); - + ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); if (!soft_reset_occured) { /* init controller by soft reset */ @@ -1695,8 +1673,6 @@ static void udc_tasklet_disconnect(unsigned long par) tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); writel(tmp, &dev->regs->cfg); } - - spin_unlock_irq(&dev->lock); } /* Reset the UDC core */ -- cgit v1.2.3