diff options
| author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-06-06 14:18:44 +0900 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-06-07 09:10:09 -0700 | 
| commit | d3af90a5e4e8fb7a93d408799682e566c9270808 (patch) | |
| tree | 9eb60a7464d0f1eb380d65ff89239b0a5a044f77 | |
| parent | 97664a207bc2601a03a300f00e6922038cd5b99c (diff) | |
| download | olio-linux-3.10-d3af90a5e4e8fb7a93d408799682e566c9270808.tar.xz olio-linux-3.10-d3af90a5e4e8fb7a93d408799682e566c9270808.zip  | |
usb: renesas_usbhs: add usbhsf_fifo
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>
| -rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 9 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/common.h | 5 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 75 | ||||
| -rw-r--r-- | drivers/usb/renesas_usbhs/fifo.h | 12 | 
4 files changed, 77 insertions, 24 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index f3664d6af66..e510b29216b 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -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); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 7bf675c23a5..06d7239a044 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -194,6 +194,11 @@ struct usbhs_priv {  	 * pipe control  	 */  	struct usbhs_pipe_info pipe_info; + +	/* +	 * fifo control +	 */ +	struct usbhs_fifo_info fifo_info;  };  /* diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 3cda71e5a35..53e2b35dd32 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -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) +{ +} diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index fcb1ecef57d..04d000ae7bd 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h @@ -19,6 +19,16 @@  #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);  |