[openwrt/openwrt] realtek: backport NAND driver for RTL93xx

LEDE Commits lede-commits at lists.infradead.org
Wed Jul 30 14:22:28 PDT 2025


robimarko pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/41b0340ff084321a4b39df8cb2cf624dd7acc57f

commit 41b0340ff084321a4b39df8cb2cf624dd7acc57f
Author: Markus Stockhausen <markus.stockhausen at gmx.de>
AuthorDate: Mon Jul 28 10:13:26 2025 -0400

    realtek: backport NAND driver for RTL93xx
    
    RTL93xx devices have a NAND controller built in. Upstream already
    has a driver in place. Include it downstream. Activate it in the
    RTL93xx builds and disable it for the RTL83xx builds.
    
    Signed-off-by: Markus Stockhausen <markus.stockhausen at gmx.de>
    Link: https://github.com/openwrt/openwrt/pull/19583
    Signed-off-by: Robert Marko <robimarko at gmail.com>
---
 ...v6.13-spi-mem-add-realtek-nand-controller.patch | 481 +++++++++++++++++++++
 ...-rtl-snand-correctly-handle-dma-transfers.patch |  96 ++++
 target/linux/realtek/rtl838x/config-6.12           |   1 +
 target/linux/realtek/rtl839x/config-6.12           |   1 +
 target/linux/realtek/rtl930x/config-6.12           |   2 +
 target/linux/realtek/rtl931x/config-6.12           |   2 +
 6 files changed, 583 insertions(+)

