#define BCM2835_SPI_CS_CS_10           0x00000002
 #define BCM2835_SPI_CS_CS_01           0x00000001
 
+#define BCM2835_SPI_FIFO_SIZE          64
+#define BCM2835_SPI_FIFO_SIZE_3_4      48
 #define BCM2835_SPI_POLLING_LIMIT_US   30
 #define BCM2835_SPI_POLLING_JIFFIES    2
 #define BCM2835_SPI_DMA_MIN_LENGTH     96
                cpu_relax();
 }
 
+/**
+ * bcm2835_rd_fifo_blind() - blindly read up to @count bytes from RX FIFO
+ * @bs: BCM2835 SPI controller
+ * @count: bytes available for reading in RX FIFO
+ */
+static inline void bcm2835_rd_fifo_blind(struct bcm2835_spi *bs, int count)
+{
+       u8 val;
+
+       count = min(count, bs->rx_len);
+       bs->rx_len -= count;
+
+       while (count) {
+               val = bcm2835_rd(bs, BCM2835_SPI_FIFO);
+               if (bs->rx_buf)
+                       *bs->rx_buf++ = val;
+               count--;
+       }
+}
+
+/**
+ * bcm2835_wr_fifo_blind() - blindly write up to @count bytes to TX FIFO
+ * @bs: BCM2835 SPI controller
+ * @count: bytes available for writing in TX FIFO
+ */
+static inline void bcm2835_wr_fifo_blind(struct bcm2835_spi *bs, int count)
+{
+       u8 val;
+
+       count = min(count, bs->tx_len);
+       bs->tx_len -= count;
+
+       while (count) {
+               val = bs->tx_buf ? *bs->tx_buf++ : 0;
+               bcm2835_wr(bs, BCM2835_SPI_FIFO, val);
+               count--;
+       }
+}
+
 static void bcm2835_spi_reset_hw(struct spi_master *master)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
 {
        struct spi_master *master = dev_id;
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
+       u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
+
+       /*
+        * An interrupt is signaled either if DONE is set (TX FIFO empty)
+        * or if RXR is set (RX FIFO >= ¾ full).
+        */
+       if (cs & BCM2835_SPI_CS_RXF)
+               bcm2835_rd_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
+       else if (cs & BCM2835_SPI_CS_RXR)
+               bcm2835_rd_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE_3_4);
+
+       if (bs->tx_len && cs & BCM2835_SPI_CS_DONE)
+               bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
 
        /* Read as many bytes as possible from FIFO */
        bcm2835_rd_fifo(bs);
 static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
                                        struct spi_device *spi,
                                        struct spi_transfer *tfr,
-                                       u32 cs)
+                                       u32 cs, bool fifo_empty)
 {
        struct bcm2835_spi *bs = spi_master_get_devdata(master);
 
        bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
 
        /* fill TX FIFO as much as possible */
+       if (fifo_empty)
+               bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
        bcm2835_wr_fifo(bs);
 
        /* enable interrupts */
         * if we are interrupted here, then the data is
         * getting transferred by the HW while we are interrupted
         */
-       bcm2835_wr_fifo(bs);
+       bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
 
        /* set the timeout */
        timeout = jiffies + BCM2835_SPI_POLLING_JIFFIES;
                                            bs->tx_len, bs->rx_len);
                        /* fall back to interrupt mode */
                        return bcm2835_spi_transfer_one_irq(master, spi,
-                                                           tfr, cs);
+                                                           tfr, cs, false);
                }
        }
 
                return bcm2835_spi_transfer_one_dma(master, spi, tfr, cs);
 
        /* run in interrupt-mode */
-       return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs);
+       return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs, true);
 }
 
 static int bcm2835_spi_prepare_message(struct spi_master *master,