diff options
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 215 |
1 files changed, 110 insertions, 105 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index f4abb0ed9872..b13e0bb5f5b8 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -112,7 +112,6 @@ struct s3c_hsotg_ep { | |||
112 | struct s3c_hsotg_req *req; | 112 | struct s3c_hsotg_req *req; |
113 | struct dentry *debugfs; | 113 | struct dentry *debugfs; |
114 | 114 | ||
115 | spinlock_t lock; | ||
116 | 115 | ||
117 | unsigned long total_data; | 116 | unsigned long total_data; |
118 | unsigned int size_loaded; | 117 | unsigned int size_loaded; |
@@ -136,7 +135,6 @@ struct s3c_hsotg_ep { | |||
136 | * @driver: USB gadget driver | 135 | * @driver: USB gadget driver |
137 | * @plat: The platform specific configuration data. | 136 | * @plat: The platform specific configuration data. |
138 | * @regs: The memory area mapped for accessing registers. | 137 | * @regs: The memory area mapped for accessing registers. |
139 | * @regs_res: The resource that was allocated when claiming register space. | ||
140 | * @irq: The IRQ number we are using | 138 | * @irq: The IRQ number we are using |
141 | * @supplies: Definition of USB power supplies | 139 | * @supplies: Definition of USB power supplies |
142 | * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. | 140 | * @dedicated_fifos: Set if the hardware has dedicated IN-EP fifos. |
@@ -157,8 +155,9 @@ struct s3c_hsotg { | |||
157 | struct usb_gadget_driver *driver; | 155 | struct usb_gadget_driver *driver; |
158 | struct s3c_hsotg_plat *plat; | 156 | struct s3c_hsotg_plat *plat; |
159 | 157 | ||
158 | spinlock_t lock; | ||
159 | |||
160 | void __iomem *regs; | 160 | void __iomem *regs; |
161 | struct resource *regs_res; | ||
162 | int irq; | 161 | int irq; |
163 | struct clk *clk; | 162 | struct clk *clk; |
164 | 163 | ||
@@ -896,7 +895,6 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
896 | struct s3c_hsotg_req *hs_req = our_req(req); | 895 | struct s3c_hsotg_req *hs_req = our_req(req); |
897 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 896 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
898 | struct s3c_hsotg *hs = hs_ep->parent; | 897 | struct s3c_hsotg *hs = hs_ep->parent; |
899 | unsigned long irqflags; | ||
900 | bool first; | 898 | bool first; |
901 | 899 | ||
902 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", | 900 | dev_dbg(hs->dev, "%s: req %p: %d@%p, noi=%d, zero=%d, snok=%d\n", |
@@ -915,19 +913,30 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
915 | return ret; | 913 | return ret; |
916 | } | 914 | } |
917 | 915 | ||
918 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
919 | |||
920 | first = list_empty(&hs_ep->queue); | 916 | first = list_empty(&hs_ep->queue); |
921 | list_add_tail(&hs_req->queue, &hs_ep->queue); | 917 | list_add_tail(&hs_req->queue, &hs_ep->queue); |
922 | 918 | ||
923 | if (first) | 919 | if (first) |
924 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); | 920 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); |
925 | 921 | ||
926 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | ||
927 | |||
928 | return 0; | 922 | return 0; |
929 | } | 923 | } |
930 | 924 | ||
925 | static int s3c_hsotg_ep_queue_lock(struct usb_ep *ep, struct usb_request *req, | ||
926 | gfp_t gfp_flags) | ||
927 | { | ||
928 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
929 | struct s3c_hsotg *hs = hs_ep->parent; | ||
930 | unsigned long flags = 0; | ||
931 | int ret = 0; | ||
932 | |||
933 | spin_lock_irqsave(&hs->lock, flags); | ||
934 | ret = s3c_hsotg_ep_queue(ep, req, gfp_flags); | ||
935 | spin_unlock_irqrestore(&hs->lock, flags); | ||
936 | |||
937 | return ret; | ||
938 | } | ||
939 | |||
931 | static void s3c_hsotg_ep_free_request(struct usb_ep *ep, | 940 | static void s3c_hsotg_ep_free_request(struct usb_ep *ep, |
932 | struct usb_request *req) | 941 | struct usb_request *req) |
933 | { | 942 | { |
@@ -1383,9 +1392,9 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | |||
1383 | */ | 1392 | */ |
1384 | 1393 | ||
1385 | if (hs_req->req.complete) { | 1394 | if (hs_req->req.complete) { |
1386 | spin_unlock(&hs_ep->lock); | 1395 | spin_unlock(&hsotg->lock); |
1387 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); | 1396 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); |
1388 | spin_lock(&hs_ep->lock); | 1397 | spin_lock(&hsotg->lock); |
1389 | } | 1398 | } |
1390 | 1399 | ||
1391 | /* | 1400 | /* |
@@ -1404,28 +1413,6 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | |||
1404 | } | 1413 | } |
1405 | 1414 | ||
1406 | /** | 1415 | /** |
1407 | * s3c_hsotg_complete_request_lock - complete a request given to us (locked) | ||
1408 | * @hsotg: The device state. | ||
1409 | * @hs_ep: The endpoint the request was on. | ||
1410 | * @hs_req: The request to complete. | ||
1411 | * @result: The result code (0 => Ok, otherwise errno) | ||
1412 | * | ||
1413 | * See s3c_hsotg_complete_request(), but called with the endpoint's | ||
1414 | * lock held. | ||
1415 | */ | ||
1416 | static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, | ||
1417 | struct s3c_hsotg_ep *hs_ep, | ||
1418 | struct s3c_hsotg_req *hs_req, | ||
1419 | int result) | ||
1420 | { | ||
1421 | unsigned long flags; | ||
1422 | |||
1423 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
1424 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); | ||
1425 | spin_unlock_irqrestore(&hs_ep->lock, flags); | ||
1426 | } | ||
1427 | |||
1428 | /** | ||
1429 | * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint | 1416 | * s3c_hsotg_rx_data - receive data from the FIFO for an endpoint |
1430 | * @hsotg: The device state. | 1417 | * @hsotg: The device state. |
1431 | * @ep_idx: The endpoint index for the data | 1418 | * @ep_idx: The endpoint index for the data |
@@ -1444,6 +1431,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1444 | int max_req; | 1431 | int max_req; |
1445 | int read_ptr; | 1432 | int read_ptr; |
1446 | 1433 | ||
1434 | |||
1447 | if (!hs_req) { | 1435 | if (!hs_req) { |
1448 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); | 1436 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); |
1449 | int ptr; | 1437 | int ptr; |
@@ -1459,8 +1447,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1459 | return; | 1447 | return; |
1460 | } | 1448 | } |
1461 | 1449 | ||
1462 | spin_lock(&hs_ep->lock); | ||
1463 | |||
1464 | to_read = size; | 1450 | to_read = size; |
1465 | read_ptr = hs_req->req.actual; | 1451 | read_ptr = hs_req->req.actual; |
1466 | max_req = hs_req->req.length - read_ptr; | 1452 | max_req = hs_req->req.length - read_ptr; |
@@ -1487,8 +1473,6 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1487 | * alignment of the data. | 1473 | * alignment of the data. |
1488 | */ | 1474 | */ |
1489 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); | 1475 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); |
1490 | |||
1491 | spin_unlock(&hs_ep->lock); | ||
1492 | } | 1476 | } |
1493 | 1477 | ||
1494 | /** | 1478 | /** |
@@ -1609,7 +1593,7 @@ static void s3c_hsotg_handle_outdone(struct s3c_hsotg *hsotg, | |||
1609 | s3c_hsotg_send_zlp(hsotg, hs_req); | 1593 | s3c_hsotg_send_zlp(hsotg, hs_req); |
1610 | } | 1594 | } |
1611 | 1595 | ||
1612 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, result); | 1596 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); |
1613 | } | 1597 | } |
1614 | 1598 | ||
1615 | /** | 1599 | /** |
@@ -1864,7 +1848,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | |||
1864 | /* Finish ZLP handling for IN EP0 transactions */ | 1848 | /* Finish ZLP handling for IN EP0 transactions */ |
1865 | if (hsotg->eps[0].sent_zlp) { | 1849 | if (hsotg->eps[0].sent_zlp) { |
1866 | dev_dbg(hsotg->dev, "zlp packet received\n"); | 1850 | dev_dbg(hsotg->dev, "zlp packet received\n"); |
1867 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); | 1851 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); |
1868 | return; | 1852 | return; |
1869 | } | 1853 | } |
1870 | 1854 | ||
@@ -1915,7 +1899,7 @@ static void s3c_hsotg_complete_in(struct s3c_hsotg *hsotg, | |||
1915 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); | 1899 | dev_dbg(hsotg->dev, "%s trying more for req...\n", __func__); |
1916 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); | 1900 | s3c_hsotg_start_req(hsotg, hs_ep, hs_req, true); |
1917 | } else | 1901 | } else |
1918 | s3c_hsotg_complete_request_lock(hsotg, hs_ep, hs_req, 0); | 1902 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, 0); |
1919 | } | 1903 | } |
1920 | 1904 | ||
1921 | /** | 1905 | /** |
@@ -2123,9 +2107,6 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2123 | int result, bool force) | 2107 | int result, bool force) |
2124 | { | 2108 | { |
2125 | struct s3c_hsotg_req *req, *treq; | 2109 | struct s3c_hsotg_req *req, *treq; |
2126 | unsigned long flags; | ||
2127 | |||
2128 | spin_lock_irqsave(&ep->lock, flags); | ||
2129 | 2110 | ||
2130 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { | 2111 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { |
2131 | /* | 2112 | /* |
@@ -2139,14 +2120,15 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2139 | s3c_hsotg_complete_request(hsotg, ep, req, | 2120 | s3c_hsotg_complete_request(hsotg, ep, req, |
2140 | result); | 2121 | result); |
2141 | } | 2122 | } |
2142 | |||
2143 | spin_unlock_irqrestore(&ep->lock, flags); | ||
2144 | } | 2123 | } |
2145 | 2124 | ||
2146 | #define call_gadget(_hs, _entry) \ | 2125 | #define call_gadget(_hs, _entry) \ |
2147 | if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ | 2126 | if ((_hs)->gadget.speed != USB_SPEED_UNKNOWN && \ |
2148 | (_hs)->driver && (_hs)->driver->_entry) \ | 2127 | (_hs)->driver && (_hs)->driver->_entry) { \ |
2149 | (_hs)->driver->_entry(&(_hs)->gadget); | 2128 | spin_unlock(&_hs->lock); \ |
2129 | (_hs)->driver->_entry(&(_hs)->gadget); \ | ||
2130 | spin_lock(&_hs->lock); \ | ||
2131 | } | ||
2150 | 2132 | ||
2151 | /** | 2133 | /** |
2152 | * s3c_hsotg_disconnect - disconnect service | 2134 | * s3c_hsotg_disconnect - disconnect service |
@@ -2388,6 +2370,7 @@ static irqreturn_t s3c_hsotg_irq(int irq, void *pw) | |||
2388 | u32 gintsts; | 2370 | u32 gintsts; |
2389 | u32 gintmsk; | 2371 | u32 gintmsk; |
2390 | 2372 | ||
2373 | spin_lock(&hsotg->lock); | ||
2391 | irq_retry: | 2374 | irq_retry: |
2392 | gintsts = readl(hsotg->regs + GINTSTS); | 2375 | gintsts = readl(hsotg->regs + GINTSTS); |
2393 | gintmsk = readl(hsotg->regs + GINTMSK); | 2376 | gintmsk = readl(hsotg->regs + GINTMSK); |
@@ -2557,6 +2540,8 @@ irq_retry: | |||
2557 | if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) | 2540 | if (gintsts & IRQ_RETRY_MASK && --retry_count > 0) |
2558 | goto irq_retry; | 2541 | goto irq_retry; |
2559 | 2542 | ||
2543 | spin_unlock(&hsotg->lock); | ||
2544 | |||
2560 | return IRQ_HANDLED; | 2545 | return IRQ_HANDLED; |
2561 | } | 2546 | } |
2562 | 2547 | ||
@@ -2604,7 +2589,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2604 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", | 2589 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", |
2605 | __func__, epctrl, epctrl_reg); | 2590 | __func__, epctrl, epctrl_reg); |
2606 | 2591 | ||
2607 | spin_lock_irqsave(&hs_ep->lock, flags); | 2592 | spin_lock_irqsave(&hsotg->lock, flags); |
2608 | 2593 | ||
2609 | epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); | 2594 | epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); |
2610 | epctrl |= DxEPCTL_MPS(mps); | 2595 | epctrl |= DxEPCTL_MPS(mps); |
@@ -2683,7 +2668,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2683 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); | 2668 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); |
2684 | 2669 | ||
2685 | out: | 2670 | out: |
2686 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2671 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2687 | return ret; | 2672 | return ret; |
2688 | } | 2673 | } |
2689 | 2674 | ||
@@ -2710,10 +2695,10 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2710 | 2695 | ||
2711 | epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); | 2696 | epctrl_reg = dir_in ? DIEPCTL(index) : DOEPCTL(index); |
2712 | 2697 | ||
2698 | spin_lock_irqsave(&hsotg->lock, flags); | ||
2713 | /* terminate all requests with shutdown */ | 2699 | /* terminate all requests with shutdown */ |
2714 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); | 2700 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); |
2715 | 2701 | ||
2716 | spin_lock_irqsave(&hs_ep->lock, flags); | ||
2717 | 2702 | ||
2718 | ctrl = readl(hsotg->regs + epctrl_reg); | 2703 | ctrl = readl(hsotg->regs + epctrl_reg); |
2719 | ctrl &= ~DxEPCTL_EPEna; | 2704 | ctrl &= ~DxEPCTL_EPEna; |
@@ -2726,7 +2711,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2726 | /* disable endpoint interrupts */ | 2711 | /* disable endpoint interrupts */ |
2727 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); | 2712 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); |
2728 | 2713 | ||
2729 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2714 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2730 | return 0; | 2715 | return 0; |
2731 | } | 2716 | } |
2732 | 2717 | ||
@@ -2761,15 +2746,15 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2761 | 2746 | ||
2762 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); | 2747 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); |
2763 | 2748 | ||
2764 | spin_lock_irqsave(&hs_ep->lock, flags); | 2749 | spin_lock_irqsave(&hs->lock, flags); |
2765 | 2750 | ||
2766 | if (!on_list(hs_ep, hs_req)) { | 2751 | if (!on_list(hs_ep, hs_req)) { |
2767 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2752 | spin_unlock_irqrestore(&hs->lock, flags); |
2768 | return -EINVAL; | 2753 | return -EINVAL; |
2769 | } | 2754 | } |
2770 | 2755 | ||
2771 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); | 2756 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); |
2772 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2757 | spin_unlock_irqrestore(&hs->lock, flags); |
2773 | 2758 | ||
2774 | return 0; | 2759 | return 0; |
2775 | } | 2760 | } |
@@ -2784,15 +2769,12 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2784 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | 2769 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); |
2785 | struct s3c_hsotg *hs = hs_ep->parent; | 2770 | struct s3c_hsotg *hs = hs_ep->parent; |
2786 | int index = hs_ep->index; | 2771 | int index = hs_ep->index; |
2787 | unsigned long irqflags; | ||
2788 | u32 epreg; | 2772 | u32 epreg; |
2789 | u32 epctl; | 2773 | u32 epctl; |
2790 | u32 xfertype; | 2774 | u32 xfertype; |
2791 | 2775 | ||
2792 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | 2776 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); |
2793 | 2777 | ||
2794 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
2795 | |||
2796 | /* write both IN and OUT control registers */ | 2778 | /* write both IN and OUT control registers */ |
2797 | 2779 | ||
2798 | epreg = DIEPCTL(index); | 2780 | epreg = DIEPCTL(index); |
@@ -2827,19 +2809,36 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2827 | 2809 | ||
2828 | writel(epctl, hs->regs + epreg); | 2810 | writel(epctl, hs->regs + epreg); |
2829 | 2811 | ||
2830 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | ||
2831 | |||
2832 | return 0; | 2812 | return 0; |
2833 | } | 2813 | } |
2834 | 2814 | ||
2815 | /** | ||
2816 | * s3c_hsotg_ep_sethalt_lock - set halt on a given endpoint with lock held | ||
2817 | * @ep: The endpoint to set halt. | ||
2818 | * @value: Set or unset the halt. | ||
2819 | */ | ||
2820 | static int s3c_hsotg_ep_sethalt_lock(struct usb_ep *ep, int value) | ||
2821 | { | ||
2822 | struct s3c_hsotg_ep *hs_ep = our_ep(ep); | ||
2823 | struct s3c_hsotg *hs = hs_ep->parent; | ||
2824 | unsigned long flags = 0; | ||
2825 | int ret = 0; | ||
2826 | |||
2827 | spin_lock_irqsave(&hs->lock, flags); | ||
2828 | ret = s3c_hsotg_ep_sethalt(ep, value); | ||
2829 | spin_unlock_irqrestore(&hs->lock, flags); | ||
2830 | |||
2831 | return ret; | ||
2832 | } | ||
2833 | |||
2835 | static struct usb_ep_ops s3c_hsotg_ep_ops = { | 2834 | static struct usb_ep_ops s3c_hsotg_ep_ops = { |
2836 | .enable = s3c_hsotg_ep_enable, | 2835 | .enable = s3c_hsotg_ep_enable, |
2837 | .disable = s3c_hsotg_ep_disable, | 2836 | .disable = s3c_hsotg_ep_disable, |
2838 | .alloc_request = s3c_hsotg_ep_alloc_request, | 2837 | .alloc_request = s3c_hsotg_ep_alloc_request, |
2839 | .free_request = s3c_hsotg_ep_free_request, | 2838 | .free_request = s3c_hsotg_ep_free_request, |
2840 | .queue = s3c_hsotg_ep_queue, | 2839 | .queue = s3c_hsotg_ep_queue_lock, |
2841 | .dequeue = s3c_hsotg_ep_dequeue, | 2840 | .dequeue = s3c_hsotg_ep_dequeue, |
2842 | .set_halt = s3c_hsotg_ep_sethalt, | 2841 | .set_halt = s3c_hsotg_ep_sethalt_lock, |
2843 | /* note, don't believe we have any call for the fifo routines */ | 2842 | /* note, don't believe we have any call for the fifo routines */ |
2844 | }; | 2843 | }; |
2845 | 2844 | ||
@@ -2954,6 +2953,7 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2954 | driver->driver.bus = NULL; | 2953 | driver->driver.bus = NULL; |
2955 | hsotg->driver = driver; | 2954 | hsotg->driver = driver; |
2956 | hsotg->gadget.dev.driver = &driver->driver; | 2955 | hsotg->gadget.dev.driver = &driver->driver; |
2956 | hsotg->gadget.dev.of_node = hsotg->dev->of_node; | ||
2957 | hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; | 2957 | hsotg->gadget.dev.dma_mask = hsotg->dev->dma_mask; |
2958 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 2958 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
2959 | 2959 | ||
@@ -2964,9 +2964,6 @@ static int s3c_hsotg_udc_start(struct usb_gadget *gadget, | |||
2964 | goto err; | 2964 | goto err; |
2965 | } | 2965 | } |
2966 | 2966 | ||
2967 | s3c_hsotg_phy_enable(hsotg); | ||
2968 | |||
2969 | s3c_hsotg_core_init(hsotg); | ||
2970 | hsotg->last_rst = jiffies; | 2967 | hsotg->last_rst = jiffies; |
2971 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); | 2968 | dev_info(hsotg->dev, "bound driver %s\n", driver->driver.name); |
2972 | return 0; | 2969 | return 0; |
@@ -2988,6 +2985,7 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
2988 | struct usb_gadget_driver *driver) | 2985 | struct usb_gadget_driver *driver) |
2989 | { | 2986 | { |
2990 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | 2987 | struct s3c_hsotg *hsotg = to_hsotg(gadget); |
2988 | unsigned long flags = 0; | ||
2991 | int ep; | 2989 | int ep; |
2992 | 2990 | ||
2993 | if (!hsotg) | 2991 | if (!hsotg) |
@@ -3000,6 +2998,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
3000 | for (ep = 0; ep < hsotg->num_of_eps; ep++) | 2998 | for (ep = 0; ep < hsotg->num_of_eps; ep++) |
3001 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); | 2999 | s3c_hsotg_ep_disable(&hsotg->eps[ep].ep); |
3002 | 3000 | ||
3001 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3002 | |||
3003 | s3c_hsotg_phy_disable(hsotg); | 3003 | s3c_hsotg_phy_disable(hsotg); |
3004 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3004 | regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
3005 | 3005 | ||
@@ -3007,6 +3007,8 @@ static int s3c_hsotg_udc_stop(struct usb_gadget *gadget, | |||
3007 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | 3007 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; |
3008 | hsotg->gadget.dev.driver = NULL; | 3008 | hsotg->gadget.dev.driver = NULL; |
3009 | 3009 | ||
3010 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3011 | |||
3010 | dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", | 3012 | dev_info(hsotg->dev, "unregistered gadget driver '%s'\n", |
3011 | driver->driver.name); | 3013 | driver->driver.name); |
3012 | 3014 | ||
@@ -3024,10 +3026,40 @@ static int s3c_hsotg_gadget_getframe(struct usb_gadget *gadget) | |||
3024 | return s3c_hsotg_read_frameno(to_hsotg(gadget)); | 3026 | return s3c_hsotg_read_frameno(to_hsotg(gadget)); |
3025 | } | 3027 | } |
3026 | 3028 | ||
3029 | /** | ||
3030 | * s3c_hsotg_pullup - connect/disconnect the USB PHY | ||
3031 | * @gadget: The usb gadget state | ||
3032 | * @is_on: Current state of the USB PHY | ||
3033 | * | ||
3034 | * Connect/Disconnect the USB PHY pullup | ||
3035 | */ | ||
3036 | static int s3c_hsotg_pullup(struct usb_gadget *gadget, int is_on) | ||
3037 | { | ||
3038 | struct s3c_hsotg *hsotg = to_hsotg(gadget); | ||
3039 | unsigned long flags = 0; | ||
3040 | |||
3041 | dev_dbg(hsotg->dev, "%s: is_in: %d\n", __func__, is_on); | ||
3042 | |||
3043 | spin_lock_irqsave(&hsotg->lock, flags); | ||
3044 | if (is_on) { | ||
3045 | s3c_hsotg_phy_enable(hsotg); | ||
3046 | s3c_hsotg_core_init(hsotg); | ||
3047 | } else { | ||
3048 | s3c_hsotg_disconnect(hsotg); | ||
3049 | s3c_hsotg_phy_disable(hsotg); | ||
3050 | } | ||
3051 | |||
3052 | hsotg->gadget.speed = USB_SPEED_UNKNOWN; | ||
3053 | spin_unlock_irqrestore(&hsotg->lock, flags); | ||
3054 | |||
3055 | return 0; | ||
3056 | } | ||
3057 | |||
3027 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { | 3058 | static struct usb_gadget_ops s3c_hsotg_gadget_ops = { |
3028 | .get_frame = s3c_hsotg_gadget_getframe, | 3059 | .get_frame = s3c_hsotg_gadget_getframe, |
3029 | .udc_start = s3c_hsotg_udc_start, | 3060 | .udc_start = s3c_hsotg_udc_start, |
3030 | .udc_stop = s3c_hsotg_udc_stop, | 3061 | .udc_stop = s3c_hsotg_udc_stop, |
3062 | .pullup = s3c_hsotg_pullup, | ||
3031 | }; | 3063 | }; |
3032 | 3064 | ||
3033 | /** | 3065 | /** |
@@ -3063,8 +3095,6 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, | |||
3063 | INIT_LIST_HEAD(&hs_ep->queue); | 3095 | INIT_LIST_HEAD(&hs_ep->queue); |
3064 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); | 3096 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); |
3065 | 3097 | ||
3066 | spin_lock_init(&hs_ep->lock); | ||
3067 | |||
3068 | /* add to the list of endpoints known by the gadget driver */ | 3098 | /* add to the list of endpoints known by the gadget driver */ |
3069 | if (epnum) | 3099 | if (epnum) |
3070 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); | 3100 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); |
@@ -3342,7 +3372,7 @@ static int ep_show(struct seq_file *seq, void *v) | |||
3342 | seq_printf(seq, "request list (%p,%p):\n", | 3372 | seq_printf(seq, "request list (%p,%p):\n", |
3343 | ep->queue.next, ep->queue.prev); | 3373 | ep->queue.next, ep->queue.prev); |
3344 | 3374 | ||
3345 | spin_lock_irqsave(&ep->lock, flags); | 3375 | spin_lock_irqsave(&hsotg->lock, flags); |
3346 | 3376 | ||
3347 | list_for_each_entry(req, &ep->queue, queue) { | 3377 | list_for_each_entry(req, &ep->queue, queue) { |
3348 | if (--show_limit < 0) { | 3378 | if (--show_limit < 0) { |
@@ -3357,7 +3387,7 @@ static int ep_show(struct seq_file *seq, void *v) | |||
3357 | req->req.actual, req->req.status); | 3387 | req->req.actual, req->req.status); |
3358 | } | 3388 | } |
3359 | 3389 | ||
3360 | spin_unlock_irqrestore(&ep->lock, flags); | 3390 | spin_unlock_irqrestore(&hsotg->lock, flags); |
3361 | 3391 | ||
3362 | return 0; | 3392 | return 0; |
3363 | } | 3393 | } |
@@ -3477,7 +3507,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3477 | return -EINVAL; | 3507 | return -EINVAL; |
3478 | } | 3508 | } |
3479 | 3509 | ||
3480 | hsotg = kzalloc(sizeof(struct s3c_hsotg), GFP_KERNEL); | 3510 | hsotg = devm_kzalloc(&pdev->dev, sizeof(struct s3c_hsotg), GFP_KERNEL); |
3481 | if (!hsotg) { | 3511 | if (!hsotg) { |
3482 | dev_err(dev, "cannot get memory\n"); | 3512 | dev_err(dev, "cannot get memory\n"); |
3483 | return -ENOMEM; | 3513 | return -ENOMEM; |
@@ -3489,46 +3519,35 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3489 | hsotg->clk = clk_get(&pdev->dev, "otg"); | 3519 | hsotg->clk = clk_get(&pdev->dev, "otg"); |
3490 | if (IS_ERR(hsotg->clk)) { | 3520 | if (IS_ERR(hsotg->clk)) { |
3491 | dev_err(dev, "cannot get otg clock\n"); | 3521 | dev_err(dev, "cannot get otg clock\n"); |
3492 | ret = PTR_ERR(hsotg->clk); | 3522 | return PTR_ERR(hsotg->clk); |
3493 | goto err_mem; | ||
3494 | } | 3523 | } |
3495 | 3524 | ||
3496 | platform_set_drvdata(pdev, hsotg); | 3525 | platform_set_drvdata(pdev, hsotg); |
3497 | 3526 | ||
3498 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 3527 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
3499 | if (!res) { | ||
3500 | dev_err(dev, "cannot find register resource 0\n"); | ||
3501 | ret = -EINVAL; | ||
3502 | goto err_clk; | ||
3503 | } | ||
3504 | |||
3505 | hsotg->regs_res = request_mem_region(res->start, resource_size(res), | ||
3506 | dev_name(dev)); | ||
3507 | if (!hsotg->regs_res) { | ||
3508 | dev_err(dev, "cannot reserve registers\n"); | ||
3509 | ret = -ENOENT; | ||
3510 | goto err_clk; | ||
3511 | } | ||
3512 | 3528 | ||
3513 | hsotg->regs = ioremap(res->start, resource_size(res)); | 3529 | hsotg->regs = devm_request_and_ioremap(&pdev->dev, res); |
3514 | if (!hsotg->regs) { | 3530 | if (!hsotg->regs) { |
3515 | dev_err(dev, "cannot map registers\n"); | 3531 | dev_err(dev, "cannot map registers\n"); |
3516 | ret = -ENXIO; | 3532 | ret = -ENXIO; |
3517 | goto err_regs_res; | 3533 | goto err_clk; |
3518 | } | 3534 | } |
3519 | 3535 | ||
3520 | ret = platform_get_irq(pdev, 0); | 3536 | ret = platform_get_irq(pdev, 0); |
3521 | if (ret < 0) { | 3537 | if (ret < 0) { |
3522 | dev_err(dev, "cannot find IRQ\n"); | 3538 | dev_err(dev, "cannot find IRQ\n"); |
3523 | goto err_regs; | 3539 | goto err_clk; |
3524 | } | 3540 | } |
3525 | 3541 | ||
3542 | spin_lock_init(&hsotg->lock); | ||
3543 | |||
3526 | hsotg->irq = ret; | 3544 | hsotg->irq = ret; |
3527 | 3545 | ||
3528 | ret = request_irq(ret, s3c_hsotg_irq, 0, dev_name(dev), hsotg); | 3546 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, |
3547 | dev_name(dev), hsotg); | ||
3529 | if (ret < 0) { | 3548 | if (ret < 0) { |
3530 | dev_err(dev, "cannot claim IRQ\n"); | 3549 | dev_err(dev, "cannot claim IRQ\n"); |
3531 | goto err_regs; | 3550 | goto err_clk; |
3532 | } | 3551 | } |
3533 | 3552 | ||
3534 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); | 3553 | dev_info(dev, "regs %p, irq %d\n", hsotg->regs, hsotg->irq); |
@@ -3558,7 +3577,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3558 | hsotg->supplies); | 3577 | hsotg->supplies); |
3559 | if (ret) { | 3578 | if (ret) { |
3560 | dev_err(dev, "failed to request supplies: %d\n", ret); | 3579 | dev_err(dev, "failed to request supplies: %d\n", ret); |
3561 | goto err_irq; | 3580 | goto err_clk; |
3562 | } | 3581 | } |
3563 | 3582 | ||
3564 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), | 3583 | ret = regulator_bulk_enable(ARRAY_SIZE(hsotg->supplies), |
@@ -3642,19 +3661,11 @@ err_ep_mem: | |||
3642 | err_supplies: | 3661 | err_supplies: |
3643 | s3c_hsotg_phy_disable(hsotg); | 3662 | s3c_hsotg_phy_disable(hsotg); |
3644 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3663 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
3645 | err_irq: | 3664 | |
3646 | free_irq(hsotg->irq, hsotg); | ||
3647 | err_regs: | ||
3648 | iounmap(hsotg->regs); | ||
3649 | |||
3650 | err_regs_res: | ||
3651 | release_resource(hsotg->regs_res); | ||
3652 | kfree(hsotg->regs_res); | ||
3653 | err_clk: | 3665 | err_clk: |
3654 | clk_disable_unprepare(hsotg->clk); | 3666 | clk_disable_unprepare(hsotg->clk); |
3655 | clk_put(hsotg->clk); | 3667 | clk_put(hsotg->clk); |
3656 | err_mem: | 3668 | |
3657 | kfree(hsotg); | ||
3658 | return ret; | 3669 | return ret; |
3659 | } | 3670 | } |
3660 | 3671 | ||
@@ -3675,12 +3686,6 @@ static int __devexit s3c_hsotg_remove(struct platform_device *pdev) | |||
3675 | usb_gadget_unregister_driver(hsotg->driver); | 3686 | usb_gadget_unregister_driver(hsotg->driver); |
3676 | } | 3687 | } |
3677 | 3688 | ||
3678 | free_irq(hsotg->irq, hsotg); | ||
3679 | iounmap(hsotg->regs); | ||
3680 | |||
3681 | release_resource(hsotg->regs_res); | ||
3682 | kfree(hsotg->regs_res); | ||
3683 | |||
3684 | s3c_hsotg_phy_disable(hsotg); | 3689 | s3c_hsotg_phy_disable(hsotg); |
3685 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); | 3690 | regulator_bulk_free(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); |
3686 | 3691 | ||