spi: bcm2835: clock divider can be a multiple of 2
[firefly-linux-kernel-4.4.55.git] / drivers / spi / spi-bcm2835.c
index 419a782ab6d50541809f0c8b10b3d8eaeeb1ae89..8de1925fe5548f9ea58579e26268f6fafe391d4b 100644 (file)
@@ -91,25 +91,23 @@ static inline void bcm2835_wr(struct bcm2835_spi *bs, unsigned reg, u32 val)
        writel(val, bs->regs + reg);
 }
 
-static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs, int len)
+static inline void bcm2835_rd_fifo(struct bcm2835_spi *bs)
 {
        u8 byte;
 
-       while (len--) {
+       while (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_RXD) {
                byte = bcm2835_rd(bs, BCM2835_SPI_FIFO);
                if (bs->rx_buf)
                        *bs->rx_buf++ = byte;
        }
 }
 
-static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs, int len)
+static inline void bcm2835_wr_fifo(struct bcm2835_spi *bs)
 {
        u8 byte;
 
-       if (len > bs->len)
-               len = bs->len;
-
-       while (len--) {
+       while ((bs->len) &&
+              (bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_TXD)) {
                byte = bs->tx_buf ? *bs->tx_buf++ : 0;
                bcm2835_wr(bs, BCM2835_SPI_FIFO, byte);
                bs->len--;
@@ -122,64 +120,28 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
        u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
 
-       /*
-        * RXR - RX needs Reading. This means 12 (or more) bytes have been
-        * transmitted and hence 12 (or more) bytes have been received.
-        *
-        * The FIFO is 16-bytes deep. We check for this interrupt to keep the
-        * FIFO full; we have a 4-byte-time buffer for IRQ latency. We check
-        * this before DONE (TX empty) just in case we delayed processing this
-        * interrupt for some reason.
-        *
-        * We only check for this case if we have more bytes to TX; at the end
-        * of the transfer, we ignore this pipelining optimization, and let
-        * bcm2835_spi_finish_transfer() drain the RX FIFO.
-        */
-       if (bs->len && (cs & BCM2835_SPI_CS_RXR)) {
-               /* Read 12 bytes of data */
-               bcm2835_rd_fifo(bs, 12);
+       /* Read as many bytes as possible from FIFO */
+       bcm2835_rd_fifo(bs);
 
-               /* Write up to 12 bytes */
-               bcm2835_wr_fifo(bs, 12);
+       if (bs->len) { /* there is more data to transmit */
+               bcm2835_wr_fifo(bs);
+       } else { /* Transfer complete */
+               /* Disable SPI interrupts */
+               cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD);
+               bcm2835_wr(bs, BCM2835_SPI_CS, cs);
 
                /*
-                * We must have written something to the TX FIFO due to the
-                * bs->len check above, so cannot be DONE. Hence, return
-                * early. Note that DONE could also be set if we serviced an
-                * RXR interrupt really late.
+                * Wake up bcm2835_spi_transfer_one(), which will call
+                * bcm2835_spi_finish_transfer(), to drain the RX FIFO.
                 */
-               return IRQ_HANDLED;
-       }
-
-       /*
-        * DONE - TX empty. This occurs when we first enable the transfer
-        * since we do not pre-fill the TX FIFO. At any other time, given that
-        * we refill the TX FIFO above based on RXR, and hence ignore DONE if
-        * RXR is set, DONE really does mean end-of-transfer.
-        */
-       if (cs & BCM2835_SPI_CS_DONE) {
-               if (bs->len) { /* First interrupt in a transfer */
-                       bcm2835_wr_fifo(bs, 16);
-               } else { /* Transfer complete */
-                       /* Disable SPI interrupts */
-                       cs &= ~(BCM2835_SPI_CS_INTR | BCM2835_SPI_CS_INTD);
-                       bcm2835_wr(bs, BCM2835_SPI_CS, cs);
-
-                       /*
-                        * Wake up bcm2835_spi_transfer_one(), which will call
-                        * bcm2835_spi_finish_transfer(), to drain the RX FIFO.
-                        */
-                       complete(&bs->done);
-               }
-
-               return IRQ_HANDLED;
+               complete(&bs->done);
        }
 
-       return IRQ_NONE;
+       return IRQ_HANDLED;
 }
 
 static int bcm2835_spi_start_transfer(struct spi_device *spi,
-               struct spi_transfer *tfr)
+                                     struct spi_transfer *tfr)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(spi->master);
        unsigned long spi_hz, clk_hz, cdiv;
@@ -191,13 +153,15 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi,
        if (spi_hz >= clk_hz / 2) {
                cdiv = 2; /* clk_hz/2 is the fastest we can go */
        } else if (spi_hz) {
-               /* CDIV must be a power of two */
-               cdiv = roundup_pow_of_two(DIV_ROUND_UP(clk_hz, spi_hz));
+               /* CDIV must be a multiple of two */
+               cdiv = DIV_ROUND_UP(clk_hz, spi_hz);
+               cdiv += (cdiv % 2);
 
                if (cdiv >= 65536)
                        cdiv = 0; /* 0 is the slowest we can go */
-       } else
+       } else {
                cdiv = 0; /* 0 is the slowest we can go */
+       }
 
        if (spi->mode & SPI_CPOL)
                cs |= BCM2835_SPI_CS_CPOL;
@@ -231,17 +195,12 @@ static int bcm2835_spi_start_transfer(struct spi_device *spi,
 }
 
 static int bcm2835_spi_finish_transfer(struct spi_device *spi,
-               struct spi_transfer *tfr, bool cs_change)
+                                      struct spi_transfer *tfr,
+                                      bool cs_change)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(spi->master);
        u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
 
-       /* Drain RX FIFO */
-       while (cs & BCM2835_SPI_CS_RXD) {
-               bcm2835_rd_fifo(bs, 1);
-               cs = bcm2835_rd(bs, BCM2835_SPI_CS);
-       }
-
        if (tfr->delay_usecs)
                udelay(tfr->delay_usecs);
 
@@ -253,7 +212,7 @@ static int bcm2835_spi_finish_transfer(struct spi_device *spi,
 }
 
 static int bcm2835_spi_transfer_one(struct spi_master *master,
-               struct spi_message *mesg)
+                                   struct spi_message *mesg)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
        struct spi_transfer *tfr;
@@ -267,8 +226,10 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
                if (err)
                        goto out;
 
-               timeout = wait_for_completion_timeout(&bs->done,
-                               msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS));
+               timeout = wait_for_completion_timeout(
+                       &bs->done,
+                       msecs_to_jiffies(BCM2835_SPI_TIMEOUT_MS)
+                       );
                if (!timeout) {
                        err = -ETIMEDOUT;
                        goto out;
@@ -343,7 +304,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
        clk_prepare_enable(bs->clk);
 
        err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0,
-                               dev_name(&pdev->dev), master);
+                              dev_name(&pdev->dev), master);
        if (err) {
                dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
                goto out_clk_disable;