Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/khorben-n900]: src/sys/arch/arm/omap Make sure interrupts are cleared on...



details:   https://anonhg.NetBSD.org/src/rev/3f4784d4e6fe
branches:  khorben-n900
changeset: 786709:3f4784d4e6fe
user:      khorben <khorben%NetBSD.org@localhost>
date:      Wed May 15 02:44:48 2013 +0000

description:
Make sure interrupts are cleared on the current channel when initiating a
transfer. Also force the current transfer to be terminated upon end of
transmission.

diffstat:

 sys/arch/arm/omap/omap2_spi.c |  38 +++++++++++++++++++++++++++++---------
 1 files changed, 29 insertions(+), 9 deletions(-)

diffs (105 lines):

diff -r ea6543a29cd0 -r 3f4784d4e6fe sys/arch/arm/omap/omap2_spi.c
--- a/sys/arch/arm/omap/omap2_spi.c     Sun May 12 20:11:39 2013 +0000
+++ b/sys/arch/arm/omap/omap2_spi.c     Wed May 15 02:44:48 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: omap2_spi.c,v 1.1.2.3 2013/05/12 20:11:39 khorben Exp $ */
+/* $NetBSD: omap2_spi.c,v 1.1.2.4 2013/05/15 02:44:48 khorben Exp $ */
 
 /*
  * Texas Instruments OMAP2/3 Multichannel SPI driver.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: omap2_spi.c,v 1.1.2.3 2013/05/12 20:11:39 khorben Exp $");
+__KERNEL_RCSID(0, "$NetBSD: omap2_spi.c,v 1.1.2.4 2013/05/15 02:44:48 khorben Exp $");
 
 #include "opt_omap.h"
 
@@ -266,6 +266,7 @@
 {
        struct omap2_spi_channel *chan;
        struct spi_transfer *st;
+       uint32_t statusval = 0;
        uint32_t enableval = 0;
        uint32_t ctrlreg;
        uint32_t ctrlval;
@@ -287,27 +288,45 @@
 
        switch (channel) {
                case 0:
+                       statusval = OMAP2_MCSPI_IRQSTATUS_RX0_OVERFLOW
+                               | OMAP2_MCSPI_IRQSTATUS_RX0_FULL
+                               | OMAP2_MCSPI_IRQSTATUS_TX0_UNDERFLOW
+                               | OMAP2_MCSPI_IRQSTATUS_TX0_EMPTY;
                        enableval = OMAP2_MCSPI_IRQENABLE_RX0_FULL
                                | OMAP2_MCSPI_IRQENABLE_TX0_UNDERFLOW
                                | OMAP2_MCSPI_IRQENABLE_TX0_EMPTY;
                        break;
                case 1:
+                       statusval = OMAP2_MCSPI_IRQSTATUS_RX1_FULL
+                               | OMAP2_MCSPI_IRQSTATUS_TX1_UNDERFLOW
+                               | OMAP2_MCSPI_IRQSTATUS_TX1_EMPTY;
                        enableval = OMAP2_MCSPI_IRQENABLE_RX1_FULL
                                | OMAP2_MCSPI_IRQENABLE_TX1_UNDERFLOW
                                | OMAP2_MCSPI_IRQENABLE_TX1_EMPTY;
                        break;
                case 2:
+                       statusval = OMAP2_MCSPI_IRQSTATUS_RX2_FULL
+                               | OMAP2_MCSPI_IRQSTATUS_TX2_UNDERFLOW
+                               | OMAP2_MCSPI_IRQSTATUS_TX2_EMPTY;
                        enableval = OMAP2_MCSPI_IRQENABLE_RX2_FULL
                                | OMAP2_MCSPI_IRQENABLE_TX2_UNDERFLOW
                                | OMAP2_MCSPI_IRQENABLE_TX2_EMPTY;
                        break;
                case 3:
+                       statusval = OMAP2_MCSPI_IRQSTATUS_RX3_FULL
+                               | OMAP2_MCSPI_IRQSTATUS_TX3_UNDERFLOW
+                               | OMAP2_MCSPI_IRQSTATUS_TX3_EMPTY;
                        enableval = OMAP2_MCSPI_IRQENABLE_RX3_FULL
                                | OMAP2_MCSPI_IRQENABLE_TX3_UNDERFLOW
                                | OMAP2_MCSPI_IRQENABLE_TX3_EMPTY;
                        break;
        }
 
+       /* clear the interrupts for this channel */
+       u32 = SPI_READ_REG(sc, OMAP2_MCSPI_IRQSTATUS);
+       u32 |= statusval;
+       SPI_WRITE_REG(sc, OMAP2_MCSPI_IRQSTATUS, u32);
+
        /* enable interrupts */
        u32 = SPI_READ_REG(sc, OMAP2_MCSPI_IRQENABLE);
        SPI_WRITE_REG(sc, OMAP2_MCSPI_IRQENABLE, u32 | enableval);
@@ -357,6 +376,9 @@
        for (i = 0; i < sc->sc_spi.sct_nslaves; i++) {
                chan = &sc->sc_channels[i];
 
+               if (!chan->running)
+                       continue;
+
                switch (i) {
                        case 0:
                                u32 |= OMAP2_MCSPI_IRQSTATUS_RX0_OVERFLOW
@@ -408,17 +430,15 @@
                        omap2_spi_recv(sc, i);
                }
 
-               if (chan->wchunk == NULL && chan->rchunk == NULL
-                               && chan->transfer != NULL) {
+               if (chan->wchunk == NULL && chan->rchunk == NULL)
+               {
                        st = chan->transfer;
                        chan->transfer = NULL;
+                       KASSERT(st != NULL);
                        spi_done(st, 0);
 
-                       spi_transq_dequeue(&chan->queue);
-                       if ((st = spi_transq_first(&chan->queue)) == NULL)
-                               omap2_spi_stop(sc, i);
-                       else
-                               chan->transfer = st;
+                       omap2_spi_stop(sc, i);
+                       omap2_spi_start(sc, i);
 
                }
        }



Home | Main Index | Thread Index | Old Index