Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / spi / spi-omap2-mcspi.c
index a72127f..7fe69d5 100644 (file)
@@ -22,7 +22,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -147,6 +146,7 @@ struct omap2_mcspi_cs {
        void __iomem            *base;
        unsigned long           phys;
        int                     word_len;
+       u16                     mode;
        struct list_head        node;
        /* Context save and restore shadow register */
        u32                     chconf0;
@@ -320,7 +320,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 disable_fifo:
        if (t->rx_buf != NULL)
                chconf &= ~OMAP2_MCSPI_CHCONF_FFER;
-       else
+
+       if (t->tx_buf != NULL)
                chconf &= ~OMAP2_MCSPI_CHCONF_FFET;
 
        mcspi_write_chconf0(spi, chconf);
@@ -899,6 +900,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
 
        mcspi_write_chconf0(spi, l);
 
+       cs->mode = spi->mode;
+
        dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
                        OMAP2_MCSPI_MAX_FREQ >> div,
                        (spi->mode & SPI_CPHA) ? "trailing" : "leading",
@@ -971,6 +974,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
                        return -ENOMEM;
                cs->base = mcspi->base + spi->chip_select * 0x14;
                cs->phys = mcspi->phys + spi->chip_select * 0x14;
+               cs->mode = 0;
                cs->chconf0 = 0;
                spi->controller_state = cs;
                /* Link this to context save list */
@@ -1051,6 +1055,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
        cs = spi->controller_state;
        cd = spi->controller_data;
 
+       /*
+        * The slave driver could have changed spi->mode in which case
+        * it will be different from cs->mode (the current hardware setup).
+        * If so, set par_override (even though its not a parity issue) so
+        * omap2_mcspi_setup_transfer will be called to configure the hardware
+        * with the correct mode on the first iteration of the loop below.
+        */
+       if (spi->mode != cs->mode)
+               par_override = 1;
+
        omap2_mcspi_set_enable(spi, 0);
        list_for_each_entry(t, &m->transfers, transfer_list) {
                if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {