diff options
author | Lukasz Majewski <l.majewski@samsung.com> | 2012-06-14 04:02:24 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-06-15 07:37:24 -0400 |
commit | 22258f4906aa87e0c0debcad22cb292453e2ebfb (patch) | |
tree | cb5ba6dadb1e11ca483e3ca3396b0b50192f2c42 /drivers/usb/gadget/s3c-hsotg.c | |
parent | 99c515005857ff7d6cd5c2ba272ccab5dc0ea648 (diff) |
usb: hsotg: samsung: Replace endpoint specific locks with a global lock
The endpoint specific locks are replaced with a global lock.
This is crucial for running s3c-hsotg driver on a SMP SoC.
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r-- | drivers/usb/gadget/s3c-hsotg.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index d37585105bb..b10791282f1 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; |
@@ -156,6 +155,8 @@ struct s3c_hsotg { | |||
156 | struct usb_gadget_driver *driver; | 155 | struct usb_gadget_driver *driver; |
157 | struct s3c_hsotg_plat *plat; | 156 | struct s3c_hsotg_plat *plat; |
158 | 157 | ||
158 | spinlock_t lock; | ||
159 | |||
159 | void __iomem *regs; | 160 | void __iomem *regs; |
160 | int irq; | 161 | int irq; |
161 | struct clk *clk; | 162 | struct clk *clk; |
@@ -901,6 +902,8 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
901 | ep->name, req, req->length, req->buf, req->no_interrupt, | 902 | ep->name, req, req->length, req->buf, req->no_interrupt, |
902 | req->zero, req->short_not_ok); | 903 | req->zero, req->short_not_ok); |
903 | 904 | ||
905 | spin_lock_irqsave(&hs->lock, irqflags); | ||
906 | |||
904 | /* initialise status of the request */ | 907 | /* initialise status of the request */ |
905 | INIT_LIST_HEAD(&hs_req->queue); | 908 | INIT_LIST_HEAD(&hs_req->queue); |
906 | req->actual = 0; | 909 | req->actual = 0; |
@@ -913,15 +916,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, | |||
913 | return ret; | 916 | return ret; |
914 | } | 917 | } |
915 | 918 | ||
916 | spin_lock_irqsave(&hs_ep->lock, irqflags); | ||
917 | |||
918 | first = list_empty(&hs_ep->queue); | 919 | first = list_empty(&hs_ep->queue); |
919 | list_add_tail(&hs_req->queue, &hs_ep->queue); | 920 | list_add_tail(&hs_req->queue, &hs_ep->queue); |
920 | 921 | ||
921 | if (first) | 922 | if (first) |
922 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); | 923 | s3c_hsotg_start_req(hs, hs_ep, hs_req, false); |
923 | 924 | ||
924 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | 925 | spin_unlock_irqrestore(&hs->lock, irqflags); |
925 | 926 | ||
926 | return 0; | 927 | return 0; |
927 | } | 928 | } |
@@ -1381,9 +1382,9 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, | |||
1381 | */ | 1382 | */ |
1382 | 1383 | ||
1383 | if (hs_req->req.complete) { | 1384 | if (hs_req->req.complete) { |
1384 | spin_unlock(&hs_ep->lock); | 1385 | spin_unlock(&hsotg->lock); |
1385 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); | 1386 | hs_req->req.complete(&hs_ep->ep, &hs_req->req); |
1386 | spin_lock(&hs_ep->lock); | 1387 | spin_lock(&hsotg->lock); |
1387 | } | 1388 | } |
1388 | 1389 | ||
1389 | /* | 1390 | /* |
@@ -1418,9 +1419,9 @@ static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, | |||
1418 | { | 1419 | { |
1419 | unsigned long flags; | 1420 | unsigned long flags; |
1420 | 1421 | ||
1421 | spin_lock_irqsave(&hs_ep->lock, flags); | 1422 | spin_lock_irqsave(&hsotg->lock, flags); |
1422 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); | 1423 | s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); |
1423 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 1424 | spin_unlock_irqrestore(&hsotg->lock, flags); |
1424 | } | 1425 | } |
1425 | 1426 | ||
1426 | /** | 1427 | /** |
@@ -1442,6 +1443,8 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1442 | int max_req; | 1443 | int max_req; |
1443 | int read_ptr; | 1444 | int read_ptr; |
1444 | 1445 | ||
1446 | spin_lock(&hsotg->lock); | ||
1447 | |||
1445 | if (!hs_req) { | 1448 | if (!hs_req) { |
1446 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); | 1449 | u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); |
1447 | int ptr; | 1450 | int ptr; |
@@ -1454,11 +1457,10 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1454 | for (ptr = 0; ptr < size; ptr += 4) | 1457 | for (ptr = 0; ptr < size; ptr += 4) |
1455 | (void)readl(fifo); | 1458 | (void)readl(fifo); |
1456 | 1459 | ||
1460 | spin_unlock(&hsotg->lock); | ||
1457 | return; | 1461 | return; |
1458 | } | 1462 | } |
1459 | 1463 | ||
1460 | spin_lock(&hs_ep->lock); | ||
1461 | |||
1462 | to_read = size; | 1464 | to_read = size; |
1463 | read_ptr = hs_req->req.actual; | 1465 | read_ptr = hs_req->req.actual; |
1464 | max_req = hs_req->req.length - read_ptr; | 1466 | max_req = hs_req->req.length - read_ptr; |
@@ -1486,7 +1488,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) | |||
1486 | */ | 1488 | */ |
1487 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); | 1489 | readsl(fifo, hs_req->req.buf + read_ptr, to_read); |
1488 | 1490 | ||
1489 | spin_unlock(&hs_ep->lock); | 1491 | spin_unlock(&hsotg->lock); |
1490 | } | 1492 | } |
1491 | 1493 | ||
1492 | /** | 1494 | /** |
@@ -2123,7 +2125,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2123 | struct s3c_hsotg_req *req, *treq; | 2125 | struct s3c_hsotg_req *req, *treq; |
2124 | unsigned long flags; | 2126 | unsigned long flags; |
2125 | 2127 | ||
2126 | spin_lock_irqsave(&ep->lock, flags); | 2128 | spin_lock_irqsave(&hsotg->lock, flags); |
2127 | 2129 | ||
2128 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { | 2130 | list_for_each_entry_safe(req, treq, &ep->queue, queue) { |
2129 | /* | 2131 | /* |
@@ -2138,7 +2140,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, | |||
2138 | result); | 2140 | result); |
2139 | } | 2141 | } |
2140 | 2142 | ||
2141 | spin_unlock_irqrestore(&ep->lock, flags); | 2143 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2142 | } | 2144 | } |
2143 | 2145 | ||
2144 | #define call_gadget(_hs, _entry) \ | 2146 | #define call_gadget(_hs, _entry) \ |
@@ -2602,7 +2604,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2602 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", | 2604 | dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", |
2603 | __func__, epctrl, epctrl_reg); | 2605 | __func__, epctrl, epctrl_reg); |
2604 | 2606 | ||
2605 | spin_lock_irqsave(&hs_ep->lock, flags); | 2607 | spin_lock_irqsave(&hsotg->lock, flags); |
2606 | 2608 | ||
2607 | epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); | 2609 | epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); |
2608 | epctrl |= DxEPCTL_MPS(mps); | 2610 | epctrl |= DxEPCTL_MPS(mps); |
@@ -2681,7 +2683,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, | |||
2681 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); | 2683 | s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); |
2682 | 2684 | ||
2683 | out: | 2685 | out: |
2684 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2686 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2685 | return ret; | 2687 | return ret; |
2686 | } | 2688 | } |
2687 | 2689 | ||
@@ -2711,7 +2713,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2711 | /* terminate all requests with shutdown */ | 2713 | /* terminate all requests with shutdown */ |
2712 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); | 2714 | kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); |
2713 | 2715 | ||
2714 | spin_lock_irqsave(&hs_ep->lock, flags); | 2716 | spin_lock_irqsave(&hsotg->lock, flags); |
2715 | 2717 | ||
2716 | ctrl = readl(hsotg->regs + epctrl_reg); | 2718 | ctrl = readl(hsotg->regs + epctrl_reg); |
2717 | ctrl &= ~DxEPCTL_EPEna; | 2719 | ctrl &= ~DxEPCTL_EPEna; |
@@ -2724,7 +2726,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) | |||
2724 | /* disable endpoint interrupts */ | 2726 | /* disable endpoint interrupts */ |
2725 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); | 2727 | s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); |
2726 | 2728 | ||
2727 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2729 | spin_unlock_irqrestore(&hsotg->lock, flags); |
2728 | return 0; | 2730 | return 0; |
2729 | } | 2731 | } |
2730 | 2732 | ||
@@ -2759,15 +2761,15 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | |||
2759 | 2761 | ||
2760 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); | 2762 | dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); |
2761 | 2763 | ||
2762 | spin_lock_irqsave(&hs_ep->lock, flags); | 2764 | spin_lock_irqsave(&hs->lock, flags); |
2763 | 2765 | ||
2764 | if (!on_list(hs_ep, hs_req)) { | 2766 | if (!on_list(hs_ep, hs_req)) { |
2765 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2767 | spin_unlock_irqrestore(&hs->lock, flags); |
2766 | return -EINVAL; | 2768 | return -EINVAL; |
2767 | } | 2769 | } |
2768 | 2770 | ||
2769 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); | 2771 | s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); |
2770 | spin_unlock_irqrestore(&hs_ep->lock, flags); | 2772 | spin_unlock_irqrestore(&hs->lock, flags); |
2771 | 2773 | ||
2772 | return 0; | 2774 | return 0; |
2773 | } | 2775 | } |
@@ -2789,7 +2791,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2789 | 2791 | ||
2790 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); | 2792 | dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); |
2791 | 2793 | ||
2792 | spin_lock_irqsave(&hs_ep->lock, irqflags); | 2794 | spin_lock_irqsave(&hs->lock, irqflags); |
2793 | 2795 | ||
2794 | /* write both IN and OUT control registers */ | 2796 | /* write both IN and OUT control registers */ |
2795 | 2797 | ||
@@ -2825,7 +2827,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) | |||
2825 | 2827 | ||
2826 | writel(epctl, hs->regs + epreg); | 2828 | writel(epctl, hs->regs + epreg); |
2827 | 2829 | ||
2828 | spin_unlock_irqrestore(&hs_ep->lock, irqflags); | 2830 | spin_unlock_irqrestore(&hs->lock, irqflags); |
2829 | 2831 | ||
2830 | return 0; | 2832 | return 0; |
2831 | } | 2833 | } |
@@ -3061,8 +3063,6 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, | |||
3061 | INIT_LIST_HEAD(&hs_ep->queue); | 3063 | INIT_LIST_HEAD(&hs_ep->queue); |
3062 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); | 3064 | INIT_LIST_HEAD(&hs_ep->ep.ep_list); |
3063 | 3065 | ||
3064 | spin_lock_init(&hs_ep->lock); | ||
3065 | |||
3066 | /* add to the list of endpoints known by the gadget driver */ | 3066 | /* add to the list of endpoints known by the gadget driver */ |
3067 | if (epnum) | 3067 | if (epnum) |
3068 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); | 3068 | list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); |
@@ -3340,7 +3340,7 @@ static int ep_show(struct seq_file *seq, void *v) | |||
3340 | seq_printf(seq, "request list (%p,%p):\n", | 3340 | seq_printf(seq, "request list (%p,%p):\n", |
3341 | ep->queue.next, ep->queue.prev); | 3341 | ep->queue.next, ep->queue.prev); |
3342 | 3342 | ||
3343 | spin_lock_irqsave(&ep->lock, flags); | 3343 | spin_lock_irqsave(&hsotg->lock, flags); |
3344 | 3344 | ||
3345 | list_for_each_entry(req, &ep->queue, queue) { | 3345 | list_for_each_entry(req, &ep->queue, queue) { |
3346 | if (--show_limit < 0) { | 3346 | if (--show_limit < 0) { |
@@ -3355,7 +3355,7 @@ static int ep_show(struct seq_file *seq, void *v) | |||
3355 | req->req.actual, req->req.status); | 3355 | req->req.actual, req->req.status); |
3356 | } | 3356 | } |
3357 | 3357 | ||
3358 | spin_unlock_irqrestore(&ep->lock, flags); | 3358 | spin_unlock_irqrestore(&hsotg->lock, flags); |
3359 | 3359 | ||
3360 | return 0; | 3360 | return 0; |
3361 | } | 3361 | } |
@@ -3507,6 +3507,8 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3507 | goto err_clk; | 3507 | goto err_clk; |
3508 | } | 3508 | } |
3509 | 3509 | ||
3510 | spin_lock_init(&hsotg->lock); | ||
3511 | |||
3510 | hsotg->irq = ret; | 3512 | hsotg->irq = ret; |
3511 | 3513 | ||
3512 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, | 3514 | ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, |