diff --git a/target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch b/target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch
new file mode 100644
index 0000000000..ab630a0ee4
--- /dev/null
+++ b/target/linux/realtek/patches-6.12/001-v6.13-spi-mem-add-realtek-nand-controller.patch
@@ -0,0 +1,481 @@
+From 42d20a6a61b8fccbb57d80df1ccde7dd82d5bbd6 Mon Sep 17 00:00:00 2001
+From: Chris Packham <chris.packham at alliedtelesis.co.nz>
+Date: Wed, 16 Oct 2024 11:54:34 +1300
+Subject: [PATCH] spi: spi-mem: Add Realtek SPI-NAND controller
+
+Add a driver for the SPI-NAND controller on the RTL9300 family of
+devices.
+
+The controller supports
+* Serial/Dual/Quad data with
+* PIO and DMA data read/write operation
+* Configurable flash access timing
+
+There is a separate ECC controller on the RTL9300 which isn't currently
+supported (instead we rely on the on-die ECC supported by most SPI-NAND
+chips).
+
+Signed-off-by: Chris Packham <chris.packham at alliedtelesis.co.nz>
+Link: https://patch.msgid.link/20241015225434.3970360-4-chris.packham@alliedtelesis.co.nz
+Signed-off-by: Mark Brown <broonie at kernel.org>
+---
+ MAINTAINERS                         |   6 +
+ drivers/spi/Kconfig                 |  11 +
+ drivers/spi/Makefile                |   1 +
+ drivers/spi/spi-realtek-rtl-snand.c | 405 ++++++++++++++++++++++++++++
+ 4 files changed, 423 insertions(+)
+ create mode 100644 drivers/spi/spi-realtek-rtl-snand.c
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -19494,6 +19494,12 @@ S:	Maintained
+ F:	Documentation/devicetree/bindings/net/dsa/realtek.yaml
+ F:	drivers/net/dsa/realtek/*
+ 
++REALTEK SPI-NAND
++M:	Chris Packham <chris.packham at alliedtelesis.co.nz>
++S:	Maintained
++F:	Documentation/devicetree/bindings/spi/realtek,rtl9301-snand.yaml
++F:	drivers/spi/spi-realtek-rtl-snand.c
++
+ REALTEK WIRELESS DRIVER (rtlwifi family)
+ M:	Ping-Ke Shih <pkshih at realtek.com>
+ L:	linux-wireless at vger.kernel.org
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -843,6 +843,17 @@ config SPI_PXA2XX
+ config SPI_PXA2XX_PCI
+ 	def_tristate SPI_PXA2XX && PCI && COMMON_CLK
+ 
++config SPI_REALTEK_SNAND
++	tristate "Realtek SPI-NAND Flash Controller"
++	depends on MACH_REALTEK_RTL || COMPILE_TEST
++	select REGMAP
++	help
++	  This enables support for the SPI-NAND Flash controller on
++	  Realtek SoCs.
++
++	  This driver does not support generic SPI. The implementation
++	  only supports the spi-mem interface.
++
+ config SPI_ROCKCHIP
+ 	tristate "Rockchip SPI controller driver"
+ 	depends on ARCH_ROCKCHIP || COMPILE_TEST
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -120,6 +120,7 @@ obj-$(CONFIG_SPI_ROCKCHIP)		+= spi-rockc
+ obj-$(CONFIG_SPI_ROCKCHIP_SFC)		+= spi-rockchip-sfc.o
+ obj-$(CONFIG_SPI_RB4XX)			+= spi-rb4xx.o
+ obj-$(CONFIG_MACH_REALTEK_RTL)		+= spi-realtek-rtl.o
++obj-$(CONFIG_SPI_REALTEK_SNAND)		+= spi-realtek-rtl-snand.o
+ obj-$(CONFIG_SPI_RPCIF)			+= spi-rpc-if.o
+ obj-$(CONFIG_SPI_RSPI)			+= spi-rspi.o
+ obj-$(CONFIG_SPI_RZV2M_CSI)		+= spi-rzv2m-csi.o
+--- /dev/null
++++ b/drivers/spi/spi-realtek-rtl-snand.c
+@@ -0,0 +1,405 @@
++// SPDX-License-Identifier: GPL-2.0-only
++
++#include <linux/completion.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/mod_devicetable.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spi-mem.h>
++
++#define SNAFCFR 0x00
++#define   SNAFCFR_DMA_IE BIT(20)
++#define SNAFCCR 0x04
++#define SNAFWCMR 0x08
++#define SNAFRCMR 0x0c
++#define SNAFRDR 0x10
++#define SNAFWDR 0x14
++#define SNAFDTR 0x18
++#define SNAFDRSAR 0x1c
++#define SNAFDIR 0x20
++#define   SNAFDIR_DMA_IP BIT(0)
++#define SNAFDLR 0x24
++#define SNAFSR 0x40
++#define  SNAFSR_NFCOS BIT(3)
++#define  SNAFSR_NFDRS BIT(2)
++#define  SNAFSR_NFDWS BIT(1)
++
++#define CMR_LEN(len) ((len) - 1)
++#define CMR_WID(width) (((width) >> 1) << 28)
++
++struct rtl_snand {
++	struct device *dev;
++	struct regmap *regmap;
++	struct completion comp;
++};
++
++static irqreturn_t rtl_snand_irq(int irq, void *data)
++{
++	struct rtl_snand *snand = data;
++	u32 val = 0;
++
++	regmap_read(snand->regmap, SNAFSR, &val);
++	if (val & (SNAFSR_NFCOS | SNAFSR_NFDRS | SNAFSR_NFDWS))
++		return IRQ_NONE;
++
++	regmap_write(snand->regmap, SNAFDIR, SNAFDIR_DMA_IP);
++	complete(&snand->comp);
++
++	return IRQ_HANDLED;
++}
++
++static bool rtl_snand_supports_op(struct spi_mem *mem,
++				  const struct spi_mem_op *op)
++{
++	if (!spi_mem_default_supports_op(mem, op))
++		return false;
++	if (op->cmd.nbytes != 1 || op->cmd.buswidth != 1)
++		return false;
++	return true;
++}
++
++static void rtl_snand_set_cs(struct rtl_snand *snand, int cs, bool active)
++{
++	u32 val;
++
++	if (active)
++		val = ~(1 << (4 * cs));
++	else
++		val = ~0;
++
++	regmap_write(snand->regmap, SNAFCCR, val);
++}
++
++static int rtl_snand_wait_ready(struct rtl_snand *snand)
++{
++	u32 val;
++
++	return regmap_read_poll_timeout(snand->regmap, SNAFSR, val, !(val & SNAFSR_NFCOS),
++					0, 2 * USEC_PER_MSEC);
++}
++
++static int rtl_snand_xfer_head(struct rtl_snand *snand, int cs, const struct spi_mem_op *op)
++{
++	int ret;
++	u32 val, len = 0;
++
++	rtl_snand_set_cs(snand, cs, true);
++
++	val = op->cmd.opcode << 24;
++	len = 1;
++	if (op->addr.nbytes && op->addr.buswidth == 1) {
++		val |= op->addr.val << ((3 - op->addr.nbytes) * 8);
++		len += op->addr.nbytes;
++	}
++
++	ret = rtl_snand_wait_ready(snand);
++	if (ret)
++		return ret;
++
++	ret = regmap_write(snand->regmap, SNAFWCMR, CMR_LEN(len));
++	if (ret)
++		return ret;
++
++	ret = regmap_write(snand->regmap, SNAFWDR, val);
++	if (ret)
++		return ret;
++
++	ret = rtl_snand_wait_ready(snand);
++	if (ret)
++		return ret;
++
++	if (op->addr.buswidth > 1) {
++		val = op->addr.val << ((3 - op->addr.nbytes) * 8);
++		len = op->addr.nbytes;
++
++		ret = regmap_write(snand->regmap, SNAFWCMR,
++				   CMR_WID(op->addr.buswidth) | CMR_LEN(len));
++		if (ret)
++			return ret;
++
++		ret = regmap_write(snand->regmap, SNAFWDR, val);
++		if (ret)
++			return ret;
++
++		ret = rtl_snand_wait_ready(snand);
++		if (ret)
++			return ret;
++	}
++
++	if (op->dummy.nbytes) {
++		val = 0;
++
++		ret = regmap_write(snand->regmap, SNAFWCMR,
++				   CMR_WID(op->dummy.buswidth) | CMR_LEN(op->dummy.nbytes));
++		if (ret)
++			return ret;
++
++		ret = regmap_write(snand->regmap, SNAFWDR, val);
++		if (ret)
++			return ret;
++
++		ret = rtl_snand_wait_ready(snand);
++		if (ret)
++			return ret;
++	}
++
++	return 0;
++}
++
++static void rtl_snand_xfer_tail(struct rtl_snand *snand, int cs)
++{
++	rtl_snand_set_cs(snand, cs, false);
++}
++
++static int rtl_snand_xfer(struct rtl_snand *snand, int cs, const struct spi_mem_op *op)
++{
++	unsigned int pos, nbytes;
++	int ret;
++	u32 val, len = 0;
++
++	ret = rtl_snand_xfer_head(snand, cs, op);
++	if (ret)
++		goto out_deselect;
++
++	if (op->data.dir == SPI_MEM_DATA_IN) {
++		pos = 0;
++		len = op->data.nbytes;
++
++		while (pos < len) {
++			nbytes = len - pos;
++			if (nbytes > 4)
++				nbytes = 4;
++
++			ret = rtl_snand_wait_ready(snand);
++			if (ret)
++				goto out_deselect;
++
++			ret = regmap_write(snand->regmap, SNAFRCMR,
++					   CMR_WID(op->data.buswidth) | CMR_LEN(nbytes));
++			if (ret)
++				goto out_deselect;
++
++			ret = rtl_snand_wait_ready(snand);
++			if (ret)
++				goto out_deselect;
++
++			ret = regmap_read(snand->regmap, SNAFRDR, &val);
++			if (ret)
++				goto out_deselect;
++
++			memcpy(op->data.buf.in + pos, &val, nbytes);
++
++			pos += nbytes;
++		}
++	} else if (op->data.dir == SPI_MEM_DATA_OUT) {
++		pos = 0;
++		len = op->data.nbytes;
++
++		while (pos < len) {
++			nbytes = len - pos;
++			if (nbytes > 4)
++				nbytes = 4;
++
++			memcpy(&val, op->data.buf.out + pos, nbytes);
++
++			pos += nbytes;
++
++			ret = regmap_write(snand->regmap, SNAFWCMR, CMR_LEN(nbytes));
++			if (ret)
++				goto out_deselect;
++
++			ret = regmap_write(snand->regmap, SNAFWDR, val);
++			if (ret)
++				goto out_deselect;
++
++			ret = rtl_snand_wait_ready(snand);
++			if (ret)
++				goto out_deselect;
++		}
++	}
++
++out_deselect:
++	rtl_snand_xfer_tail(snand, cs);
++
++	if (ret)
++		dev_err(snand->dev, "transfer failed %d\n", ret);
++
++	return ret;
++}
++
++static int rtl_snand_dma_xfer(struct rtl_snand *snand, int cs, const struct spi_mem_op *op)
++{
++	int ret;
++	dma_addr_t buf_dma;
++	enum dma_data_direction dir;
++	u32 trig;
++
++	ret = rtl_snand_xfer_head(snand, cs, op);
++	if (ret)
++		goto out_deselect;
++
++	if (op->data.dir == SPI_MEM_DATA_IN) {
++		dir = DMA_FROM_DEVICE;
++		trig = 0;
++	} else if (op->data.dir == SPI_MEM_DATA_OUT) {
++		dir = DMA_TO_DEVICE;
++		trig = 1;
++	} else {
++		ret = -EOPNOTSUPP;
++		goto out_deselect;
++	}
++
++	buf_dma = dma_map_single(snand->dev, op->data.buf.in, op->data.nbytes, dir);
++	ret = dma_mapping_error(snand->dev, buf_dma);
++	if (ret)
++		goto out_deselect;
++
++	ret = regmap_write(snand->regmap, SNAFDIR, SNAFDIR_DMA_IP);
++	if (ret)
++		goto out_unmap;
++
++	ret = regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, SNAFCFR_DMA_IE);
++	if (ret)
++		goto out_unmap;
++
++	reinit_completion(&snand->comp);
++
++	ret = regmap_write(snand->regmap, SNAFDRSAR, buf_dma);
++	if (ret)
++		goto out_disable_int;
++
++	ret = regmap_write(snand->regmap, SNAFDLR,
++			   CMR_WID(op->data.buswidth) | (op->data.nbytes & 0xffff));
++	if (ret)
++		goto out_disable_int;
++
++	ret = regmap_write(snand->regmap, SNAFDTR, trig);
++	if (ret)
++		goto out_disable_int;
++
++	if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000)))
++		ret = -ETIMEDOUT;
++
++	if (ret)
++		goto out_disable_int;
++
++out_disable_int:
++	regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, 0);
++out_unmap:
++	dma_unmap_single(snand->dev, buf_dma, op->data.nbytes, dir);
++out_deselect:
++	rtl_snand_xfer_tail(snand, cs);
++
++	if (ret)
++		dev_err(snand->dev, "transfer failed %d\n", ret);
++
++	return ret;
++}
++
++static bool rtl_snand_dma_op(const struct spi_mem_op *op)
++{
++	switch (op->data.dir) {
++	case SPI_MEM_DATA_IN:
++	case SPI_MEM_DATA_OUT:
++		return op->data.nbytes > 32;
++	default:
++		return false;
++	}
++}
++
++static int rtl_snand_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
++{
++	struct rtl_snand *snand = spi_controller_get_devdata(mem->spi->controller);
++	int cs = spi_get_chipselect(mem->spi, 0);
++
++	dev_dbg(snand->dev, "cs %d op cmd %02x %d:%d, dummy %d:%d, addr %08llx@%d:%d, data %d:%d\n",
++		cs, op->cmd.opcode,
++		op->cmd.buswidth, op->cmd.nbytes, op->dummy.buswidth,
++		op->dummy.nbytes, op->addr.val, op->addr.buswidth,
++		op->addr.nbytes, op->data.buswidth, op->data.nbytes);
++
++	if (rtl_snand_dma_op(op))
++		return rtl_snand_dma_xfer(snand, cs, op);
++	else
++		return rtl_snand_xfer(snand, cs, op);
++}
++
++static const struct spi_controller_mem_ops rtl_snand_mem_ops = {
++	.supports_op = rtl_snand_supports_op,
++	.exec_op = rtl_snand_exec_op,
++};
++
++static const struct of_device_id rtl_snand_match[] = {
++	{ .compatible = "realtek,rtl9301-snand" },
++	{ .compatible = "realtek,rtl9302b-snand" },
++	{ .compatible = "realtek,rtl9302c-snand" },
++	{ .compatible = "realtek,rtl9303-snand" },
++	{},
++};
++MODULE_DEVICE_TABLE(of, rtl_snand_match);
++
++static int rtl_snand_probe(struct platform_device *pdev)
++{
++	struct rtl_snand *snand;
++	struct device *dev = &pdev->dev;
++	struct spi_controller *ctrl;
++	void __iomem *base;
++	const struct regmap_config rc = {
++		.reg_bits	= 32,
++		.val_bits	= 32,
++		.reg_stride	= 4,
++		.cache_type	= REGCACHE_NONE,
++	};
++	int irq, ret;
++
++	ctrl = devm_spi_alloc_host(dev, sizeof(*snand));
++	if (!ctrl)
++		return -ENOMEM;
++
++	snand = spi_controller_get_devdata(ctrl);
++	snand->dev = dev;
++
++	base = devm_platform_ioremap_resource(pdev, 0);
++	if (IS_ERR(base))
++		return PTR_ERR(base);
++
++	snand->regmap = devm_regmap_init_mmio(dev, base, &rc);
++	if (IS_ERR(snand->regmap))
++		return PTR_ERR(snand->regmap);
++
++	init_completion(&snand->comp);
++
++	irq = platform_get_irq(pdev, 0);
++	if (irq < 0)
++		return irq;
++
++	ret = dma_set_mask(snand->dev, DMA_BIT_MASK(32));
++	if (ret)
++		return dev_err_probe(dev, ret, "failed to set DMA mask\n");
++
++	ret = devm_request_irq(dev, irq, rtl_snand_irq, 0, "rtl-snand", snand);
++	if (ret)
++		return dev_err_probe(dev, ret, "failed to request irq\n");
++
++	ctrl->num_chipselect = 2;
++	ctrl->mem_ops = &rtl_snand_mem_ops;
++	ctrl->bits_per_word_mask = SPI_BPW_MASK(8);
++	ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD;
++	device_set_node(&ctrl->dev, dev_fwnode(dev));
++
++	return devm_spi_register_controller(dev, ctrl);
++}
++
++static struct platform_driver rtl_snand_driver = {
++	.driver = {
++		.name = "realtek-rtl-snand",
++		.of_match_table = rtl_snand_match,
++	},
++	.probe = rtl_snand_probe,
++};
++module_platform_driver(rtl_snand_driver);
++
++MODULE_DESCRIPTION("Realtek SPI-NAND Flash Controller Driver");
++MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch b/target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch
new file mode 100644
index 0000000000..a929c67097
--- /dev/null
+++ b/target/linux/realtek/patches-6.12/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch
@@ -0,0 +1,96 @@
+From 25d284715845a465a1a3693a09cf8b6ab8bd9caf Mon Sep 17 00:00:00 2001
+From: Chris Packham <chris.packham at alliedtelesis.co.nz>
+Date: Thu, 31 Oct 2024 08:49:20 +1300
+Subject: [PATCH] spi: spi-mem: rtl-snand: Correctly handle DMA transfers
+
+The RTL9300 has some limitations on the maximum DMA transfers possible.
+For reads this is 2080 bytes (520*4) for writes this is 520 bytes. Deal
+with this by splitting transfers into appropriately sized parts.
+
+Fixes: 42d20a6a61b8 ("spi: spi-mem: Add Realtek SPI-NAND controller")
+Signed-off-by: Chris Packham <chris.packham at alliedtelesis.co.nz>
+Link: https://patch.msgid.link/20241030194920.3202282-1-chris.packham@alliedtelesis.co.nz
+Signed-off-by: Mark Brown <broonie at kernel.org>
+---
+ drivers/spi/spi-realtek-rtl-snand.c | 46 +++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 16 deletions(-)
+
+--- a/drivers/spi/spi-realtek-rtl-snand.c
++++ b/drivers/spi/spi-realtek-rtl-snand.c
+@@ -231,19 +231,22 @@ out_deselect:
+ 
+ static int rtl_snand_dma_xfer(struct rtl_snand *snand, int cs, const struct spi_mem_op *op)
+ {
++	unsigned int pos, nbytes;
+ 	int ret;
+ 	dma_addr_t buf_dma;
+ 	enum dma_data_direction dir;
+-	u32 trig;
++	u32 trig, len, maxlen;
+ 
+ 	ret = rtl_snand_xfer_head(snand, cs, op);
+ 	if (ret)
+ 		goto out_deselect;
+ 
+ 	if (op->data.dir == SPI_MEM_DATA_IN) {
++		maxlen = 2080;
+ 		dir = DMA_FROM_DEVICE;
+ 		trig = 0;
+ 	} else if (op->data.dir == SPI_MEM_DATA_OUT) {
++		maxlen = 520;
+ 		dir = DMA_TO_DEVICE;
+ 		trig = 1;
+ 	} else {
+@@ -264,26 +267,37 @@ static int rtl_snand_dma_xfer(struct rtl
+ 	if (ret)
+ 		goto out_unmap;
+ 
+-	reinit_completion(&snand->comp);
++	pos = 0;
++	len = op->data.nbytes;
+ 
+-	ret = regmap_write(snand->regmap, SNAFDRSAR, buf_dma);
+-	if (ret)
+-		goto out_disable_int;
++	while (pos < len) {
++		nbytes = len - pos;
++		if (nbytes > maxlen)
++			nbytes = maxlen;
+ 
+-	ret = regmap_write(snand->regmap, SNAFDLR,
+-			   CMR_WID(op->data.buswidth) | (op->data.nbytes & 0xffff));
+-	if (ret)
+-		goto out_disable_int;
++		reinit_completion(&snand->comp);
+ 
+-	ret = regmap_write(snand->regmap, SNAFDTR, trig);
+-	if (ret)
+-		goto out_disable_int;
++		ret = regmap_write(snand->regmap, SNAFDRSAR, buf_dma + pos);
++		if (ret)
++			goto out_disable_int;
+ 
+-	if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000)))
+-		ret = -ETIMEDOUT;
++		pos += nbytes;
+ 
+-	if (ret)
+-		goto out_disable_int;
++		ret = regmap_write(snand->regmap, SNAFDLR,
++				CMR_WID(op->data.buswidth) | nbytes);
++		if (ret)
++			goto out_disable_int;
++
++		ret = regmap_write(snand->regmap, SNAFDTR, trig);
++		if (ret)
++			goto out_disable_int;
++
++		if (!wait_for_completion_timeout(&snand->comp, usecs_to_jiffies(20000)))
++			ret = -ETIMEDOUT;
++
++		if (ret)
++			goto out_disable_int;
++	}
+ 
+ out_disable_int:
+ 	regmap_update_bits(snand->regmap, SNAFCFR, SNAFCFR_DMA_IE, 0);
diff --git a/target/linux/realtek/rtl838x/config-6.12 b/target/linux/realtek/rtl838x/config-6.12
index 6676ae9660..a7cd07212c 100644
--- a/target/linux/realtek/rtl838x/config-6.12
+++ b/target/linux/realtek/rtl838x/config-6.12
@@ -226,6 +226,7 @@ CONFIG_SFP=y
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 CONFIG_SPI_MEM=y
+# CONFIG_SPI_REALTEK_SNAND is not set
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
 CONFIG_SRAM=y
 CONFIG_SWPHY=y
diff --git a/target/linux/realtek/rtl839x/config-6.12 b/target/linux/realtek/rtl839x/config-6.12
index de849a41c1..15a01c87da 100644
--- a/target/linux/realtek/rtl839x/config-6.12
+++ b/target/linux/realtek/rtl839x/config-6.12
@@ -239,6 +239,7 @@ CONFIG_SOCK_RX_QUEUE_MAPPING=y
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 CONFIG_SPI_MEM=y
+# CONFIG_SPI_REALTEK_SNAND is not set
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
 CONFIG_SRAM=y
 CONFIG_SWPHY=y
diff --git a/target/linux/realtek/rtl930x/config-6.12 b/target/linux/realtek/rtl930x/config-6.12
index 531360df5f..74eeac1f00 100644
--- a/target/linux/realtek/rtl930x/config-6.12
+++ b/target/linux/realtek/rtl930x/config-6.12
@@ -137,6 +137,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_SPI_NAND=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
 CONFIG_MTD_SPLIT_EVA_FW=y
@@ -206,6 +207,7 @@ CONFIG_SFP=y
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 CONFIG_SPI_MEM=y
+CONFIG_SPI_REALTEK_SNAND=y
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
 CONFIG_SWPHY=y
 CONFIG_SYSCTL_EXCEPTION_TRACE=y
diff --git a/target/linux/realtek/rtl931x/config-6.12 b/target/linux/realtek/rtl931x/config-6.12
index 8d79bcbec2..8d2a3553b4 100644
--- a/target/linux/realtek/rtl931x/config-6.12
+++ b/target/linux/realtek/rtl931x/config-6.12
@@ -153,6 +153,7 @@ CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_GEOMETRY=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_SPI_NAND=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
 CONFIG_MTD_SPLIT_EVA_FW=y
@@ -227,6 +228,7 @@ CONFIG_SOCK_RX_QUEUE_MAPPING=y
 CONFIG_SPI=y
 CONFIG_SPI_MASTER=y
 CONFIG_SPI_MEM=y
+CONFIG_SPI_REALTEK_SNAND=y
 CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
 CONFIG_SWPHY=y
 CONFIG_SYNC_R4K=y




More information about the lede-commits mailing list