The Control register is written by the driver.
Use a cached copy of the register so that the reads
thereafter can use the variable instead of the register read.

Signed-off-by: Shubhrajyoti Datta <[email protected]>
---
 drivers/spi/spi-xilinx.c |   34 +++++++++++++++++++---------------
 1 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 3009121..73f4453 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -91,6 +91,7 @@ struct xilinx_spi {
        u8 bytes_per_word;
        int buffer_size;        /* buffer size in words */
        u32 cs_inactive;        /* Level of the CS pins when inactive*/
+       u32 cr;                 /* Control Register*/
        unsigned int (*read_fn)(void __iomem *);
        void (*write_fn)(u32, void __iomem *);
 };
@@ -180,15 +181,15 @@ static void xspi_init_hw(struct xilinx_spi *xspi)
        xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET);
        /* Disable the transmitter, enable Manual Slave Select Assertion,
         * put SPI controller into master mode, and enable it */
-       xspi->write_fn(XSPI_CR_MANUAL_SSELECT | XSPI_CR_MASTER_MODE |
-               XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | XSPI_CR_RXFIFO_RESET,
-               regs_base + XSPI_CR_OFFSET);
+       xspi->cr = XSPI_CR_MANUAL_SSELECT | XSPI_CR_MASTER_MODE |
+               XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | XSPI_CR_RXFIFO_RESET;
+       xspi->write_fn(xspi->cr, regs_base + XSPI_CR_OFFSET);
+       xspi->cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
 }
 
 static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
 {
        struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
-       u16 cr;
        u32 cs;
 
        if (is_on == BITBANG_CS_INACTIVE) {
@@ -198,16 +199,16 @@ static void xilinx_spi_chipselect(struct spi_device *spi, 
int is_on)
        }
 
        /* Set the SPI clock phase and polarity */
-       cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & ~XSPI_CR_MODE_MASK;
+       xspi->cr &=  ~XSPI_CR_MODE_MASK;
        if (spi->mode & SPI_CPHA)
-               cr |= XSPI_CR_CPHA;
+               xspi->cr |= XSPI_CR_CPHA;
        if (spi->mode & SPI_CPOL)
-               cr |= XSPI_CR_CPOL;
+               xspi->cr |= XSPI_CR_CPOL;
        if (spi->mode & SPI_LSB_FIRST)
-               cr |= XSPI_CR_LSB_FIRST;
+               xspi->cr |= XSPI_CR_LSB_FIRST;
        if (spi->mode & SPI_LOOP)
-               cr |= XSPI_CR_LOOP;
-       xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
+               xspi->cr |= XSPI_CR_LOOP;
+       xspi->write_fn(xspi->cr, xspi->regs + XSPI_CR_OFFSET);
 
        /* We do not check spi->max_speed_hz here as the SPI clock
         * frequency is not software programmable (the IP block design
@@ -254,7 +255,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, 
struct spi_transfer *t)
                u32 isr;
                use_irq = true;
                /* Inhibit irq to avoid spurious irqs on tx_empty*/
-               cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
+               cr = xspi->cr;
+               xspi->cr = cr | XSPI_CR_TRANS_INHIBIT;
                xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
                               xspi->regs + XSPI_CR_OFFSET);
                /* ACK old irqs (if any) */
@@ -283,7 +285,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, 
struct spi_transfer *t)
                 */
 
                if (use_irq) {
-                       xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
+                       xspi->cr = cr;
+                       xspi->write_fn(xspi->cr, xspi->regs + XSPI_CR_OFFSET);
                        wait_for_completion(&xspi->done);
                        /* A transmit has just completed. Process received data
                         * and check for more data to transmit. Always inhibit
@@ -291,8 +294,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, 
struct spi_transfer *t)
                         * register/FIFO, or make sure it is stopped if we're
                         * done.
                         */
-                       xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
-                                      xspi->regs + XSPI_CR_OFFSET);
+                       xspi->cr = xspi->cr | XSPI_CR_TRANS_INHIBIT;
+                       xspi->write_fn(xspi->cr, xspi->regs + XSPI_CR_OFFSET);
                        sr = XSPI_SR_TX_EMPTY_MASK;
                } else
                        sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET);
@@ -318,7 +321,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, 
struct spi_transfer *t)
 
        if (use_irq) {
                xspi->write_fn(0, xspi->regs + XIPIF_V123B_DGIER_OFFSET);
-               xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
+               xspi->cr = cr;
+               xspi->write_fn(xspi->cr, xspi->regs + XSPI_CR_OFFSET);
        }
 
        return t->len;
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to