diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index d78e114e17e0..9823d710c4d6 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -167,6 +167,10 @@ struct qspi_platform_data {
 
 /**
  * struct zynqmp_qspi - Defines qspi driver instance
+ * @lower		Pointer to "lower" SPI bus
+ * @upper		Pointer to "upper" SPI bus
+ * @merged		Pointer to legacy SPI bus which is a combination of
+ * 			@lower and @upper
  * @ctlr:		Pointer to the spi controller information
  * @regs:		Virtual address of the QSPI controller registers
  * @refclk:		Pointer to the peripheral clock
@@ -191,7 +195,7 @@ struct qspi_platform_data {
  * @has_tapdelay:	Used for tapdelay register available in qspi
  */
 struct zynqmp_qspi {
-	struct spi_controller *ctlr;
+	struct spi_controller *lower, *upper, *merged;
 	void __iomem *regs;
 	struct clk *refclk;
 	struct clk *pclk;
@@ -467,20 +471,33 @@ static void zynqmp_qspi_copy_read_data(struct zynqmp_qspi *xqspi,
  */
 static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high)
 {
-	struct zynqmp_qspi *xqspi = spi_controller_get_devdata(qspi->controller);
+	struct spi_controller *ctlr = qspi->controller;
+	struct zynqmp_qspi *xqspi = spi_controller_get_devdata(ctlr);
 	ulong timeout;
 	u32 genfifoentry = 0, statusreg;
 
 	genfifoentry |= GQSPI_GENFIFO_MODE_SPI;
 
 	if (!is_high) {
-		if (!spi_get_chipselect(qspi, 0)) {
-			xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER;
-			xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER;
+		bool upper;
+
+		if (ctlr == xqspi->lower) {
+			upper = false;
+		} else if (ctlr == xqspi->upper) {
+			upper = true;
 		} else {
+			WARN_ON_ONCE(ctlr != xqspi->merged);
+			upper = spi_get_chipselect(qspi, 0);
+		}
+
+		if (upper) {
 			xqspi->genfifobus = GQSPI_GENFIFO_BUS_UPPER;
 			xqspi->genfifocs = GQSPI_GENFIFO_CS_UPPER;
+		} else {
+			xqspi->genfifobus = GQSPI_GENFIFO_BUS_LOWER;
+			xqspi->genfifocs = GQSPI_GENFIFO_CS_LOWER;
 		}
+
 		genfifoentry |= xqspi->genfifobus;
 		genfifoentry |= xqspi->genfifocs;
 		genfifoentry |= GQSPI_GENFIFO_CS_SETUP;
@@ -962,12 +979,28 @@ static int zynqmp_qspi_read_op(struct zynqmp_qspi *xqspi, u8 rx_nbits,
 static int __maybe_unused zynqmp_qspi_suspend(struct device *dev)
 {
 	struct zynqmp_qspi *xqspi = dev_get_drvdata(dev);
-	struct spi_controller *ctlr = xqspi->ctlr;
 	int ret;
 
-	ret = spi_controller_suspend(ctlr);
-	if (ret)
-		return ret;
+	if (xqspi->merged) {
+		ret = spi_controller_suspend(xqspi->merged);
+		if (ret)
+			return ret;
+	} else {
+		if (xqspi->lower) {
+			ret = spi_controller_suspend(xqspi->lower);
+			if (ret)
+				return ret;
+		}
+
+		if (xqspi->upper) {
+			ret = spi_controller_suspend(xqspi->upper);
+			if (ret) {
+				if (xqspi->lower)
+					spi_controller_resume(xqspi->lower);
+				return ret;
+			}
+		}
+	}
 
 	zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
 
@@ -986,13 +1019,18 @@ static int __maybe_unused zynqmp_qspi_suspend(struct device *dev)
 static int __maybe_unused zynqmp_qspi_resume(struct device *dev)
 {
 	struct zynqmp_qspi *xqspi = dev_get_drvdata(dev);
-	struct spi_controller *ctlr = xqspi->ctlr;
+	int ret = 0;
 
 	zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, GQSPI_EN_MASK);
 
-	spi_controller_resume(ctlr);
+	if (xqspi->merged)
+		ret = spi_controller_resume(xqspi->merged);
+	if (xqspi->lower)
+		ret = spi_controller_resume(xqspi->lower) ?: ret;
+	if (xqspi->upper)
+		ret = spi_controller_resume(xqspi->upper) ?: ret;
 
-	return 0;
+	return ret;
 }
 
 /**
@@ -1253,6 +1291,41 @@ static const struct spi_controller_mem_ops zynqmp_qspi_mem_ops = {
 	.exec_op = zynqmp_qspi_exec_op,
 };
 
+static void zynqmp_qspi_release_node(void *of_node)
+{
+	of_node_put(of_node);
+}
+
+static struct spi_controller *
+zynqmp_qspi_alloc_split(struct zynqmp_qspi *xqspi, const char *name)
+{
+	struct spi_controller *ctlr;
+	struct device_node *np;
+	u32 num_cs;
+	int err;
+
+	np = of_get_child_by_name(xqspi->dev->of_node, name);
+	if (!np)
+		return NULL;
+
+	err = devm_add_action_or_reset(xqspi->dev, zynqmp_qspi_release_node,
+				       np);
+	if (err)
+		return ERR_PTR(err);
+
+	ctlr = devm_spi_alloc_host(xqspi->dev, 0);
+	if (!ctlr)
+		return ERR_PTR(-ENOMEM);
+
+	ctlr->dev.of_node = np;
+	if (of_property_read_u32(np, "num-cs", &num_cs))
+		ctlr->num_chipselect = GQSPI_DEFAULT_NUM_CS;
+	else
+		ctlr->num_chipselect = num_cs;
+
+	return ctlr;
+}
+
 static int zynqmp_qspi_register_ctlr(struct zynqmp_qspi *xqspi,
 				     struct spi_controller *ctlr)
 {
@@ -1261,6 +1334,7 @@ static int zynqmp_qspi_register_ctlr(struct zynqmp_qspi *xqspi,
 	if (!ctlr)
 		return 0;
 
+	spi_controller_set_devdata(ctlr, xqspi);
 	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
 		SPI_TX_DUAL | SPI_TX_QUAD;
 	ctlr->max_speed_hz = xqspi->speed_hz;
@@ -1287,22 +1361,47 @@ static int zynqmp_qspi_register_ctlr(struct zynqmp_qspi *xqspi,
 static int zynqmp_qspi_probe(struct platform_device *pdev)
 {
 	int ret = 0;
-	struct spi_controller *ctlr;
 	struct zynqmp_qspi *xqspi;
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	u32 num_cs;
 	const struct qspi_platform_data *p_data;
 
-	ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*xqspi));
-	if (!ctlr)
+	xqspi = devm_kzalloc(dev, sizeof(*xqspi), GFP_KERNEL);
+	if (!xqspi)
 		return -ENOMEM;
 
-	xqspi = spi_controller_get_devdata(ctlr);
 	xqspi->dev = dev;
-	xqspi->ctlr = ctlr;
 	platform_set_drvdata(pdev, xqspi);
 
+	xqspi->lower = zynqmp_qspi_alloc_split(xqspi, "spi-lower");
+	if (IS_ERR(xqspi->lower))
+		return PTR_ERR(xqspi->lower);
+
+	xqspi->upper = zynqmp_qspi_alloc_split(xqspi, "spi-upper");
+	if (IS_ERR(xqspi->upper))
+		return PTR_ERR(xqspi->upper);
+
+	if (!xqspi->lower && !xqspi->upper) {
+		struct spi_controller *ctlr = devm_spi_alloc_host(dev, 0);
+		u32 num_cs;
+
+		if (!ctlr)
+			return -ENOMEM;
+
+		ret = of_property_read_u32(dev->of_node, "num-cs", &num_cs);
+		if (ret < 0) {
+			ctlr->num_chipselect = GQSPI_DEFAULT_NUM_CS;
+		} else if (num_cs > GQSPI_MAX_NUM_CS) {
+			dev_err(dev, "only %d chip selects are available\n",
+				GQSPI_MAX_NUM_CS);
+			return -EINVAL;
+		} else {
+			ctlr->num_chipselect = num_cs;
+		}
+
+		ctlr->dev.of_node = dev->of_node;
+		xqspi->merged = ctlr;
+	}
+
 	p_data = of_device_get_match_data(&pdev->dev);
 	if (p_data && (p_data->quirks & QSPI_QUIRK_HAS_TAPDELAY))
 		xqspi->has_tapdelay = true;
@@ -1375,19 +1474,15 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
 	if (ret)
 		goto clk_dis_all;
 
-	ret = of_property_read_u32(np, "num-cs", &num_cs);
-	if (ret < 0) {
-		ctlr->num_chipselect = GQSPI_DEFAULT_NUM_CS;
-	} else if (num_cs > GQSPI_MAX_NUM_CS) {
-		ret = -EINVAL;
-		dev_err(&pdev->dev, "only %d chip selects are available\n",
-			GQSPI_MAX_NUM_CS);
+	ret = zynqmp_qspi_register_ctlr(xqspi, xqspi->lower);
+	if (ret)
 		goto clk_dis_all;
-	} else {
-		ctlr->num_chipselect = num_cs;
-	}
 
-	ret = zynqmp_qspi_register_ctlr(xqspi, ctlr);
+	ret = zynqmp_qspi_register_ctlr(xqspi, xqspi->upper);
+	if (ret)
+		goto clk_dis_all;
+
+	ret = zynqmp_qspi_register_ctlr(xqspi, xqspi->merged);
 	if (ret)
 		goto clk_dis_all;
 
