Commit d3cb25a1 authored by Pengyu Ma's avatar Pengyu Ma Committed by Felipe Balbi

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:
 [<c15ac7fa>] dump_stack+0x16/0x18
 [<c103084f>] warn_slowpath_common+0x7f/0xa0
 [<c15b2d6f>] ? preempt_count_sub+0x6f/0xc0
 [<c15b2d6f>] ? preempt_count_sub+0x6f/0xc0
 [<c10308a3>] warn_slowpath_fmt+0x33/0x40
 [<c15b2d6f>] preempt_count_sub+0x6f/0xc0
 [<faadbc82>] pch_udc_pcd_pullup+0x32/0xa0 [pch_udc]
 [<fa9747d9>] usb_gadget_remove_driver+0x29/0x60 [udc_core]
 [<fa974869>] usb_gadget_unregister_driver+0x59/0x80 [udc_core]
 [<faa78310>] usb_composite_unregister+0x10/0x20 [libcomposite]
 [<faae50f1>] cleanup+0xd/0xf [g_serial]
 [<c1084c47>] SyS_delete_module+0xf7/0x150
 [<c111f8dd>] ? ____fput+0xd/0x10
 [<c104b2ae>] ? task_work_run+0x6e/0xa0
 [<c15afda5>] 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: default avatarPengyu Ma <pengyu.ma@windriver.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent f811a383
...@@ -620,9 +620,9 @@ static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, ...@@ -620,9 +620,9 @@ static inline void pch_udc_vbus_session(struct pch_udc_dev *dev,
dev->vbus_session = 1; dev->vbus_session = 1;
} else { } else {
if (dev->driver && dev->driver->disconnect) { if (dev->driver && dev->driver->disconnect) {
spin_unlock(&dev->lock);
dev->driver->disconnect(&dev->gadget);
spin_lock(&dev->lock); spin_lock(&dev->lock);
dev->driver->disconnect(&dev->gadget);
spin_unlock(&dev->lock);
} }
pch_udc_set_disconnect(dev); pch_udc_set_disconnect(dev);
dev->vbus_session = 0; dev->vbus_session = 0;
...@@ -1191,9 +1191,9 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) ...@@ -1191,9 +1191,9 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on)
pch_udc_reconnect(dev); pch_udc_reconnect(dev);
} else { } else {
if (dev->driver && dev->driver->disconnect) { if (dev->driver && dev->driver->disconnect) {
spin_unlock(&dev->lock);
dev->driver->disconnect(&dev->gadget);
spin_lock(&dev->lock); spin_lock(&dev->lock);
dev->driver->disconnect(&dev->gadget);
spin_unlock(&dev->lock);
} }
pch_udc_set_disconnect(dev); pch_udc_set_disconnect(dev);
} }
...@@ -1488,11 +1488,11 @@ static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req, ...@@ -1488,11 +1488,11 @@ static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req,
req->dma_mapped = 0; req->dma_mapped = 0;
} }
ep->halted = 1; ep->halted = 1;
spin_unlock(&dev->lock); spin_lock(&dev->lock);
if (!ep->in) if (!ep->in)
pch_udc_ep_clear_rrdy(ep); pch_udc_ep_clear_rrdy(ep);
usb_gadget_giveback_request(&ep->ep, &req->req); usb_gadget_giveback_request(&ep->ep, &req->req);
spin_lock(&dev->lock); spin_unlock(&dev->lock);
ep->halted = halted; ep->halted = halted;
} }
...@@ -2414,7 +2414,7 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) ...@@ -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; dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IDX].ep;
else /* OUT */ else /* OUT */
dev->gadget.ep0 = &ep->ep; dev->gadget.ep0 = &ep->ep;
spin_unlock(&dev->lock); spin_lock(&dev->lock);
/* If Mass storage Reset */ /* If Mass storage Reset */
if ((dev->setup_data.bRequestType == 0x21) && if ((dev->setup_data.bRequestType == 0x21) &&
(dev->setup_data.bRequest == 0xFF)) (dev->setup_data.bRequest == 0xFF))
...@@ -2422,7 +2422,7 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) ...@@ -2422,7 +2422,7 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev)
/* call gadget with setup data received */ /* call gadget with setup data received */
setup_supported = dev->driver->setup(&dev->gadget, setup_supported = dev->driver->setup(&dev->gadget,
&dev->setup_data); &dev->setup_data);
spin_lock(&dev->lock); spin_unlock(&dev->lock);
if (dev->setup_data.bRequestType & USB_DIR_IN) { if (dev->setup_data.bRequestType & USB_DIR_IN) {
ep->td_data->status = (ep->td_data->status & ep->td_data->status = (ep->td_data->status &
...@@ -2594,9 +2594,9 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) ...@@ -2594,9 +2594,9 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev)
empty_req_queue(ep); empty_req_queue(ep);
} }
if (dev->driver) { if (dev->driver) {
spin_unlock(&dev->lock);
usb_gadget_udc_reset(&dev->gadget, dev->driver);
spin_lock(&dev->lock); 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) ...@@ -2675,9 +2675,9 @@ static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev)
dev->ep[i].halted = 0; dev->ep[i].halted = 0;
} }
dev->stall = 0; dev->stall = 0;
spin_unlock(&dev->lock);
ret = dev->driver->setup(&dev->gadget, &dev->setup_data);
spin_lock(&dev->lock); 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) ...@@ -2712,9 +2712,9 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev)
dev->stall = 0; dev->stall = 0;
/* call gadget zero with setup data received */ /* call gadget zero with setup data received */
spin_unlock(&dev->lock);
ret = dev->driver->setup(&dev->gadget, &dev->setup_data);
spin_lock(&dev->lock); 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) ...@@ -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_intr & UDC_DEVINT_US) {
if (dev->driver if (dev->driver
&& dev->driver->suspend) { && dev->driver->suspend) {
spin_unlock(&dev->lock);
dev->driver->suspend(&dev->gadget);
spin_lock(&dev->lock); spin_lock(&dev->lock);
dev->driver->suspend(&dev->gadget);
spin_unlock(&dev->lock);
} }
vbus = pch_vbus_gpio_get_value(dev); vbus = pch_vbus_gpio_get_value(dev);
if ((dev->vbus_session == 0) if ((dev->vbus_session == 0)
&& (vbus != 1)) { && (vbus != 1)) {
if (dev->driver && dev->driver->disconnect) { if (dev->driver && dev->driver->disconnect) {
spin_unlock(&dev->lock);
dev->driver->disconnect(&dev->gadget);
spin_lock(&dev->lock); spin_lock(&dev->lock);
dev->driver->disconnect(&dev->gadget);
spin_unlock(&dev->lock);
} }
pch_udc_reconnect(dev); pch_udc_reconnect(dev);
} else if ((dev->vbus_session == 0) } else if ((dev->vbus_session == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment