void __iomem *base;
        struct device *dev;
        struct clk *clk;
+       int irq;
        u32 src_clk;
        u32 hw_mode;
        u32 trans_len;
        u32 hw_speed_hz;
        u32 len;
        int status;
+       struct completion xfer_completion;
        const void *tx_buf;
        void *rx_buf;
        int (*read_bufs)(struct sprd_spi *ss, u32 len);
        return ret;
 }
 
+static irqreturn_t sprd_spi_handle_irq(int irq, void *data)
+{
+       struct sprd_spi *ss = (struct sprd_spi *)data;
+       u32 val = readl_relaxed(ss->base + SPRD_SPI_INT_MASK_STS);
+
+       if (val & SPRD_SPI_MASK_TX_END) {
+               writel_relaxed(SPRD_SPI_TX_END_CLR, ss->base + SPRD_SPI_INT_CLR);
+               if (!(ss->trans_mode & SPRD_SPI_RX_MODE))
+                       complete(&ss->xfer_completion);
+
+               return IRQ_HANDLED;
+       }
+
+       if (val & SPRD_SPI_MASK_RX_END) {
+               writel_relaxed(SPRD_SPI_RX_END_CLR, ss->base + SPRD_SPI_INT_CLR);
+               complete(&ss->xfer_completion);
+
+               return IRQ_HANDLED;
+       }
+
+       return IRQ_NONE;
+}
+
+static int sprd_spi_irq_init(struct platform_device *pdev, struct sprd_spi *ss)
+{
+       int ret;
+
+       ss->irq = platform_get_irq(pdev, 0);
+       if (ss->irq < 0) {
+               dev_err(&pdev->dev, "failed to get irq resource\n");
+               return ss->irq;
+       }
+
+       ret = devm_request_irq(&pdev->dev, ss->irq, sprd_spi_handle_irq,
+                               0, pdev->name, ss);
+       if (ret)
+               dev_err(&pdev->dev, "failed to request spi irq %d, ret = %d\n",
+                       ss->irq, ret);
+
+       return ret;
+}
+
 static int sprd_spi_clk_init(struct platform_device *pdev, struct sprd_spi *ss)
 {
        struct clk *clk_spi, *clk_parent;
        sctlr->max_speed_hz = min_t(u32, ss->src_clk >> 1,
                                    SPRD_SPI_MAX_SPEED_HZ);
 
+       init_completion(&ss->xfer_completion);
        platform_set_drvdata(pdev, sctlr);
        ret = sprd_spi_clk_init(pdev, ss);
        if (ret)
                goto free_controller;
 
+       ret = sprd_spi_irq_init(pdev, ss);
+       if (ret)
+               goto free_controller;
+
        ret = clk_prepare_enable(ss->clk);
        if (ret)
                goto free_controller;
                return ret;
        }
 
+       spi_controller_suspend(sctlr);
+
        clk_disable_unprepare(ss->clk);
        pm_runtime_put_noidle(&pdev->dev);
        pm_runtime_disable(&pdev->dev);