Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[linux-2.6-microblaze.git] / drivers / spi / spi-pxa2xx.c
index 9071333..4c7a71f 100644 (file)
@@ -461,6 +461,16 @@ int pxa2xx_spi_flush(struct driver_data *drv_data)
        return limit;
 }
 
+static void pxa2xx_spi_off(struct driver_data *drv_data)
+{
+       /* On MMP, disabling SSE seems to corrupt the rx fifo */
+       if (drv_data->ssp_type == MMP2_SSP)
+               return;
+
+       pxa2xx_spi_write(drv_data, SSCR0,
+                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+}
+
 static int null_writer(struct driver_data *drv_data)
 {
        u8 n_bytes = drv_data->n_bytes;
@@ -587,8 +597,7 @@ static void int_error_stop(struct driver_data *drv_data, const char* msg)
        if (!pxa25x_ssp_comp(drv_data))
                pxa2xx_spi_write(drv_data, SSTO, 0);
        pxa2xx_spi_flush(drv_data);
-       pxa2xx_spi_write(drv_data, SSCR0,
-                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+       pxa2xx_spi_off(drv_data);
 
        dev_err(&drv_data->pdev->dev, "%s\n", msg);
 
@@ -686,8 +695,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
 
 static void handle_bad_msg(struct driver_data *drv_data)
 {
-       pxa2xx_spi_write(drv_data, SSCR0,
-                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+       pxa2xx_spi_off(drv_data);
        pxa2xx_spi_write(drv_data, SSCR1,
                         pxa2xx_spi_read(drv_data, SSCR1) & ~drv_data->int_cr1);
        if (!pxa25x_ssp_comp(drv_data))
@@ -1062,7 +1070,8 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
            || (pxa2xx_spi_read(drv_data, SSCR1) & change_mask)
            != (cr1 & change_mask)) {
                /* stop the SSP, and update the other bits */
-               pxa2xx_spi_write(drv_data, SSCR0, cr0 & ~SSCR0_SSE);
+               if (drv_data->ssp_type != MMP2_SSP)
+                       pxa2xx_spi_write(drv_data, SSCR0, cr0 & ~SSCR0_SSE);
                if (!pxa25x_ssp_comp(drv_data))
                        pxa2xx_spi_write(drv_data, SSTO, chip->timeout);
                /* first set CR1 without interrupt and service enables */
@@ -1118,8 +1127,7 @@ static int pxa2xx_spi_slave_abort(struct spi_controller *controller)
        if (!pxa25x_ssp_comp(drv_data))
                pxa2xx_spi_write(drv_data, SSTO, 0);
        pxa2xx_spi_flush(drv_data);
-       pxa2xx_spi_write(drv_data, SSCR0,
-                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+       pxa2xx_spi_off(drv_data);
 
        dev_dbg(&drv_data->pdev->dev, "transfer aborted\n");
 
@@ -1135,8 +1143,7 @@ static void pxa2xx_spi_handle_err(struct spi_controller *controller,
        struct driver_data *drv_data = spi_controller_get_devdata(controller);
 
        /* Disable the SSP */
-       pxa2xx_spi_write(drv_data, SSCR0,
-                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+       pxa2xx_spi_off(drv_data);
        /* Clear and disable interrupts and service requests */
        write_SSSR_CS(drv_data, drv_data->clear_sr);
        pxa2xx_spi_write(drv_data, SSCR1,
@@ -1161,8 +1168,7 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_controller *controller)
        struct driver_data *drv_data = spi_controller_get_devdata(controller);
 
        /* Disable the SSP now */
-       pxa2xx_spi_write(drv_data, SSCR0,
-                        pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);
+       pxa2xx_spi_off(drv_data);
 
        return 0;
 }
@@ -1423,6 +1429,9 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
        /* KBL-H */
        { PCI_VDEVICE(INTEL, 0xa2a9), LPSS_SPT_SSP },
        { PCI_VDEVICE(INTEL, 0xa2aa), LPSS_SPT_SSP },
+       /* CML-V */
+       { PCI_VDEVICE(INTEL, 0xa3a9), LPSS_SPT_SSP },
+       { PCI_VDEVICE(INTEL, 0xa3aa), LPSS_SPT_SSP },
        /* BXT A-Step */
        { PCI_VDEVICE(INTEL, 0x0ac2), LPSS_BXT_SSP },
        { PCI_VDEVICE(INTEL, 0x0ac4), LPSS_BXT_SSP },