struct completion       xfer_completion;
 
-       /* scratch buffer */
-       void                    *buffer;
-       dma_addr_t              buffer_dma;
-
        struct atmel_spi_caps   caps;
 
        bool                    use_dma;
        u32                     csr;
 };
 
-#define BUFFER_SIZE            PAGE_SIZE
+#define SPI_MAX_DMA_XFER       65535 /* true for both PDC and DMA */
 #define INVALID_DMA_ADDRESS    0xffffffff
 
 /*
                cpu_relax();
        }
 
-       if (xfer->tx_buf) {
-               if (xfer->bits_per_word > 8)
-                       spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos));
-               else
-                       spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos));
-       } else {
-               spi_writel(as, TDR, 0);
-       }
+       if (xfer->bits_per_word > 8)
+               spi_writel(as, TDR, *(u16 *)(xfer->tx_buf + xfer_pos));
+       else
+               spi_writel(as, TDR, *(u8 *)(xfer->tx_buf + xfer_pos));
 
        dev_dbg(master->dev.parent,
                "  start pio xfer %p: len %u tx %p rx %p bitpw %d\n",
 
        /* Fill TX FIFO */
        while (num_data >= 2) {
-               if (xfer->tx_buf) {
-                       if (xfer->bits_per_word > 8) {
-                               td0 = *words++;
-                               td1 = *words++;
-                       } else {
-                               td0 = *bytes++;
-                               td1 = *bytes++;
-                       }
+               if (xfer->bits_per_word > 8) {
+                       td0 = *words++;
+                       td1 = *words++;
                } else {
-                       td0 = 0;
-                       td1 = 0;
+                       td0 = *bytes++;
+                       td1 = *bytes++;
                }
 
                spi_writel(as, TDR, (td1 << 16) | td0);
        }
 
        if (num_data) {
-               if (xfer->tx_buf) {
-                       if (xfer->bits_per_word > 8)
-                               td0 = *words++;
-                       else
-                               td0 = *bytes++;
-               } else {
-                       td0 = 0;
-               }
+               if (xfer->bits_per_word > 8)
+                       td0 = *words++;
+               else
+                       td0 = *bytes++;
 
                spi_writew(as, TDR, td0);
                num_data--;
 
        /* prepare the RX dma transfer */
        sg_init_table(&as->dma.sgrx, 1);
-       if (xfer->rx_buf) {
-               as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len - *plen;
-       } else {
-               as->dma.sgrx.dma_address = as->buffer_dma;
-               if (len > BUFFER_SIZE)
-                       len = BUFFER_SIZE;
-       }
+       as->dma.sgrx.dma_address = xfer->rx_dma + xfer->len - *plen;
 
        /* prepare the TX dma transfer */
        sg_init_table(&as->dma.sgtx, 1);
-       if (xfer->tx_buf) {
-               as->dma.sgtx.dma_address = xfer->tx_dma + xfer->len - *plen;
-       } else {
-               as->dma.sgtx.dma_address = as->buffer_dma;
-               if (len > BUFFER_SIZE)
-                       len = BUFFER_SIZE;
-               memset(as->buffer, 0, len);
-       }
+       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;
        struct atmel_spi        *as = spi_master_get_devdata(master);
        u32                     len = *plen;
 
-       /* use scratch buffer only when rx or tx data is unspecified */
-       if (xfer->rx_buf)
-               *rx_dma = xfer->rx_dma + xfer->len - *plen;
-       else {
-               *rx_dma = as->buffer_dma;
-               if (len > BUFFER_SIZE)
-                       len = BUFFER_SIZE;
-       }
-
-       if (xfer->tx_buf)
-               *tx_dma = xfer->tx_dma + xfer->len - *plen;
-       else {
-               *tx_dma = as->buffer_dma;
-               if (len > BUFFER_SIZE)
-                       len = BUFFER_SIZE;
-               memset(as->buffer, 0, len);
-               dma_sync_single_for_device(&as->pdev->dev,
-                               as->buffer_dma, len, DMA_TO_DEVICE);
-       }
+       *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;
 }
        u16             *rxp16;
        unsigned long   xfer_pos = xfer->len - as->current_remaining_bytes;
 
-       if (xfer->rx_buf) {
-               if (xfer->bits_per_word > 8) {
-                       rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos);
-                       *rxp16 = spi_readl(as, RDR);
-               } else {
-                       rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
-                       *rxp = spi_readl(as, RDR);
-               }
+       if (xfer->bits_per_word > 8) {
+               rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos);
+               *rxp16 = spi_readl(as, RDR);
        } else {
-               spi_readl(as, RDR);
+               rxp = ((u8 *)xfer->rx_buf) + xfer_pos;
+               *rxp = spi_readl(as, RDR);
        }
        if (xfer->bits_per_word > 8) {
                if (as->current_remaining_bytes > 2)
        /* Read data */
        while (num_data) {
                rd = spi_readl(as, RDR);
-               if (xfer->rx_buf) {
-                       if (xfer->bits_per_word > 8)
-                               *words++ = rd;
-                       else
-                               *bytes++ = rd;
-               }
+               if (xfer->bits_per_word > 8)
+                       *words++ = rd;
+               else
+                       *bytes++ = rd;
                num_data--;
        }
 }
        master->bus_num = pdev->id;
        master->num_chipselect = master->dev.of_node ? 0 : 4;
        master->setup = atmel_spi_setup;
+       master->flags = (SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX);
        master->transfer_one_message = atmel_spi_transfer_one_message;
        master->cleanup = atmel_spi_cleanup;
        master->auto_runtime_pm = true;
+       master->max_dma_len = SPI_MAX_DMA_XFER;
        platform_set_drvdata(pdev, master);
 
        as = spi_master_get_devdata(master);
 
-       /*
-        * Scratch buffer is used for throwaway rx and tx data.
-        * It's coherent to minimize dcache pollution.
-        */
-       as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
-                                       &as->buffer_dma, GFP_KERNEL);
-       if (!as->buffer)
-               goto out_free;
-
        spin_lock_init(&as->lock);
 
        as->pdev = pdev;
        as->regs = devm_ioremap_resource(&pdev->dev, regs);
        if (IS_ERR(as->regs)) {
                ret = PTR_ERR(as->regs);
-               goto out_free_buffer;
+               goto out_unmap_regs;
        }
        as->phybase = regs->start;
        as->irq = irq;
        clk_disable_unprepare(clk);
 out_free_irq:
 out_unmap_regs:
-out_free_buffer:
-       dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
-                       as->buffer_dma);
 out_free:
        spi_master_put(master);
        return ret;
        spi_readl(as, SR);
        spin_unlock_irq(&as->lock);
 
-       dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
-                       as->buffer_dma);
-
        clk_disable_unprepare(as->clk);
 
        pm_runtime_put_noidle(&pdev->dev);