OSDN Git Service

spi: bcm2835aux: unifying code between polling and interrupt driven code
authorMartin Sperl <kernel@martin.sperl.org>
Sat, 30 Mar 2019 09:30:58 +0000 (09:30 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Sep 2019 09:29:49 +0000 (10:29 +0100)
[ Upstream commit 7188a6f0eee3f1fae5d826cfc6d569657ff950ec ]

Sharing more code between polling and interrupt-driven mode.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/spi/spi-bcm2835aux.c

index 6f4c6aa..5b2c2b2 100644 (file)
@@ -181,23 +181,13 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)
                      BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
 }
 
-static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
 {
-       struct spi_master *master = dev_id;
-       struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
-       irqreturn_t ret = IRQ_NONE;
-
-       /* IRQ may be shared, so return if our interrupts are disabled */
-       if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
-             (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
-               return ret;
-
        /* check if we have data to read */
        while (bs->rx_len &&
               (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
                  BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
                bcm2835aux_rd_fifo(bs);
-               ret = IRQ_HANDLED;
        }
 
        /* check if we have data to write */
@@ -206,7 +196,6 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
               (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
                  BCM2835_AUX_SPI_STAT_TX_FULL))) {
                bcm2835aux_wr_fifo(bs);
-               ret = IRQ_HANDLED;
        }
 
        /* and check if we have reached "done" */
@@ -214,8 +203,21 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
               (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
                  BCM2835_AUX_SPI_STAT_BUSY))) {
                bcm2835aux_rd_fifo(bs);
-               ret = IRQ_HANDLED;
        }
+}
+
+static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
+{
+       struct spi_master *master = dev_id;
+       struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+       /* IRQ may be shared, so return if our interrupts are disabled */
+       if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
+             (BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
+               return IRQ_NONE;
+
+       /* do common fifo handling */
+       bcm2835aux_spi_transfer_helper(bs);
 
        /* and if rx_len is 0 then wake up completion and disable spi */
        if (!bs->rx_len) {
@@ -223,8 +225,7 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
                complete(&master->xfer_completion);
        }
 
-       /* and return */
-       return ret;
+       return IRQ_HANDLED;
 }
 
 static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
@@ -270,7 +271,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
 {
        struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
        unsigned long timeout;
-       u32 stat;
 
        /* configure spi */
        bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
@@ -281,24 +281,9 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
 
        /* loop until finished the transfer */
        while (bs->rx_len) {
-               /* read status */
-               stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT);
-
-               /* fill in tx fifo with remaining data */
-               if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) {
-                       bcm2835aux_wr_fifo(bs);
-                       continue;
-               }
 
-               /* read data from fifo for both cases */
-               if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) {
-                       bcm2835aux_rd_fifo(bs);
-                       continue;
-               }
-               if (!(stat & BCM2835_AUX_SPI_STAT_BUSY)) {
-                       bcm2835aux_rd_fifo(bs);
-                       continue;
-               }
+               /* do common fifo handling */
+               bcm2835aux_spi_transfer_helper(bs);
 
                /* there is still data pending to read check the timeout */
                if (bs->rx_len && time_after(jiffies, timeout)) {