Merge branch 'spi-5.6' into spi-next
[linux-2.6-microblaze.git] / drivers / spi / spi-dw.c
index 73f50f4..31e3f86 100644 (file)
@@ -172,9 +172,11 @@ static inline u32 rx_max(struct dw_spi *dws)
 
 static void dw_writer(struct dw_spi *dws)
 {
-       u32 max = tx_max(dws);
+       u32 max;
        u16 txw = 0;
 
+       spin_lock(&dws->buf_lock);
+       max = tx_max(dws);
        while (max--) {
                /* Set the tx word if the transfer's original "tx" is not null */
                if (dws->tx_end - dws->len) {
@@ -186,13 +188,16 @@ static void dw_writer(struct dw_spi *dws)
                dw_write_io_reg(dws, DW_SPI_DR, txw);
                dws->tx += dws->n_bytes;
        }
+       spin_unlock(&dws->buf_lock);
 }
 
 static void dw_reader(struct dw_spi *dws)
 {
-       u32 max = rx_max(dws);
+       u32 max;
        u16 rxw;
 
+       spin_lock(&dws->buf_lock);
+       max = rx_max(dws);
        while (max--) {
                rxw = dw_read_io_reg(dws, DW_SPI_DR);
                /* Care rx only if the transfer's original "rx" is not null */
@@ -204,6 +209,7 @@ static void dw_reader(struct dw_spi *dws)
                }
                dws->rx += dws->n_bytes;
        }
+       spin_unlock(&dws->buf_lock);
 }
 
 static void int_error_stop(struct dw_spi *dws, const char *msg)
@@ -276,18 +282,23 @@ static int dw_spi_transfer_one(struct spi_controller *master,
 {
        struct dw_spi *dws = spi_controller_get_devdata(master);
        struct chip_data *chip = spi_get_ctldata(spi);
+       unsigned long flags;
        u8 imask = 0;
        u16 txlevel = 0;
        u32 cr0;
        int ret;
 
        dws->dma_mapped = 0;
-
+       spin_lock_irqsave(&dws->buf_lock, flags);
        dws->tx = (void *)transfer->tx_buf;
        dws->tx_end = dws->tx + transfer->len;
        dws->rx = transfer->rx_buf;
        dws->rx_end = dws->rx + transfer->len;
        dws->len = transfer->len;
+       spin_unlock_irqrestore(&dws->buf_lock, flags);
+
+       /* Ensure dw->rx and dw->rx_end are visible */
+       smp_mb();
 
        spi_enable_chip(dws, 0);
 
@@ -472,6 +483,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
        dws->type = SSI_MOTO_SPI;
        dws->dma_inited = 0;
        dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
+       spin_lock_init(&dws->buf_lock);
 
        spi_controller_set_devdata(master, dws);