diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 321965607fc040a02d208dec203bbf38cb6555ee..9a855bb006940f37cbfdb280fdf57522b36d8849 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -409,6 +409,8 @@ static void pump_transfers(unsigned long data) if (chip != dws->prev_chip) cs_change = 1; + spi_enable_chip(dws, 0); + cr0 = chip->cr0; /* Handle per transfer options for bpw and speed */ @@ -423,6 +425,8 @@ static void pump_transfers(unsigned long data) chip->speed_hz = speed; chip->clk_div = clk_div; + + spi_set_clk(dws, chip->clk_div); } } if (transfer->bits_per_word) { @@ -451,44 +455,32 @@ static void pump_transfers(unsigned long data) cr0 |= (chip->tmode << SPI_TMOD_OFFSET); } + dw_writew(dws, DW_SPI_CTRL0, cr0); + spi_chip_sel(dws, spi, 1); + /* Check if current transfer is a DMA transaction */ dws->dma_mapped = map_dma_buffers(dws); + /* For poll mode just disable all interrupts */ + spi_mask_intr(dws, 0xff); + /* * Interrupt mode * we only need set the TXEI IRQ, as TX/RX always happen syncronizely */ if (!dws->dma_mapped && !chip->poll_mode) { txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes); + dw_writew(dws, DW_SPI_TXFLTR, txlevel); + /* Set the interrupt mask */ imask |= SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI; + spi_umask_intr(dws, imask); + dws->transfer_handler = interrupt_transfer; } - /* - * Reprogram registers only if - * 1. chip select changes - * 2. clk_div is changed - * 3. control value changes - */ - if (dw_readw(dws, DW_SPI_CTRL0) != cr0 || cs_change || clk_div || imask) { - spi_enable_chip(dws, 0); - - dw_writew(dws, DW_SPI_CTRL0, cr0); - - spi_set_clk(dws, chip->clk_div); - spi_chip_sel(dws, spi, 1); - - /* Set the interrupt mask, for poll mode just disable all int */ - spi_mask_intr(dws, 0xff); - if (imask) - spi_umask_intr(dws, imask); - if (txlevel) - dw_writew(dws, DW_SPI_TXFLTR, txlevel); - - spi_enable_chip(dws, 1); - } + spi_enable_chip(dws, 1); if (cs_change) dws->prev_chip = chip;