From: Pengyu Ma Date: Mon, 3 Aug 2015 03:28:24 +0000 (+0800) Subject: usb: gadget: udc: fix spin_lock in pch_udc X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=d3cb25a12138a09bc948c0091d3d42e519980659;p=deliverable%2Flinux.git usb: gadget: udc: fix spin_lock in pch_udc When remove module g_serial on quark platform, the following Warning on: Modules linked in: usb_f_acm u_serial g_serial(-) pch_udc libcomposite configfs udc_core ad7298 industrialio_triggered_buffer kfifo_buf tpm_i2c_infineon indus CPU: 0 PID: 369 Comm: modprobe Not tainted 3.14.29ltsi-WR7.0.0.0_standard #6 Hardware name: Intel Corp. QUARK/CrossHill, BIOS 0x010100F5 01/01/2014 f641df0c f641df0c f641dec8 c15ac7fa f641defc c103084f c16c2356 f641df28 00000171 c16b855c 000009dd c15b2d6f 000009dd c15b2d6f f6bd2000 faae5480 00000000 f641df14 c10308a3 00000009 f641df0c c16c2356 f641df28 f641df2c Call Trace: [] dump_stack+0x16/0x18 [] warn_slowpath_common+0x7f/0xa0 [] ? preempt_count_sub+0x6f/0xc0 [] ? preempt_count_sub+0x6f/0xc0 [] warn_slowpath_fmt+0x33/0x40 [] preempt_count_sub+0x6f/0xc0 [] pch_udc_pcd_pullup+0x32/0xa0 [pch_udc] [] usb_gadget_remove_driver+0x29/0x60 [udc_core] [] usb_gadget_unregister_driver+0x59/0x80 [udc_core] [] usb_composite_unregister+0x10/0x20 [libcomposite] [] cleanup+0xd/0xf [g_serial] [] SyS_delete_module+0xf7/0x150 [] ? ____fput+0xd/0x10 [] ? task_work_run+0x6e/0xa0 [] syscall_call+0x7/0x7 g_serial module on quark is depended on pch_udc module, ttyGSX cann't recieve data and warning on when remove g_serial. It was unlocked before the modification of the structure it was protecting, fix it as "lock -> unlock" to resolve this. Signed-off-by: Pengyu Ma Signed-off-by: Felipe Balbi --- diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index dcf5defdb9e5..e071c62d7f24 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -620,9 +620,9 @@ static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, dev->vbus_session = 1; } else { if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); spin_lock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_unlock(&dev->lock); } pch_udc_set_disconnect(dev); dev->vbus_session = 0; @@ -1191,9 +1191,9 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) pch_udc_reconnect(dev); } else { if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); spin_lock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_unlock(&dev->lock); } pch_udc_set_disconnect(dev); } @@ -1488,11 +1488,11 @@ static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req, req->dma_mapped = 0; } ep->halted = 1; - spin_unlock(&dev->lock); + spin_lock(&dev->lock); if (!ep->in) pch_udc_ep_clear_rrdy(ep); usb_gadget_giveback_request(&ep->ep, &req->req); - spin_lock(&dev->lock); + spin_unlock(&dev->lock); ep->halted = halted; } @@ -2414,7 +2414,7 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IDX].ep; else /* OUT */ dev->gadget.ep0 = &ep->ep; - spin_unlock(&dev->lock); + spin_lock(&dev->lock); /* If Mass storage Reset */ if ((dev->setup_data.bRequestType == 0x21) && (dev->setup_data.bRequest == 0xFF)) @@ -2422,7 +2422,7 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) /* call gadget with setup data received */ setup_supported = dev->driver->setup(&dev->gadget, &dev->setup_data); - spin_lock(&dev->lock); + spin_unlock(&dev->lock); if (dev->setup_data.bRequestType & USB_DIR_IN) { ep->td_data->status = (ep->td_data->status & @@ -2594,9 +2594,9 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) empty_req_queue(ep); } if (dev->driver) { - spin_unlock(&dev->lock); - usb_gadget_udc_reset(&dev->gadget, dev->driver); spin_lock(&dev->lock); + usb_gadget_udc_reset(&dev->gadget, dev->driver); + spin_unlock(&dev->lock); } } @@ -2675,9 +2675,9 @@ static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev) dev->ep[i].halted = 0; } dev->stall = 0; - spin_unlock(&dev->lock); - ret = dev->driver->setup(&dev->gadget, &dev->setup_data); spin_lock(&dev->lock); + ret = dev->driver->setup(&dev->gadget, &dev->setup_data); + spin_unlock(&dev->lock); } /** @@ -2712,9 +2712,9 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) dev->stall = 0; /* call gadget zero with setup data received */ - spin_unlock(&dev->lock); - ret = dev->driver->setup(&dev->gadget, &dev->setup_data); spin_lock(&dev->lock); + ret = dev->driver->setup(&dev->gadget, &dev->setup_data); + spin_unlock(&dev->lock); } /** @@ -2747,18 +2747,18 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_US) { if (dev->driver && dev->driver->suspend) { - spin_unlock(&dev->lock); - dev->driver->suspend(&dev->gadget); spin_lock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_unlock(&dev->lock); } vbus = pch_vbus_gpio_get_value(dev); if ((dev->vbus_session == 0) && (vbus != 1)) { if (dev->driver && dev->driver->disconnect) { - spin_unlock(&dev->lock); - dev->driver->disconnect(&dev->gadget); spin_lock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_unlock(&dev->lock); } pch_udc_reconnect(dev); } else if ((dev->vbus_session == 0)