aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches/0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches/0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch')
-rwxr-xr-xtarget/linux/s3c24xx/patches/0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch61
1 files changed, 61 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches/0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch b/target/linux/s3c24xx/patches/0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch
new file mode 100755
index 0000000000..2ed8283e8c
--- /dev/null
+++ b/target/linux/s3c24xx/patches/0022-s3c2410_udc-2440_dual_packet-workaround.patch.patch
@@ -0,0 +1,61 @@
+From 5207363cc9d50f99a2ad490eff5efa913b1c10ba Mon Sep 17 00:00:00 2001
+From: mokopatches <mokopatches@openmoko.org>
+Date: Wed, 16 Jul 2008 14:44:50 +0100
+Subject: [PATCH] s3c2410_udc-2440_dual_packet-workaround.patch
+ This is a patch that seems to make the USB hangs on the S3C2440 go away. At
+ least a good amount of ping torture didn't make them come back so far.
+
+The issue is that, if there are several back-to-back packets,
+sometimes no interrupt is generated for one of them. This
+seems to be caused by the mysterious dual packet mode, which
+the USB hardware enters automatically if the endpoint size is
+half that of the FIFO. (On the 2440, this is the normal
+situation for bulk data endpoints.)
+
+There is also a timing factor in this. I think what happens is
+that the USB hardware automatically sends an acknowledgement
+if there is only one packet in the FIFO (the FIFO has space
+for two). If another packet arrives before the host has
+retrieved and acknowledged the previous one, no interrupt is
+generated for that second one.
+
+However, there may be an indication. There is one undocumented
+bit (none of the 244x manuals document it), OUT_CRS1_REG[1],
+that seems to be set suspiciously often when this condition
+occurs. There is also CLR_DATA_TOGGLE, OUT_CRS1_REG[7], which
+may have a function related to this. (The Samsung manual is
+rather terse on that, as usual.)
+
+This needs to be examined further. For now, the patch seems to do the
+trick.
+
+Note that this is not a clean solution by any means, because we
+might potentially get stuck in that interrupt for quite a while.
+---
+ drivers/usb/gadget/s3c2410_udc.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
+index 6b1ef48..c1a4379 100644
+--- a/drivers/usb/gadget/s3c2410_udc.c
++++ b/drivers/usb/gadget/s3c2410_udc.c
+@@ -845,6 +845,7 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
+ u32 ep_csr1;
+ u32 idx;
+
++handle_ep_again:
+ if (likely (!list_empty(&ep->queue)))
+ req = list_entry(ep->queue.next,
+ struct s3c2410_request, queue);
+@@ -884,6 +885,8 @@ static void s3c2410_udc_handle_ep(struct s3c2410_ep *ep)
+
+ if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && req) {
+ s3c2410_udc_read_fifo(ep,req);
++ if (s3c2410_udc_fifo_count_out())
++ goto handle_ep_again;
+ }
+ }
+ }
+--
+1.5.6.3
+