summaryrefslogtreecommitdiff
path: root/drivers/usb/renesas_usbhs/fifo.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 14:18:07 +0900
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 09:10:07 -0700
commit4bd0481152d0d5e8326d7e24329b0069713ed718 (patch)
treeeee0db4a089f8a853305293a72bc10b3d8b8177c /drivers/usb/renesas_usbhs/fifo.c
parente8d548d549688d335236f7f6f8bcee141a207ff8 (diff)
usb: renesas_usbhs: divide data transfer functions
DMAEngine will be supported to this driver in the future. Then, both PIO and DMA data transfer method should be supported. But, the transfer function can returns the result immediately in PIO version, but it can't in DMA version. This patch divides data transfer functions into top/bottom half in preparation for DMAEngine support. 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/fifo.c')
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 3fd3adf90541..098388489813 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -20,6 +20,20 @@
#include "./pipe.h"
/*
+ * packet info function
+ */
+void usbhs_pkt_update(struct usbhs_pkt *pkt,
+ struct usbhs_pipe *pipe,
+ void *buf, int len)
+{
+ pkt->pipe = pipe;
+ pkt->buf = buf;
+ pkt->length = len;
+ pkt->actual = 0;
+ pkt->maxp = 0;
+}
+
+/*
* FIFO ctrl
*/
static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
@@ -93,13 +107,16 @@ int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
return usbhsf_fifo_select(pipe, 1);
}
-int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
+int usbhs_fifo_write(struct usbhs_pkt *pkt)
{
+ struct usbhs_pipe *pipe = pkt->pipe;
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
void __iomem *addr = priv->base + CFIFO;
int maxp = usbhs_pipe_get_maxpacket(pipe);
int total_len;
- int i, ret;
+ u8 *buf = pkt->buf;
+ int i, ret, len;
ret = usbhs_pipe_is_accessible(pipe);
if (ret < 0)
@@ -113,7 +130,7 @@ int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
if (ret < 0)
return ret;
- len = min(len, maxp);
+ len = min(pkt->length, maxp);
total_len = len;
/*
@@ -135,7 +152,16 @@ int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
if (total_len < maxp)
usbhsf_send_terminator(pipe);
- return total_len;
+ usbhs_pipe_enable(pipe);
+
+ /* update pkt */
+ if (info->tx_done) {
+ pkt->actual = total_len;
+ pkt->maxp = maxp;
+ info->tx_done(pkt);
+ }
+
+ return 0;
}
int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
@@ -154,13 +180,16 @@ int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
return ret;
}
-int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
+int usbhs_fifo_read(struct usbhs_pkt *pkt)
{
+ struct usbhs_pipe *pipe = pkt->pipe;
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
void __iomem *addr = priv->base + CFIFO;
- int rcv_len;
+ u8 *buf = pkt->buf;
+ int rcv_len, len;
int i, ret;
- int total_len;
+ int total_len = 0;
u32 data = 0;
ret = usbhsf_fifo_select(pipe, 0);
@@ -181,10 +210,10 @@ int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
*/
if (0 == rcv_len) {
usbhsf_fifo_clear(pipe);
- return 0;
+ goto usbhs_fifo_read_end;
}
- len = min(rcv_len, len);
+ len = min(rcv_len, pkt->length);
total_len = len;
/*
@@ -207,5 +236,13 @@ int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
}
- return total_len;
+usbhs_fifo_read_end:
+ if (info->rx_done) {
+ /* update pkt */
+ pkt->actual = total_len;
+ pkt->maxp = usbhs_pipe_get_maxpacket(pipe);
+ info->rx_done(pkt);
+ }
+
+ return 0;
}