diff options
Diffstat (limited to 'drivers/usb/gadget/fsl_qe_udc.c')
-rw-r--r-- | drivers/usb/gadget/fsl_qe_udc.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index d6c5bcd40064..d701bf4698d2 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -1622,6 +1622,8 @@ static int qe_ep_disable(struct usb_ep *_ep) | |||
1622 | nuke(ep, -ESHUTDOWN); | 1622 | nuke(ep, -ESHUTDOWN); |
1623 | ep->desc = NULL; | 1623 | ep->desc = NULL; |
1624 | ep->stopped = 1; | 1624 | ep->stopped = 1; |
1625 | ep->tx_req = NULL; | ||
1626 | qe_ep_reset(udc, ep->epnum); | ||
1625 | spin_unlock_irqrestore(&udc->lock, flags); | 1627 | spin_unlock_irqrestore(&udc->lock, flags); |
1626 | 1628 | ||
1627 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); | 1629 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); |
@@ -1681,14 +1683,11 @@ static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
1681 | kfree(req); | 1683 | kfree(req); |
1682 | } | 1684 | } |
1683 | 1685 | ||
1684 | /* queues (submits) an I/O request to an endpoint */ | 1686 | static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req) |
1685 | static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1686 | gfp_t gfp_flags) | ||
1687 | { | 1687 | { |
1688 | struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); | 1688 | struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); |
1689 | struct qe_req *req = container_of(_req, struct qe_req, req); | 1689 | struct qe_req *req = container_of(_req, struct qe_req, req); |
1690 | struct qe_udc *udc; | 1690 | struct qe_udc *udc; |
1691 | unsigned long flags; | ||
1692 | int reval; | 1691 | int reval; |
1693 | 1692 | ||
1694 | udc = ep->udc; | 1693 | udc = ep->udc; |
@@ -1732,7 +1731,7 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1732 | list_add_tail(&req->queue, &ep->queue); | 1731 | list_add_tail(&req->queue, &ep->queue); |
1733 | dev_vdbg(udc->dev, "gadget have request in %s! %d\n", | 1732 | dev_vdbg(udc->dev, "gadget have request in %s! %d\n", |
1734 | ep->name, req->req.length); | 1733 | ep->name, req->req.length); |
1735 | spin_lock_irqsave(&udc->lock, flags); | 1734 | |
1736 | /* push the request to device */ | 1735 | /* push the request to device */ |
1737 | if (ep_is_in(ep)) | 1736 | if (ep_is_in(ep)) |
1738 | reval = ep_req_send(ep, req); | 1737 | reval = ep_req_send(ep, req); |
@@ -1748,11 +1747,24 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1748 | if (ep->dir == USB_DIR_OUT) | 1747 | if (ep->dir == USB_DIR_OUT) |
1749 | reval = ep_req_receive(ep, req); | 1748 | reval = ep_req_receive(ep, req); |
1750 | 1749 | ||
1751 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1752 | |||
1753 | return 0; | 1750 | return 0; |
1754 | } | 1751 | } |
1755 | 1752 | ||
1753 | /* queues (submits) an I/O request to an endpoint */ | ||
1754 | static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1755 | gfp_t gfp_flags) | ||
1756 | { | ||
1757 | struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); | ||
1758 | struct qe_udc *udc = ep->udc; | ||
1759 | unsigned long flags; | ||
1760 | int ret; | ||
1761 | |||
1762 | spin_lock_irqsave(&udc->lock, flags); | ||
1763 | ret = __qe_ep_queue(_ep, _req); | ||
1764 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1765 | return ret; | ||
1766 | } | ||
1767 | |||
1756 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ | 1768 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ |
1757 | static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | 1769 | static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) |
1758 | { | 1770 | { |
@@ -2008,7 +2020,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value, | |||
2008 | udc->ep0_dir = USB_DIR_IN; | 2020 | udc->ep0_dir = USB_DIR_IN; |
2009 | 2021 | ||
2010 | /* data phase */ | 2022 | /* data phase */ |
2011 | status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); | 2023 | status = __qe_ep_queue(&ep->ep, &req->req); |
2012 | 2024 | ||
2013 | if (status == 0) | 2025 | if (status == 0) |
2014 | return; | 2026 | return; |
@@ -2151,6 +2163,9 @@ static int reset_irq(struct qe_udc *udc) | |||
2151 | { | 2163 | { |
2152 | unsigned char i; | 2164 | unsigned char i; |
2153 | 2165 | ||
2166 | if (udc->usb_state == USB_STATE_DEFAULT) | ||
2167 | return 0; | ||
2168 | |||
2154 | qe_usb_disable(); | 2169 | qe_usb_disable(); |
2155 | out_8(&udc->usb_regs->usb_usadr, 0); | 2170 | out_8(&udc->usb_regs->usb_usadr, 0); |
2156 | 2171 | ||
@@ -2442,8 +2457,12 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc) | |||
2442 | struct usb_ctlr __iomem *qe_usbregs; | 2457 | struct usb_ctlr __iomem *qe_usbregs; |
2443 | qe_usbregs = udc->usb_regs; | 2458 | qe_usbregs = udc->usb_regs; |
2444 | 2459 | ||
2445 | /* Init the usb register */ | 2460 | /* Spec says that we must enable the USB controller to change mode. */ |
2446 | out_8(&qe_usbregs->usb_usmod, 0x01); | 2461 | out_8(&qe_usbregs->usb_usmod, 0x01); |
2462 | /* Mode changed, now disable it, since muram isn't initialized yet. */ | ||
2463 | out_8(&qe_usbregs->usb_usmod, 0x00); | ||
2464 | |||
2465 | /* Initialize the rest. */ | ||
2447 | out_be16(&qe_usbregs->usb_usbmr, 0); | 2466 | out_be16(&qe_usbregs->usb_usbmr, 0); |
2448 | out_8(&qe_usbregs->usb_uscom, 0); | 2467 | out_8(&qe_usbregs->usb_uscom, 0); |
2449 | out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); | 2468 | out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); |
@@ -2604,6 +2623,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2604 | (unsigned long)udc_controller); | 2623 | (unsigned long)udc_controller); |
2605 | /* request irq and disable DR */ | 2624 | /* request irq and disable DR */ |
2606 | udc_controller->usb_irq = irq_of_parse_and_map(np, 0); | 2625 | udc_controller->usb_irq = irq_of_parse_and_map(np, 0); |
2626 | if (!udc_controller->usb_irq) { | ||
2627 | ret = -EINVAL; | ||
2628 | goto err_noirq; | ||
2629 | } | ||
2607 | 2630 | ||
2608 | ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, | 2631 | ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, |
2609 | driver_name, udc_controller); | 2632 | driver_name, udc_controller); |
@@ -2625,6 +2648,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2625 | err6: | 2648 | err6: |
2626 | free_irq(udc_controller->usb_irq, udc_controller); | 2649 | free_irq(udc_controller->usb_irq, udc_controller); |
2627 | err5: | 2650 | err5: |
2651 | irq_dispose_mapping(udc_controller->usb_irq); | ||
2652 | err_noirq: | ||
2628 | if (udc_controller->nullmap) { | 2653 | if (udc_controller->nullmap) { |
2629 | dma_unmap_single(udc_controller->gadget.dev.parent, | 2654 | dma_unmap_single(udc_controller->gadget.dev.parent, |
2630 | udc_controller->nullp, 256, | 2655 | udc_controller->nullp, 256, |
@@ -2648,7 +2673,7 @@ err2: | |||
2648 | iounmap(udc_controller->usb_regs); | 2673 | iounmap(udc_controller->usb_regs); |
2649 | err1: | 2674 | err1: |
2650 | kfree(udc_controller); | 2675 | kfree(udc_controller); |
2651 | 2676 | udc_controller = NULL; | |
2652 | return ret; | 2677 | return ret; |
2653 | } | 2678 | } |
2654 | 2679 | ||
@@ -2710,6 +2735,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) | |||
2710 | kfree(ep->txframe); | 2735 | kfree(ep->txframe); |
2711 | 2736 | ||
2712 | free_irq(udc_controller->usb_irq, udc_controller); | 2737 | free_irq(udc_controller->usb_irq, udc_controller); |
2738 | irq_dispose_mapping(udc_controller->usb_irq); | ||
2713 | 2739 | ||
2714 | tasklet_kill(&udc_controller->rx_tasklet); | 2740 | tasklet_kill(&udc_controller->rx_tasklet); |
2715 | 2741 | ||