aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/s3c-hsotg.c
diff options
context:
space:
mode:
authorLukasz Majewski <l.majewski@samsung.com>2012-06-14 04:02:24 -0400
committerFelipe Balbi <balbi@ti.com>2012-06-15 07:37:24 -0400
commit22258f4906aa87e0c0debcad22cb292453e2ebfb (patch)
treecb5ba6dadb1e11ca483e3ca3396b0b50192f2c42 /drivers/usb/gadget/s3c-hsotg.c
parent99c515005857ff7d6cd5c2ba272ccab5dc0ea648 (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.c54
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
2683out: 2685out:
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,