diff options
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/ci13xxx_udc.c | 120 |
1 files changed, 39 insertions, 81 deletions
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index c18068df73a1..560b539b9def 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -96,9 +96,6 @@ ctrl_endpt_in_desc = { | |||
96 | .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), | 96 | .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), |
97 | }; | 97 | }; |
98 | 98 | ||
99 | /* UDC descriptor */ | ||
100 | static struct ci13xxx *_udc; | ||
101 | |||
102 | /* Interrupt statistics */ | 99 | /* Interrupt statistics */ |
103 | #define ISR_MASK 0x1F | 100 | #define ISR_MASK 0x1F |
104 | static struct { | 101 | static struct { |
@@ -1679,7 +1676,8 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) | |||
1679 | usb_ep_fifo_flush(&udc->ep0out->ep); | 1676 | usb_ep_fifo_flush(&udc->ep0out->ep); |
1680 | usb_ep_fifo_flush(&udc->ep0in->ep); | 1677 | usb_ep_fifo_flush(&udc->ep0in->ep); |
1681 | 1678 | ||
1682 | udc->driver->disconnect(gadget); | 1679 | if (udc->driver) |
1680 | udc->driver->disconnect(gadget); | ||
1683 | 1681 | ||
1684 | /* make sure to disable all endpoints */ | 1682 | /* make sure to disable all endpoints */ |
1685 | gadget_for_each_ep(ep, gadget) { | 1683 | gadget_for_each_ep(ep, gadget) { |
@@ -1789,7 +1787,7 @@ __acquires(mEp->lock) | |||
1789 | 1787 | ||
1790 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | 1788 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { |
1791 | /* Assume that device is bus powered for now. */ | 1789 | /* Assume that device is bus powered for now. */ |
1792 | *(u16 *)req->buf = _udc->remote_wakeup << 1; | 1790 | *(u16 *)req->buf = udc->remote_wakeup << 1; |
1793 | retval = 0; | 1791 | retval = 0; |
1794 | } else if ((setup->bRequestType & USB_RECIP_MASK) \ | 1792 | } else if ((setup->bRequestType & USB_RECIP_MASK) \ |
1795 | == USB_RECIP_ENDPOINT) { | 1793 | == USB_RECIP_ENDPOINT) { |
@@ -1896,7 +1894,7 @@ __acquires(mEp->lock) | |||
1896 | spin_unlock(mEp->lock); | 1894 | spin_unlock(mEp->lock); |
1897 | if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) && | 1895 | if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) && |
1898 | mReq->req.length) | 1896 | mReq->req.length) |
1899 | mEpTemp = _udc->ep0in; | 1897 | mEpTemp = mEp->udc->ep0in; |
1900 | mReq->req.complete(&mEpTemp->ep, &mReq->req); | 1898 | mReq->req.complete(&mEpTemp->ep, &mReq->req); |
1901 | spin_lock(mEp->lock); | 1899 | spin_lock(mEp->lock); |
1902 | } | 1900 | } |
@@ -2276,6 +2274,7 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
2276 | { | 2274 | { |
2277 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | 2275 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); |
2278 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); | 2276 | struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req); |
2277 | struct ci13xxx *udc = mEp->udc; | ||
2279 | int retval = 0; | 2278 | int retval = 0; |
2280 | unsigned long flags; | 2279 | unsigned long flags; |
2281 | 2280 | ||
@@ -2288,8 +2287,8 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
2288 | 2287 | ||
2289 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { | 2288 | if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { |
2290 | if (req->length) | 2289 | if (req->length) |
2291 | mEp = (_udc->ep0_dir == RX) ? | 2290 | mEp = (udc->ep0_dir == RX) ? |
2292 | _udc->ep0out : _udc->ep0in; | 2291 | udc->ep0out : udc->ep0in; |
2293 | if (!list_empty(&mEp->qh.queue)) { | 2292 | if (!list_empty(&mEp->qh.queue)) { |
2294 | _ep_nuke(mEp); | 2293 | _ep_nuke(mEp); |
2295 | retval = -EOVERFLOW; | 2294 | retval = -EOVERFLOW; |
@@ -2555,9 +2554,10 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
2555 | return -ENOTSUPP; | 2554 | return -ENOTSUPP; |
2556 | } | 2555 | } |
2557 | 2556 | ||
2558 | static int ci13xxx_start(struct usb_gadget_driver *driver, | 2557 | static int ci13xxx_start(struct usb_gadget *gadget, |
2559 | int (*bind)(struct usb_gadget *)); | 2558 | struct usb_gadget_driver *driver); |
2560 | static int ci13xxx_stop(struct usb_gadget_driver *driver); | 2559 | static int ci13xxx_stop(struct usb_gadget *gadget, |
2560 | struct usb_gadget_driver *driver); | ||
2561 | /** | 2561 | /** |
2562 | * Device operations part of the API to the USB controller hardware, | 2562 | * Device operations part of the API to the USB controller hardware, |
2563 | * which don't involve endpoints (or i/o) | 2563 | * which don't involve endpoints (or i/o) |
@@ -2567,8 +2567,8 @@ static const struct usb_gadget_ops usb_gadget_ops = { | |||
2567 | .vbus_session = ci13xxx_vbus_session, | 2567 | .vbus_session = ci13xxx_vbus_session, |
2568 | .wakeup = ci13xxx_wakeup, | 2568 | .wakeup = ci13xxx_wakeup, |
2569 | .vbus_draw = ci13xxx_vbus_draw, | 2569 | .vbus_draw = ci13xxx_vbus_draw, |
2570 | .start = ci13xxx_start, | 2570 | .udc_start = ci13xxx_start, |
2571 | .stop = ci13xxx_stop, | 2571 | .udc_stop = ci13xxx_stop, |
2572 | }; | 2572 | }; |
2573 | 2573 | ||
2574 | static int init_eps(struct ci13xxx *udc) | 2574 | static int init_eps(struct ci13xxx *udc) |
@@ -2621,39 +2621,24 @@ static int init_eps(struct ci13xxx *udc) | |||
2621 | 2621 | ||
2622 | /** | 2622 | /** |
2623 | * ci13xxx_start: register a gadget driver | 2623 | * ci13xxx_start: register a gadget driver |
2624 | * @gadget: our gadget | ||
2624 | * @driver: the driver being registered | 2625 | * @driver: the driver being registered |
2625 | * @bind: the driver's bind callback | ||
2626 | * | 2626 | * |
2627 | * Check ci13xxx_start() at <linux/usb/gadget.h> for details. | ||
2628 | * Interrupts are enabled here. | 2627 | * Interrupts are enabled here. |
2629 | */ | 2628 | */ |
2630 | static int ci13xxx_start(struct usb_gadget_driver *driver, | 2629 | static int ci13xxx_start(struct usb_gadget *gadget, |
2631 | int (*bind)(struct usb_gadget *)) | 2630 | struct usb_gadget_driver *driver) |
2632 | { | 2631 | { |
2633 | struct ci13xxx *udc = _udc; | 2632 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); |
2634 | unsigned long flags; | 2633 | unsigned long flags; |
2635 | int i, j; | ||
2636 | int retval = -ENOMEM; | 2634 | int retval = -ENOMEM; |
2637 | 2635 | ||
2638 | trace(udc->dev, "%p", driver); | 2636 | trace(udc->dev, "%p", driver); |
2639 | 2637 | ||
2640 | if (driver == NULL || | 2638 | if (driver->disconnect == NULL) |
2641 | bind == NULL || | ||
2642 | driver->setup == NULL || | ||
2643 | driver->disconnect == NULL) | ||
2644 | return -EINVAL; | 2639 | return -EINVAL; |
2645 | else if (udc == NULL) | ||
2646 | return -ENODEV; | ||
2647 | else if (udc->driver != NULL) | ||
2648 | return -EBUSY; | ||
2649 | |||
2650 | spin_lock_irqsave(&udc->lock, flags); | ||
2651 | 2640 | ||
2652 | dev_info(udc->dev, "hw_ep_max = %d\n", udc->hw_ep_max); | ||
2653 | 2641 | ||
2654 | udc->gadget.dev.driver = NULL; | ||
2655 | |||
2656 | spin_unlock_irqrestore(&udc->lock, flags); | ||
2657 | udc->ep0out->ep.desc = &ctrl_endpt_out_desc; | 2642 | udc->ep0out->ep.desc = &ctrl_endpt_out_desc; |
2658 | retval = usb_ep_enable(&udc->ep0out->ep); | 2643 | retval = usb_ep_enable(&udc->ep0out->ep); |
2659 | if (retval) | 2644 | if (retval) |
@@ -2665,19 +2650,6 @@ static int ci13xxx_start(struct usb_gadget_driver *driver, | |||
2665 | return retval; | 2650 | return retval; |
2666 | spin_lock_irqsave(&udc->lock, flags); | 2651 | spin_lock_irqsave(&udc->lock, flags); |
2667 | 2652 | ||
2668 | /* bind gadget */ | ||
2669 | driver->driver.bus = NULL; | ||
2670 | udc->gadget.dev.driver = &driver->driver; | ||
2671 | |||
2672 | spin_unlock_irqrestore(&udc->lock, flags); | ||
2673 | retval = bind(&udc->gadget); /* MAY SLEEP */ | ||
2674 | spin_lock_irqsave(&udc->lock, flags); | ||
2675 | |||
2676 | if (retval) { | ||
2677 | udc->gadget.dev.driver = NULL; | ||
2678 | goto done; | ||
2679 | } | ||
2680 | |||
2681 | udc->driver = driver; | 2653 | udc->driver = driver; |
2682 | pm_runtime_get_sync(&udc->gadget.dev); | 2654 | pm_runtime_get_sync(&udc->gadget.dev); |
2683 | if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) { | 2655 | if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) { |
@@ -2701,23 +2673,15 @@ static int ci13xxx_start(struct usb_gadget_driver *driver, | |||
2701 | 2673 | ||
2702 | /** | 2674 | /** |
2703 | * ci13xxx_stop: unregister a gadget driver | 2675 | * ci13xxx_stop: unregister a gadget driver |
2704 | * | ||
2705 | * Check usb_gadget_unregister_driver() at "usb_gadget.h" for details | ||
2706 | */ | 2676 | */ |
2707 | static int ci13xxx_stop(struct usb_gadget_driver *driver) | 2677 | static int ci13xxx_stop(struct usb_gadget *gadget, |
2678 | struct usb_gadget_driver *driver) | ||
2708 | { | 2679 | { |
2709 | struct ci13xxx *udc = _udc; | 2680 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); |
2710 | unsigned long i, flags; | 2681 | unsigned long flags; |
2711 | 2682 | ||
2712 | trace(udc->dev, "%p", driver); | 2683 | trace(udc->dev, "%p", driver); |
2713 | 2684 | ||
2714 | if (driver == NULL || | ||
2715 | driver->unbind == NULL || | ||
2716 | driver->setup == NULL || | ||
2717 | driver->disconnect == NULL || | ||
2718 | driver != udc->driver) | ||
2719 | return -EINVAL; | ||
2720 | |||
2721 | spin_lock_irqsave(&udc->lock, flags); | 2685 | spin_lock_irqsave(&udc->lock, flags); |
2722 | 2686 | ||
2723 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) || | 2687 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) || |
@@ -2726,20 +2690,13 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) | |||
2726 | if (udc->udc_driver->notify_event) | 2690 | if (udc->udc_driver->notify_event) |
2727 | udc->udc_driver->notify_event(udc, | 2691 | udc->udc_driver->notify_event(udc, |
2728 | CI13XXX_CONTROLLER_STOPPED_EVENT); | 2692 | CI13XXX_CONTROLLER_STOPPED_EVENT); |
2693 | udc->driver = NULL; | ||
2729 | spin_unlock_irqrestore(&udc->lock, flags); | 2694 | spin_unlock_irqrestore(&udc->lock, flags); |
2730 | _gadget_stop_activity(&udc->gadget); | 2695 | _gadget_stop_activity(&udc->gadget); |
2731 | spin_lock_irqsave(&udc->lock, flags); | 2696 | spin_lock_irqsave(&udc->lock, flags); |
2732 | pm_runtime_put(&udc->gadget.dev); | 2697 | pm_runtime_put(&udc->gadget.dev); |
2733 | } | 2698 | } |
2734 | 2699 | ||
2735 | /* unbind gadget */ | ||
2736 | spin_unlock_irqrestore(&udc->lock, flags); | ||
2737 | driver->unbind(&udc->gadget); /* MAY SLEEP */ | ||
2738 | spin_lock_irqsave(&udc->lock, flags); | ||
2739 | |||
2740 | udc->gadget.dev.driver = NULL; | ||
2741 | udc->driver = NULL; | ||
2742 | |||
2743 | spin_unlock_irqrestore(&udc->lock, flags); | 2700 | spin_unlock_irqrestore(&udc->lock, flags); |
2744 | 2701 | ||
2745 | return 0; | 2702 | return 0; |
@@ -2756,7 +2713,7 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) | |||
2756 | */ | 2713 | */ |
2757 | static irqreturn_t udc_irq(int irq, void *data) | 2714 | static irqreturn_t udc_irq(int irq, void *data) |
2758 | { | 2715 | { |
2759 | struct ci13xxx *udc = _udc; | 2716 | struct ci13xxx *udc = data; |
2760 | irqreturn_t retval; | 2717 | irqreturn_t retval; |
2761 | u32 intr; | 2718 | u32 intr; |
2762 | 2719 | ||
@@ -2846,7 +2803,7 @@ static void udc_release(struct device *dev) | |||
2846 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask | 2803 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask |
2847 | */ | 2804 | */ |
2848 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | 2805 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, |
2849 | void __iomem *regs) | 2806 | void __iomem *regs, struct ci13xxx **_udc) |
2850 | { | 2807 | { |
2851 | struct ci13xxx *udc; | 2808 | struct ci13xxx *udc; |
2852 | int retval = 0; | 2809 | int retval = 0; |
@@ -2872,7 +2829,6 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2872 | udc->gadget.name = driver->name; | 2829 | udc->gadget.name = driver->name; |
2873 | 2830 | ||
2874 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2831 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
2875 | udc->gadget.ep0 = NULL; | ||
2876 | 2832 | ||
2877 | dev_set_name(&udc->gadget.dev, "gadget"); | 2833 | dev_set_name(&udc->gadget.dev, "gadget"); |
2878 | udc->gadget.dev.dma_mask = dev->dma_mask; | 2834 | udc->gadget.dev.dma_mask = dev->dma_mask; |
@@ -2950,7 +2906,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2950 | pm_runtime_no_callbacks(&udc->gadget.dev); | 2906 | pm_runtime_no_callbacks(&udc->gadget.dev); |
2951 | pm_runtime_enable(&udc->gadget.dev); | 2907 | pm_runtime_enable(&udc->gadget.dev); |
2952 | 2908 | ||
2953 | _udc = udc; | 2909 | *_udc = udc; |
2954 | return retval; | 2910 | return retval; |
2955 | 2911 | ||
2956 | remove_trans: | 2912 | remove_trans: |
@@ -2975,7 +2931,7 @@ free_qh_pool: | |||
2975 | dma_pool_destroy(udc->qh_pool); | 2931 | dma_pool_destroy(udc->qh_pool); |
2976 | free_udc: | 2932 | free_udc: |
2977 | kfree(udc); | 2933 | kfree(udc); |
2978 | _udc = NULL; | 2934 | *_udc = NULL; |
2979 | return retval; | 2935 | return retval; |
2980 | } | 2936 | } |
2981 | 2937 | ||
@@ -2984,9 +2940,8 @@ free_udc: | |||
2984 | * | 2940 | * |
2985 | * No interrupts active, the IRQ has been released | 2941 | * No interrupts active, the IRQ has been released |
2986 | */ | 2942 | */ |
2987 | static void udc_remove(void) | 2943 | static void udc_remove(struct ci13xxx *udc) |
2988 | { | 2944 | { |
2989 | struct ci13xxx *udc = _udc; | ||
2990 | int i; | 2945 | int i; |
2991 | 2946 | ||
2992 | if (udc == NULL) | 2947 | if (udc == NULL) |
@@ -3014,13 +2969,13 @@ static void udc_remove(void) | |||
3014 | 2969 | ||
3015 | kfree(udc->hw_bank.regmap); | 2970 | kfree(udc->hw_bank.regmap); |
3016 | kfree(udc); | 2971 | kfree(udc); |
3017 | _udc = NULL; | ||
3018 | } | 2972 | } |
3019 | 2973 | ||
3020 | static int __devinit ci_udc_probe(struct platform_device *pdev) | 2974 | static int __devinit ci_udc_probe(struct platform_device *pdev) |
3021 | { | 2975 | { |
3022 | struct device *dev = &pdev->dev; | 2976 | struct device *dev = &pdev->dev; |
3023 | struct ci13xxx_udc_driver *driver = dev->platform_data; | 2977 | struct ci13xxx_udc_driver *driver = dev->platform_data; |
2978 | struct ci13xxx *udc; | ||
3024 | struct resource *res; | 2979 | struct resource *res; |
3025 | void __iomem *base; | 2980 | void __iomem *base; |
3026 | int ret; | 2981 | int ret; |
@@ -3042,30 +2997,33 @@ static int __devinit ci_udc_probe(struct platform_device *pdev) | |||
3042 | return -ENOMEM; | 2997 | return -ENOMEM; |
3043 | } | 2998 | } |
3044 | 2999 | ||
3045 | ret = udc_probe(driver, dev, base); | 3000 | ret = udc_probe(driver, dev, base, &udc); |
3046 | if (ret) | 3001 | if (ret) |
3047 | return ret; | 3002 | return ret; |
3048 | 3003 | ||
3049 | _udc->irq = platform_get_irq(pdev, 0); | 3004 | udc->irq = platform_get_irq(pdev, 0); |
3050 | if (_udc->irq < 0) { | 3005 | if (udc->irq < 0) { |
3051 | dev_err(dev, "missing IRQ\n"); | 3006 | dev_err(dev, "missing IRQ\n"); |
3052 | ret = -ENODEV; | 3007 | ret = -ENODEV; |
3053 | goto out; | 3008 | goto out; |
3054 | } | 3009 | } |
3055 | 3010 | ||
3056 | ret = request_irq(_udc->irq, udc_irq, IRQF_SHARED, driver->name, _udc); | 3011 | platform_set_drvdata(pdev, udc); |
3012 | ret = request_irq(udc->irq, udc_irq, IRQF_SHARED, driver->name, udc); | ||
3057 | 3013 | ||
3058 | out: | 3014 | out: |
3059 | if (ret) | 3015 | if (ret) |
3060 | udc_remove(); | 3016 | udc_remove(udc); |
3061 | 3017 | ||
3062 | return ret; | 3018 | return ret; |
3063 | } | 3019 | } |
3064 | 3020 | ||
3065 | static int __devexit ci_udc_remove(struct platform_device *pdev) | 3021 | static int __devexit ci_udc_remove(struct platform_device *pdev) |
3066 | { | 3022 | { |
3067 | free_irq(_udc->irq, _udc); | 3023 | struct ci13xxx *udc = platform_get_drvdata(pdev); |
3068 | udc_remove(); | 3024 | |
3025 | free_irq(udc->irq, udc); | ||
3026 | udc_remove(udc); | ||
3069 | 3027 | ||
3070 | return 0; | 3028 | return 0; |
3071 | } | 3029 | } |