struct atmel_spi_dma {
        struct dma_chan                 *chan_rx;
        struct dma_chan                 *chan_tx;
-       struct scatterlist              sgrx;
-       struct scatterlist              sgtx;
        struct dma_async_tx_descriptor  *data_desc_rx;
        struct dma_async_tx_descriptor  *data_desc_tx;
 
        return as->use_dma && xfer->len >= DMA_MIN_BYTES;
 }
 
+static bool atmel_spi_can_dma(struct spi_master *master,
+                             struct spi_device *spi,
+                             struct spi_transfer *xfer)
+{
+       struct atmel_spi *as = spi_master_get_devdata(master);
+
+       return atmel_spi_use_dma(as, xfer);
+}
+
 static int atmel_spi_dma_slave_config(struct atmel_spi *as,
                                struct dma_slave_config *slave_config,
                                u8 bits_per_word)
        struct dma_async_tx_descriptor *txdesc;
        struct dma_slave_config slave_config;
        dma_cookie_t            cookie;
-       u32     len = *plen;
 
        dev_vdbg(master->dev.parent, "atmel_spi_next_xfer_dma_submit\n");
 
        /* release lock for DMA operations */
        atmel_spi_unlock(as);
 
-       /* prepare the RX dma transfer */
-       sg_init_table(&as->dma.sgrx, 1);
-       as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len - *plen;
-
-       /* prepare the TX dma transfer */
-       sg_init_table(&as->dma.sgtx, 1);
-       as->dma.sgtx.dma_address = xfer->tx_dma + xfer->len - *plen;
-
-       if (len > master->max_dma_len)
-               len = master->max_dma_len;
-
-       sg_dma_len(&as->dma.sgtx) = len;
-       sg_dma_len(&as->dma.sgrx) = len;
-
-       *plen = len;
+       *plen = xfer->len;
 
        if (atmel_spi_dma_slave_config(as, &slave_config,
                                       xfer->bits_per_word))
                goto err_exit;
 
        /* Send both scatterlists */
-       rxdesc = dmaengine_prep_slave_sg(rxchan, &as->dma.sgrx, 1,
+       rxdesc = dmaengine_prep_slave_sg(rxchan,
+                                        xfer->rx_sg.sgl, xfer->rx_sg.nents,
                                         DMA_FROM_DEVICE,
                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!rxdesc)
                goto err_dma;
 
-       txdesc = dmaengine_prep_slave_sg(txchan, &as->dma.sgtx, 1,
+       txdesc = dmaengine_prep_slave_sg(txchan,
+                                        xfer->tx_sg.sgl, xfer->tx_sg.nents,
                                         DMA_TO_DEVICE,
                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!txdesc)
                                dma_addr_t *rx_dma,
                                u32 *plen)
 {
-       struct atmel_spi        *as = spi_master_get_devdata(master);
-       u32                     len = *plen;
-
        *rx_dma = xfer->rx_dma + xfer->len - *plen;
        *tx_dma = xfer->tx_dma + xfer->len - *plen;
-       if (len > master->max_dma_len)
-               len = master->max_dma_len;
-
-       *plen = len;
+       if (*plen > master->max_dma_len)
+               *plen = master->max_dma_len;
 }
 
 static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
         * better fault reporting.
         */
        if ((!msg->is_dma_mapped)
-               && (atmel_spi_use_dma(as, xfer) || as->use_pdc)) {
+               && as->use_pdc) {
                if (atmel_spi_dma_map_xfer(as, xfer) < 0)
                        return -ENOMEM;
        }
                }
 
                if (!msg->is_dma_mapped
-                       && (atmel_spi_use_dma(as, xfer) || as->use_pdc))
+                       && as->use_pdc)
                        atmel_spi_dma_unmap_xfer(master, xfer);
 
                return 0;
        }
 
        if (!msg->is_dma_mapped
-               && (atmel_spi_use_dma(as, xfer) || as->use_pdc))
+               && as->use_pdc)
                atmel_spi_dma_unmap_xfer(master, xfer);
 
        if (xfer->delay_usecs)
        master->cleanup = atmel_spi_cleanup;
        master->auto_runtime_pm = true;
        master->max_dma_len = SPI_MAX_DMA_XFER;
+       master->can_dma = atmel_spi_can_dma;
        platform_set_drvdata(pdev, master);
 
        as = spi_master_get_devdata(master);
        as->use_pdc = false;
        if (as->caps.has_dma_support) {
                ret = atmel_spi_configure_dma(as);
-               if (ret == 0)
+               if (ret == 0) {
+                       master->dma_tx = as->dma.chan_tx;
+                       master->dma_rx = as->dma.chan_rx;
                        as->use_dma = true;
-               else if (ret == -EPROBE_DEFER)
+               } else if (ret == -EPROBE_DEFER) {
                        return ret;
+               }
        } else {
                as->use_pdc = true;
        }