usb: renesas_usbhs: add usbhsf_fifo
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Mon, 6 Jun 2011 05:18:44 +0000 (14:18 +0900)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 7 Jun 2011 16:10:09 +0000 (09:10 -0700)
renesas_usbhs has CFIFO/D0FIFO/D1FIFO.
But current renesas_usbhs is using CFIFO (for PIO) only for now.
The fifo selection method is needed for DMAEngine support.
This is a preparation for DMAEngine support

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/renesas_usbhs/common.c
drivers/usb/renesas_usbhs/common.h
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/renesas_usbhs/fifo.h

index f3664d6..e510b29 100644 (file)
@@ -323,10 +323,14 @@ static int __devinit usbhs_probe(struct platform_device *pdev)
        if (ret < 0)
                goto probe_end_iounmap;
 
-       ret = usbhs_mod_probe(priv);
+       ret = usbhs_fifo_probe(priv);
        if (ret < 0)
                goto probe_end_pipe_exit;
 
+       ret = usbhs_mod_probe(priv);
+       if (ret < 0)
+               goto probe_end_fifo_exit;
+
        /* dev_set_drvdata should be called after usbhs_mod_init */
        dev_set_drvdata(&pdev->dev, priv);
 
@@ -374,6 +378,8 @@ probe_end_call_remove:
        usbhs_platform_call(priv, hardware_exit, pdev);
 probe_end_mod_exit:
        usbhs_mod_remove(priv);
+probe_end_fifo_exit:
+       usbhs_fifo_remove(priv);
 probe_end_pipe_exit:
        usbhs_pipe_remove(priv);
 probe_end_iounmap:
@@ -404,6 +410,7 @@ static int __devexit usbhs_remove(struct platform_device *pdev)
 
        usbhs_platform_call(priv, hardware_exit, pdev);
        usbhs_mod_remove(priv);
+       usbhs_fifo_remove(priv);
        usbhs_pipe_remove(priv);
        iounmap(priv->base);
        kfree(priv);
index 7bf675c..06d7239 100644 (file)
@@ -194,6 +194,11 @@ struct usbhs_priv {
         * pipe control
         */
        struct usbhs_pipe_info pipe_info;
+
+       /*
+        * fifo control
+        */
+       struct usbhs_fifo_info fifo_info;
 };
 
 /*
index 3cda71e..53e2b35 100644 (file)
@@ -19,6 +19,8 @@
 #include "./common.h"
 #include "./pipe.h"
 
+#define usbhsf_get_cfifo(p)    (&((p)->fifo_info.cfifo))
+
 /*
  *             packet info function
  */
@@ -194,20 +196,22 @@ static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
 /*
  *             FIFO ctrl
  */
-static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
+static void usbhsf_send_terminator(struct usbhs_pipe *pipe,
+                                  struct usbhs_fifo *fifo)
 {
        struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
 
-       usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
+       usbhs_bset(priv, fifo->ctr, BVAL, BVAL);
 }
 
-static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
+static int usbhsf_fifo_barrier(struct usbhs_priv *priv,
+                              struct usbhs_fifo *fifo)
 {
        int timeout = 1024;
 
        do {
                /* The FIFO port is accessible */
-               if (usbhs_read(priv, CFIFOCTR) & FRDY)
+               if (usbhs_read(priv, fifo->ctr) & FRDY)
                        return 0;
 
                udelay(10);
@@ -216,22 +220,26 @@ static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
        return -EBUSY;
 }
 
-static void usbhsf_fifo_clear(struct usbhs_pipe *pipe)
+static void usbhsf_fifo_clear(struct usbhs_pipe *pipe,
+                             struct usbhs_fifo *fifo)
 {
        struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
 
        if (!usbhs_pipe_is_dcp(pipe))
-               usbhsf_fifo_barrier(priv);
+               usbhsf_fifo_barrier(priv, fifo);
 
-       usbhs_write(priv, CFIFOCTR, BCLR);
+       usbhs_write(priv, fifo->ctr, BCLR);
 }
 
-static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv)
+static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv,
+                              struct usbhs_fifo *fifo)
 {
-       return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
+       return usbhs_read(priv, fifo->ctr) & DTLN_MASK;
 }
 
-static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
+static int usbhsf_fifo_select(struct usbhs_pipe *pipe,
+                             struct usbhs_fifo *fifo,
+                             int write)
 {
        struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
        struct device *dev = usbhs_priv_to_dev(priv);
@@ -243,11 +251,11 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
                base |= (1 == write) << 5;      /* ISEL */
 
        /* "base" will be used below  */
-       usbhs_write(priv, CFIFOSEL, base | MBW_32);
+       usbhs_write(priv, fifo->sel, base | MBW_32);
 
        /* check ISEL and CURPIPE value */
        while (timeout--) {
-               if (base == (mask & usbhs_read(priv, CFIFOSEL)))
+               if (base == (mask & usbhs_read(priv, fifo->sel)))
                        return 0;
                udelay(10);
        }
@@ -265,14 +273,15 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done)
        struct usbhs_pipe *pipe = pkt->pipe;
        struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
        struct device *dev = usbhs_priv_to_dev(priv);
