aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>2014-11-03 20:05:44 -0500
committerFelipe Balbi <balbi@ti.com>2014-11-05 14:22:12 -0500
commit4ef35b10bff24304a5cbbf78719ce5f24d311d1f (patch)
treeaac9aae7650622ff989fcb088cdc9d52f1a08f14
parent04a5def3df1cea758662615e075f64677690c75f (diff)
usb: renesas_usbhs: fix the timing of dcp_control_transfer_done
According to the datasheet, this driver should clear the INTSTS0.CTRT bit before this controller detects the next stage transition. Otherwise, the driver may not be able to clear the bit after the controller went to the next stage transition. After that, the driver will not be able to clear the INTSTS0.VALID, and a usb control transfer will not finish finally. If we use the testusb tool, it is easy to reproduce this issue: # testusb -a -t 10 Since the previous code handled a data stage and a status stage in the usbhsf_pio_try_push(), it may not clear the INTSTS0.CTRT at the right timing. So, this patch change the timing of usbhs_dcp_control_transfer_done() to the usbhsg_irq_ctrl_stage(). Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c16
-rw-r--r--drivers/usb/renesas_usbhs/mod_gadget.c3
2 files changed, 3 insertions, 16 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index b0c97a3f1bfe..0e079256e533 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -577,14 +577,6 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
577 usbhs_pipe_number(pipe), 577 usbhs_pipe_number(pipe),
578 pkt->length, pkt->actual, *is_done, pkt->zero); 578 pkt->length, pkt->actual, *is_done, pkt->zero);
579 579
580 /*
581 * Transmission end
582 */
583 if (*is_done) {
584 if (usbhs_pipe_is_dcp(pipe))
585 usbhs_dcp_control_transfer_done(pipe);
586 }
587
588 usbhsf_fifo_unselect(pipe, fifo); 580 usbhsf_fifo_unselect(pipe, fifo);
589 581
590 return 0; 582 return 0;
@@ -722,14 +714,6 @@ usbhs_fifo_read_end:
722 usbhs_pipe_number(pipe), 714 usbhs_pipe_number(pipe),
723 pkt->length, pkt->actual, *is_done, pkt->zero); 715 pkt->length, pkt->actual, *is_done, pkt->zero);
724 716
725 /*
726 * Transmission end
727 */
728 if (*is_done) {
729 if (usbhs_pipe_is_dcp(pipe))
730 usbhs_dcp_control_transfer_done(pipe);
731 }
732
733usbhs_fifo_read_busy: 717usbhs_fifo_read_busy:
734 usbhsf_fifo_unselect(pipe, fifo); 718 usbhsf_fifo_unselect(pipe, fifo);
735 719
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c
index cb2d529e3a33..2457306e0924 100644
--- a/drivers/usb/renesas_usbhs/mod_gadget.c
+++ b/drivers/usb/renesas_usbhs/mod_gadget.c
@@ -485,6 +485,9 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv,
485 case NODATA_STATUS_STAGE: 485 case NODATA_STATUS_STAGE:
486 pipe->handler = &usbhs_ctrl_stage_end_handler; 486 pipe->handler = &usbhs_ctrl_stage_end_handler;
487 break; 487 break;
488 case READ_STATUS_STAGE:
489 case WRITE_STATUS_STAGE:
490 usbhs_dcp_control_transfer_done(pipe);
488 default: 491 default:
489 return ret; 492 return ret;
490 } 493 }