aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:09 -0400
commit97664a207bc2601a03a300f00e6922038cd5b99c (patch)
tree19202c1dc78068e52a337cf34bff79d7c6e1b92f
parent8a2c225ddb2d23a9b3f70af2ec70d28e4abd0b8e (diff)
usb: renesas_usbhs: shrink spin lock area
spin lock was very effective while doing 1 packet send/recv on current renesas_usbhs driver. But this lock is enough only - modify packet/pipe link - modify interrpt mask - modify fifo access This patch shrink spin lock area Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/renesas_usbhs/common.h4
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c138
-rw-r--r--drivers/usb/renesas_usbhs/fifo.h17
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c309
4 files changed, 177 insertions, 291 deletions
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h
index 0aadcb402764..7bf675c23a5e 100644
--- a/drivers/usb/renesas_usbhs/common.h
+++ b/drivers/usb/renesas_usbhs/common.h
@@ -204,6 +204,10 @@ void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data);
204void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); 204void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data);
205 205
206int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev); 206int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev);
207
208#define usbhs_lock(p, f) spin_lock_irqsave(usbhs_priv_to_lock(p), f)
209#define usbhs_unlock(p, f) spin_unlock_irqrestore(usbhs_priv_to_lock(p), f)
210
207/* 211/*
208 * sysconfig 212 * sysconfig
209 */ 213 */
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index e9c4d3d8ef6e..3cda71e5a35a 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -22,7 +22,7 @@
22/* 22/*
23 * packet info function 23 * packet info function
24 */ 24 */
25static int usbhsf_null_handle(struct usbhs_pkt *pkt) 25static int usbhsf_null_handle(struct usbhs_pkt *pkt, int *is_done)
26{ 26{
27 struct usbhs_priv *priv = usbhs_pipe_to_priv(pkt->pipe); 27 struct usbhs_priv *priv = usbhs_pipe_to_priv(pkt->pipe);
28 struct device *dev = usbhs_priv_to_dev(priv); 28 struct device *dev = usbhs_priv_to_dev(priv);
@@ -48,6 +48,10 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
48{ 48{
49 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 49 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
50 struct device *dev = usbhs_priv_to_dev(priv); 50 struct device *dev = usbhs_priv_to_dev(priv);
51 unsigned long flags;
52
53 /******************** spin lock ********************/
54 usbhs_lock(priv, flags);
51 55
52 if (!handler) { 56 if (!handler) {
53 dev_err(dev, "no handler function\n"); 57 dev_err(dev, "no handler function\n");
@@ -63,14 +67,17 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
63 pkt->length = len; 67 pkt->length = len;
64 pkt->zero = zero; 68 pkt->zero = zero;
65 pkt->actual = 0; 69 pkt->actual = 0;
70
71 usbhs_unlock(priv, flags);
72 /******************** spin unlock ******************/
66} 73}
67 74
68void usbhs_pkt_pop(struct usbhs_pkt *pkt) 75static void __usbhsf_pkt_del(struct usbhs_pkt *pkt)
69{ 76{
70 list_del_init(&pkt->node); 77 list_del_init(&pkt->node);
71} 78}
72 79
73struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe) 80static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe)
74{ 81{
75 if (list_empty(&pipe->list)) 82 if (list_empty(&pipe->list))
76 return NULL; 83 return NULL;
@@ -78,6 +85,71 @@ struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe)
78 return list_entry(pipe->list.next, struct usbhs_pkt, node); 85 return list_entry(pipe->list.next, struct usbhs_pkt, node);
79} 86}
80 87
88struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
89{
90 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
91 unsigned long flags;
92
93 /******************** spin lock ********************/
94 usbhs_lock(priv, flags);
95
96 if (!pkt)
97 pkt = __usbhsf_pkt_get(pipe);
98
99 if (pkt)
100 __usbhsf_pkt_del(pkt);
101
102 usbhs_unlock(priv, flags);
103 /******************** spin unlock ******************/
104
105 return pkt;
106}
107
108int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type)
109{
110 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
111 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
112 struct usbhs_pkt *pkt;
113 struct device *dev = usbhs_priv_to_dev(priv);
114 int (*func)(struct usbhs_pkt *pkt, int *is_done);
115 unsigned long flags;
116 int ret = 0;
117 int is_done = 0;
118
119 /******************** spin lock ********************/
120 usbhs_lock(priv, flags);
121
122 pkt = __usbhsf_pkt_get(pipe);
123 if (!pkt)
124 goto __usbhs_pkt_handler_end;
125
126 switch (type) {
127 case USBHSF_PKT_PREPARE:
128 func = pkt->handler->prepare;
129 break;
130 case USBHSF_PKT_TRY_RUN:
131 func = pkt->handler->try_run;
132 break;
133 default:
134 dev_err(dev, "unknown pkt hander\n");
135 goto __usbhs_pkt_handler_end;
136 }
137
138 ret = func(pkt, &is_done);
139
140 if (is_done)
141 __usbhsf_pkt_del(pkt);
142
143__usbhs_pkt_handler_end:
144 usbhs_unlock(priv, flags);
145 /******************** spin unlock ******************/
146
147 if (is_done)
148 info->done(pkt);
149
150 return ret;
151}
152
81/* 153/*
82 * irq enable/disable function 154 * irq enable/disable function
83 */ 155 */
@@ -188,18 +260,17 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
188/* 260/*
189 * PIO fifo functions 261 * PIO fifo functions
190 */ 262 */
191static int usbhsf_try_push(struct usbhs_pkt *pkt) 263static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done)
192{ 264{
193 struct usbhs_pipe *pipe = pkt->pipe; 265 struct usbhs_pipe *pipe = pkt->pipe;
194 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 266 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
195 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
196 struct device *dev = usbhs_priv_to_dev(priv); 267 struct device *dev = usbhs_priv_to_dev(priv);
197 void __iomem *addr = priv->base + CFIFO; 268 void __iomem *addr = priv->base + CFIFO;
198 u8 *buf; 269 u8 *buf;
199 int maxp = usbhs_pipe_get_maxpacket(pipe); 270 int maxp = usbhs_pipe_get_maxpacket(pipe);
200 int total_len; 271 int total_len;
201 int i, ret, len; 272 int i, ret, len;
202 int is_short, is_done; 273 int is_short;
203 274
204 ret = usbhsf_fifo_select(pipe, 1); 275 ret = usbhsf_fifo_select(pipe, 1);
205 if (ret < 0) 276 if (ret < 0)
@@ -240,11 +311,11 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt)
240 pkt->actual += total_len; 311 pkt->actual += total_len;
241 312
242 if (pkt->actual < pkt->length) 313 if (pkt->actual < pkt->length)
243 is_done = 0; /* there are remainder data */ 314 *is_done = 0; /* there are remainder data */
244 else if (is_short) 315 else if (is_short)
245 is_done = 1; /* short packet */ 316 *is_done = 1; /* short packet */
246 else 317 else
247 is_done = !pkt->zero; /* send zero packet ? */ 318 *is_done = !pkt->zero; /* send zero packet ? */
248 319
249 /* 320 /*
250 * pipe/irq handling 321 * pipe/irq handling
@@ -252,21 +323,19 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt)
252 if (is_short) 323 if (is_short)
253 usbhsf_send_terminator(pipe); 324 usbhsf_send_terminator(pipe);
254 325
255 usbhsf_tx_irq_ctrl(pipe, !is_done); 326 usbhsf_tx_irq_ctrl(pipe, !*is_done);
256 usbhs_pipe_enable(pipe); 327 usbhs_pipe_enable(pipe);
257 328
258 dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", 329 dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n",
259 usbhs_pipe_number(pipe), 330 usbhs_pipe_number(pipe),
260 pkt->length, pkt->actual, is_done, pkt->zero); 331 pkt->length, pkt->actual, *is_done, pkt->zero);
261 332
262 /* 333 /*
263 * Transmission end 334 * Transmission end
264 */ 335 */
265 if (is_done) { 336 if (*is_done) {
266 if (usbhs_pipe_is_dcp(pipe)) 337 if (usbhs_pipe_is_dcp(pipe))
267 usbhs_dcp_control_transfer_done(pipe); 338 usbhs_dcp_control_transfer_done(pipe);
268
269 info->done(pkt);
270 } 339 }
271 340
272 return 0; 341 return 0;
@@ -286,7 +355,7 @@ struct usbhs_pkt_handle usbhs_fifo_push_handler = {
286 .try_run = usbhsf_try_push, 355 .try_run = usbhsf_try_push,
287}; 356};
288 357
289static int usbhsf_prepare_pop(struct usbhs_pkt *pkt) 358static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
290{ 359{
291 struct usbhs_pipe *pipe = pkt->pipe; 360 struct usbhs_pipe *pipe = pkt->pipe;
292 int ret; 361 int ret;
@@ -304,7 +373,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt)
304 return ret; 373 return ret;
305} 374}
306 375
307static int usbhsf_try_pop(struct usbhs_pkt *pkt) 376static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done)
308{ 377{
309 struct usbhs_pipe *pipe = pkt->pipe; 378 struct usbhs_pipe *pipe = pkt->pipe;
310 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); 379 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
@@ -316,7 +385,6 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt)
316 int rcv_len, len; 385 int rcv_len, len;
317 int i, ret; 386 int i, ret;
318 int total_len = 0; 387 int total_len = 0;
319 int is_done = 0;
320 388
321 ret = usbhsf_fifo_select(pipe, 0); 389 ret = usbhsf_fifo_select(pipe, 0);
322 if (ret < 0) 390 if (ret < 0)
@@ -367,22 +435,16 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt)
367 435
368usbhs_fifo_read_end: 436usbhs_fifo_read_end:
369 if ((pkt->actual == pkt->length) || /* receive all data */ 437 if ((pkt->actual == pkt->length) || /* receive all data */
370 (total_len < maxp)) /* short packet */ 438 (total_len < maxp)) { /* short packet */
371 is_done = 1; 439 *is_done = 1;
372
373 dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n",
374 usbhs_pipe_number(pipe),
375 pkt->length, pkt->actual, is_done, pkt->zero);
376
377 if (is_done) {
378 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
379
380 usbhsf_rx_irq_ctrl(pipe, 0); 440 usbhsf_rx_irq_ctrl(pipe, 0);
381 usbhs_pipe_disable(pipe); 441 usbhs_pipe_disable(pipe);
382
383 info->done(pkt);
384 } 442 }
385 443
444 dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n",
445 usbhs_pipe_number(pipe),
446 pkt->length, pkt->actual, *is_done, pkt->zero);
447
386 return 0; 448 return 0;
387} 449}
388 450
@@ -394,15 +456,11 @@ struct usbhs_pkt_handle usbhs_fifo_pop_handler = {
394/* 456/*
395 * handler function 457 * handler function
396 */ 458 */
397static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt) 459static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt, int *is_done)
398{ 460{
399 struct usbhs_pipe *pipe = pkt->pipe; 461 usbhs_dcp_control_transfer_done(pkt->pipe);
400 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
401 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
402 462
403 usbhs_dcp_control_transfer_done(pipe); 463 *is_done = 1;
404
405 info->done(pkt);
406 464
407 return 0; 465 return 0;
408} 466}
@@ -419,7 +477,6 @@ static int usbhsf_irq_empty(struct usbhs_priv *priv,
419 struct usbhs_irq_state *irq_state) 477 struct usbhs_irq_state *irq_state)
420{ 478{
421 struct usbhs_pipe *pipe; 479 struct usbhs_pipe *pipe;
422 struct usbhs_pkt *pkt;
423 struct device *dev = usbhs_priv_to_dev(priv); 480 struct device *dev = usbhs_priv_to_dev(priv);
424 int i, ret; 481 int i, ret;
425 482
@@ -438,8 +495,7 @@ static int usbhsf_irq_empty(struct usbhs_priv *priv,
438 if (!(irq_state->bempsts & (1 << i))) 495 if (!(irq_state->bempsts & (1 << i)))
439 continue; 496 continue;
440 497
441 pkt = usbhs_pkt_get(pipe); 498 ret = usbhs_pkt_run(pipe);
442 ret = usbhs_pkt_run(pkt);
443 if (ret < 0) 499 if (ret < 0)
444 dev_err(dev, "irq_empty run_error %d : %d\n", i, ret); 500 dev_err(dev, "irq_empty run_error %d : %d\n", i, ret);
445 } 501 }
@@ -451,7 +507,6 @@ static int usbhsf_irq_ready(struct usbhs_priv *priv,
451 struct usbhs_irq_state *irq_state) 507 struct usbhs_irq_state *irq_state)
452{ 508{
453 struct usbhs_pipe *pipe; 509 struct usbhs_pipe *pipe;
454 struct usbhs_pkt *pkt;
455 struct device *dev = usbhs_priv_to_dev(priv); 510 struct device *dev = usbhs_priv_to_dev(priv);
456 int i, ret; 511 int i, ret;
457 512
@@ -470,8 +525,7 @@ static int usbhsf_irq_ready(struct usbhs_priv *priv,
470 if (!(irq_state->brdysts & (1 << i))) 525 if (!(irq_state->brdysts & (1 << i)))
471 continue; 526 continue;
472 527
473 pkt = usbhs_pkt_get(pipe); 528 ret = usbhs_pkt_run(pipe);
474 ret = usbhs_pkt_run(pkt);
475 if (ret < 0) 529 if (ret < 0)
476 dev_err(dev, "irq_ready run_error %d : %d\n", i, ret); 530 dev_err(dev, "irq_ready run_error %d : %d\n", i, ret);
477 } 531 }
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h
index eab3258e9834..fcb1ecef57da 100644
--- a/drivers/usb/renesas_usbhs/fifo.h
+++ b/drivers/usb/renesas_usbhs/fifo.h
@@ -31,8 +31,8 @@ struct usbhs_pkt {
31}; 31};
32 32
33struct usbhs_pkt_handle { 33struct usbhs_pkt_handle {
34 int (*prepare)(struct usbhs_pkt *pkt); 34 int (*prepare)(struct usbhs_pkt *pkt, int *is_done);
35 int (*try_run)(struct usbhs_pkt *pkt); 35 int (*try_run)(struct usbhs_pkt *pkt, int *is_done);
36}; 36};
37 37
38/* 38/*
@@ -44,6 +44,11 @@ void usbhs_fifo_quit(struct usbhs_priv *priv);
44/* 44/*
45 * packet info 45 * packet info
46 */ 46 */
47enum {
48 USBHSF_PKT_PREPARE,
49 USBHSF_PKT_TRY_RUN,
50};
51
47extern struct usbhs_pkt_handle usbhs_fifo_push_handler; 52extern struct usbhs_pkt_handle usbhs_fifo_push_handler;
48extern struct usbhs_pkt_handle usbhs_fifo_pop_handler; 53extern struct usbhs_pkt_handle usbhs_fifo_pop_handler;
49extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler; 54extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler;
@@ -52,10 +57,10 @@ void usbhs_pkt_init(struct usbhs_pkt *pkt);
52void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, 57void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
53 struct usbhs_pkt_handle *handler, 58 struct usbhs_pkt_handle *handler,
54 void *buf, int len, int zero); 59 void *buf, int len, int zero);
55void usbhs_pkt_pop(struct usbhs_pkt *pkt); 60struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt);
56struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe); 61int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type);
57 62
58#define usbhs_pkt_start(p) ((p)->handler->prepare(p)) 63#define usbhs_pkt_start(p) __usbhs_pkt_handler(p, USBHSF_PKT_PREPARE)
59#define usbhs_pkt_run(p) ((p)->handler->try_run(p)) 64#define usbhs_pkt_run(p) __usbhs_pkt_handler(p, USBHSF_PKT_TRY_RUN)
60 65
61#endif /* RENESAS_USB_FIFO_H */ 66#endif /* RENESAS_USB_FIFO_H */
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 28b2b37f9661..b5a5ba7efb5e 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -92,7 +92,6 @@ struct usbhsg_recip_handle {
92 container_of(r, struct usbhsg_request, req) 92 container_of(r, struct usbhsg_request, req)
93 93
94#define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) 94#define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep)
95#define usbhsg_gpriv_to_lock(gp) usbhs_priv_to_lock((gp)->mod.priv)
96#define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) 95#define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv)
97#define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) 96#define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv)
98#define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) 97#define usbhsg_gpriv_to_dcp(gp) ((gp)->uep)
@@ -115,35 +114,6 @@ struct usbhsg_recip_handle {
115#define usbhsg_status_has(gp, b) (gp->status & b) 114#define usbhsg_status_has(gp, b) (gp->status & b)
116 115
117/* 116/*
118 * usbhsg_trylock
119 *
120 * This driver don't use spin_try_lock
121 * to avoid warning of CONFIG_DEBUG_SPINLOCK
122 */
123static spinlock_t *usbhsg_trylock(struct usbhsg_gpriv *gpriv,
124 unsigned long *flags)
125{
126 spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv);
127
128 /* check spin lock status
129 * to avoid deadlock/nest */
130 if (spin_is_locked(lock))
131 return NULL;
132
133 spin_lock_irqsave(lock, *flags);
134
135 return lock;
136}
137
138static void usbhsg_unlock(spinlock_t *lock, unsigned long *flags)
139{
140 if (!lock)
141 return;
142
143 spin_unlock_irqrestore(lock, *flags);
144}
145
146/*
147 * list push/pop 117 * list push/pop
148 */ 118 */
149static void usbhsg_queue_push(struct usbhsg_uep *uep, 119static void usbhsg_queue_push(struct usbhsg_uep *uep,
@@ -155,9 +125,6 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep,
155 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq); 125 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
156 struct usb_request *req = &ureq->req; 126 struct usb_request *req = &ureq->req;
157 127
158 /*
159 ********* assume under spin lock *********
160 */
161 usbhs_pkt_push(pipe, pkt, uep->handler, 128 usbhs_pkt_push(pipe, pkt, uep->handler,
162 req->buf, req->length, req->zero); 129 req->buf, req->length, req->zero);
163 req->actual = 0; 130 req->actual = 0;
@@ -168,44 +135,11 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep,
168 req->length); 135 req->length);
169} 136}
170 137
171static int usbhsg_queue_start(struct usbhsg_uep *uep) 138static void usbhsg_queue_start(struct usbhsg_uep *uep)
172{ 139{
173 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
174 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 140 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
175 struct usbhs_pkt *pkt;
176 spinlock_t *lock;
177 unsigned long flags;
178 int ret = 0;
179
180 /*
181 * CAUTION [*queue handler*]
182 *
183 * This function will be called for start/restart queue operation.
184 * OTOH the most much worry for USB driver is spinlock nest.
185 * Specially it are
186 * - usb_ep_ops :: queue
187 * - usb_request :: complete
188 *
189 * But the caller of this function need not care about spinlock.
190 * This function is using usbhsg_trylock for it.
191 * if "is_locked" is 1, this mean this function lock it.
192 * but if it is 0, this mean it is already under spin lock.
193 * see also
194 * CAUTION [*endpoint queue*]
195 * CAUTION [*request complete*]
196 */
197
198 /****************** spin try lock *******************/
199 lock = usbhsg_trylock(gpriv, &flags);
200
201 pkt = usbhs_pkt_get(pipe);
202 if (pkt)
203 ret = usbhs_pkt_start(pkt);
204
205 usbhsg_unlock(lock, &flags);
206 /******************** spin unlock ******************/
207 141
208 return ret; 142 usbhs_pkt_start(pipe);
209} 143}
210 144
211static void usbhsg_queue_pop(struct usbhsg_uep *uep, 145static void usbhsg_queue_pop(struct usbhsg_uep *uep,
@@ -215,34 +149,9 @@ static void usbhsg_queue_pop(struct usbhsg_uep *uep,
215 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 149 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
216 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 150 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
217 struct device *dev = usbhsg_gpriv_to_dev(gpriv); 151 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
218 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
219
220 /*
221 ********* assume under spin lock *********
222 */
223
224 /*
225 * CAUTION [*request complete*]
226 *
227 * There is a possibility not to be called in correct order
228 * if "complete" is called without spinlock.
229 *
230 * So, this function assume it is under spinlock,
231 * and call usb_request :: complete.
232 *
233 * But this "complete" will push next usb_request.
234 * It mean "usb_ep_ops :: queue" which is using spinlock is called
235 * under spinlock.
236 *
237 * To avoid dead-lock, this driver is using usbhsg_trylock.
238 * CAUTION [*endpoint queue*]
239 * CAUTION [*queue handler*]
240 */
241 152
242 dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); 153 dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe));
243 154
244 usbhs_pkt_pop(pkt);
245
246 ureq->req.status = status; 155 ureq->req.status = status;
247 ureq->req.complete(&uep->ep, &ureq->req); 156 ureq->req.complete(&uep->ep, &ureq->req);
248 157
@@ -293,8 +202,6 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv,
293 202
294 usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 203 usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
295 204
296 usbhsg_queue_start(uep);
297
298 return 0; 205 return 0;
299} 206}
300 207
@@ -325,7 +232,8 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
325 uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); 232 uep = usbhsg_gpriv_to_nth_uep(gpriv, nth);
326 if (!usbhsg_uep_to_pipe(uep)) { 233 if (!usbhsg_uep_to_pipe(uep)) {
327 dev_err(dev, "wrong recip request\n"); 234 dev_err(dev, "wrong recip request\n");
328 return -EINVAL; 235 ret = -EINVAL;
236 goto usbhsg_recip_run_handle_end;
329 } 237 }
330 238
331 switch (recip) { 239 switch (recip) {
@@ -348,10 +256,20 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv,
348 } 256 }
349 257
350 if (func) { 258 if (func) {
259 unsigned long flags;
260
351 dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); 261 dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg);
262
263 /******************** spin lock ********************/
264 usbhs_lock(priv, flags);
352 ret = func(priv, uep, ctrl); 265 ret = func(priv, uep, ctrl);
266 usbhs_unlock(priv, flags);
267 /******************** spin unlock ******************/
353 } 268 }
354 269
270usbhsg_recip_run_handle_end:
271 usbhsg_queue_start(uep);
272
355 return ret; 273 return ret;
356} 274}
357 275
@@ -445,44 +363,17 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
445 * usb_dcp_ops 363 * usb_dcp_ops
446 * 364 *
447 */ 365 */
448static int usbhsg_dcp_enable(struct usbhsg_uep *uep)
449{
450 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
451 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
452 struct usbhs_pipe *pipe;
453
454 /*
455 ********* assume under spin lock *********
456 */
457
458 pipe = usbhs_dcp_malloc(priv);
459 if (!pipe)
460 return -EIO;
461
462 uep->pipe = pipe;
463 uep->pipe->mod_private = uep;
464
465 return 0;
466}
467
468#define usbhsg_dcp_disable usbhsg_pipe_disable
469static int usbhsg_pipe_disable(struct usbhsg_uep *uep) 366static int usbhsg_pipe_disable(struct usbhsg_uep *uep)
470{ 367{
471 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 368 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
472 struct usbhs_pkt *pkt; 369 struct usbhs_pkt *pkt;
473 370
474 /*
475 ********* assume under spin lock *********
476 */
477
478 usbhs_pipe_disable(pipe); 371 usbhs_pipe_disable(pipe);
479 372
480 while (1) { 373 while (1) {
481 pkt = usbhs_pkt_get(pipe); 374 pkt = usbhs_pkt_pop(pipe, NULL);
482 if (!pkt) 375 if (!pkt)
483 break; 376 break;
484
485 usbhs_pkt_pop(pkt);
486 } 377 }
487 378
488 return 0; 379 return 0;
@@ -509,8 +400,6 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
509 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 400 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
510 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); 401 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
511 struct usbhs_pipe *pipe; 402 struct usbhs_pipe *pipe;
512 spinlock_t *lock;
513 unsigned long flags;
514 int ret = -EIO; 403 int ret = -EIO;
515 404
516 /* 405 /*
@@ -520,9 +409,6 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
520 if (uep->pipe) 409 if (uep->pipe)
521 return 0; 410 return 0;
522 411
523 /******************** spin lock ********************/
524 lock = usbhsg_trylock(gpriv, &flags);
525
526 pipe = usbhs_pipe_malloc(priv, desc); 412 pipe = usbhs_pipe_malloc(priv, desc);
527 if (pipe) { 413 if (pipe) {
528 uep->pipe = pipe; 414 uep->pipe = pipe;
@@ -536,29 +422,14 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
536 ret = 0; 422 ret = 0;
537 } 423 }
538 424
539 usbhsg_unlock(lock, &flags);
540 /******************** spin unlock ******************/
541
542 return ret; 425 return ret;
543} 426}
544 427
545static int usbhsg_ep_disable(struct usb_ep *ep) 428static int usbhsg_ep_disable(struct usb_ep *ep)
546{ 429{
547 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 430 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
548 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
549 spinlock_t *lock;
550 unsigned long flags;
551 int ret;
552 431
553 /******************** spin lock ********************/ 432 return usbhsg_pipe_disable(uep);
554 lock = usbhsg_trylock(gpriv, &flags);
555
556 ret = usbhsg_pipe_disable(uep);
557
558 usbhsg_unlock(lock, &flags);
559 /******************** spin unlock ******************/
560
561 return ret;
562} 433}
563 434
564static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, 435static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep,
@@ -591,69 +462,28 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req,
591 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 462 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
592 struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 463 struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
593 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 464 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
594 spinlock_t *lock;
595 unsigned long flags;
596 int ret = 0;
597
598 /*
599 * CAUTION [*endpoint queue*]
600 *
601 * This function will be called from usb_request :: complete
602 * or usb driver timing.
603 * If this function is called from usb_request :: complete,
604 * it is already under spinlock on this driver.
605 * but it is called frm usb driver, this function should call spinlock.
606 *
607 * This function is using usbshg_trylock to solve this issue.
608 * if "is_locked" is 1, this mean this function lock it.
609 * but if it is 0, this mean it is already under spin lock.
610 * see also
611 * CAUTION [*queue handler*]
612 * CAUTION [*request complete*]
613 */
614
615 /******************** spin lock ********************/
616 lock = usbhsg_trylock(gpriv, &flags);
617 465
618 /* param check */ 466 /* param check */
619 if (usbhsg_is_not_connected(gpriv) || 467 if (usbhsg_is_not_connected(gpriv) ||
620 unlikely(!gpriv->driver) || 468 unlikely(!gpriv->driver) ||
621 unlikely(!pipe)) 469 unlikely(!pipe))
622 ret = -ESHUTDOWN; 470 return -ESHUTDOWN;
623 else
624 usbhsg_queue_push(uep, ureq);
625
626 usbhsg_unlock(lock, &flags);
627 /******************** spin unlock ******************/
628 471
472 usbhsg_queue_push(uep, ureq);
629 usbhsg_queue_start(uep); 473 usbhsg_queue_start(uep);
630 474
631 return ret; 475 return 0;
632} 476}
633 477
634static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) 478static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
635{ 479{
636 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 480 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
637 struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); 481 struct usbhsg_request *ureq = usbhsg_req_to_ureq(req);
638 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 482 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
639 spinlock_t *lock;
640 unsigned long flags;
641
642 /*
643 * see
644 * CAUTION [*queue handler*]
645 * CAUTION [*endpoint queue*]
646 * CAUTION [*request complete*]
647 */
648
649 /******************** spin lock ********************/
650 lock = usbhsg_trylock(gpriv, &flags);
651 483
484 usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq));
652 usbhsg_queue_pop(uep, ureq, -ECONNRESET); 485 usbhsg_queue_pop(uep, ureq, -ECONNRESET);
653 486
654 usbhsg_unlock(lock, &flags);
655 /******************** spin unlock ******************/
656
657 return 0; 487 return 0;
658} 488}
659 489
@@ -662,42 +492,32 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge)
662 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); 492 struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
663 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 493 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
664 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 494 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
495 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
665 struct device *dev = usbhsg_gpriv_to_dev(gpriv); 496 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
666 spinlock_t *lock;
667 unsigned long flags; 497 unsigned long flags;
668 int ret = -EAGAIN;
669 498
670 /* 499 usbhsg_pipe_disable(uep);
671 * see
672 * CAUTION [*queue handler*]
673 * CAUTION [*endpoint queue*]
674 * CAUTION [*request complete*]
675 */
676
677 /******************** spin lock ********************/
678 lock = usbhsg_trylock(gpriv, &flags);
679 if (!usbhs_pkt_get(pipe)) {
680 500
681 dev_dbg(dev, "set halt %d (pipe %d)\n", 501 dev_dbg(dev, "set halt %d (pipe %d)\n",
682 halt, usbhs_pipe_number(pipe)); 502 halt, usbhs_pipe_number(pipe));
683 503
684 if (halt) 504 /******************** spin lock ********************/
685 usbhs_pipe_stall(pipe); 505 usbhs_lock(priv, flags);
686 else
687 usbhs_pipe_disable(pipe);
688 506
689 if (halt && wedge) 507 if (halt)
690 usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); 508 usbhs_pipe_stall(pipe);
691 else 509 else
692 usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); 510 usbhs_pipe_disable(pipe);
693 511
694 ret = 0; 512 if (halt && wedge)
695 } 513 usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE);
514 else
515 usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE);
696 516
697 usbhsg_unlock(lock, &flags); 517 usbhs_unlock(priv, flags);
698 /******************** spin unlock ******************/ 518 /******************** spin unlock ******************/
699 519
700 return ret; 520 return 0;
701} 521}
702 522
703static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) 523static int usbhsg_ep_set_halt(struct usb_ep *ep, int value)
@@ -733,20 +553,26 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
733 struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 553 struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
734 struct usbhs_mod *mod = usbhs_mod_get_current(priv); 554 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
735 struct device *dev = usbhs_priv_to_dev(priv); 555 struct device *dev = usbhs_priv_to_dev(priv);
736 spinlock_t *lock;
737 unsigned long flags; 556 unsigned long flags;
557 int ret = 0;
738 558
739 /******************** spin lock ********************/ 559 /******************** spin lock ********************/
740 lock = usbhsg_trylock(gpriv, &flags); 560 usbhs_lock(priv, flags);
741 561
742 /*
743 * enable interrupt and systems if ready
744 */
745 usbhsg_status_set(gpriv, status); 562 usbhsg_status_set(gpriv, status);
746 if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 563 if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) &&
747 usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) 564 usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)))
748 goto usbhsg_try_start_unlock; 565 ret = -1; /* not ready */
566
567 usbhs_unlock(priv, flags);
568 /******************** spin unlock ********************/
569
570 if (ret < 0)
571 return 0; /* not ready is not error */
749 572
573 /*
574 * enable interrupt and systems if ready
575 */
750 dev_dbg(dev, "start gadget\n"); 576 dev_dbg(dev, "start gadget\n");
751 577
752 /* 578 /*
@@ -756,7 +582,10 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
756 usbhsg_queue_done); 582 usbhsg_queue_done);
757 usbhs_fifo_init(priv); 583 usbhs_fifo_init(priv);
758 usbhsg_uep_init(gpriv); 584 usbhsg_uep_init(gpriv);
759 usbhsg_dcp_enable(dcp); 585
586 /* dcp init */
587 dcp->pipe = usbhs_dcp_malloc(priv);
588 dcp->pipe->mod_private = dcp;
760 589
761 /* 590 /*
762 * system config enble 591 * system config enble
@@ -775,10 +604,6 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
775 mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; 604 mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage;
776 usbhs_irq_callback_update(priv, mod); 605 usbhs_irq_callback_update(priv, mod);
777 606
778usbhsg_try_start_unlock:
779 usbhsg_unlock(lock, &flags);
780 /******************** spin unlock ********************/
781
782 return 0; 607 return 0;
783} 608}
784 609
@@ -788,20 +613,26 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
788 struct usbhs_mod *mod = usbhs_mod_get_current(priv); 613 struct usbhs_mod *mod = usbhs_mod_get_current(priv);
789 struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); 614 struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv);
790 struct device *dev = usbhs_priv_to_dev(priv); 615 struct device *dev = usbhs_priv_to_dev(priv);
791 spinlock_t *lock;
792 unsigned long flags; 616 unsigned long flags;
617 int ret = 0;
793 618
794 /******************** spin lock ********************/ 619 /******************** spin lock ********************/
795 lock = usbhsg_trylock(gpriv, &flags); 620 usbhs_lock(priv, flags);
796 621
797 /*
798 * disable interrupt and systems if 1st try
799 */
800 usbhsg_status_clr(gpriv, status); 622 usbhsg_status_clr(gpriv, status);
801 if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && 623 if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) &&
802 !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) 624 !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))
803 goto usbhsg_try_stop_unlock; 625 ret = -1; /* already done */
626
627 usbhs_unlock(priv, flags);
628 /******************** spin unlock ********************/
629
630 if (ret < 0)
631 return 0; /* already done is not error */
804 632
633 /*
634 * disable interrupt and systems if 1st try
635 */
805 usbhs_fifo_quit(priv); 636 usbhs_fifo_quit(priv);
806 637
807 /* disable all irq */ 638 /* disable all irq */
@@ -809,8 +640,6 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
809 mod->irq_ctrl_stage = NULL; 640 mod->irq_ctrl_stage = NULL;
810 usbhs_irq_callback_update(priv, mod); 641 usbhs_irq_callback_update(priv, mod);
811 642
812 usbhsg_dcp_disable(dcp);
813
814 gpriv->gadget.speed = USB_SPEED_UNKNOWN; 643 gpriv->gadget.speed = USB_SPEED_UNKNOWN;
815 644
816 /* disable sys */ 645 /* disable sys */
@@ -818,8 +647,7 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
818 usbhs_sys_function_ctrl(priv, 0); 647 usbhs_sys_function_ctrl(priv, 0);
819 usbhs_sys_usb_ctrl(priv, 0); 648 usbhs_sys_usb_ctrl(priv, 0);
820 649
821 usbhsg_unlock(lock, &flags); 650 usbhsg_pipe_disable(dcp);
822 /******************** spin unlock ********************/
823 651
824 if (gpriv->driver && 652 if (gpriv->driver &&
825 gpriv->driver->disconnect) 653 gpriv->driver->disconnect)
@@ -828,11 +656,6 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
828 dev_dbg(dev, "stop gadget\n"); 656 dev_dbg(dev, "stop gadget\n");
829 657
830 return 0; 658 return 0;
831
832usbhsg_try_stop_unlock:
833 usbhsg_unlock(lock, &flags);
834
835 return 0;
836} 659}
837 660
838/* 661/*