linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] spi: sirf: fix the issue while transferring more than 256 words
@ 2013-03-18  7:47 Barry Song
       [not found] ` <1363592828-6347-1-git-send-email-Barry.Song-kQvG35nSl+M@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Barry Song @ 2013-03-18  7:47 UTC (permalink / raw)
  To: grant.likely
  Cc: Qipan Li, workgroup.linux, Zhiwu Song, Barry Song,
	spi-devel-general, linux-arm-kernel

From: Qipan Li <Qipan.Li@csr.com>

currently, spi irq handler only does rx processing and  fetching data from rx
fifo when "FRM_END" irq happens. FRM_END indicates one transfer completes. if
rx size is less than 256, it works well.
but the problem is that spi rx fifo size is only 256 bytes, then if data size
of one frame is more than 256, before FRM_END comes, rx fifo will be filled with
RXFIFO_OFLOW overflow interrupt, it will make us lose some data due to fifo
overflow.
Explicitly we need do fetch work from device rx fifo in irq handler not only in
"FRM_END" irq but also in "THD_REACH" irq. THD_REACH means rx fifo has come to
its threshold and will come to overflow if we don't take data from it in time.

In this patch, we fix this issue. we take data from rx fifo when either FRM_END
or RX_THD_REACH irq comes, we put data into tx fifo when either TX_FIFO_EMPTY
or TX_THD_REACH irq comes.

Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Zhiwu Song <Zhiwu.Song@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
---
 drivers/spi/spi-sirf.c |   43 +++++++++++++------------------------------
 1 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c
index f59d417..d2bd1e5 100644
--- a/drivers/spi/spi-sirf.c
+++ b/drivers/spi/spi-sirf.c
@@ -142,9 +142,6 @@ struct sirfsoc_spi {
 	unsigned int left_tx_cnt;
 	unsigned int left_rx_cnt;
 
-	/* tasklet to push tx msg into FIFO */
-	struct tasklet_struct tasklet_tx;
-
 	int chipselect[0];
 };
 
@@ -236,17 +233,6 @@ static void spi_sirfsoc_tx_word_u32(struct sirfsoc_spi *sspi)
 	sspi->left_tx_cnt--;
 }
 
-static void spi_sirfsoc_tasklet_tx(unsigned long arg)
-{
-	struct sirfsoc_spi *sspi = (struct sirfsoc_spi *)arg;
-
-	/* Fill Tx FIFO while there are left words to be transmitted */
-	while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) &
-			SIRFSOC_SPI_FIFO_FULL)) &&
-			sspi->left_tx_cnt)
-		sspi->tx_word(sspi);
-}
-
 static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
 {
 	struct sirfsoc_spi *sspi = dev_id;
@@ -261,25 +247,25 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
 		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
 	}
 
-	if (spi_stat & SIRFSOC_SPI_FRM_END) {
+	if (spi_stat & (SIRFSOC_SPI_FRM_END
+			| SIRFSOC_SPI_RXFIFO_THD_REACH))
 		while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS)
 				& SIRFSOC_SPI_FIFO_EMPTY)) &&
 				sspi->left_rx_cnt)
 			sspi->rx_word(sspi);
 
-		/* Received all words */
-		if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) {
-			complete(&sspi->done);
-			writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
-		}
-	}
-
-	if (spi_stat & SIRFSOC_SPI_RXFIFO_THD_REACH ||
-		spi_stat & SIRFSOC_SPI_TXFIFO_THD_REACH ||
-		spi_stat & SIRFSOC_SPI_RX_FIFO_FULL ||
-		spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY)
-		tasklet_schedule(&sspi->tasklet_tx);
+	if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY
+			| SIRFSOC_SPI_TXFIFO_THD_REACH))
+		while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
+				& SIRFSOC_SPI_FIFO_FULL)) &&
+				sspi->left_tx_cnt)
+			sspi->tx_word(sspi);
 
+	/* Received all words */
+	if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) {
+		complete(&sspi->done);
+		writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
+	}
 	return IRQ_HANDLED;
 }
 
@@ -573,9 +559,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
 
 	init_completion(&sspi->done);
 
-	tasklet_init(&sspi->tasklet_tx, spi_sirfsoc_tasklet_tx,
-		     (unsigned long)sspi);
-
 	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
 	writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
 	writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
-- 
1.7.5.4



Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] spi: sirf: fix the issue while transferring more than 256 words
       [not found] ` <1363592828-6347-1-git-send-email-Barry.Song-kQvG35nSl+M@public.gmane.org>
