diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index 1a6381de6f33d7018eb00842fa9ee8cd8f1f01f7..4c34ef9d5220f4c7e9d7c1af78501126994dcfed 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -379,6 +379,26 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static void rockchip_spi_poll_completion(struct rockchip_spi *rs,
+					 struct spi_controller *ctlr,
+					 unsigned int timeout_ms)
+{
+	ktime_t ktime = ktime_get();
+	ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms);
+
+	do {
+		rockchip_spi_isr(0, ctlr);
+
+		if (completion_done(&ctlr->xfer_completion))
+			return;
+
+		ktime = ktime_get();
+
+	} while (ktime_before(ktime, ktimeout));
+
+	dev_err(rs->dev, "atomic transfer timeout\n");
+}
+
 static int rockchip_spi_prepare_irq(struct rockchip_spi *rs,
 				    struct spi_controller *ctlr,
 				    struct spi_transfer *xfer)
@@ -400,6 +420,11 @@ static int rockchip_spi_prepare_irq(struct rockchip_spi *rs,
 	else
 		writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
 
+	if (ctlr->atomic_xfer) {
+		rockchip_spi_poll_completion(rs, ctlr, 1000);
+		return 0;
+	}
+
 	/* 1 means the transfer is in progress */
 	return 1;
 }
@@ -677,7 +702,7 @@ static int rockchip_spi_transfer_one(
 {
 	struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
 	int ret;
-	bool use_dma;
+	bool use_dma = false;
 
 	/* Zero length transfers won't trigger an interrupt on completion */
 	if (!xfer->len) {
@@ -700,7 +725,9 @@ static int rockchip_spi_transfer_one(
 
 	rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2;
 	rs->xfer = xfer;
-	use_dma = ctlr->can_dma ? ctlr->can_dma(ctlr, spi, xfer) : false;
+
+	if (!ctlr->atomic_xfer)
+		use_dma = ctlr->can_dma ? ctlr->can_dma(ctlr, spi, xfer) : false;
 
 	ret = rockchip_spi_config(rs, spi, xfer, use_dma, ctlr->target);
 	if (ret)
@@ -1015,6 +1042,11 @@ static int rockchip_spi_runtime_resume(struct device *dev)
 }
 #endif /* CONFIG_PM */
 
+static void rockchip_spi_shutdown(struct platform_device *pdev)
+{
+	pm_runtime_get_sync(&pdev->dev);
+}
+
 static const struct dev_pm_ops rockchip_spi_pm = {
 	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_spi_suspend, rockchip_spi_resume)
 	SET_RUNTIME_PM_OPS(rockchip_spi_runtime_suspend,
@@ -1046,6 +1078,7 @@ static struct platform_driver rockchip_spi_driver = {
 	},
 	.probe = rockchip_spi_probe,
 	.remove = rockchip_spi_remove,
+	.shutdown = rockchip_spi_shutdown,
 };
 
 module_platform_driver(rockchip_spi_driver);