提交 22258f49 编写于 作者: L Lukasz Majewski 提交者: Felipe Balbi

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: NLukasz Majewski <l.majewski@samsung.com>
Signed-off-by: NKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: NFelipe Balbi <balbi@ti.com>
上级 99c51500
...@@ -112,7 +112,6 @@ struct s3c_hsotg_ep { ...@@ -112,7 +112,6 @@ struct s3c_hsotg_ep {
struct s3c_hsotg_req *req; struct s3c_hsotg_req *req;
struct dentry *debugfs; struct dentry *debugfs;
spinlock_t lock;
unsigned long total_data; unsigned long total_data;
unsigned int size_loaded; unsigned int size_loaded;
...@@ -156,6 +155,8 @@ struct s3c_hsotg { ...@@ -156,6 +155,8 @@ struct s3c_hsotg {
struct usb_gadget_driver *driver; struct usb_gadget_driver *driver;
struct s3c_hsotg_plat *plat; struct s3c_hsotg_plat *plat;
spinlock_t lock;
void __iomem *regs; void __iomem *regs;
int irq; int irq;
struct clk *clk; struct clk *clk;
...@@ -901,6 +902,8 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -901,6 +902,8 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
ep->name, req, req->length, req->buf, req->no_interrupt, ep->name, req, req->length, req->buf, req->no_interrupt,
req->zero, req->short_not_ok); req->zero, req->short_not_ok);
spin_lock_irqsave(&hs->lock, irqflags);
/* initialise status of the request */ /* initialise status of the request */
INIT_LIST_HEAD(&hs_req->queue); INIT_LIST_HEAD(&hs_req->queue);
req->actual = 0; req->actual = 0;
...@@ -913,15 +916,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req, ...@@ -913,15 +916,13 @@ static int s3c_hsotg_ep_queue(struct usb_ep *ep, struct usb_request *req,
return ret; return ret;
} }
spin_lock_irqsave(&hs_ep->lock, irqflags);
first = list_empty(&hs_ep->queue); first = list_empty(&hs_ep->queue);
list_add_tail(&hs_req->queue, &hs_ep->queue); list_add_tail(&hs_req->queue, &hs_ep->queue);
if (first) if (first)
s3c_hsotg_start_req(hs, hs_ep, hs_req, false); s3c_hsotg_start_req(hs, hs_ep, hs_req, false);
spin_unlock_irqrestore(&hs_ep->lock, irqflags); spin_unlock_irqrestore(&hs->lock, irqflags);
return 0; return 0;
} }
...@@ -1381,9 +1382,9 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg, ...@@ -1381,9 +1382,9 @@ static void s3c_hsotg_complete_request(struct s3c_hsotg *hsotg,
*/ */
if (hs_req->req.complete) { if (hs_req->req.complete) {
spin_unlock(&hs_ep->lock); spin_unlock(&hsotg->lock);
hs_req->req.complete(&hs_ep->ep, &hs_req->req); hs_req->req.complete(&hs_ep->ep, &hs_req->req);
spin_lock(&hs_ep->lock); spin_lock(&hsotg->lock);
} }
/* /*
...@@ -1418,9 +1419,9 @@ static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg, ...@@ -1418,9 +1419,9 @@ static void s3c_hsotg_complete_request_lock(struct s3c_hsotg *hsotg,
{ {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&hs_ep->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result); s3c_hsotg_complete_request(hsotg, hs_ep, hs_req, result);
spin_unlock_irqrestore(&hs_ep->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
} }
/** /**
...@@ -1442,6 +1443,8 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) ...@@ -1442,6 +1443,8 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size)
int max_req; int max_req;
int read_ptr; int read_ptr;
spin_lock(&hsotg->lock);
if (!hs_req) { if (!hs_req) {
u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx)); u32 epctl = readl(hsotg->regs + DOEPCTL(ep_idx));
int ptr; int ptr;
...@@ -1454,11 +1457,10 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size) ...@@ -1454,11 +1457,10 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size)
for (ptr = 0; ptr < size; ptr += 4) for (ptr = 0; ptr < size; ptr += 4)
(void)readl(fifo); (void)readl(fifo);
spin_unlock(&hsotg->lock);
return; return;
} }
spin_lock(&hs_ep->lock);
to_read = size; to_read = size;
read_ptr = hs_req->req.actual; read_ptr = hs_req->req.actual;
max_req = hs_req->req.length - read_ptr; 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,7 +1488,7 @@ static void s3c_hsotg_rx_data(struct s3c_hsotg *hsotg, int ep_idx, int size)
*/ */
readsl(fifo, hs_req->req.buf + read_ptr, to_read); readsl(fifo, hs_req->req.buf + read_ptr, to_read);
spin_unlock(&hs_ep->lock); spin_unlock(&hsotg->lock);
} }
/** /**
...@@ -2123,7 +2125,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, ...@@ -2123,7 +2125,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg,
struct s3c_hsotg_req *req, *treq; struct s3c_hsotg_req *req, *treq;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ep->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
list_for_each_entry_safe(req, treq, &ep->queue, queue) { list_for_each_entry_safe(req, treq, &ep->queue, queue) {
/* /*
...@@ -2138,7 +2140,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg, ...@@ -2138,7 +2140,7 @@ static void kill_all_requests(struct s3c_hsotg *hsotg,
result); result);
} }
spin_unlock_irqrestore(&ep->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
} }
#define call_gadget(_hs, _entry) \ #define call_gadget(_hs, _entry) \
...@@ -2602,7 +2604,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, ...@@ -2602,7 +2604,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n", dev_dbg(hsotg->dev, "%s: read DxEPCTL=0x%08x from 0x%08x\n",
__func__, epctrl, epctrl_reg); __func__, epctrl, epctrl_reg);
spin_lock_irqsave(&hs_ep->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK); epctrl &= ~(DxEPCTL_EPType_MASK | DxEPCTL_MPS_MASK);
epctrl |= DxEPCTL_MPS(mps); epctrl |= DxEPCTL_MPS(mps);
...@@ -2681,7 +2683,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep, ...@@ -2681,7 +2683,7 @@ static int s3c_hsotg_ep_enable(struct usb_ep *ep,
s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1); s3c_hsotg_ctrl_epint(hsotg, index, dir_in, 1);
out: out:
spin_unlock_irqrestore(&hs_ep->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
return ret; return ret;
} }
...@@ -2711,7 +2713,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) ...@@ -2711,7 +2713,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
/* terminate all requests with shutdown */ /* terminate all requests with shutdown */
kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false); kill_all_requests(hsotg, hs_ep, -ESHUTDOWN, false);
spin_lock_irqsave(&hs_ep->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
ctrl = readl(hsotg->regs + epctrl_reg); ctrl = readl(hsotg->regs + epctrl_reg);
ctrl &= ~DxEPCTL_EPEna; ctrl &= ~DxEPCTL_EPEna;
...@@ -2724,7 +2726,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep) ...@@ -2724,7 +2726,7 @@ static int s3c_hsotg_ep_disable(struct usb_ep *ep)
/* disable endpoint interrupts */ /* disable endpoint interrupts */
s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0); s3c_hsotg_ctrl_epint(hsotg, hs_ep->index, hs_ep->dir_in, 0);
spin_unlock_irqrestore(&hs_ep->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
return 0; return 0;
} }
...@@ -2759,15 +2761,15 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) ...@@ -2759,15 +2761,15 @@ static int s3c_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req); dev_info(hs->dev, "ep_dequeue(%p,%p)\n", ep, req);
spin_lock_irqsave(&hs_ep->lock, flags); spin_lock_irqsave(&hs->lock, flags);
if (!on_list(hs_ep, hs_req)) { if (!on_list(hs_ep, hs_req)) {
spin_unlock_irqrestore(&hs_ep->lock, flags); spin_unlock_irqrestore(&hs->lock, flags);
return -EINVAL; return -EINVAL;
} }
s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET); s3c_hsotg_complete_request(hs, hs_ep, hs_req, -ECONNRESET);
spin_unlock_irqrestore(&hs_ep->lock, flags); spin_unlock_irqrestore(&hs->lock, flags);
return 0; return 0;
} }
...@@ -2789,7 +2791,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) ...@@ -2789,7 +2791,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value); dev_info(hs->dev, "%s(ep %p %s, %d)\n", __func__, ep, ep->name, value);
spin_lock_irqsave(&hs_ep->lock, irqflags); spin_lock_irqsave(&hs->lock, irqflags);
/* write both IN and OUT control registers */ /* write both IN and OUT control registers */
...@@ -2825,7 +2827,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value) ...@@ -2825,7 +2827,7 @@ static int s3c_hsotg_ep_sethalt(struct usb_ep *ep, int value)
writel(epctl, hs->regs + epreg); writel(epctl, hs->regs + epreg);
spin_unlock_irqrestore(&hs_ep->lock, irqflags); spin_unlock_irqrestore(&hs->lock, irqflags);
return 0; return 0;
} }
...@@ -3061,8 +3063,6 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, ...@@ -3061,8 +3063,6 @@ static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg,
INIT_LIST_HEAD(&hs_ep->queue); INIT_LIST_HEAD(&hs_ep->queue);
INIT_LIST_HEAD(&hs_ep->ep.ep_list); INIT_LIST_HEAD(&hs_ep->ep.ep_list);
spin_lock_init(&hs_ep->lock);
/* add to the list of endpoints known by the gadget driver */ /* add to the list of endpoints known by the gadget driver */
if (epnum) if (epnum)
list_add_tail(&hs_ep->ep.ep_list, &hsotg->gadget.ep_list); 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,7 +3340,7 @@ static int ep_show(struct seq_file *seq, void *v)
seq_printf(seq, "request list (%p,%p):\n", seq_printf(seq, "request list (%p,%p):\n",
ep->queue.next, ep->queue.prev); ep->queue.next, ep->queue.prev);
spin_lock_irqsave(&ep->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
list_for_each_entry(req, &ep->queue, queue) { list_for_each_entry(req, &ep->queue, queue) {
if (--show_limit < 0) { if (--show_limit < 0) {
...@@ -3355,7 +3355,7 @@ static int ep_show(struct seq_file *seq, void *v) ...@@ -3355,7 +3355,7 @@ static int ep_show(struct seq_file *seq, void *v)
req->req.actual, req->req.status); req->req.actual, req->req.status);
} }
spin_unlock_irqrestore(&ep->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
return 0; return 0;
} }
...@@ -3507,6 +3507,8 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) ...@@ -3507,6 +3507,8 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev)
goto err_clk; goto err_clk;
} }
spin_lock_init(&hsotg->lock);
hsotg->irq = ret; hsotg->irq = ret;
ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0, ret = devm_request_irq(&pdev->dev, hsotg->irq, s3c_hsotg_irq, 0,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册