@ 2013-05-15 12:59   ` Barry Song
  2013-05-16 17:23     ` Mark Brown
  0 siblings, 1 reply; 5+ messages in thread
From: Barry Song @ 2013-05-15 12:59 UTC (permalink / raw)
  To: grant.likely-s3s/WqlpOiPyB63q8FvJNQ, broonie-DgEjT+Ai2ygdnm+yROfE0A
  Cc: Qipan Li, workgroup.linux-kQvG35nSl+M, Zhiwu Song, Barry Song,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

ping Mark, Ping Grant.

2013/3/18 Barry Song <Barry.Song-kQvG35nSl+M@public.gmane.org>:
> From: Qipan Li <Qipan.Li-kQvG35nSl+M@public.gmane.org>
>
> currently, spi irq handler only does rx processing and  fetching data from rx
> fifo when "FRM_END" irq happens. FRM_END indicates one transfer completes. if
> rx size is less than 256, it works well.
> but the problem is that spi rx fifo size is only 256 bytes, then if data size
> of one frame is more than 256, before FRM_END comes, rx fifo will be filled with
> RXFIFO_OFLOW overflow interrupt, it will make us lose some data due to fifo
> overflow.
> Explicitly we need do fetch work from device rx fifo in irq handler not only in
> "FRM_END" irq but also in "THD_REACH" irq. THD_REACH means rx fifo has come to
> its threshold and will come to overflow if we don't take data from it in time.
>
> In this patch, we fix this issue. we take data from rx fifo when either FRM_END
> or RX_THD_REACH irq comes, we put data into tx fifo when either TX_FIFO_EMPTY
> or TX_THD_REACH irq comes.
>
> Signed-off-by: Qipan Li <Qipan.Li-kQvG35nSl+M@public.gmane.org>
> Signed-off-by: Zhiwu Song <Zhiwu.Song-kQvG35nSl+M@public.gmane.org>
> Signed-off-by: Barry Song <Baohua.Song-kQvG35nSl+M@public.gmane.org>
> ---
>  drivers/spi/spi-sirf.c |   43 +++++++++++++------------------------------
>  1 files changed, 13 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c
> index f59d417..d2bd1e5 100644
> --- a/drivers/spi/spi-sirf.c
> +++ b/drivers/spi/spi-sirf.c
> @@ -142,9 +142,6 @@ struct sirfsoc_spi {
>         unsigned int left_tx_cnt;
>         unsigned int left_rx_cnt;
>
> -       /* tasklet to push tx msg into FIFO */
> -       struct tasklet_struct tasklet_tx;
> -
>         int chipselect[0];
>  };
>
> @@ -236,17 +233,6 @@ static void spi_sirfsoc_tx_word_u32(struct sirfsoc_spi *sspi)
>         sspi->left_tx_cnt--;
>  }
>
> -static void spi_sirfsoc_tasklet_tx(unsigned long arg)
> -{
> -       struct sirfsoc_spi *sspi = (struct sirfsoc_spi *)arg;
> -
> -       /* Fill Tx FIFO while there are left words to be transmitted */
> -       while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) &
> -                       SIRFSOC_SPI_FIFO_FULL)) &&
> -                       sspi->left_tx_cnt)
> -               sspi->tx_word(sspi);
> -}
> -
>  static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
>  {
>         struct sirfsoc_spi *sspi = dev_id;
> @@ -261,25 +247,25 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id)
>                 writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
>         }
>
> -       if (spi_stat & SIRFSOC_SPI_FRM_END) {
> +       if (spi_stat & (SIRFSOC_SPI_FRM_END
> +                       | SIRFSOC_SPI_RXFIFO_THD_REACH))
>                 while (!((readl(sspi->base + SIRFSOC_SPI_RXFIFO_STATUS)
>                                 & SIRFSOC_SPI_FIFO_EMPTY)) &&
>                                 sspi->left_rx_cnt)
>                         sspi->rx_word(sspi);
>
> -               /* Received all words */
> -               if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) {
> -                       complete(&sspi->done);
> -                       writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
> -               }
> -       }
> -
> -       if (spi_stat & SIRFSOC_SPI_RXFIFO_THD_REACH ||
> -               spi_stat & SIRFSOC_SPI_TXFIFO_THD_REACH ||
> -               spi_stat & SIRFSOC_SPI_RX_FIFO_FULL ||
> -               spi_stat & SIRFSOC_SPI_TXFIFO_EMPTY)
> -               tasklet_schedule(&sspi->tasklet_tx);
> +       if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY
> +                       | SIRFSOC_SPI_TXFIFO_THD_REACH))
> +               while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS)
> +                               & SIRFSOC_SPI_FIFO_FULL)) &&
> +                               sspi->left_tx_cnt)
> +                       sspi->tx_word(sspi);
>
> +       /* Received all words */
> +       if ((sspi->left_rx_cnt == 0) && (sspi->left_tx_cnt == 0)) {
> +               complete(&sspi->done);
> +               writel(0x0, sspi->base + SIRFSOC_SPI_INT_EN);
> +       }
>         return IRQ_HANDLED;
>  }
>
> @@ -573,9 +559,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
>
>         init_completion(&sspi->done);
>
> -       tasklet_init(&sspi->tasklet_tx, spi_sirfsoc_tasklet_tx,
> -                    (unsigned long)sspi);
> -
>         writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
>         writel(SIRFSOC_SPI_FIFO_RESET, sspi->base + SIRFSOC_SPI_TXFIFO_OP);
>         writel(SIRFSOC_SPI_FIFO_START, sspi->base + SIRFSOC_SPI_RXFIFO_OP);
> --
> 1.7.5.4

