linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] spi: spi-imx: use threaded interrupt
@ 2014-09-01 14:35 Lucas Stach
       [not found] ` <1409582106-2845-1-git-send-email-l.stach-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  0 siblings, 1 reply; 2+ messages in thread
From: Lucas Stach @ 2014-09-01 14:35 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, kernel-bIcnvbaLZ9MEGnE8C9+IrQ

From: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>

The i.MX SPI driver fills/flushes the FIFOs in interrupt context. With
longer SPI messages this introduces big latencies in the system. Using
a threaded interrupt avoids this issue.

Signed-off-by: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Signed-off-by: Lucas Stach <l.stach-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
---
 drivers/spi/spi-imx.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 5daff2054ae4..5e40801e1c52 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -672,6 +672,15 @@ static irqreturn_t spi_imx_isr(int irq, void *dev_id)
 {
 	struct spi_imx_data *spi_imx = dev_id;
 
+	spi_imx->devtype_data->intctrl(spi_imx, 0);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t spi_imx_isr_thread(int irq, void *dev_id)
+{
+	struct spi_imx_data *spi_imx = dev_id;
+
 	while (spi_imx->devtype_data->rx_available(spi_imx)) {
 		spi_imx->rx(spi_imx);
 		spi_imx->txfifo--;
@@ -679,6 +688,7 @@ static irqreturn_t spi_imx_isr(int irq, void *dev_id)
 
 	if (spi_imx->count) {
 		spi_imx_push(spi_imx);
+		spi_imx->devtype_data->intctrl(spi_imx, MXC_INT_TE);
 		return IRQ_HANDLED;
 	}
 
@@ -691,7 +701,6 @@ static irqreturn_t spi_imx_isr(int irq, void *dev_id)
 		return IRQ_HANDLED;
 	}
 
-	spi_imx->devtype_data->intctrl(spi_imx, 0);
 	complete(&spi_imx->xfer_done);
 
 	return IRQ_HANDLED;
@@ -883,8 +892,8 @@ static int spi_imx_probe(struct platform_device *pdev)
 		goto out_master_put;
 	}
 
-	ret = devm_request_irq(&pdev->dev, spi_imx->irq, spi_imx_isr, 0,
-			       dev_name(&pdev->dev), spi_imx);
+	ret = request_threaded_irq(spi_imx->irq, spi_imx_isr,
+			spi_imx_isr_thread, 0, dev_name(&pdev->dev), spi_imx);
 	if (ret) {
 		dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
 		goto out_master_put;
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH] spi: spi-imx: use threaded interrupt
       [not found] ` <1409582106-2845-1-git-send-email-l.stach-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2014-09-01 14:57   ` Mark Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2014-09-01 14:57 UTC (permalink / raw)
  To: Lucas Stach
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
	Marek Vasut

[-- Attachment #1: Type: text/plain, Size: 2209 bytes --]

On Mon, Sep 01, 2014 at 04:35:06PM +0200, Lucas Stach wrote:
> From: Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
> 
> The i.MX SPI driver fills/flushes the FIFOs in interrupt context. With
> longer SPI messages this introduces big latencies in the system. Using
> a threaded interrupt avoids this issue.

Adding Marek.  A few things here:

> diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
> index 5daff2054ae4..5e40801e1c52 100644
> --- a/drivers/spi/spi-imx.c
> +++ b/drivers/spi/spi-imx.c
> @@ -672,6 +672,15 @@ static irqreturn_t spi_imx_isr(int irq, void *dev_id)
>  {
>  	struct spi_imx_data *spi_imx = dev_id;
>  
> +	spi_imx->devtype_data->intctrl(spi_imx, 0);
> +
> +	return IRQ_WAKE_THREAD;
> +}

This means we unconditionally defer to the thread which means that we
will add latency in any case where we've not got any more data to place
in the FIFO.  That doesn't seem great.  I'd expect the driver to only
defer in cases where it was going to call one of the FIFO handling
functions (ideally it'd be possible to do some sort of copybreak based
on the amount of data to fill but I'm not sure it's worth the effort of
trying to pick numbers for that) and still complete transfers in hardirq
context in cases where that's all that needs doing.

I'm also not sure why the interrupt needs masking here - the driver
doesn't support shared interrupts so doesn't this just duplicate what
the interrupt subsystem is doing when it implements threading?  As
things stand it looks like the hard interrupt handler may as well just
be omitted.

> @@ -883,8 +892,8 @@ static int spi_imx_probe(struct platform_device *pdev)
>  		goto out_master_put;
>  	}
>  
> -	ret = devm_request_irq(&pdev->dev, spi_imx->irq, spi_imx_isr, 0,
> -			       dev_name(&pdev->dev), spi_imx);
> +	ret = request_threaded_irq(spi_imx->irq, spi_imx_isr,
> +			spi_imx_isr_thread, 0, dev_name(&pdev->dev), spi_imx);
>  	if (ret) {
>  		dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
>  		goto out_master_put;

You've removed a devm_ but not added any free_irq() calls.  There's a
devm_request_threaded_irq() so you could just use that?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

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

end of thread, other threads:[~2014-09-01 14:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-01 14:35 [PATCH] spi: spi-imx: use threaded interrupt Lucas Stach
     [not found] ` <1409582106-2845-1-git-send-email-l.stach-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2014-09-01 14:57   ` 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).