aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/mod_gadget.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:28 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:08 -0400
commitdad67397f2090b29cd1f169e6a4ac6f3532c6858 (patch)
tree02f3fe42ef7307b5c70a901b59598478897baa1b /drivers/usb/renesas_usbhs/mod_gadget.c
parent659d495404d20ff8f96644fca82c772455f1226c (diff)
usb: renesas_usbhs: modify data transfer interrupt
On current driver, overall data transfer method was implemented in fifo.c, but its interrupt which is member of packet queue control was still in mod_gadget.c. This patch move it into fifo.c. By this patch, the packet/fifo control is independent from mod_gadget. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_gadget.c')
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c291
1 files changed, 23 insertions, 268 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index 298984f533dd..50c7566369eb 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -31,7 +31,6 @@ struct usbhsg_request {
31 31
32#define EP_NAME_SIZE 8 32#define EP_NAME_SIZE 8
33struct usbhsg_gpriv; 33struct usbhsg_gpriv;
34struct usbhsg_pipe_handle;
35struct usbhsg_uep { 34struct usbhsg_uep {
36 struct usb_ep ep; 35 struct usb_ep ep;
37 struct usbhs_pipe *pipe; 36 struct usbhs_pipe *pipe;
@@ -39,7 +38,7 @@ struct usbhsg_uep {
39 char ep_name[EP_NAME_SIZE]; 38 char ep_name[EP_NAME_SIZE];
40 39
41 struct usbhsg_gpriv *gpriv; 40 struct usbhsg_gpriv *gpriv;
42 struct usbhsg_pipe_handle *handler; 41 struct usbhs_pkt_handle *handler;
43}; 42};
44 43
45struct usbhsg_gpriv { 44struct usbhsg_gpriv {
@@ -57,11 +56,6 @@ struct usbhsg_gpriv {
57#define USBHSG_STATUS_WEDGE (1 << 2) 56#define USBHSG_STATUS_WEDGE (1 << 2)
58}; 57};
59 58
60struct usbhsg_pipe_handle {
61 int (*prepare)(struct usbhsg_uep *uep, struct usbhsg_request *ureq);
62 int (*try_run)(struct usbhsg_uep *uep, struct usbhsg_request *ureq);
63};
64
65struct usbhsg_recip_handle { 59struct usbhsg_recip_handle {
66 char *name; 60 char *name;
67 int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, 61 int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep,
@@ -164,7 +158,8 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep,
164 /* 158 /*
165 ********* assume under spin lock ********* 159 ********* assume under spin lock *********
166 */ 160 */
167 usbhs_pkt_push(pipe, pkt, req->buf, req->length, req->zero); 161 usbhs_pkt_push(pipe, pkt, uep->handler,
162 req->buf, req->length, req->zero);
168 req->actual = 0; 163 req->actual = 0;
169 req->status = -EINPROGRESS; 164 req->status = -EINPROGRESS;
170 165
@@ -187,22 +182,15 @@ static struct usbhsg_request *usbhsg_queue_get(struct usbhsg_uep *uep)
187 return usbhsg_pkt_to_ureq(pkt); 182 return usbhsg_pkt_to_ureq(pkt);
188} 183}
189 184
190#define usbhsg_queue_prepare(uep) __usbhsg_queue_handler(uep, 1); 185static int usbhsg_queue_start(struct usbhsg_uep *uep)
191#define usbhsg_queue_handle(uep) __usbhsg_queue_handler(uep, 0);
192static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare)
193{ 186{
194 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); 187 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep);
195 struct device *dev = usbhsg_gpriv_to_dev(gpriv); 188 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
196 struct usbhsg_request *ureq; 189 struct usbhs_pkt *pkt;
197 spinlock_t *lock; 190 spinlock_t *lock;
198 unsigned long flags; 191 unsigned long flags;
199 int ret = 0; 192 int ret = 0;
200 193
201 if (!uep->handler) {
202 dev_err(dev, "no handler function\n");
203 return -EIO;
204 }
205
206 /* 194 /*
207 * CAUTION [*queue handler*] 195 * CAUTION [*queue handler*]
208 * 196 *
@@ -224,13 +212,10 @@ static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare)
224 /****************** spin try lock *******************/ 212 /****************** spin try lock *******************/
225 lock = usbhsg_trylock(gpriv, &flags); 213 lock = usbhsg_trylock(gpriv, &flags);
226 214
227 ureq = usbhsg_queue_get(uep); 215 pkt = usbhs_pkt_get(pipe);
228 if (ureq) { 216 if (pkt)
229 if (prepare) 217 ret = usbhs_pkt_start(pkt);
230 ret = uep->handler->prepare(uep, ureq); 218
231 else
232 ret = uep->handler->try_run(uep, ureq);
233 }
234 usbhsg_unlock(lock, &flags); 219 usbhsg_unlock(lock, &flags);
235 /******************** spin unlock ******************/ 220 /******************** spin unlock ******************/
236 221
@@ -277,59 +262,10 @@ static void usbhsg_queue_pop(struct usbhsg_uep *uep,
277 262
278 /* more request ? */ 263 /* more request ? */
279 if (0 == status) 264 if (0 == status)
280 usbhsg_queue_prepare(uep); 265 usbhsg_queue_start(uep);
281} 266}
282 267
283/* 268static void usbhsg_queue_done(struct usbhs_pkt *pkt)
284 * irq enable/disable function
285 */
286#define usbhsg_irq_callback_ctrl(uep, status, enable) \
287 ({ \
288 struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); \
289 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); \
290 struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); \
291 struct usbhs_mod *mod = usbhs_mod_get_current(priv); \
292 if (!mod) \
293 return; \
294 if (enable) \
295 mod->irq_##status |= (1 << usbhs_pipe_number(pipe)); \
296 else \
297 mod->irq_##status &= ~(1 << usbhs_pipe_number(pipe)); \
298 usbhs_irq_callback_update(priv, mod); \
299 })
300
301static void usbhsg_irq_empty_ctrl(struct usbhsg_uep *uep, int enable)
302{
303 usbhsg_irq_callback_ctrl(uep, bempsts, enable);
304}
305
306static void usbhsg_irq_ready_ctrl(struct usbhsg_uep *uep, int enable)
307{
308 usbhsg_irq_callback_ctrl(uep, brdysts, enable);
309}
310
311/*
312 * handler function
313 */
314static int usbhsg_try_run_ctrl_stage_end(struct usbhsg_uep *uep,
315 struct usbhsg_request *ureq)
316{
317 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
318
319 /*
320 ********* assume under spin lock *********
321 */
322
323 usbhs_dcp_control_transfer_done(pipe);
324 usbhsg_queue_pop(uep, ureq, 0);
325
326 return 0;
327}
328
329/*
330 * packet send hander
331 */
332static void usbhsg_send_packet_done(struct usbhs_pkt *pkt)
333{ 269{
334 struct usbhs_pipe *pipe = pkt->pipe; 270 struct usbhs_pipe *pipe = pkt->pipe;
335 struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); 271 struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
@@ -340,108 +276,6 @@ static void usbhsg_send_packet_done(struct usbhs_pkt *pkt)
340 usbhsg_queue_pop(uep, ureq, 0); 276 usbhsg_queue_pop(uep, ureq, 0);
341} 277}
342 278
343static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep,
344 struct usbhsg_request *ureq)
345{
346 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
347
348 /*
349 ********* assume under spin lock *********
350 */
351
352 usbhs_fifo_write(pkt);
353
354 return 0;
355}
356
357static int usbhsg_prepare_send_packet(struct usbhsg_uep *uep,
358 struct usbhsg_request *ureq)
359{
360 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
361
362 /*
363 ********* assume under spin lock *********
364 */
365
366 usbhs_fifo_prepare_write(pipe);
367 usbhsg_try_run_send_packet(uep, ureq);
368
369 return 0;
370}
371
372/*
373 * packet recv hander
374 */
375static void usbhsg_receive_packet_done(struct usbhs_pkt *pkt)
376{
377 struct usbhs_pipe *pipe = pkt->pipe;
378 struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
379 struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
380
381 ureq->req.actual = pkt->actual;
382
383 usbhsg_queue_pop(uep, ureq, 0);
384}
385
386static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep,
387 struct usbhsg_request *ureq)
388{
389 struct usbhs_pkt *pkt = usbhsg_ureq_to_pkt(ureq);
390
391 /*
392 ********* assume under spin lock *********
393 */
394
395 return usbhs_fifo_read(pkt);
396}
397
398static int usbhsg_prepare_receive_packet(struct usbhsg_uep *uep,
399 struct usbhsg_request *ureq)
400{
401 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
402
403 /*
404 ********* assume under spin lock *********
405 */
406
407 return usbhs_fifo_prepare_read(pipe);
408}
409
410static struct usbhsg_pipe_handle usbhsg_handler_send_by_empty = {
411 .prepare = usbhsg_prepare_send_packet,
412 .try_run = usbhsg_try_run_send_packet,
413};
414
415static struct usbhsg_pipe_handle usbhsg_handler_send_by_ready = {
416 .prepare = usbhsg_prepare_send_packet,
417 .try_run = usbhsg_try_run_send_packet,
418};
419
420static struct usbhsg_pipe_handle usbhsg_handler_recv_by_ready = {
421 .prepare = usbhsg_prepare_receive_packet,
422 .try_run = usbhsg_try_run_receive_packet,
423};
424
425static struct usbhsg_pipe_handle usbhsg_handler_ctrl_stage_end = {
426 .prepare = usbhsg_try_run_ctrl_stage_end,
427 .try_run = usbhsg_try_run_ctrl_stage_end,
428};
429
430/*
431 * DCP pipe can NOT use "ready interrupt" for "send"
432 * it should use "empty" interrupt.
433 * see
434 * "Operation" - "Interrupt Function" - "BRDY Interrupt"
435 *
436 * on the other hand, normal pipe can use "ready interrupt" for "send"
437 * even though it is single/double buffer
438 */
439#define usbhsg_handler_send_ctrl usbhsg_handler_send_by_empty
440#define usbhsg_handler_recv_ctrl usbhsg_handler_recv_by_ready
441
442#define usbhsg_handler_send_packet usbhsg_handler_send_by_ready
443#define usbhsg_handler_recv_packet usbhsg_handler_recv_by_ready
444
445/* 279/*
446 * USB_TYPE_STANDARD / clear feature functions 280 * USB_TYPE_STANDARD / clear feature functions
447 */ 281 */
@@ -473,7 +307,7 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv,
473 307
474 usbhsg_recip_handler_std_control_done(priv, uep, ctrl); 308 usbhsg_recip_handler_std_control_done(priv, uep, ctrl);
475 309
476 usbhsg_queue_prepare(uep); 310 usbhsg_queue_start(uep);
477 311
478 return 0; 312 return 0;
479} 313}
@@ -580,13 +414,13 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
580 414
581 switch (stage) { 415 switch (stage) {
582 case READ_DATA_STAGE: 416 case READ_DATA_STAGE:
583 dcp->handler = &usbhsg_handler_send_ctrl; 417 dcp->handler = &usbhs_fifo_push_handler;
584 break; 418 break;
585 case WRITE_DATA_STAGE: 419 case WRITE_DATA_STAGE:
586 dcp->handler = &usbhsg_handler_recv_ctrl; 420 dcp->handler = &usbhs_fifo_pop_handler;
587 break; 421 break;
588 case NODATA_STATUS_STAGE: 422 case NODATA_STATUS_STAGE:
589 dcp->handler = &usbhsg_handler_ctrl_stage_end; 423 dcp->handler = &usbhs_ctrl_stage_end_handler;
590 break; 424 break;
591 default: 425 default:
592 return ret; 426 return ret;
@@ -620,72 +454,6 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
620 return ret; 454 return ret;
621} 455}
622 456
623static int usbhsg_irq_empty(struct usbhs_priv *priv,
624 struct usbhs_irq_state *irq_state)
625{
626 struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
627 struct usbhsg_uep *uep;
628 struct usbhs_pipe *pipe;
629 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
630 int i, ret;
631
632 if (!irq_state->bempsts) {
633 dev_err(dev, "debug %s !!\n", __func__);
634 return -EIO;
635 }
636
637 dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts);
638
639 /*
640 * search interrupted "pipe"
641 * not "uep".
642 */
643 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
644 if (!(irq_state->bempsts & (1 << i)))
645 continue;
646
647 uep = usbhsg_pipe_to_uep(pipe);
648 ret = usbhsg_queue_handle(uep);
649 if (ret < 0)
650 dev_err(dev, "send error %d : %d\n", i, ret);
651 }
652
653 return 0;
654}
655
656static int usbhsg_irq_ready(struct usbhs_priv *priv,
657 struct usbhs_irq_state *irq_state)
658{
659 struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
660 struct usbhsg_uep *uep;
661 struct usbhs_pipe *pipe;
662 struct device *dev = usbhsg_gpriv_to_dev(gpriv);
663 int i, ret;
664
665 if (!irq_state->brdysts) {
666 dev_err(dev, "debug %s !!\n", __func__);
667 return -EIO;
668 }
669
670 dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts);
671
672 /*
673 * search interrupted "pipe"
674 * not "uep".
675 */
676 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
677 if (!(irq_state->brdysts & (1 << i)))
678 continue;
679
680 uep = usbhsg_pipe_to_uep(pipe);
681 ret = usbhsg_queue_handle(uep);
682 if (ret < 0)
683 dev_err(dev, "receive error %d : %d\n", i, ret);
684 }
685
686 return 0;
687}
688
689/* 457/*
690 * 458 *
691 * usb_dcp_ops 459 * usb_dcp_ops
@@ -716,7 +484,6 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep)
716{ 484{
717 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); 485 struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
718 struct usbhsg_request *ureq; 486 struct usbhsg_request *ureq;
719 int disable = 0;
720 487
721 /* 488 /*
722 ********* assume under spin lock ********* 489 ********* assume under spin lock *********
@@ -724,12 +491,6 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep)
724 491
725 usbhs_pipe_disable(pipe); 492 usbhs_pipe_disable(pipe);
726 493
727 /*
728 * disable pipe irq
729 */
730 usbhsg_irq_empty_ctrl(uep, disable);
731 usbhsg_irq_ready_ctrl(uep, disable);
732
733 while (1) { 494 while (1) {
734 ureq = usbhsg_queue_get(uep); 495 ureq = usbhsg_queue_get(uep);
735 if (!ureq) 496 if (!ureq)
@@ -782,9 +543,9 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
782 pipe->mod_private = uep; 543 pipe->mod_private = uep;
783 544
784 if (usb_endpoint_dir_in(desc)) 545 if (usb_endpoint_dir_in(desc))
785 uep->handler = &usbhsg_handler_send_packet; 546 uep->handler = &usbhs_fifo_push_handler;
786 else 547 else
787 uep->handler = &usbhsg_handler_recv_packet; 548 uep->handler = &usbhs_fifo_pop_handler;
788 549
789 ret = 0; 550 ret = 0;
790 } 551 }
@@ -879,7 +640,7 @@ static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req,
879 usbhsg_unlock(lock, &flags); 640 usbhsg_unlock(lock, &flags);
880 /******************** spin unlock ******************/ 641 /******************** spin unlock ******************/
881 642
882 usbhsg_queue_prepare(uep); 643 usbhsg_queue_start(uep);
883 644
884 return ret; 645 return ret;
885} 646}
@@ -1006,8 +767,8 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
1006 * pipe initialize and enable DCP 767 * pipe initialize and enable DCP
1007 */ 768 */
1008 usbhs_pipe_init(priv, 769 usbhs_pipe_init(priv,
1009 usbhsg_send_packet_done, 770 usbhsg_queue_done);
1010 usbhsg_receive_packet_done); 771 usbhs_fifo_init(priv);
1011 usbhsg_uep_init(gpriv); 772 usbhsg_uep_init(gpriv);
1012 usbhsg_dcp_enable(dcp); 773 usbhsg_dcp_enable(dcp);
1013 774
@@ -1026,10 +787,6 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
1026 */ 787 */
1027 mod->irq_dev_state = usbhsg_irq_dev_state; 788 mod->irq_dev_state = usbhsg_irq_dev_state;
1028 mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; 789 mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage;
1029 mod->irq_empty = usbhsg_irq_empty;
1030 mod->irq_ready = usbhsg_irq_ready;
1031 mod->irq_bempsts = 0;
1032 mod->irq_brdysts = 0;
1033 usbhs_irq_callback_update(priv, mod); 790 usbhs_irq_callback_update(priv, mod);
1034 791
1035usbhsg_try_start_unlock: 792usbhsg_try_start_unlock:
@@ -1059,13 +816,11 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status)
1059 !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) 816 !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))
1060 goto usbhsg_try_stop_unlock; 817 goto usbhsg_try_stop_unlock;
1061 818
819 usbhs_fifo_quit(priv);
820
1062 /* disable all irq */ 821 /* disable all irq */
1063 mod->irq_dev_state = NULL; 822 mod->irq_dev_state = NULL;
1064 mod->irq_ctrl_stage = NULL; 823 mod->irq_ctrl_stage = NULL;
1065 mod->irq_empty = NULL;
1066 mod->irq_ready = NULL;
1067 mod->irq_bempsts = 0;
1068 mod->irq_brdysts = 0;
1069 usbhs_irq_callback_update(priv, mod); 824 usbhs_irq_callback_update(priv, mod);
1070 825
1071 usbhsg_dcp_disable(dcp); 826 usbhsg_dcp_disable(dcp);