------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] spi: sirf: fix the issue while transferring more than 256 words
  2013-05-15 12:59   ` Barry Song
@ 2013-05-16 17:23     ` Mark Brown
       [not found]       ` <20130516172358.GA1627-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Mark Brown @ 2013-05-16 17:23 UTC (permalink / raw)
  To: Barry Song
  Cc: Qipan Li, workgroup.linux, Zhiwu Song, grant.likely, Barry Song,
	spi-devel-general, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 164 bytes --]

On Wed, May 15, 2013 at 08:59:47PM +0800, Barry Song wrote:
> ping Mark, Ping Grant.

Don't top post, don't send contentless pings.  At a guess you didn't CC
me...

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] spi: sirf: fix the issue while transferring more than 256 words
       [not found]       ` <20130516172358.GA1627-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
@ 2013-05-17  1:58         ` Barry Song
  2013-05-17 11:03           ` Mark Brown
  0 siblings, 1 reply; 5+ messages in thread
From: Barry Song @ 2013-05-17  1:58 UTC (permalink / raw)
  To: Mark Brown
  Cc: Qipan Li, workgroup.linux-kQvG35nSl+M, Zhiwu Song, Barry Song,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

2013/5/17 Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
> On Wed, May 15, 2013 at 08:59:47PM +0800, Barry Song wrote:
>> ping Mark, Ping Grant.
>
> Don't top post, don't send contentless pings.  At a guess you didn't CC
> me...

yes. i missed you in CC. sorry for that, Mark. so do you want me to resend it?

-barry

------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] spi: sirf: fix the issue while transferring more than 256 words
  2013-05-17  1:58         ` Barry Song
@ 2013-05-17 11:03           ` Mark Brown
  0 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2013-05-17 11:03 UTC (permalink / raw)
  To: Barry Song
  Cc: Qipan Li, workgroup.linux, Zhiwu Song, grant.likely, Barry Song,
	spi-devel-general, linux-arm-kernel


[-- Attachment #1.1: Type: text/plain, Size: 288 bytes --]

On Fri, May 17, 2013 at 09:58:24AM +0800, Barry Song wrote:
> 2013/5/17 Mark Brown <broonie@kernel.org>:

> > Don't top post, don't send contentless pings.  At a guess you didn't CC
> > me...

> yes. i missed you in CC. sorry for that, Mark. so do you want me to resend it?

Yes, please.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-05-17 11:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-18  7:47 [PATCH] spi: sirf: fix the issue while transferring more than 256 words Barry Song
     [not found] ` <1363592828-6347-1-git-send-email-Barry.Song-kQvG35nSl+M@public.gmane.org>
2013-05-15 12:59   ` Barry Song
2013-05-16 17:23     ` Mark Brown
     [not found]       ` <20130516172358.GA1627-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2013-05-17  1:58         ` Barry Song
2013-05-17 11:03           ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).