-       void __iomem *addr = priv->base + CFIFO;
+       struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */
+       void __iomem *addr = priv->base + fifo->port;
        u8 *buf;
        int maxp = usbhs_pipe_get_maxpacket(pipe);
        int total_len;
        int i, ret, len;
        int is_short;
 
-       ret = usbhsf_fifo_select(pipe, 1);
+       ret = usbhsf_fifo_select(pipe, fifo, 1);
        if (ret < 0)
                goto usbhs_fifo_write_busy;
 
@@ -280,7 +289,7 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done)
        if (ret < 0)
                goto usbhs_fifo_write_busy;
 
-       ret = usbhsf_fifo_barrier(priv);
+       ret = usbhsf_fifo_barrier(priv, fifo);
        if (ret < 0)
                goto usbhs_fifo_write_busy;
 
@@ -321,7 +330,7 @@ static int usbhsf_try_push(struct usbhs_pkt *pkt, int *is_done)
         * pipe/irq handling
         */
        if (is_short)
-               usbhsf_send_terminator(pipe);
+               usbhsf_send_terminator(pipe, fifo);
 
        usbhsf_tx_irq_ctrl(pipe, !*is_done);
        usbhs_pipe_enable(pipe);
@@ -358,19 +367,21 @@ struct usbhs_pkt_handle usbhs_fifo_push_handler = {
 static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
 {
        struct usbhs_pipe *pipe = pkt->pipe;
+       struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+       struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */
        int ret;
 
        /*
         * select pipe and enable it to prepare packet receive
         */
-       ret = usbhsf_fifo_select(pipe, 0);
+       ret = usbhsf_fifo_select(pipe, fifo, 0);
        if (ret < 0)
                return ret;
 
        usbhs_pipe_enable(pipe);
        usbhsf_rx_irq_ctrl(pipe, 1);
 
-       return ret;
+       return 0;
 }
 
 static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done)
@@ -378,7 +389,8 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done)
        struct usbhs_pipe *pipe = pkt->pipe;
        struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
        struct device *dev = usbhs_priv_to_dev(priv);
-       void __iomem *addr = priv->base + CFIFO;
+       struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */
+       void __iomem *addr = priv->base + fifo->port;
        u8 *buf;
        u32 data = 0;
        int maxp = usbhs_pipe_get_maxpacket(pipe);
@@ -386,15 +398,15 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done)
        int i, ret;
        int total_len = 0;
 
-       ret = usbhsf_fifo_select(pipe, 0);
+       ret = usbhsf_fifo_select(pipe, fifo, 0);
        if (ret < 0)
                return ret;
 
-       ret = usbhsf_fifo_barrier(priv);
+       ret = usbhsf_fifo_barrier(priv, fifo);
        if (ret < 0)
                return ret;
 
-       rcv_len = usbhsf_fifo_rcv_len(priv);
+       rcv_len = usbhsf_fifo_rcv_len(priv, fifo);
 
        buf             = pkt->buf    + pkt->actual;
        len             = pkt->length - pkt->actual;
@@ -408,7 +420,7 @@ static int usbhsf_try_pop(struct usbhs_pkt *pkt, int *is_done)
         * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
         */
        if (0 == rcv_len) {
-               usbhsf_fifo_clear(pipe);
+               usbhsf_fifo_clear(pipe, fifo);
                goto usbhs_fifo_read_end;
        }
 
@@ -555,3 +567,20 @@ void usbhs_fifo_quit(struct usbhs_priv *priv)
        mod->irq_bempsts        = 0;
        mod->irq_brdysts        = 0;
 }
+
+int usbhs_fifo_probe(struct usbhs_priv *priv)
+{
+       struct usbhs_fifo *fifo;
+
+       /* CFIFO */
+       fifo = usbhsf_get_cfifo(priv);
+       fifo->port      = CFIFO;
+       fifo->sel       = CFIFOSEL;
+       fifo->ctr       = CFIFOCTR;
+
+       return 0;
+}
+
+void usbhs_fifo_remove(struct usbhs_priv *priv)
+{
+}
index fcb1ece..04d000a 100644 (file)
 
 #include "pipe.h"
 
+struct usbhs_fifo {
+       u32 port;       /* xFIFO */
+       u32 sel;        /* xFIFOSEL */
+       u32 ctr;        /* xFIFOCTR */
+};
+
+struct usbhs_fifo_info {
+       struct usbhs_fifo cfifo;
+};
+
 struct usbhs_pkt_handle;
 struct usbhs_pkt {
        struct list_head node;
@@ -38,6 +48,8 @@ struct usbhs_pkt_handle {
 /*
  * fifo
  */
+int usbhs_fifo_probe(struct usbhs_priv *priv);
+void usbhs_fifo_remove(struct usbhs_priv *priv);
 void usbhs_fifo_init(struct usbhs_priv *priv);
 void usbhs_fifo_quit(struct usbhs_priv *priv);