diff -uNr a/spi-omap2-mcspi.c b/spi-omap2-mcspi.c --- a/spi-omap2-mcspi.c 2014-04-17 13:47:28.759432608 -0300 +++ b/spi-omap2-mcspi.c 2014-04-17 13:48:29.035431679 -0300 @@ -305,6 +305,8 @@ const u8 * tx; void __iomem *chstat_reg; struct edmacc_param param; + int a_cnt, b_cnt, c_cnt, b_cntrld; + static const u8 dummy=0; mcspi = spi_master_get_devdata(spi->master); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; @@ -333,27 +335,29 @@ element_count = count >> 2; } - if (tx != NULL) { - int a_cnt, b_cnt, c_cnt, b_cntrld; - - a_cnt = 1 << data_type; - b_cnt = 1; - c_cnt = element_count / 256; - b_cntrld = SZ_64K - 1; + a_cnt = 1 << data_type; + b_cnt = 1; + c_cnt = element_count / 256; + b_cntrld = SZ_64K - 1; - param.opt = TCINTEN | - EDMA_TCC(mcspi_dma->dma_tx_channel) | SYNCDIM ; - param.src = xfer->tx_dma; - param.a_b_cnt = a_cnt | b_cnt << 16; - param.dst = tx_reg; + if (tx != NULL) { param.src_dst_bidx = a_cnt; - param.link_bcntrld = b_cntrld << 16; param.src_dst_cidx = a_cnt; - param.ccnt = element_count; - edma_write_slot(mcspi_dma->dma_tx_channel, ¶m); - edma_link(mcspi_dma->dma_tx_channel, - mcspi_dma->dummy_param_slot); } + else { + tx = xfer->tx_buf = &dummy; + param.src_dst_bidx = 0; + param.src_dst_cidx = 0; + } + + param.opt = TCINTEN | EDMA_TCC(mcspi_dma->dma_tx_channel) | SYNCDIM; + param.src = xfer->tx_dma; + param.a_b_cnt = a_cnt | b_cnt << 16; + param.dst = tx_reg; + param.link_bcntrld = b_cntrld << 16; + param.ccnt = element_count; + edma_write_slot(mcspi_dma->dma_tx_channel, ¶m); + edma_link(mcspi_dma->dma_tx_channel, mcspi_dma->dummy_param_slot); if (rx != NULL) { int a_cnt, b_cnt, c_cnt, b_cntrld; @@ -929,31 +933,31 @@ chconf &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; chconf &= ~OMAP2_MCSPI_CHCONF_TURBO; - if (t->tx_buf == NULL) - chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; - else if (t->rx_buf == NULL) - chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; - - if (cd && cd->turbo_mode && t->tx_buf == NULL) { - /* Turbo mode is for more than one word */ - if (t->len > ((cs->word_len + 7) >> 3)) - chconf |= OMAP2_MCSPI_CHCONF_TURBO; - } - - mcspi_write_chconf0(spi, chconf); - if (t->len) { unsigned count; - /* RX_ONLY mode needs dummy data in TX reg */ - if (t->tx_buf == NULL) - __raw_writel(0, cs->base - + OMAP2_MCSPI_TX0); + if (t->rx_buf == NULL) + chconf |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; - if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) + if (cd && cd->turbo_mode && t->tx_buf == NULL) { + /* Turbo mode is for more than one word */ + if (t->len > ((cs->word_len + 7) >> 3)) + chconf |= OMAP2_MCSPI_CHCONF_TURBO; + } + + if (m->is_dma_mapped || t->len >= DMA_MIN_BYTES) { + mcspi_write_chconf0(spi, chconf); count = omap2_mcspi_txrx_dma(spi, t); - else + } + else { + if (t->len < DMA_MIN_BYTES && t->tx_buf == NULL) + chconf |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; + mcspi_write_chconf0(spi, chconf); + /* RX_ONLY mode needs dummy data in TX reg */ + if (t->tx_buf == NULL) + __raw_writel(0, cs->base + OMAP2_MCSPI_TX0); count = omap2_mcspi_txrx_pio(spi, t); + } m->actual_length += count; if (count != t->len) {