]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
realtek: 6.18: remove obsolete patches
authorJonas Jelonek <jelonek.jonas@gmail.com>
Wed, 21 Jan 2026 23:17:04 +0000 (23:17 +0000)
committerRobert Marko <robimarko@gmail.com>
Sun, 29 Mar 2026 16:08:21 +0000 (18:08 +0200)
Remove patches which are accepted upstream and were backported to
pre-6.18. Those are obsolete now.

Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/21181
Signed-off-by: Robert Marko <robimarko@gmail.com>
26 files changed:
target/linux/realtek/patches-6.18/001-v6.13-spi-mem-add-realtek-nand-controller.patch [deleted file]
target/linux/realtek/patches-6.18/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch [deleted file]
target/linux/realtek/patches-6.18/003-v6.13-01-dt-bindings-i2c-Add-Realtek-RTL-I2C-Controller.patch [deleted file]
target/linux/realtek/patches-6.18/003-v6.13-02-i2c-Add-driver-for-the-RTL9300-I2C-controller.patch [deleted file]
target/linux/realtek/patches-6.18/004-v6.16-dt-bindings-i2c-realtek-rtl9301-Fix-missing-reg-cons.patch [deleted file]
target/linux/realtek/patches-6.18/005-01-v6.17-i2c-rtl9300-Fix-out-of-bounds-bug-in-rtl9300_i2c_smb.patch [deleted file]
target/linux/realtek/patches-6.18/005-02-v6.17-i2c-rtl9300-Fix-multi-byte-I2C-write.patch [deleted file]
target/linux/realtek/patches-6.18/005-03-v6.17-i2c-rtl9300-Increase-timeout-for-transfer-polling.patch [deleted file]
target/linux/realtek/patches-6.18/005-04-v6.17-i2c-rtl9300-Add-missing-count-byte-for-SMBus-Block-O.patch [deleted file]
target/linux/realtek/patches-6.18/006-01-v6.17-i2c-rtl9300-fix-channel-number-bound-check.patch [deleted file]
target/linux/realtek/patches-6.18/006-02-v6.17-i2c-rtl9300-ensure-data-length-is-within-supported-r.patch [deleted file]
target/linux/realtek/patches-6.18/006-03-v6.17-i2c-rtl9300-remove-broken-SMBus-Quick-operation-supp.patch [deleted file]
target/linux/realtek/patches-6.18/007-01-v6.17-i2c-rtl9300-Drop-unsupported-I2C_FUNC_SMBUS_I2C_BLOC.patch [deleted file]
target/linux/realtek/patches-6.18/007-02-v6.18-i2c-rtl9300-Implement-I2C-block-read-and-write.patch [deleted file]
target/linux/realtek/patches-6.18/008-01-v6.18-i2c-rtl9300-use-regmap-fields-and-API-for-registers.patch [deleted file]
target/linux/realtek/patches-6.18/008-02-v6.18-dt-bindings-i2c-realtek-rtl9301-i2c-fix-wording-and-.patch [deleted file]
target/linux/realtek/patches-6.18/008-03-v6.18-i2c-rtl9300-rename-internal-sda_pin-to-sda_num.patch [deleted file]
target/linux/realtek/patches-6.18/008-04-v6.18-i2c-rtl9300-move-setting-SCL-frequency-to-config_io.patch [deleted file]
target/linux/realtek/patches-6.18/008-05-v6.18-i2c-rtl9300-do-not-set-read-mode-on-every-transfer.patch [deleted file]
target/linux/realtek/patches-6.18/008-06-v6.18-i2c-rtl9300-separate-xfer-configuration-and-executio.patch [deleted file]
target/linux/realtek/patches-6.18/008-07-v6.18-i2c-rtl9300-use-scoped-guard-instead-of-explicit-loc.patch [deleted file]
target/linux/realtek/patches-6.18/008-08-v6.18-dt-bindings-i2c-realtek-rtl9301-i2c-extend-for-RTL93.patch [deleted file]
target/linux/realtek/patches-6.18/008-09-v6.18-i2c-rtl9300-add-support-for-RTL9310-I2C-controller.patch [deleted file]
target/linux/realtek/patches-6.18/020-02-v6.18-timer-rtl-otto-drop-set-counter-function.patch [deleted file]
target/linux/realtek/patches-6.18/021-v6.18-mtd-nand-add-realtek-ecc-engine.patch [deleted file]
target/linux/realtek/patches-6.18/302-6.17-irqchip-mips-gic-forced-affinity.patch [deleted file]

diff --git a/target/linux/realtek/patches-6.18/001-v6.13-spi-mem-add-realtek-nand-controller.patch b/target/linux/realtek/patches-6.18/001-v6.13-spi-mem-add-realtek-nand-controller.patch
deleted file mode 100644 (file)
index 1828e77..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-From 42d20a6a61b8fccbb57d80df1ccde7dd82d5bbd6 Mon Sep 17 00:00:00 2001
-From: Chris Packham <chris.packham@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@alliedtelesis.co.nz>
-Link: https://patch.msgid.link/20241015225434.3970360-4-chris.packham@alliedtelesis.co.nz
-Signed-off-by: Mark Brown <broonie@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
-@@ -19507,6 +19507,12 @@ S:    Maintained
- F:    Documentation/devicetree/bindings/net/dsa/realtek.yaml
- F:    drivers/net/dsa/realtek/*
-+REALTEK SPI-NAND
-+M:    Chris Packham <chris.packham@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@realtek.com>
- L:    linux-wireless@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.18/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch b/target/linux/realtek/patches-6.18/002-v6.13-spi-mem-rtl-snand-correctly-handle-dma-transfers.patch
deleted file mode 100644 (file)
index a929c67..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-From 25d284715845a465a1a3693a09cf8b6ab8bd9caf Mon Sep 17 00:00:00 2001
-From: Chris Packham <chris.packham@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@alliedtelesis.co.nz>
-Link: https://patch.msgid.link/20241030194920.3202282-1-chris.packham@alliedtelesis.co.nz
-Signed-off-by: Mark Brown <broonie@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/patches-6.18/003-v6.13-01-dt-bindings-i2c-Add-Realtek-RTL-I2C-Controller.patch b/target/linux/realtek/patches-6.18/003-v6.13-01-dt-bindings-i2c-Add-Realtek-RTL-I2C-Controller.patch
deleted file mode 100644 (file)
index 8ec0d04..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-From c5eda0333076e031197816454998a918f1de0831 Mon Sep 17 00:00:00 2001
-From: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Date: Fri, 1 Nov 2024 09:03:46 +1300
-Subject: [PATCH] dt-bindings: i2c: Add Realtek RTL I2C Controller
-
-Add dt-schema for the I2C controller on the RTL9300 Ethernet switch
-with integrated SoC.
-
-Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-@@ -0,0 +1,69 @@
-+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-+%YAML 1.2
-+---
-+$id: http://devicetree.org/schemas/i2c/realtek,rtl9301-i2c.yaml#
-+$schema: http://devicetree.org/meta-schemas/core.yaml#
-+
-+title: Realtek RTL I2C Controller
-+
-+maintainers:
-+  - Chris Packham <chris.packham@alliedtelesis.co.nz>
-+
-+description:
-+  The RTL9300 SoC has two I2C controllers. Each of these has an SCL line (which
-+  if not-used for SCL can be a GPIO). There are 8 common SDA lines that can be
-+  assigned to either I2C controller.
-+
-+properties:
-+  compatible:
-+    oneOf:
-+      - items:
-+          - enum:
-+              - realtek,rtl9302b-i2c
-+              - realtek,rtl9302c-i2c
-+              - realtek,rtl9303-i2c
-+          - const: realtek,rtl9301-i2c
-+      - const: realtek,rtl9301-i2c
-+
-+  reg:
-+    description: Register offset and size this I2C controller.
-+
-+  "#address-cells":
-+    const: 1
-+
-+  "#size-cells":
-+    const: 0
-+
-+patternProperties:
-+  '^i2c@[0-7]$':
-+    $ref: /schemas/i2c/i2c-controller.yaml
-+    unevaluatedProperties: false
-+
-+    properties:
-+      reg:
-+        description: The SDA pin associated with the I2C bus.
-+        maxItems: 1
-+
-+    required:
-+      - reg
-+
-+required:
-+  - compatible
-+  - reg
-+
-+additionalProperties: false
-+
-+examples:
-+  - |
-+    i2c@36c {
-+      compatible = "realtek,rtl9301-i2c";
-+      reg = <0x36c 0x14>;
-+      #address-cells = <1>;
-+      #size-cells = <0>;
-+
-+      i2c@2 {
-+        reg = <2>;
-+        #address-cells = <1>;
-+        #size-cells = <0>;
-+      };
-+    };
diff --git a/target/linux/realtek/patches-6.18/003-v6.13-02-i2c-Add-driver-for-the-RTL9300-I2C-controller.patch b/target/linux/realtek/patches-6.18/003-v6.13-02-i2c-Add-driver-for-the-RTL9300-I2C-controller.patch
deleted file mode 100644 (file)
index d522928..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-From c366be720235301fdadf67e6f1ea6ff32669c074 Mon Sep 17 00:00:00 2001
-From: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Date: Wed, 6 Nov 2024 13:18:35 +1300
-Subject: [PATCH] i2c: Add driver for the RTL9300 I2C controller
-
-Add support for the I2C controller on the RTL9300 SoC. There are two I2C
-controllers in the RTL9300 that are part of the Ethernet switch register
-block. Each of these controllers owns a SCL pin (GPIO8 for the fiorst
-I2C controller, GPIO17 for the second). There are 8 possible SDA pins
-(GPIO9-16) that can be assigned to either I2C controller. This
-relationship is represented in the device tree with a child node for
-each SDA line in use.
-
-This is based on the openwrt implementation[1] but has been
-significantly modified
-
-[1] - https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/realtek/files-5.15/drivers/i2c/busses/i2c-rtl9300.c
-
-Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -20164,6 +20164,13 @@ S:    Maintained
- T:    git https://github.com/pkshih/rtw.git
- F:    drivers/net/wireless/realtek/rtl8xxxu/
-+RTL9300 I2C DRIVER (rtl9300-i2c)
-+M:    Chris Packham <chris.packham@alliedtelesis.co.nz>
-+L:    linux-i2c@vger.kernel.org
-+S:    Maintained
-+F:    Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-+F:    drivers/i2c/busses/i2c-rtl9300.c
-+
- RTRS TRANSPORT DRIVERS
- M:    Md. Haris Iqbal <haris.iqbal@ionos.com>
- M:    Jack Wang <jinpu.wang@ionos.com>
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -1062,6 +1062,16 @@ config I2C_RK3X
-         This driver can also be built as a module. If so, the module will
-         be called i2c-rk3x.
-+config I2C_RTL9300
-+      tristate "Realtek RTL9300 I2C controller"
-+      depends on MACH_REALTEK_RTL || COMPILE_TEST
-+      help
-+        Say Y here to include support for the I2C controller in Realtek
-+        RTL9300 SoCs.
-+
-+        This driver can also be built as a module. If so, the module will
-+        be called i2c-rtl9300.
-+
- config I2C_RZV2M
-       tristate "Renesas RZ/V2M adapter"
-       depends on ARCH_RENESAS || COMPILE_TEST
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -103,6 +103,7 @@ obj-$(CONFIG_I2C_QCOM_GENI)        += i2c-qcom-
- obj-$(CONFIG_I2C_QUP)         += i2c-qup.o
- obj-$(CONFIG_I2C_RIIC)                += i2c-riic.o
- obj-$(CONFIG_I2C_RK3X)                += i2c-rk3x.o
-+obj-$(CONFIG_I2C_RTL9300)     += i2c-rtl9300.o
- obj-$(CONFIG_I2C_RZV2M)               += i2c-rzv2m.o
- obj-$(CONFIG_I2C_S3C2410)     += i2c-s3c2410.o
- obj-$(CONFIG_I2C_SH7760)      += i2c-sh7760.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -0,0 +1,423 @@
-+// SPDX-License-Identifier: GPL-2.0-only
-+
-+#include <linux/bits.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-mux.h>
-+#include <linux/mod_devicetable.h>
-+#include <linux/mfd/syscon.h>
-+#include <linux/mutex.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+enum rtl9300_bus_freq {
-+      RTL9300_I2C_STD_FREQ,
-+      RTL9300_I2C_FAST_FREQ,
-+};
-+
-+struct rtl9300_i2c;
-+
-+struct rtl9300_i2c_chan {
-+      struct i2c_adapter adap;
-+      struct rtl9300_i2c *i2c;
-+      enum rtl9300_bus_freq bus_freq;
-+      u8 sda_pin;
-+};
-+
-+#define RTL9300_I2C_MUX_NCHAN 8
-+
-+struct rtl9300_i2c {
-+      struct regmap *regmap;
-+      struct device *dev;
-+      struct rtl9300_i2c_chan chans[RTL9300_I2C_MUX_NCHAN];
-+      u32 reg_base;
-+      u8 sda_pin;
-+      struct mutex lock;
-+};
-+
-+#define RTL9300_I2C_MST_CTRL1                         0x0
-+#define  RTL9300_I2C_MST_CTRL1_MEM_ADDR_OFS           8
-+#define  RTL9300_I2C_MST_CTRL1_MEM_ADDR_MASK          GENMASK(31, 8)
-+#define  RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_OFS                4
-+#define  RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_MASK               GENMASK(6, 4)
-+#define  RTL9300_I2C_MST_CTRL1_GPIO_SCL_SEL           BIT(3)
-+#define  RTL9300_I2C_MST_CTRL1_RWOP                   BIT(2)
-+#define  RTL9300_I2C_MST_CTRL1_I2C_FAIL                       BIT(1)
-+#define  RTL9300_I2C_MST_CTRL1_I2C_TRIG                       BIT(0)
-+#define RTL9300_I2C_MST_CTRL2                         0x4
-+#define  RTL9300_I2C_MST_CTRL2_RD_MODE                        BIT(15)
-+#define  RTL9300_I2C_MST_CTRL2_DEV_ADDR_OFS           8
-+#define  RTL9300_I2C_MST_CTRL2_DEV_ADDR_MASK          GENMASK(14, 8)
-+#define  RTL9300_I2C_MST_CTRL2_DATA_WIDTH_OFS         4
-+#define  RTL9300_I2C_MST_CTRL2_DATA_WIDTH_MASK                GENMASK(7, 4)
-+#define  RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_OFS     2
-+#define  RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_MASK    GENMASK(3, 2)
-+#define  RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS           0
-+#define  RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK          GENMASK(1, 0)
-+#define RTL9300_I2C_MST_DATA_WORD0                    0x8
-+#define RTL9300_I2C_MST_DATA_WORD1                    0xc
-+#define RTL9300_I2C_MST_DATA_WORD2                    0x10
-+#define RTL9300_I2C_MST_DATA_WORD3                    0x14
-+
-+#define RTL9300_I2C_MST_GLB_CTRL                      0x384
-+
-+static int rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len)
-+{
-+      u32 val, mask;
-+      int ret;
-+
-+      val = len << RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_OFS;
-+      mask = RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_MASK;
-+
-+      ret = regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL2, mask, val);
-+      if (ret)
-+              return ret;
-+
-+      val = reg << RTL9300_I2C_MST_CTRL1_MEM_ADDR_OFS;
-+      mask = RTL9300_I2C_MST_CTRL1_MEM_ADDR_MASK;
-+
-+      return regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val);
-+}
-+
-+static int rtl9300_i2c_config_io(struct rtl9300_i2c *i2c, u8 sda_pin)
-+{
-+      int ret;
-+      u32 val, mask;
-+
-+      ret = regmap_update_bits(i2c->regmap, RTL9300_I2C_MST_GLB_CTRL, BIT(sda_pin), BIT(sda_pin));
-+      if (ret)
-+              return ret;
-+
-+      val = (sda_pin << RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_OFS) |
-+              RTL9300_I2C_MST_CTRL1_GPIO_SCL_SEL;
-+      mask = RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_MASK | RTL9300_I2C_MST_CTRL1_GPIO_SCL_SEL;
-+
-+      return regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val);
-+}
-+
-+static int rtl9300_i2c_config_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan,
-+                                 u16 addr, u16 len)
-+{
-+      u32 val, mask;
-+
-+      val = chan->bus_freq << RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS;
-+      mask = RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK;
-+
-+      val |= addr << RTL9300_I2C_MST_CTRL2_DEV_ADDR_OFS;
-+      mask |= RTL9300_I2C_MST_CTRL2_DEV_ADDR_MASK;
-+
-+      val |= ((len - 1) & 0xf) << RTL9300_I2C_MST_CTRL2_DATA_WIDTH_OFS;
-+      mask |= RTL9300_I2C_MST_CTRL2_DATA_WIDTH_MASK;
-+
-+      mask |= RTL9300_I2C_MST_CTRL2_RD_MODE;
-+
-+      return regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL2, mask, val);
-+}
-+
-+static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len)
-+{
-+      u32 vals[4] = {};
-+      int i, ret;
-+
-+      if (len > 16)
-+              return -EIO;
-+
-+      ret = regmap_bulk_read(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
-+                             vals, ARRAY_SIZE(vals));
-+      if (ret)
-+              return ret;
-+
-+      for (i = 0; i < len; i++) {
-+              buf[i] = vals[i/4] & 0xff;
-+              vals[i/4] >>= 8;
-+      }
-+
-+      return 0;
-+}
-+
-+static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, int len)
-+{
-+      u32 vals[4] = {};
-+      int i;
-+
-+      if (len > 16)
-+              return -EIO;
-+
-+      for (i = 0; i < len; i++) {
-+              if (i % 4 == 0)
-+                      vals[i/4] = 0;
-+              vals[i/4] <<= 8;
-+              vals[i/4] |= buf[i];
-+      }
-+
-+      return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
-+                              vals, ARRAY_SIZE(vals));
-+}
-+
-+static int rtl9300_i2c_writel(struct rtl9300_i2c *i2c, u32 data)
-+{
-+      return regmap_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, data);
-+}
-+
-+static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write,
-+                                  int size, union i2c_smbus_data *data, int len)
-+{
-+      u32 val, mask;
-+      int ret;
-+
-+      val = read_write == I2C_SMBUS_WRITE ? RTL9300_I2C_MST_CTRL1_RWOP : 0;
-+      mask = RTL9300_I2C_MST_CTRL1_RWOP;
-+
-+      val |= RTL9300_I2C_MST_CTRL1_I2C_TRIG;
-+      mask |= RTL9300_I2C_MST_CTRL1_I2C_TRIG;
-+
-+      ret = regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1,
-+                                     val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 2000);
-+      if (ret)
-+              return ret;
-+
-+      if (val & RTL9300_I2C_MST_CTRL1_I2C_FAIL)
-+              return -EIO;
-+
-+      if (read_write == I2C_SMBUS_READ) {
-+              if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA) {
-+                      ret = regmap_read(i2c->regmap,
-+                                        i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val);
-+                      if (ret)
-+                              return ret;
-+                      data->byte = val & 0xff;
-+              } else if (size == I2C_SMBUS_WORD_DATA) {
-+                      ret = regmap_read(i2c->regmap,
-+                                        i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val);
-+                      if (ret)
-+                              return ret;
-+                      data->word = val & 0xffff;
-+              } else {
-+                      ret = rtl9300_i2c_read(i2c, &data->block[0], len);
-+                      if (ret)
-+                              return ret;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+static int rtl9300_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags,
-+                                char read_write, u8 command, int size,
-+                                union i2c_smbus_data *data)
-+{
-+      struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
-+      struct rtl9300_i2c *i2c = chan->i2c;
-+      int len = 0, ret;
-+
-+      mutex_lock(&i2c->lock);
-+      if (chan->sda_pin != i2c->sda_pin) {
-+              ret = rtl9300_i2c_config_io(i2c, chan->sda_pin);
-+              if (ret)
-+                      goto out_unlock;
-+              i2c->sda_pin = chan->sda_pin;
-+      }
-+
-+      switch (size) {
-+      case I2C_SMBUS_QUICK:
-+              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
-+              if (ret)
-+                      goto out_unlock;
-+              ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
-+              if (ret)
-+                      goto out_unlock;
-+              break;
-+
-+      case I2C_SMBUS_BYTE:
-+              if (read_write == I2C_SMBUS_WRITE) {
-+                      ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
-+                      if (ret)
-+                              goto out_unlock;
-+                      ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
-+                      if (ret)
-+                              goto out_unlock;
-+              } else {
-+                      ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 1);
-+                      if (ret)
-+                              goto out_unlock;
-+                      ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
-+                      if (ret)
-+                              goto out_unlock;
-+              }
-+              break;
-+
-+      case I2C_SMBUS_BYTE_DATA:
-+              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
-+              if (ret)
-+                      goto out_unlock;
-+              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 1);
-+              if (ret)
-+                      goto out_unlock;
-+              if (read_write == I2C_SMBUS_WRITE) {
-+                      ret = rtl9300_i2c_writel(i2c, data->byte);
-+                      if (ret)
-+                              goto out_unlock;
-+              }
-+              break;
-+
-+      case I2C_SMBUS_WORD_DATA:
-+              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
-+              if (ret)
-+                      goto out_unlock;
-+              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 2);
-+              if (ret)
-+                      goto out_unlock;
-+              if (read_write == I2C_SMBUS_WRITE) {
-+                      ret = rtl9300_i2c_writel(i2c, data->word);
-+                      if (ret)
-+                              goto out_unlock;
-+              }
-+              break;
-+
-+      case I2C_SMBUS_BLOCK_DATA:
-+              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
-+              if (ret)
-+                      goto out_unlock;
-+              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]);
-+              if (ret)
-+                      goto out_unlock;
-+              if (read_write == I2C_SMBUS_WRITE) {
-+                      ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]);
-+                      if (ret)
-+                              goto out_unlock;
-+              }
-+              len = data->block[0];
-+              break;
-+
-+      default:
-+              dev_err(&adap->dev, "Unsupported transaction %d\n", size);
-+              ret = -EOPNOTSUPP;
-+              goto out_unlock;
-+      }
-+
-+      ret = rtl9300_i2c_execute_xfer(i2c, read_write, size, data, len);
-+
-+out_unlock:
-+      mutex_unlock(&i2c->lock);
-+
-+      return ret;
-+}
-+
-+static u32 rtl9300_i2c_func(struct i2c_adapter *a)
-+{
-+      return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
-+             I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
-+             I2C_FUNC_SMBUS_BLOCK_DATA;
-+}
-+
-+static const struct i2c_algorithm rtl9300_i2c_algo = {
-+      .smbus_xfer     = rtl9300_i2c_smbus_xfer,
-+      .functionality  = rtl9300_i2c_func,
-+};
-+
-+static struct i2c_adapter_quirks rtl9300_i2c_quirks = {
-+      .flags          = I2C_AQ_NO_CLK_STRETCH,
-+      .max_read_len   = 16,
-+      .max_write_len  = 16,
-+};
-+
-+static int rtl9300_i2c_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct rtl9300_i2c *i2c;
-+      u32 clock_freq, sda_pin;
-+      int ret, i = 0;
-+      struct fwnode_handle *child;
-+
-+      i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
-+      if (!i2c)
-+              return -ENOMEM;
-+
-+      i2c->regmap = syscon_node_to_regmap(dev->parent->of_node);
-+      if (IS_ERR(i2c->regmap))
-+              return PTR_ERR(i2c->regmap);
-+      i2c->dev = dev;
-+
-+      mutex_init(&i2c->lock);
-+
-+      ret = device_property_read_u32(dev, "reg", &i2c->reg_base);
-+      if (ret)
-+              return ret;
-+
-+      platform_set_drvdata(pdev, i2c);
-+
-+      if (device_get_child_node_count(dev) >= RTL9300_I2C_MUX_NCHAN)
-+              return dev_err_probe(dev, -EINVAL, "Too many channels\n");
-+
-+      device_for_each_child_node(dev, child) {
-+              struct rtl9300_i2c_chan *chan = &i2c->chans[i];
-+              struct i2c_adapter *adap = &chan->adap;
-+
-+              ret = fwnode_property_read_u32(child, "reg", &sda_pin);
-+              if (ret)
-+                      return ret;
-+
-+              ret = fwnode_property_read_u32(child, "clock-frequency", &clock_freq);
-+              if (ret)
-+                      clock_freq = I2C_MAX_STANDARD_MODE_FREQ;
-+
-+              switch (clock_freq) {
-+              case I2C_MAX_STANDARD_MODE_FREQ:
-+                      chan->bus_freq = RTL9300_I2C_STD_FREQ;
-+                      break;
-+
-+              case I2C_MAX_FAST_MODE_FREQ:
-+                      chan->bus_freq = RTL9300_I2C_FAST_FREQ;
-+                      break;
-+              default:
-+                      dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
-+                               sda_pin, clock_freq);
-+                      break;
-+              }
-+
-+              chan->sda_pin = sda_pin;
-+              chan->i2c = i2c;
-+              adap = &i2c->chans[i].adap;
-+              adap->owner = THIS_MODULE;
-+              adap->algo = &rtl9300_i2c_algo;
-+              adap->quirks = &rtl9300_i2c_quirks;
-+              adap->retries = 3;
-+              adap->dev.parent = dev;
-+              i2c_set_adapdata(adap, chan);
-+              adap->dev.of_node = to_of_node(child);
-+              snprintf(adap->name, sizeof(adap->name), "%s SDA%d\n", dev_name(dev), sda_pin);
-+              i++;
-+
-+              ret = devm_i2c_add_adapter(dev, adap);
-+              if (ret)
-+                      return ret;
-+      }
-+      i2c->sda_pin = 0xff;
-+
-+      return 0;
-+}
-+
-+static const struct of_device_id i2c_rtl9300_dt_ids[] = {
-+      { .compatible = "realtek,rtl9301-i2c" },
-+      { .compatible = "realtek,rtl9302b-i2c" },
-+      { .compatible = "realtek,rtl9302c-i2c" },
-+      { .compatible = "realtek,rtl9303-i2c" },
-+      {}
-+};
-+MODULE_DEVICE_TABLE(of, i2c_rtl9300_dt_ids);
-+
-+static struct platform_driver rtl9300_i2c_driver = {
-+      .probe = rtl9300_i2c_probe,
-+      .driver = {
-+              .name = "i2c-rtl9300",
-+              .of_match_table = i2c_rtl9300_dt_ids,
-+      },
-+};
-+
-+module_platform_driver(rtl9300_i2c_driver);
-+
-+MODULE_DESCRIPTION("RTL9300 I2C controller driver");
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/realtek/patches-6.18/004-v6.16-dt-bindings-i2c-realtek-rtl9301-Fix-missing-reg-cons.patch b/target/linux/realtek/patches-6.18/004-v6.16-dt-bindings-i2c-realtek-rtl9301-Fix-missing-reg-cons.patch
deleted file mode 100644 (file)
index c460eb1..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From 5f05fc6e2218db7ecc52c60eb34b707fe69262c2 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Wed, 2 Jul 2025 08:15:31 +0200
-Subject: [PATCH] dt-bindings: i2c: realtek,rtl9301: Fix missing 'reg'
- constraint
-
-Lists should have fixed amount if items, so add missing constraint to
-the 'reg' property (only one address space entry).
-
-Fixes: c5eda0333076 ("dt-bindings: i2c: Add Realtek RTL I2C Controller")
-Cc: <stable@vger.kernel.org> # v6.13+
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250702061530.6940-2-krzysztof.kozlowski@linaro.org
-
---- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-+++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-@@ -26,7 +26,8 @@ properties:
-       - const: realtek,rtl9301-i2c
-   reg:
--    description: Register offset and size this I2C controller.
-+    items:
-+      - description: Register offset and size this I2C controller.
-   "#address-cells":
-     const: 1
diff --git a/target/linux/realtek/patches-6.18/005-01-v6.17-i2c-rtl9300-Fix-out-of-bounds-bug-in-rtl9300_i2c_smb.patch b/target/linux/realtek/patches-6.18/005-01-v6.17-i2c-rtl9300-Fix-out-of-bounds-bug-in-rtl9300_i2c_smb.patch
deleted file mode 100644 (file)
index 2ffb659..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-From 57f312b955938fc4663f430cb57a71f2414f601b Mon Sep 17 00:00:00 2001
-From: Alex Guo <alexguo1023@gmail.com>
-Date: Sun, 10 Aug 2025 20:05:13 +0200
-Subject: [PATCH] i2c: rtl9300: Fix out-of-bounds bug in rtl9300_i2c_smbus_xfer
-
-The data->block[0] variable comes from user. Without proper check,
-the variable may be very large to cause an out-of-bounds bug.
-
-Fix this bug by checking the value of data->block[0] first.
-
-1. commit 39244cc75482 ("i2c: ismt: Fix an out-of-bounds bug in
-   ismt_access()")
-2. commit 92fbb6d1296f ("i2c: xgene-slimpro: Fix out-of-bounds bug in
-   xgene_slimpro_i2c_xfer()")
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Signed-off-by: Alex Guo <alexguo1023@gmail.com>
-Cc: <stable@vger.kernel.org> # v6.13+
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250810-i2c-rtl9300-multi-byte-v5-1-cd9dca0db722@narfation.org
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -281,6 +281,10 @@ static int rtl9300_i2c_smbus_xfer(struct
-               ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
-               if (ret)
-                       goto out_unlock;
-+              if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
-+                      ret = -EINVAL;
-+                      goto out_unlock;
-+              }
-               ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]);
-               if (ret)
-                       goto out_unlock;
diff --git a/target/linux/realtek/patches-6.18/005-02-v6.17-i2c-rtl9300-Fix-multi-byte-I2C-write.patch b/target/linux/realtek/patches-6.18/005-02-v6.17-i2c-rtl9300-Fix-multi-byte-I2C-write.patch
deleted file mode 100644 (file)
index ac6bb52..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-From d67b740b9edfa46310355e2b68050f79ebf05a4c Mon Sep 17 00:00:00 2001
-From: Harshal Gohel <hg@simonwunderlich.de>
-Date: Sun, 10 Aug 2025 20:05:14 +0200
-Subject: [PATCH] i2c: rtl9300: Fix multi-byte I2C write
-
-The RTL93xx I2C controller has 4 32 bit registers to store the bytes for
-the upcoming I2C transmission. The first byte is stored in the
-least-significant byte of the first register. And the last byte in the most
-significant byte of the last register. A map of the transferred bytes to
-their order in the registers is:
-
-reg 0: 0x04_03_02_01
-reg 1: 0x08_07_06_05
-reg 2: 0x0c_0b_0a_09
-reg 3: 0x10_0f_0e_0d
-
-The i2c_read() function basically demonstrates how the hardware would pick
-up bytes from this register set. But the i2c_write() function was just
-pushing bytes one after another to the least significant byte of a register
-AFTER shifting the last one to the next more significant byte position.
-
-If you would then have tried to send a buffer with numbers 1-11 using
-i2c_write(), you would have ended up with following register content:
-
-reg 0: 0x01_02_03_04
-reg 1: 0x05_06_07_08
-reg 2: 0x00_09_0a_0b
-reg 3: 0x00_00_00_00
-
-On the wire, you would then have seen:
-
-  Sr Addr Wr [A] 04 A 03 A 02 A 01 A 08 A 07 A 06 A 05 A 0b A 0a A 09 A P
-
-But the correct data transmission was expected to be
-
-  Sr Addr Wr [A] 01 A 02 A 03 A 04 A 05 A 06 A 07 A 08 A 09 A 0a A 0b A P
-
-Because of this multi-byte ordering problem, only single byte i2c_write()
-operations were executed correctly (on the wire).
-
-By shifting the byte directly to the correct end position in the register,
-it is possible to avoid this incorrect byte ordering and fix multi-byte
-transmissions.
-
-The second initialization (to 0) of vals was also be dropped because this
-array is initialized to 0 on the stack by using `= {};`. This makes the
-fix a lot more readable.
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
-Cc: <stable@vger.kernel.org> # v6.13+
-Co-developed-by: Sven Eckelmann <sven@narfation.org>
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250810-i2c-rtl9300-multi-byte-v5-2-cd9dca0db722@narfation.org
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -143,10 +143,10 @@ static int rtl9300_i2c_write(struct rtl9
-               return -EIO;
-       for (i = 0; i < len; i++) {
--              if (i % 4 == 0)
--                      vals[i/4] = 0;
--              vals[i/4] <<= 8;
--              vals[i/4] |= buf[i];
-+              unsigned int shift = (i % 4) * 8;
-+              unsigned int reg = i / 4;
-+
-+              vals[reg] |= buf[i] << shift;
-       }
-       return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
diff --git a/target/linux/realtek/patches-6.18/005-03-v6.17-i2c-rtl9300-Increase-timeout-for-transfer-polling.patch b/target/linux/realtek/patches-6.18/005-03-v6.17-i2c-rtl9300-Increase-timeout-for-transfer-polling.patch
deleted file mode 100644 (file)
index bfb4f48..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From ceee7776c010c5f09d30985c9e5223b363a6172a Mon Sep 17 00:00:00 2001
-From: Sven Eckelmann <sven@narfation.org>
-Date: Sun, 10 Aug 2025 20:05:15 +0200
-Subject: [PATCH] i2c: rtl9300: Increase timeout for transfer polling
-
-The timeout for transfers was only set to 2ms. Because of this relatively
-low limit, 12-byte read operations to the frontend MCU of a RTL8239 POE PSE
-chip cluster was consistently resulting in a timeout.
-
-The original OpenWrt downstream driver [1] was not using any timeout limit
-at all. This is also possible by setting the timeout_us parameter of
-regmap_read_poll_timeout() to 0. But since the driver currently implements
-the ETIMEDOUT error, it is more sensible to increase the timeout in such a
-way that communication with the (quite common) Realtek I2C-connected POE
-management solution is possible.
-
-[1] https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/realtek/files-6.12/drivers/i2c/busses/i2c-rtl9300.c;h=c4d973195ef39dc56d6207e665d279745525fcac#l202
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-Cc: <stable@vger.kernel.org> # v6.13+
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250810-i2c-rtl9300-multi-byte-v5-3-cd9dca0db722@narfation.org
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -175,7 +175,7 @@ static int rtl9300_i2c_execute_xfer(stru
-               return ret;
-       ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1,
--                                     val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 2000);
-+                                     val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 100000);
-       if (ret)
-               return ret;
diff --git a/target/linux/realtek/patches-6.18/005-04-v6.17-i2c-rtl9300-Add-missing-count-byte-for-SMBus-Block-O.patch b/target/linux/realtek/patches-6.18/005-04-v6.17-i2c-rtl9300-Add-missing-count-byte-for-SMBus-Block-O.patch
deleted file mode 100644 (file)
index b5314b2..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-From 82b350dd8185ce790e61555c436f90b6501af23c Mon Sep 17 00:00:00 2001
-From: Sven Eckelmann <sven@narfation.org>
-Date: Sun, 10 Aug 2025 20:05:16 +0200
-Subject: [PATCH] i2c: rtl9300: Add missing count byte for SMBus Block Ops
-
-The expected on-wire format of an SMBus Block Write is
-
-  S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
-
-Everything starting from the Count byte is provided by the I2C subsystem in
-the array data->block. But the driver was skipping the Count byte
-(data->block[0]) when sending it to the RTL93xx I2C controller.
-
-Only the actual data could be seen on the wire:
-
-  S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
-
-This wire format is not SMBus Block Write compatible but matches the format
-of an I2C Block Write. Simply adding the count byte to the buffer for the
-I2C controller is enough to fix the transmission.
-
-This also affects read because the I2C controller must receive the count
-byte + $count * data bytes.
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-Cc: <stable@vger.kernel.org> # v6.13+
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250810-i2c-rtl9300-multi-byte-v5-4-cd9dca0db722@narfation.org
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -285,15 +285,15 @@ static int rtl9300_i2c_smbus_xfer(struct
-                       ret = -EINVAL;
-                       goto out_unlock;
-               }
--              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]);
-+              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0] + 1);
-               if (ret)
-                       goto out_unlock;
-               if (read_write == I2C_SMBUS_WRITE) {
--                      ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]);
-+                      ret = rtl9300_i2c_write(i2c, &data->block[0], data->block[0] + 1);
-                       if (ret)
-                               goto out_unlock;
-               }
--              len = data->block[0];
-+              len = data->block[0] + 1;
-               break;
-       default:
diff --git a/target/linux/realtek/patches-6.18/006-01-v6.17-i2c-rtl9300-fix-channel-number-bound-check.patch b/target/linux/realtek/patches-6.18/006-01-v6.17-i2c-rtl9300-fix-channel-number-bound-check.patch
deleted file mode 100644 (file)
index 2076a0a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From cd6c956fbc13156bcbcca084b46a8380caebc2a8 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sun, 31 Aug 2025 10:04:46 +0000
-Subject: [PATCH] i2c: rtl9300: fix channel number bound check
-
-Fix the current check for number of channels (child nodes in the device
-tree). Before, this was:
-
-if (device_get_child_node_count(dev) >= RTL9300_I2C_MUX_NCHAN)
-
-RTL9300_I2C_MUX_NCHAN gives the maximum number of channels so checking
-with '>=' isn't correct because it doesn't allow the last channel
-number. Thus, fix it to:
-
-if (device_get_child_node_count(dev) > RTL9300_I2C_MUX_NCHAN)
-
-Issue occured on a TP-Link TL-ST1008F v2.0 device (8 SFP+ ports) and fix
-is tested there.
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Cc: stable@vger.kernel.org # v6.13+
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250831100457.3114-2-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -353,7 +353,7 @@ static int rtl9300_i2c_probe(struct plat
-       platform_set_drvdata(pdev, i2c);
--      if (device_get_child_node_count(dev) >= RTL9300_I2C_MUX_NCHAN)
-+      if (device_get_child_node_count(dev) > RTL9300_I2C_MUX_NCHAN)
-               return dev_err_probe(dev, -EINVAL, "Too many channels\n");
-       device_for_each_child_node(dev, child) {
diff --git a/target/linux/realtek/patches-6.18/006-02-v6.17-i2c-rtl9300-ensure-data-length-is-within-supported-r.patch b/target/linux/realtek/patches-6.18/006-02-v6.17-i2c-rtl9300-ensure-data-length-is-within-supported-r.patch
deleted file mode 100644 (file)
index 382c47a..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 06418cb5a1a542a003fdb4ad8e76ea542d57cfba Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sun, 31 Aug 2025 10:04:47 +0000
-Subject: [PATCH] i2c: rtl9300: ensure data length is within supported range
-
-Add an explicit check for the xfer length to 'rtl9300_i2c_config_xfer'
-to ensure the data length isn't within the supported range. In
-particular a data length of 0 is not supported by the hardware and
-causes unintended or destructive behaviour.
-
-This limitation becomes obvious when looking at the register
-documentation [1]. 4 bits are reserved for DATA_WIDTH and the value
-of these 4 bits is used as N + 1, allowing a data length range of
-1 <= len <= 16.
-
-Affected by this is the SMBus Quick Operation which works with a data
-length of 0. Passing 0 as the length causes an underflow of the value
-due to:
-
-(len - 1) & 0xf
-
-and effectively specifying a transfer length of 16 via the registers.
-This causes a 16-byte write operation instead of a Quick Write. For
-example, on SFP modules without write-protected EEPROM this soft-bricks
-them by overwriting some initial bytes.
-
-For completeness, also add a quirk for the zero length.
-
-[1] https://svanheule.net/realtek/longan/register/i2c_mst1_ctrl2
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Cc: stable@vger.kernel.org # v6.13+
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250831100457.3114-3-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -99,6 +99,9 @@ static int rtl9300_i2c_config_xfer(struc
- {
-       u32 val, mask;
-+      if (len < 1 || len > 16)
-+              return -EINVAL;
-+
-       val = chan->bus_freq << RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS;
-       mask = RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK;
-@@ -323,7 +326,7 @@ static const struct i2c_algorithm rtl930
- };
- static struct i2c_adapter_quirks rtl9300_i2c_quirks = {
--      .flags          = I2C_AQ_NO_CLK_STRETCH,
-+      .flags          = I2C_AQ_NO_CLK_STRETCH | I2C_AQ_NO_ZERO_LEN,
-       .max_read_len   = 16,
-       .max_write_len  = 16,
- };
diff --git a/target/linux/realtek/patches-6.18/006-03-v6.17-i2c-rtl9300-remove-broken-SMBus-Quick-operation-supp.patch b/target/linux/realtek/patches-6.18/006-03-v6.17-i2c-rtl9300-remove-broken-SMBus-Quick-operation-supp.patch
deleted file mode 100644 (file)
index 6de11af..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-From ede965fd555ac2536cf651893a998dbfd8e57b86 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sun, 31 Aug 2025 10:04:48 +0000
-Subject: [PATCH] i2c: rtl9300: remove broken SMBus Quick operation support
-
-Remove the SMBus Quick operation from this driver because it is not
-natively supported by the hardware and is wrongly implemented in the
-driver.
-
-The I2C controllers in Realtek RTL9300 and RTL9310 are SMBus-compliant
-but there doesn't seem to be native support for the SMBus Quick
-operation. It is not explicitly mentioned in the documentation but
-looking at the registers which configure an SMBus transaction, one can
-see that the data length cannot be set to 0. This suggests that the
-hardware doesn't allow any SMBus message without data bytes (except for
-those it does on it's own, see SMBus Block Read).
-
-The current implementation of SMBus Quick operation passes a length of
-0 (which is actually invalid). Before the fix of a bug in a previous
-commit, this led to a read operation of 16 bytes from any register (the
-one of a former transaction or any other value.
-
-This caused issues like soft-bricked SFP modules after a simple probe
-with i2cdetect which uses Quick by default. Running this with SFP
-modules whose EEPROM isn't write-protected, some of the initial bytes
-are overwritten because a 16-byte write operation is executed instead of
-a Quick Write. (This temporarily soft-bricked one of my DAC cables.)
-
-Because SMBus Quick operation is obviously not supported on these
-controllers (because a length of 0 cannot be set, even when no register
-address is set), remove that instead of claiming there is support. There
-also shouldn't be any kind of emulated 'Quick' which just does another
-kind of operation in the background. Otherwise, specific issues occur
-in case of a 'Quick' Write which actually writes unknown data to an
-unknown register.
-
-Fixes: c366be720235 ("i2c: Add driver for the RTL9300 I2C controller")
-Cc: stable@vger.kernel.org # v6.13+
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250831100457.3114-4-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -225,15 +225,6 @@ static int rtl9300_i2c_smbus_xfer(struct
-       }
-       switch (size) {
--      case I2C_SMBUS_QUICK:
--              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
--              if (ret)
--                      goto out_unlock;
--              ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
--              if (ret)
--                      goto out_unlock;
--              break;
--
-       case I2C_SMBUS_BYTE:
-               if (read_write == I2C_SMBUS_WRITE) {
-                       ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
-@@ -315,9 +306,9 @@ out_unlock:
- static u32 rtl9300_i2c_func(struct i2c_adapter *a)
- {
--      return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
--             I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
--             I2C_FUNC_SMBUS_BLOCK_DATA;
-+      return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
-+             I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
-+             I2C_FUNC_SMBUS_I2C_BLOCK;
- }
- static const struct i2c_algorithm rtl9300_i2c_algo = {
diff --git a/target/linux/realtek/patches-6.18/007-01-v6.17-i2c-rtl9300-Drop-unsupported-I2C_FUNC_SMBUS_I2C_BLOC.patch b/target/linux/realtek/patches-6.18/007-01-v6.17-i2c-rtl9300-Drop-unsupported-I2C_FUNC_SMBUS_I2C_BLOC.patch
deleted file mode 100644 (file)
index 901c48a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-From 095530512152e6811278de9c30f170f0ac9705eb Mon Sep 17 00:00:00 2001
-From: Sven Eckelmann <sven@narfation.org>
-Date: Sat, 27 Sep 2025 11:52:16 +0200
-Subject: [PATCH] i2c: rtl9300: Drop unsupported I2C_FUNC_SMBUS_I2C_BLOCK
-
-While applying the patch for commit ede965fd555a ("i2c: rtl9300: remove
-broken SMBus Quick operation support"), a conflict was incorrectly solved
-by adding the I2C_FUNC_SMBUS_I2C_BLOCK feature flag. But the code to handle
-I2C_SMBUS_I2C_BLOCK_DATA requests will be added by a separate commit.
-
-Fixes: ede965fd555a ("i2c: rtl9300: remove broken SMBus Quick operation support")
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -307,8 +307,7 @@ out_unlock:
- static u32 rtl9300_i2c_func(struct i2c_adapter *a)
- {
-       return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
--             I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
--             I2C_FUNC_SMBUS_I2C_BLOCK;
-+             I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA;
- }
- static const struct i2c_algorithm rtl9300_i2c_algo = {
diff --git a/target/linux/realtek/patches-6.18/007-02-v6.18-i2c-rtl9300-Implement-I2C-block-read-and-write.patch b/target/linux/realtek/patches-6.18/007-02-v6.18-i2c-rtl9300-Implement-I2C-block-read-and-write.patch
deleted file mode 100644 (file)
index d97b769..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-From 415216ae3196e67bdb9515519f219d553bd38d3a Mon Sep 17 00:00:00 2001
-From: Harshal Gohel <hg@simonwunderlich.de>
-Date: Sat, 27 Sep 2025 11:52:17 +0200
-Subject: [PATCH] i2c: rtl9300: Implement I2C block read and write
-
-It was noticed that the original implementation of SMBus Block Write in the
-driver was actually an I2C Block Write. Both differ only in the Count byte
-before the actual data:
-
-  S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
-
-The I2C Block Write is just skipping this Count byte and starts directly
-with the data:
-
-  S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
-
-The I2C controller of RTL93xx doesn't handle this Count byte special and it
-is simply another one of (16 possible) data bytes. Adding support for the
-I2C Block Write therefore only requires skipping the count byte (0) in
-data->block.
-
-It is similar for reads. The SMBUS Block read is having a Count byte before
-the data:
-
-  S Addr Wr [A] Comm [A]
-            Sr Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P
-
-And the I2C Block Read is directly starting with the actual data:
-
-  S Addr Wr [A] Comm [A]
-            Sr Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
-
-The I2C controller is also not handling this byte in a special way. It
-simply provides every byte after the Rd marker + Ack as part of the 16 byte
-receive buffer (registers). The content of this buffer just has to be
-copied to the right position in the receive data->block.
-
-Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
-Co-developed-by: Sven Eckelmann <sven@narfation.org>
-Signed-off-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Reviewed-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -186,22 +186,32 @@ static int rtl9300_i2c_execute_xfer(stru
-               return -EIO;
-       if (read_write == I2C_SMBUS_READ) {
--              if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA) {
-+              switch (size) {
-+              case I2C_SMBUS_BYTE:
-+              case I2C_SMBUS_BYTE_DATA:
-                       ret = regmap_read(i2c->regmap,
-                                         i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val);
-                       if (ret)
-                               return ret;
-                       data->byte = val & 0xff;
--              } else if (size == I2C_SMBUS_WORD_DATA) {
-+                      break;
-+              case I2C_SMBUS_WORD_DATA:
-                       ret = regmap_read(i2c->regmap,
-                                         i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val);
-                       if (ret)
-                               return ret;
-                       data->word = val & 0xffff;
--              } else {
-+                      break;
-+              case I2C_SMBUS_I2C_BLOCK_DATA:
-+                      ret = rtl9300_i2c_read(i2c, &data->block[1], len);
-+                      if (ret)
-+                              return ret;
-+                      break;
-+              default:
-                       ret = rtl9300_i2c_read(i2c, &data->block[0], len);
-                       if (ret)
-                               return ret;
-+                      break;
-               }
-       }
-@@ -290,6 +300,25 @@ static int rtl9300_i2c_smbus_xfer(struct
-               len = data->block[0] + 1;
-               break;
-+      case I2C_SMBUS_I2C_BLOCK_DATA:
-+              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
-+              if (ret)
-+                      goto out_unlock;
-+              if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
-+                      ret = -EINVAL;
-+                      goto out_unlock;
-+              }
-+              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]);
-+              if (ret)
-+                      goto out_unlock;
-+              if (read_write == I2C_SMBUS_WRITE) {
-+                      ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]);
-+                      if (ret)
-+                              goto out_unlock;
-+              }
-+              len = data->block[0];
-+              break;
-+
-       default:
-               dev_err(&adap->dev, "Unsupported transaction %d\n", size);
-               ret = -EOPNOTSUPP;
-@@ -307,7 +336,8 @@ out_unlock:
- static u32 rtl9300_i2c_func(struct i2c_adapter *a)
- {
-       return I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA |
--             I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA;
-+             I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA |
-+             I2C_FUNC_SMBUS_I2C_BLOCK;
- }
- static const struct i2c_algorithm rtl9300_i2c_algo = {
diff --git a/target/linux/realtek/patches-6.18/008-01-v6.18-i2c-rtl9300-use-regmap-fields-and-API-for-registers.patch b/target/linux/realtek/patches-6.18/008-01-v6.18-i2c-rtl9300-use-regmap-fields-and-API-for-registers.patch
deleted file mode 100644 (file)
index 30bd16e..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-From 5a6ecb27435ef7a67d7bec4543f0c6303f34e8a6 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:23 +0000
-Subject: [PATCH] i2c: rtl9300: use regmap fields and API for registers
-
-Adapt the RTL9300 I2C controller driver to use more of the regmap
-API, especially make use of reg_field and regmap_field instead of macros
-to represent registers. Most register operations are performed through
-regmap_field_* API then.
-
-Handle SCL selection using separate chip-specific functions since this
-is already known to differ between the Realtek SoC families in such a
-way that this cannot be properly handled using just a different
-reg_field.
-
-This makes it easier to add support for newer generations or to handle
-differences between specific revisions within a series. Just by
-defining a separate driver data structure with the corresponding
-register field definitions and linking it to a new compatible.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-2-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -23,97 +23,117 @@ struct rtl9300_i2c_chan {
-       u8 sda_pin;
- };
-+enum rtl9300_i2c_reg_scope {
-+      REG_SCOPE_GLOBAL,
-+      REG_SCOPE_MASTER,
-+};
-+
-+struct rtl9300_i2c_reg_field {
-+      struct reg_field field;
-+      enum rtl9300_i2c_reg_scope scope;
-+};
-+
-+enum rtl9300_i2c_reg_fields {
-+      F_DATA_WIDTH = 0,
-+      F_DEV_ADDR,
-+      F_I2C_FAIL,
-+      F_I2C_TRIG,
-+      F_MEM_ADDR,
-+      F_MEM_ADDR_WIDTH,
-+      F_RD_MODE,
-+      F_RWOP,
-+      F_SCL_FREQ,
-+      F_SCL_SEL,
-+      F_SDA_OUT_SEL,
-+      F_SDA_SEL,
-+
-+      /* keep last */
-+      F_NUM_FIELDS
-+};
-+
-+struct rtl9300_i2c_drv_data {
-+      struct rtl9300_i2c_reg_field field_desc[F_NUM_FIELDS];
-+      int (*select_scl)(struct rtl9300_i2c *i2c, u8 scl);
-+      u32 data_reg;
-+      u8 max_nchan;
-+};
-+
- #define RTL9300_I2C_MUX_NCHAN 8
- struct rtl9300_i2c {
-       struct regmap *regmap;
-       struct device *dev;
-       struct rtl9300_i2c_chan chans[RTL9300_I2C_MUX_NCHAN];
-+      struct regmap_field *fields[F_NUM_FIELDS];
-       u32 reg_base;
-+      u32 data_reg;
-       u8 sda_pin;
-       struct mutex lock;
- };
- #define RTL9300_I2C_MST_CTRL1                         0x0
--#define  RTL9300_I2C_MST_CTRL1_MEM_ADDR_OFS           8
--#define  RTL9300_I2C_MST_CTRL1_MEM_ADDR_MASK          GENMASK(31, 8)
--#define  RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_OFS                4
--#define  RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_MASK               GENMASK(6, 4)
--#define  RTL9300_I2C_MST_CTRL1_GPIO_SCL_SEL           BIT(3)
--#define  RTL9300_I2C_MST_CTRL1_RWOP                   BIT(2)
--#define  RTL9300_I2C_MST_CTRL1_I2C_FAIL                       BIT(1)
--#define  RTL9300_I2C_MST_CTRL1_I2C_TRIG                       BIT(0)
- #define RTL9300_I2C_MST_CTRL2                         0x4
--#define  RTL9300_I2C_MST_CTRL2_RD_MODE                        BIT(15)
--#define  RTL9300_I2C_MST_CTRL2_DEV_ADDR_OFS           8
--#define  RTL9300_I2C_MST_CTRL2_DEV_ADDR_MASK          GENMASK(14, 8)
--#define  RTL9300_I2C_MST_CTRL2_DATA_WIDTH_OFS         4
--#define  RTL9300_I2C_MST_CTRL2_DATA_WIDTH_MASK                GENMASK(7, 4)
--#define  RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_OFS     2
--#define  RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_MASK    GENMASK(3, 2)
--#define  RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS           0
--#define  RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK          GENMASK(1, 0)
- #define RTL9300_I2C_MST_DATA_WORD0                    0x8
- #define RTL9300_I2C_MST_DATA_WORD1                    0xc
- #define RTL9300_I2C_MST_DATA_WORD2                    0x10
- #define RTL9300_I2C_MST_DATA_WORD3                    0x14
--
- #define RTL9300_I2C_MST_GLB_CTRL                      0x384
- static int rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len)
- {
--      u32 val, mask;
-       int ret;
--      val = len << RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_OFS;
--      mask = RTL9300_I2C_MST_CTRL2_MEM_ADDR_WIDTH_MASK;
--
--      ret = regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL2, mask, val);
-+      ret = regmap_field_write(i2c->fields[F_MEM_ADDR_WIDTH], len);
-       if (ret)
-               return ret;
--      val = reg << RTL9300_I2C_MST_CTRL1_MEM_ADDR_OFS;
--      mask = RTL9300_I2C_MST_CTRL1_MEM_ADDR_MASK;
-+      return regmap_field_write(i2c->fields[F_MEM_ADDR], reg);
-+}
--      return regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val);
-+static int rtl9300_i2c_select_scl(struct rtl9300_i2c *i2c, u8 scl)
-+{
-+      return regmap_field_write(i2c->fields[F_SCL_SEL], 1);
- }
- static int rtl9300_i2c_config_io(struct rtl9300_i2c *i2c, u8 sda_pin)
- {
-+      struct rtl9300_i2c_drv_data *drv_data;
-       int ret;
--      u32 val, mask;
--      ret = regmap_update_bits(i2c->regmap, RTL9300_I2C_MST_GLB_CTRL, BIT(sda_pin), BIT(sda_pin));
-+      drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
-+
-+      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(sda_pin), BIT(sda_pin));
-       if (ret)
-               return ret;
--      val = (sda_pin << RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_OFS) |
--              RTL9300_I2C_MST_CTRL1_GPIO_SCL_SEL;
--      mask = RTL9300_I2C_MST_CTRL1_SDA_OUT_SEL_MASK | RTL9300_I2C_MST_CTRL1_GPIO_SCL_SEL;
-+      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], sda_pin);
-+      if (ret)
-+              return ret;
--      return regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val);
-+      return drv_data->select_scl(i2c, 0);
- }
- static int rtl9300_i2c_config_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan,
-                                  u16 addr, u16 len)
- {
--      u32 val, mask;
-+      int ret;
-       if (len < 1 || len > 16)
-               return -EINVAL;
--      val = chan->bus_freq << RTL9300_I2C_MST_CTRL2_SCL_FREQ_OFS;
--      mask = RTL9300_I2C_MST_CTRL2_SCL_FREQ_MASK;
--
--      val |= addr << RTL9300_I2C_MST_CTRL2_DEV_ADDR_OFS;
--      mask |= RTL9300_I2C_MST_CTRL2_DEV_ADDR_MASK;
-+      ret = regmap_field_write(i2c->fields[F_SCL_FREQ], chan->bus_freq);
-+      if (ret)
-+              return ret;
--      val |= ((len - 1) & 0xf) << RTL9300_I2C_MST_CTRL2_DATA_WIDTH_OFS;
--      mask |= RTL9300_I2C_MST_CTRL2_DATA_WIDTH_MASK;
-+      ret = regmap_field_write(i2c->fields[F_DEV_ADDR], addr);
-+      if (ret)
-+              return ret;
--      mask |= RTL9300_I2C_MST_CTRL2_RD_MODE;
-+      ret = regmap_field_write(i2c->fields[F_DATA_WIDTH], (len - 1) & 0xf);
-+      if (ret)
-+              return ret;
--      return regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL2, mask, val);
-+      return regmap_field_write(i2c->fields[F_RD_MODE], 0);
- }
- static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len)
-@@ -124,8 +144,7 @@ static int rtl9300_i2c_read(struct rtl93
-       if (len > 16)
-               return -EIO;
--      ret = regmap_bulk_read(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
--                             vals, ARRAY_SIZE(vals));
-+      ret = regmap_bulk_read(i2c->regmap, i2c->data_reg, vals, ARRAY_SIZE(vals));
-       if (ret)
-               return ret;
-@@ -152,52 +171,49 @@ static int rtl9300_i2c_write(struct rtl9
-               vals[reg] |= buf[i] << shift;
-       }
--      return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
--                              vals, ARRAY_SIZE(vals));
-+      return regmap_bulk_write(i2c->regmap, i2c->data_reg, vals, ARRAY_SIZE(vals));
- }
- static int rtl9300_i2c_writel(struct rtl9300_i2c *i2c, u32 data)
- {
--      return regmap_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, data);
-+      return regmap_write(i2c->regmap, i2c->data_reg, data);
- }
- static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write,
-                                   int size, union i2c_smbus_data *data, int len)
- {
--      u32 val, mask;
-+      u32 val;
-       int ret;
--      val = read_write == I2C_SMBUS_WRITE ? RTL9300_I2C_MST_CTRL1_RWOP : 0;
--      mask = RTL9300_I2C_MST_CTRL1_RWOP;
--
--      val |= RTL9300_I2C_MST_CTRL1_I2C_TRIG;
--      mask |= RTL9300_I2C_MST_CTRL1_I2C_TRIG;
-+      ret = regmap_field_write(i2c->fields[F_RWOP], read_write == I2C_SMBUS_WRITE);
-+      if (ret)
-+              return ret;
--      ret = regmap_update_bits(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1, mask, val);
-+      ret = regmap_field_write(i2c->fields[F_I2C_TRIG], 1);
-       if (ret)
-               return ret;
--      ret = regmap_read_poll_timeout(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_CTRL1,
--                                     val, !(val & RTL9300_I2C_MST_CTRL1_I2C_TRIG), 100, 100000);
-+      ret = regmap_field_read_poll_timeout(i2c->fields[F_I2C_TRIG], val, !val, 100, 100000);
-       if (ret)
-               return ret;
--      if (val & RTL9300_I2C_MST_CTRL1_I2C_FAIL)
-+      ret = regmap_field_read(i2c->fields[F_I2C_FAIL], &val);
-+      if (ret)
-+              return ret;
-+      if (val)
-               return -EIO;
-       if (read_write == I2C_SMBUS_READ) {
-               switch (size) {
-               case I2C_SMBUS_BYTE:
-               case I2C_SMBUS_BYTE_DATA:
--                      ret = regmap_read(i2c->regmap,
--                                        i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val);
-+                      ret = regmap_read(i2c->regmap, i2c->data_reg, &val);
-                       if (ret)
-                               return ret;
-                       data->byte = val & 0xff;
-                       break;
-               case I2C_SMBUS_WORD_DATA:
--                      ret = regmap_read(i2c->regmap,
--                                        i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0, &val);
-+                      ret = regmap_read(i2c->regmap, i2c->data_reg, &val);
-                       if (ret)
-                               return ret;
-                       data->word = val & 0xffff;
-@@ -355,9 +371,11 @@ static int rtl9300_i2c_probe(struct plat
- {
-       struct device *dev = &pdev->dev;
-       struct rtl9300_i2c *i2c;
-+      struct fwnode_handle *child;
-+      struct rtl9300_i2c_drv_data *drv_data;
-+      struct reg_field fields[F_NUM_FIELDS];
-       u32 clock_freq, sda_pin;
-       int ret, i = 0;
--      struct fwnode_handle *child;
-       i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
-       if (!i2c)
-@@ -376,9 +394,22 @@ static int rtl9300_i2c_probe(struct plat
-       platform_set_drvdata(pdev, i2c);
--      if (device_get_child_node_count(dev) > RTL9300_I2C_MUX_NCHAN)
-+      drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
-+      if (device_get_child_node_count(dev) > drv_data->max_nchan)
-               return dev_err_probe(dev, -EINVAL, "Too many channels\n");
-+      i2c->data_reg = i2c->reg_base + drv_data->data_reg;
-+      for (i = 0; i < F_NUM_FIELDS; i++) {
-+              fields[i] = drv_data->field_desc[i].field;
-+              if (drv_data->field_desc[i].scope == REG_SCOPE_MASTER)
-+                      fields[i].reg += i2c->reg_base;
-+      }
-+      ret = devm_regmap_field_bulk_alloc(dev, i2c->regmap, i2c->fields,
-+                                         fields, F_NUM_FIELDS);
-+      if (ret)
-+              return ret;
-+
-+      i = 0;
-       device_for_each_child_node(dev, child) {
-               struct rtl9300_i2c_chan *chan = &i2c->chans[i];
-               struct i2c_adapter *adap = &chan->adap;
-@@ -395,7 +426,6 @@ static int rtl9300_i2c_probe(struct plat
-               case I2C_MAX_STANDARD_MODE_FREQ:
-                       chan->bus_freq = RTL9300_I2C_STD_FREQ;
-                       break;
--
-               case I2C_MAX_FAST_MODE_FREQ:
-                       chan->bus_freq = RTL9300_I2C_FAST_FREQ;
-                       break;
-@@ -427,11 +457,37 @@ static int rtl9300_i2c_probe(struct plat
-       return 0;
- }
-+#define GLB_REG_FIELD(reg, msb, lsb)    \
-+      { .field = REG_FIELD(reg, msb, lsb), .scope = REG_SCOPE_GLOBAL }
-+#define MST_REG_FIELD(reg, msb, lsb)    \
-+      { .field = REG_FIELD(reg, msb, lsb), .scope = REG_SCOPE_MASTER }
-+
-+static const struct rtl9300_i2c_drv_data rtl9300_i2c_drv_data = {
-+      .field_desc = {
-+              [F_MEM_ADDR]            = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 8, 31),
-+              [F_SDA_OUT_SEL]         = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 4, 6),
-+              [F_SCL_SEL]             = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 3, 3),
-+              [F_RWOP]                = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 2, 2),
-+              [F_I2C_FAIL]            = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 1, 1),
-+              [F_I2C_TRIG]            = MST_REG_FIELD(RTL9300_I2C_MST_CTRL1, 0, 0),
-+              [F_RD_MODE]             = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 15, 15),
-+              [F_DEV_ADDR]            = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 8, 14),
-+              [F_DATA_WIDTH]          = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 4, 7),
-+              [F_MEM_ADDR_WIDTH]      = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 2, 3),
-+              [F_SCL_FREQ]            = MST_REG_FIELD(RTL9300_I2C_MST_CTRL2, 0, 1),
-+              [F_SDA_SEL]             = GLB_REG_FIELD(RTL9300_I2C_MST_GLB_CTRL, 0, 7),
-+      },
-+      .select_scl = rtl9300_i2c_select_scl,
-+      .data_reg = RTL9300_I2C_MST_DATA_WORD0,
-+      .max_nchan = RTL9300_I2C_MUX_NCHAN,
-+};
-+
-+
- static const struct of_device_id i2c_rtl9300_dt_ids[] = {
--      { .compatible = "realtek,rtl9301-i2c" },
--      { .compatible = "realtek,rtl9302b-i2c" },
--      { .compatible = "realtek,rtl9302c-i2c" },
--      { .compatible = "realtek,rtl9303-i2c" },
-+      { .compatible = "realtek,rtl9301-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-+      { .compatible = "realtek,rtl9302b-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-+      { .compatible = "realtek,rtl9302c-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-+      { .compatible = "realtek,rtl9303-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-       {}
- };
- MODULE_DEVICE_TABLE(of, i2c_rtl9300_dt_ids);
diff --git a/target/linux/realtek/patches-6.18/008-02-v6.18-dt-bindings-i2c-realtek-rtl9301-i2c-fix-wording-and-.patch b/target/linux/realtek/patches-6.18/008-02-v6.18-dt-bindings-i2c-realtek-rtl9301-i2c-fix-wording-and-.patch
deleted file mode 100644 (file)
index 1eefe48..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From 80f3e37d5e734bbfe891592bb669ceb5e8b314dc Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:24 +0000
-Subject: [PATCH] dt-bindings: i2c: realtek,rtl9301-i2c: fix wording and typos
-
-Fix wording of binding description to use plural because there is not
-only a single RTL9300 SoC. RTL9300 describes a whole family of Realtek
-SoCs.
-
-Add missing word 'of' in description of reg property.
-
-Change 'SDA pin' to 'SDA line number' because the property must contain
-the SDA (channel) number ranging from 0-7 instead of a real pin number.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-3-jelonek.jonas@gmail.com
-
---- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-+++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-@@ -10,7 +10,7 @@ maintainers:
-   - Chris Packham <chris.packham@alliedtelesis.co.nz>
- description:
--  The RTL9300 SoC has two I2C controllers. Each of these has an SCL line (which
-+  RTL9300 SoCs have two I2C controllers. Each of these has an SCL line (which
-   if not-used for SCL can be a GPIO). There are 8 common SDA lines that can be
-   assigned to either I2C controller.
-@@ -27,7 +27,7 @@ properties:
-   reg:
-     items:
--      - description: Register offset and size this I2C controller.
-+      - description: Register offset and size of this I2C controller.
-   "#address-cells":
-     const: 1
-@@ -42,7 +42,7 @@ patternProperties:
-     properties:
-       reg:
--        description: The SDA pin associated with the I2C bus.
-+        description: The SDA line number associated with the I2C bus.
-         maxItems: 1
-     required:
diff --git a/target/linux/realtek/patches-6.18/008-03-v6.18-i2c-rtl9300-rename-internal-sda_pin-to-sda_num.patch b/target/linux/realtek/patches-6.18/008-03-v6.18-i2c-rtl9300-rename-internal-sda_pin-to-sda_num.patch
deleted file mode 100644 (file)
index 37f0976..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-From 8ff3819d7edcd56e4c533b9391a156cd607048fa Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:25 +0000
-Subject: [PATCH] i2c: rtl9300: rename internal sda_pin to sda_num
-
-Rename the internally used 'sda_pin' to 'sda_num' to make it clear that
-this is NOT the actual pin number of the GPIO pin but rather the logical
-SDA channel number. Although the alternate function SDA_Y is sometimes
-given with the GPIO number, this is not always the case. Thus, avoid any
-confusion or misconfiguration by giving the variable the correct name.
-
-This follows the description change in the devicetree bindings.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-4-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -20,7 +20,7 @@ struct rtl9300_i2c_chan {
-       struct i2c_adapter adap;
-       struct rtl9300_i2c *i2c;
-       enum rtl9300_bus_freq bus_freq;
--      u8 sda_pin;
-+      u8 sda_num;
- };
- enum rtl9300_i2c_reg_scope {
-@@ -67,7 +67,7 @@ struct rtl9300_i2c {
-       struct regmap_field *fields[F_NUM_FIELDS];
-       u32 reg_base;
-       u32 data_reg;
--      u8 sda_pin;
-+      u8 sda_num;
-       struct mutex lock;
- };
-@@ -102,11 +102,11 @@ static int rtl9300_i2c_config_io(struct
-       drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
--      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(sda_pin), BIT(sda_pin));
-+      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(sda_num), BIT(sda_num));
-       if (ret)
-               return ret;
--      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], sda_pin);
-+      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], sda_num);
-       if (ret)
-               return ret;
-@@ -243,11 +243,11 @@ static int rtl9300_i2c_smbus_xfer(struct
-       int len = 0, ret;
-       mutex_lock(&i2c->lock);
--      if (chan->sda_pin != i2c->sda_pin) {
-+      if (chan->sda_num != i2c->sda_num) {
-               ret = rtl9300_i2c_config_io(i2c, chan->sda_pin);
-               if (ret)
-                       goto out_unlock;
--              i2c->sda_pin = chan->sda_pin;
-+              i2c->sda_num = chan->sda_num;
-       }
-       switch (size) {
-@@ -374,7 +374,7 @@ static int rtl9300_i2c_probe(struct plat
-       struct fwnode_handle *child;
-       struct rtl9300_i2c_drv_data *drv_data;
-       struct reg_field fields[F_NUM_FIELDS];
--      u32 clock_freq, sda_pin;
-+      u32 clock_freq, sda_num;
-       int ret, i = 0;
-       i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
-@@ -414,7 +414,7 @@ static int rtl9300_i2c_probe(struct plat
-               struct rtl9300_i2c_chan *chan = &i2c->chans[i];
-               struct i2c_adapter *adap = &chan->adap;
--              ret = fwnode_property_read_u32(child, "reg", &sda_pin);
-+              ret = fwnode_property_read_u32(child, "reg", &sda_num);
-               if (ret)
-                       return ret;
-@@ -431,11 +431,11 @@ static int rtl9300_i2c_probe(struct plat
-                       break;
-               default:
-                       dev_warn(i2c->dev, "SDA%d clock-frequency %d not supported using default\n",
--                               sda_pin, clock_freq);
-+                               sda_num, clock_freq);
-                       break;
-               }
--              chan->sda_pin = sda_pin;
-+              chan->sda_num = sda_num;
-               chan->i2c = i2c;
-               adap = &i2c->chans[i].adap;
-               adap->owner = THIS_MODULE;
-@@ -445,14 +445,14 @@ static int rtl9300_i2c_probe(struct plat
-               adap->dev.parent = dev;
-               i2c_set_adapdata(adap, chan);
-               adap->dev.of_node = to_of_node(child);
--              snprintf(adap->name, sizeof(adap->name), "%s SDA%d\n", dev_name(dev), sda_pin);
-+              snprintf(adap->name, sizeof(adap->name), "%s SDA%d\n", dev_name(dev), sda_num);
-               i++;
-               ret = devm_i2c_add_adapter(dev, adap);
-               if (ret)
-                       return ret;
-       }
--      i2c->sda_pin = 0xff;
-+      i2c->sda_num = 0xff;
-       return 0;
- }
diff --git a/target/linux/realtek/patches-6.18/008-04-v6.18-i2c-rtl9300-move-setting-SCL-frequency-to-config_io.patch b/target/linux/realtek/patches-6.18/008-04-v6.18-i2c-rtl9300-move-setting-SCL-frequency-to-config_io.patch
deleted file mode 100644 (file)
index 8620ce9..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-From 6b0549abc8582a81425f89a436def8e28d8d7dce Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:26 +0000
-Subject: [PATCH] i2c: rtl9300: move setting SCL frequency to config_io
-
-Move the register operation to set the SCL frequency to the
-rtl9300_i2c_config_io function instead of the rtl9300_i2c_config_xfer
-function. This rather belongs there next to selecting the current SDA
-output line.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-5-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -95,18 +95,23 @@ static int rtl9300_i2c_select_scl(struct
-       return regmap_field_write(i2c->fields[F_SCL_SEL], 1);
- }
--static int rtl9300_i2c_config_io(struct rtl9300_i2c *i2c, u8 sda_pin)
-+static int rtl9300_i2c_config_io(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan)
- {
-       struct rtl9300_i2c_drv_data *drv_data;
-       int ret;
-       drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
--      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(sda_num), BIT(sda_num));
-+      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(chan->sda_num),
-+                                     BIT(chan->sda_num));
-       if (ret)
-               return ret;
--      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], sda_num);
-+      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], chan->sda_num);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_field_write(i2c->fields[F_SCL_FREQ], chan->bus_freq);
-       if (ret)
-               return ret;
-@@ -121,10 +126,6 @@ static int rtl9300_i2c_config_xfer(struc
-       if (len < 1 || len > 16)
-               return -EINVAL;
--      ret = regmap_field_write(i2c->fields[F_SCL_FREQ], chan->bus_freq);
--      if (ret)
--              return ret;
--
-       ret = regmap_field_write(i2c->fields[F_DEV_ADDR], addr);
-       if (ret)
-               return ret;
-@@ -244,7 +245,7 @@ static int rtl9300_i2c_smbus_xfer(struct
-       mutex_lock(&i2c->lock);
-       if (chan->sda_num != i2c->sda_num) {
--              ret = rtl9300_i2c_config_io(i2c, chan->sda_pin);
-+              ret = rtl9300_i2c_config_io(i2c, chan);
-               if (ret)
-                       goto out_unlock;
-               i2c->sda_num = chan->sda_num;
diff --git a/target/linux/realtek/patches-6.18/008-05-v6.18-i2c-rtl9300-do-not-set-read-mode-on-every-transfer.patch b/target/linux/realtek/patches-6.18/008-05-v6.18-i2c-rtl9300-do-not-set-read-mode-on-every-transfer.patch
deleted file mode 100644 (file)
index 5dc6878..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0cb24186d0ebd7dd12c070fed9d782bf7c6dfb1e Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:27 +0000
-Subject: [PATCH] i2c: rtl9300: do not set read mode on every transfer
-
-Move the operation to set the read mode from config_xfer to probe.
-
-The I2C controller of RTL9300 and RTL9310 support a legacy message mode
-for READs with 'Read Address Data' instead of the standard format 'Write
-Address ; Read Data'. There is no way to pass that via smbus_xfer, thus
-there is no point in supported this in the driver and moreover no point
-in setting this on every transaction. Setting this once in the probe
-call is sufficient.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-6-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -130,11 +130,7 @@ static int rtl9300_i2c_config_xfer(struc
-       if (ret)
-               return ret;
--      ret = regmap_field_write(i2c->fields[F_DATA_WIDTH], (len - 1) & 0xf);
--      if (ret)
--              return ret;
--
--      return regmap_field_write(i2c->fields[F_RD_MODE], 0);
-+      return regmap_field_write(i2c->fields[F_DATA_WIDTH], (len - 1) & 0xf);
- }
- static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len)
-@@ -455,6 +451,11 @@ static int rtl9300_i2c_probe(struct plat
-       }
-       i2c->sda_num = 0xff;
-+      /* only use standard read format */
-+      ret = regmap_field_write(i2c->fields[F_RD_MODE], 0);
-+      if (ret)
-+              return ret;
-+
-       return 0;
- }
diff --git a/target/linux/realtek/patches-6.18/008-06-v6.18-i2c-rtl9300-separate-xfer-configuration-and-executio.patch b/target/linux/realtek/patches-6.18/008-06-v6.18-i2c-rtl9300-separate-xfer-configuration-and-executio.patch
deleted file mode 100644 (file)
index 2d329fd..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-From 447dd46f95014eb4ea94f6164963bf23ce05b927 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:28 +0000
-Subject: [PATCH] i2c: rtl9300: separate xfer configuration and execution
-
-So far, the rtl9300_i2c_smbus_xfer code is quite a mess with function
-calls distributed over the whole function setting different values in
-different cases. Calls to rtl9300_i2c_config_xfer and
-rtl9300_i2c_reg_addr_set are used in every case-block with varying
-values whose meaning is not instantly obvious. In some cases, there are
-additional calls within these case-blocks doing more things.
-
-This is in general a bad design and especially really bad for
-readability and maintainability because it distributes changes or
-issues to multiple locations due to the same function being called with
-different hardcoded values in different places.
-
-To have a good structure, setting different parameters based on the
-desired operation should not be interleaved with applying these
-parameters to the hardware registers. Or in different words, the
-parameter site should be mixed with the call site.
-
-Thus, separate configuration and execution of an SMBus xfer within
-rtl9300_i2c_smbus_xfer to improve readability and maintainability. Add a
-new 'struct rtl9300_i2c_xfer' to carry the required parameters for an
-xfer which are configured based on the input parameters within a single
-switch-case block, without having any function calls within this block.
-
-The function calls to actually apply these values to the hardware
-registers then appear below in a single place and just operate on the
-passed instance of 'struct rtl9300_i2c_xfer'. These are
-'rtl9300_i2c_prepare_xfer' which combines applying all parameters of the
-xfer to the corresponding register, and 'rtl9300_i2c_do_xfer' which
-actually executes the xfer and does post-processing if needed.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-7-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -8,6 +8,7 @@
- #include <linux/mutex.h>
- #include <linux/platform_device.h>
- #include <linux/regmap.h>
-+#include <linux/unaligned.h>
- enum rtl9300_bus_freq {
-       RTL9300_I2C_STD_FREQ,
-@@ -71,6 +72,22 @@ struct rtl9300_i2c {
-       struct mutex lock;
- };
-+enum rtl9300_i2c_xfer_type {
-+      RTL9300_I2C_XFER_BYTE,
-+      RTL9300_I2C_XFER_WORD,
-+      RTL9300_I2C_XFER_BLOCK,
-+};
-+
-+struct rtl9300_i2c_xfer {
-+      enum rtl9300_i2c_xfer_type type;
-+      u16 dev_addr;
-+      u8 reg_addr;
-+      u8 reg_addr_len;
-+      u8 *data;
-+      u8 data_len;
-+      bool write;
-+};
-+
- #define RTL9300_I2C_MST_CTRL1                         0x0
- #define RTL9300_I2C_MST_CTRL2                         0x4
- #define RTL9300_I2C_MST_DATA_WORD0                    0x8
-@@ -95,45 +112,37 @@ static int rtl9300_i2c_select_scl(struct
-       return regmap_field_write(i2c->fields[F_SCL_SEL], 1);
- }
--static int rtl9300_i2c_config_io(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan)
-+static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan)
- {
-       struct rtl9300_i2c_drv_data *drv_data;
-       int ret;
--      drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
-+      if (i2c->sda_num == chan->sda_num)
-+              return 0;
--      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(chan->sda_num),
--                                     BIT(chan->sda_num));
-+      ret = regmap_field_write(i2c->fields[F_SCL_FREQ], chan->bus_freq);
-       if (ret)
-               return ret;
--      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], chan->sda_num);
-+      drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
-+      ret = drv_data->select_scl(i2c, 0);
-       if (ret)
-               return ret;
--      ret = regmap_field_write(i2c->fields[F_SCL_FREQ], chan->bus_freq);
-+      ret = regmap_field_update_bits(i2c->fields[F_SDA_SEL], BIT(chan->sda_num),
-+                                     BIT(chan->sda_num));
-       if (ret)
-               return ret;
--      return drv_data->select_scl(i2c, 0);
--}
--
--static int rtl9300_i2c_config_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan,
--                                 u16 addr, u16 len)
--{
--      int ret;
--
--      if (len < 1 || len > 16)
--              return -EINVAL;
--
--      ret = regmap_field_write(i2c->fields[F_DEV_ADDR], addr);
-+      ret = regmap_field_write(i2c->fields[F_SDA_OUT_SEL], chan->sda_num);
-       if (ret)
-               return ret;
--      return regmap_field_write(i2c->fields[F_DATA_WIDTH], (len - 1) & 0xf);
-+      i2c->sda_num = chan->sda_num;
-+      return 0;
- }
--static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, int len)
-+static int rtl9300_i2c_read(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
- {
-       u32 vals[4] = {};
-       int i, ret;
-@@ -153,7 +162,7 @@ static int rtl9300_i2c_read(struct rtl93
-       return 0;
- }
--static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, int len)
-+static int rtl9300_i2c_write(struct rtl9300_i2c *i2c, u8 *buf, u8 len)
- {
-       u32 vals[4] = {};
-       int i;
-@@ -176,16 +185,51 @@ static int rtl9300_i2c_writel(struct rtl
-       return regmap_write(i2c->regmap, i2c->data_reg, data);
- }
--static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write,
--                                  int size, union i2c_smbus_data *data, int len)
-+static int rtl9300_i2c_prepare_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_xfer *xfer)
- {
--      u32 val;
-       int ret;
--      ret = regmap_field_write(i2c->fields[F_RWOP], read_write == I2C_SMBUS_WRITE);
-+      if (xfer->data_len < 1 || xfer->data_len > 16)
-+              return -EINVAL;
-+
-+      ret = regmap_field_write(i2c->fields[F_DEV_ADDR], xfer->dev_addr);
-       if (ret)
-               return ret;
-+      ret = rtl9300_i2c_reg_addr_set(i2c, xfer->reg_addr, xfer->reg_addr_len);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_field_write(i2c->fields[F_RWOP], xfer->write);
-+      if (ret)
-+              return ret;
-+
-+      ret = regmap_field_write(i2c->fields[F_DATA_WIDTH], (xfer->data_len - 1) & 0xf);
-+      if (ret)
-+              return ret;
-+
-+      if (xfer->write) {
-+              switch (xfer->type) {
-+              case RTL9300_I2C_XFER_BYTE:
-+                      ret = rtl9300_i2c_writel(i2c, *xfer->data);
-+                      break;
-+              case RTL9300_I2C_XFER_WORD:
-+                      ret = rtl9300_i2c_writel(i2c, get_unaligned((const u16 *)xfer->data));
-+                      break;
-+              default:
-+                      ret = rtl9300_i2c_write(i2c, xfer->data, xfer->data_len);
-+                      break;
-+              }
-+      }
-+
-+      return ret;
-+}
-+
-+static int rtl9300_i2c_do_xfer(struct rtl9300_i2c *i2c, struct rtl9300_i2c_xfer *xfer)
-+{
-+      u32 val;
-+      int ret;
-+
-       ret = regmap_field_write(i2c->fields[F_I2C_TRIG], 1);
-       if (ret)
-               return ret;
-@@ -200,28 +244,24 @@ static int rtl9300_i2c_execute_xfer(stru
-       if (val)
-               return -EIO;
--      if (read_write == I2C_SMBUS_READ) {
--              switch (size) {
--              case I2C_SMBUS_BYTE:
--              case I2C_SMBUS_BYTE_DATA:
-+      if (!xfer->write) {
-+              switch (xfer->type) {
-+              case RTL9300_I2C_XFER_BYTE:
-                       ret = regmap_read(i2c->regmap, i2c->data_reg, &val);
-                       if (ret)
-                               return ret;
--                      data->byte = val & 0xff;
-+
-+                      *xfer->data = val & 0xff;
-                       break;
--              case I2C_SMBUS_WORD_DATA:
-+              case RTL9300_I2C_XFER_WORD:
-                       ret = regmap_read(i2c->regmap, i2c->data_reg, &val);
-                       if (ret)
-                               return ret;
--                      data->word = val & 0xffff;
--                      break;
--              case I2C_SMBUS_I2C_BLOCK_DATA:
--                      ret = rtl9300_i2c_read(i2c, &data->block[1], len);
--                      if (ret)
--                              return ret;
-+
-+                      put_unaligned(val & 0xffff, (u16*)xfer->data);
-                       break;
-               default:
--                      ret = rtl9300_i2c_read(i2c, &data->block[0], len);
-+                      ret = rtl9300_i2c_read(i2c, xfer->data, xfer->data_len);
-                       if (ret)
-                               return ret;
-                       break;
-@@ -237,108 +277,62 @@ static int rtl9300_i2c_smbus_xfer(struct
- {
-       struct rtl9300_i2c_chan *chan = i2c_get_adapdata(adap);
-       struct rtl9300_i2c *i2c = chan->i2c;
--      int len = 0, ret;
-+      struct rtl9300_i2c_xfer xfer = {0};
-+      int ret;
-+
-+      if (addr > 0x7f)
-+              return -EINVAL;
-       mutex_lock(&i2c->lock);
--      if (chan->sda_num != i2c->sda_num) {
--              ret = rtl9300_i2c_config_io(i2c, chan);
--              if (ret)
--                      goto out_unlock;
--              i2c->sda_num = chan->sda_num;
--      }
-+
-+      ret = rtl9300_i2c_config_chan(i2c, chan);
-+      if (ret)
-+              goto out_unlock;
-+
-+      xfer.dev_addr = addr & 0x7f;
-+      xfer.write = (read_write == I2C_SMBUS_WRITE);
-+      xfer.reg_addr = command;
-+      xfer.reg_addr_len = 1;
-       switch (size) {
-       case I2C_SMBUS_BYTE:
--              if (read_write == I2C_SMBUS_WRITE) {
--                      ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 0);
--                      if (ret)
--                              goto out_unlock;
--                      ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
--                      if (ret)
--                              goto out_unlock;
--              } else {
--                      ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 1);
--                      if (ret)
--                              goto out_unlock;
--                      ret = rtl9300_i2c_reg_addr_set(i2c, 0, 0);
--                      if (ret)
--                              goto out_unlock;
--              }
-+              xfer.data = (read_write == I2C_SMBUS_READ) ? &data->byte : &command;
-+              xfer.data_len = 1;
-+              xfer.reg_addr = 0;
-+              xfer.reg_addr_len = 0;
-+              xfer.type = RTL9300_I2C_XFER_BYTE;
-               break;
--
-       case I2C_SMBUS_BYTE_DATA:
--              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
--              if (ret)
--                      goto out_unlock;
--              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 1);
--              if (ret)
--                      goto out_unlock;
--              if (read_write == I2C_SMBUS_WRITE) {
--                      ret = rtl9300_i2c_writel(i2c, data->byte);
--                      if (ret)
--                              goto out_unlock;
--              }
-+              xfer.data = &data->byte;
-+              xfer.data_len = 1;
-+              xfer.type = RTL9300_I2C_XFER_BYTE;
-               break;
--
-       case I2C_SMBUS_WORD_DATA:
--              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
--              if (ret)
--                      goto out_unlock;
--              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, 2);
--              if (ret)
--                      goto out_unlock;
--              if (read_write == I2C_SMBUS_WRITE) {
--                      ret = rtl9300_i2c_writel(i2c, data->word);
--                      if (ret)
--                              goto out_unlock;
--              }
-+              xfer.data = (u8 *)&data->word;
-+              xfer.data_len = 2;
-+              xfer.type = RTL9300_I2C_XFER_WORD;
-               break;
--
-       case I2C_SMBUS_BLOCK_DATA:
--              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
--              if (ret)
--                      goto out_unlock;
--              if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
--                      ret = -EINVAL;
--                      goto out_unlock;
--              }
--              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0] + 1);
--              if (ret)
--                      goto out_unlock;
--              if (read_write == I2C_SMBUS_WRITE) {
--                      ret = rtl9300_i2c_write(i2c, &data->block[0], data->block[0] + 1);
--                      if (ret)
--                              goto out_unlock;
--              }
--              len = data->block[0] + 1;
-+              xfer.data = &data->block[0];
-+              xfer.data_len = data->block[0] + 1;
-+              xfer.type = RTL9300_I2C_XFER_BLOCK;
-               break;
--
-       case I2C_SMBUS_I2C_BLOCK_DATA:
--              ret = rtl9300_i2c_reg_addr_set(i2c, command, 1);
--              if (ret)
--                      goto out_unlock;
--              if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) {
--                      ret = -EINVAL;
--                      goto out_unlock;
--              }
--              ret = rtl9300_i2c_config_xfer(i2c, chan, addr, data->block[0]);
--              if (ret)
--                      goto out_unlock;
--              if (read_write == I2C_SMBUS_WRITE) {
--                      ret = rtl9300_i2c_write(i2c, &data->block[1], data->block[0]);
--                      if (ret)
--                              goto out_unlock;
--              }
--              len = data->block[0];
-+              xfer.data = &data->block[1];
-+              xfer.data_len = data->block[0];
-+              xfer.type = RTL9300_I2C_XFER_BLOCK;
-               break;
--
-       default:
-               dev_err(&adap->dev, "Unsupported transaction %d\n", size);
-               ret = -EOPNOTSUPP;
-               goto out_unlock;
-       }
--      ret = rtl9300_i2c_execute_xfer(i2c, read_write, size, data, len);
-+      ret = rtl9300_i2c_prepare_xfer(i2c, &xfer);
-+      if (ret)
-+              goto out_unlock;
-+
-+      ret = rtl9300_i2c_do_xfer(i2c, &xfer);
- out_unlock:
-       mutex_unlock(&i2c->lock);
diff --git a/target/linux/realtek/patches-6.18/008-07-v6.18-i2c-rtl9300-use-scoped-guard-instead-of-explicit-loc.patch b/target/linux/realtek/patches-6.18/008-07-v6.18-i2c-rtl9300-use-scoped-guard-instead-of-explicit-loc.patch
deleted file mode 100644 (file)
index 58552ca..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From bcd5f0da57e6c47a884dcad94ad6b0e32cce8705 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:29 +0000
-Subject: [PATCH] i2c: rtl9300: use scoped guard instead of explicit
- lock/unlock
-
-Use the scoped guard infrastructure which unlocks a mutex automatically
-when the guard goes out of scope, instead of explicit lock and unlock.
-This simplifies the code and control flow in rtl9300_i2c_smbus_xfer and
-removes the need of using goto in error cases to unlock before
-returning.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Chris Packham <chris.packham@alliedtelesis.co.nz> # On RTL9302C based board
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-8-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -72,6 +72,8 @@ struct rtl9300_i2c {
-       struct mutex lock;
- };
-+DEFINE_GUARD(rtl9300_i2c, struct rtl9300_i2c *, mutex_lock(&_T->lock), mutex_unlock(&_T->lock))
-+
- enum rtl9300_i2c_xfer_type {
-       RTL9300_I2C_XFER_BYTE,
-       RTL9300_I2C_XFER_WORD,
-@@ -283,11 +285,11 @@ static int rtl9300_i2c_smbus_xfer(struct
-       if (addr > 0x7f)
-               return -EINVAL;
--      mutex_lock(&i2c->lock);
-+      guard(rtl9300_i2c)(i2c);
-       ret = rtl9300_i2c_config_chan(i2c, chan);
-       if (ret)
--              goto out_unlock;
-+              return ret;
-       xfer.dev_addr = addr & 0x7f;
-       xfer.write = (read_write == I2C_SMBUS_WRITE);
-@@ -324,20 +326,14 @@ static int rtl9300_i2c_smbus_xfer(struct
-               break;
-       default:
-               dev_err(&adap->dev, "Unsupported transaction %d\n", size);
--              ret = -EOPNOTSUPP;
--              goto out_unlock;
-+              return -EOPNOTSUPP;
-       }
-       ret = rtl9300_i2c_prepare_xfer(i2c, &xfer);
-       if (ret)
--              goto out_unlock;
--
--      ret = rtl9300_i2c_do_xfer(i2c, &xfer);
--
--out_unlock:
--      mutex_unlock(&i2c->lock);
-+              return ret;
--      return ret;
-+      return rtl9300_i2c_do_xfer(i2c, &xfer);
- }
- static u32 rtl9300_i2c_func(struct i2c_adapter *a)
diff --git a/target/linux/realtek/patches-6.18/008-08-v6.18-dt-bindings-i2c-realtek-rtl9301-i2c-extend-for-RTL93.patch b/target/linux/realtek/patches-6.18/008-08-v6.18-dt-bindings-i2c-realtek-rtl9301-i2c-extend-for-RTL93.patch
deleted file mode 100644 (file)
index 9bc6851..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-From 17689aafb793599a862617a127429dd3d6f675c9 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:30 +0000
-Subject: [PATCH] dt-bindings: i2c: realtek,rtl9301-i2c: extend for RTL9310
- support
-
-Adjust the regex for child-node address to account for the fact that
-RTL9310 supports 12 instead of only 8 SDA lines. Also, narrow this per
-variant.
-
-Add a vendor-specific property to explicitly specify the SCL line number
-of the defined I2C controller/master. This is required, in particular
-for RTL9310, to operate on the correct SCL for each controller. Require
-this property to be specified for RTL9310.
-
-Add compatibles for known SoC variants RTL9311, RTL9312 and RTL9313.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-9-jelonek.jonas@gmail.com
-
---- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-+++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
-@@ -13,6 +13,8 @@ description:
-   RTL9300 SoCs have two I2C controllers. Each of these has an SCL line (which
-   if not-used for SCL can be a GPIO). There are 8 common SDA lines that can be
-   assigned to either I2C controller.
-+  RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
-+  can be assigned to either I2C controller.
- properties:
-   compatible:
-@@ -23,7 +25,15 @@ properties:
-               - realtek,rtl9302c-i2c
-               - realtek,rtl9303-i2c
-           - const: realtek,rtl9301-i2c
--      - const: realtek,rtl9301-i2c
-+      - items:
-+          - enum:
-+              - realtek,rtl9311-i2c
-+              - realtek,rtl9312-i2c
-+              - realtek,rtl9313-i2c
-+          - const: realtek,rtl9310-i2c
-+      - enum:
-+          - realtek,rtl9301-i2c
-+          - realtek,rtl9310-i2c
-   reg:
-     items:
-@@ -35,8 +45,14 @@ properties:
-   "#size-cells":
-     const: 0
-+  realtek,scl:
-+    $ref: /schemas/types.yaml#/definitions/uint32
-+    description:
-+      The SCL line number of this I2C controller.
-+    enum: [ 0, 1 ]
-+
- patternProperties:
--  '^i2c@[0-7]$':
-+  '^i2c@[0-9ab]$':
-     $ref: /schemas/i2c/i2c-controller.yaml
-     unevaluatedProperties: false
-@@ -48,6 +64,25 @@ patternProperties:
-     required:
-       - reg
-+
-+allOf:
-+  - if:
-+      properties:
-+        compatible:
-+          contains:
-+            const: realtek,rtl9310-i2c
-+    then:
-+      required:
-+        - realtek,scl
-+  - if:
-+      properties:
-+        compatible:
-+          contains:
-+            const: realtek,rtl9301-i2c
-+    then:
-+      patternProperties:
-+        '^i2c@[89ab]$': false
-+
- required:
-   - compatible
-   - reg
diff --git a/target/linux/realtek/patches-6.18/008-09-v6.18-i2c-rtl9300-add-support-for-RTL9310-I2C-controller.patch b/target/linux/realtek/patches-6.18/008-09-v6.18-i2c-rtl9300-add-support-for-RTL9310-I2C-controller.patch
deleted file mode 100644 (file)
index 6d5a23c..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-From 8d43287120ce6437e7a77e735d99137f3fdb3ae9 Mon Sep 17 00:00:00 2001
-From: Jonas Jelonek <jelonek.jonas@gmail.com>
-Date: Sat, 27 Sep 2025 10:19:31 +0000
-Subject: [PATCH] i2c: rtl9300: add support for RTL9310 I2C controller
-
-Add support for the internal I2C controllers of RTL9310 series based
-SoCs to the driver for RTL9300. Add register definitions, chip-specific
-functions and compatible strings for known RTL9310-based SoCs RTL9311,
-RTL9312 and RTL9313.
-
-Make use of a new device tree property 'realtek,scl' which needs to be
-specified in case both or only the second master is used. This is
-required due how the register layout changed in contrast to RTL9300,
-which has SCL selection in a global register instead of a
-master-specific one.
-
-Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
-Tested-by: Sven Eckelmann <sven@narfation.org>
-Reviewed-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
-Tested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
-Link: https://lore.kernel.org/r/20250927101931.71575-10-jelonek.jonas@gmail.com
-
---- a/drivers/i2c/busses/i2c-rtl9300.c
-+++ b/drivers/i2c/busses/i2c-rtl9300.c
-@@ -60,14 +60,16 @@ struct rtl9300_i2c_drv_data {
- };
- #define RTL9300_I2C_MUX_NCHAN 8
-+#define RTL9310_I2C_MUX_NCHAN 12
- struct rtl9300_i2c {
-       struct regmap *regmap;
-       struct device *dev;
--      struct rtl9300_i2c_chan chans[RTL9300_I2C_MUX_NCHAN];
-+      struct rtl9300_i2c_chan chans[RTL9310_I2C_MUX_NCHAN];
-       struct regmap_field *fields[F_NUM_FIELDS];
-       u32 reg_base;
-       u32 data_reg;
-+      u8 scl_num;
-       u8 sda_num;
-       struct mutex lock;
- };
-@@ -98,6 +100,12 @@ struct rtl9300_i2c_xfer {
- #define RTL9300_I2C_MST_DATA_WORD3                    0x14
- #define RTL9300_I2C_MST_GLB_CTRL                      0x384
-+#define RTL9310_I2C_MST_IF_CTRL                               0x1004
-+#define RTL9310_I2C_MST_IF_SEL                                0x1008
-+#define RTL9310_I2C_MST_CTRL                          0x0
-+#define RTL9310_I2C_MST_MEMADDR_CTRL                  0x4
-+#define RTL9310_I2C_MST_DATA_CTRL                     0x8
-+
- static int rtl9300_i2c_reg_addr_set(struct rtl9300_i2c *i2c, u32 reg, u16 len)
- {
-       int ret;
-@@ -114,6 +122,11 @@ static int rtl9300_i2c_select_scl(struct
-       return regmap_field_write(i2c->fields[F_SCL_SEL], 1);
- }
-+static int rtl9310_i2c_select_scl(struct rtl9300_i2c *i2c, u8 scl)
-+{
-+      return regmap_field_update_bits(i2c->fields[F_SCL_SEL], BIT(scl), BIT(scl));
-+}
-+
- static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan)
- {
-       struct rtl9300_i2c_drv_data *drv_data;
-@@ -127,7 +140,7 @@ static int rtl9300_i2c_config_chan(struc
-               return ret;
-       drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
--      ret = drv_data->select_scl(i2c, 0);
-+      ret = drv_data->select_scl(i2c, i2c->scl_num);
-       if (ret)
-               return ret;
-@@ -361,7 +374,7 @@ static int rtl9300_i2c_probe(struct plat
-       struct fwnode_handle *child;
-       struct rtl9300_i2c_drv_data *drv_data;
-       struct reg_field fields[F_NUM_FIELDS];
--      u32 clock_freq, sda_num;
-+      u32 clock_freq, scl_num, sda_num;
-       int ret, i = 0;
-       i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
-@@ -379,6 +392,11 @@ static int rtl9300_i2c_probe(struct plat
-       if (ret)
-               return ret;
-+      ret = device_property_read_u32(dev, "realtek,scl", &scl_num);
-+      if (ret || scl_num != 1)
-+              scl_num = 0;
-+      i2c->scl_num = (u8)scl_num;
-+
-       platform_set_drvdata(pdev, i2c);
-       drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev);
-@@ -474,12 +492,35 @@ static const struct rtl9300_i2c_drv_data
-       .max_nchan = RTL9300_I2C_MUX_NCHAN,
- };
-+static const struct rtl9300_i2c_drv_data rtl9310_i2c_drv_data = {
-+      .field_desc = {
-+              [F_SCL_SEL]             = GLB_REG_FIELD(RTL9310_I2C_MST_IF_SEL, 12, 13),
-+              [F_SDA_SEL]             = GLB_REG_FIELD(RTL9310_I2C_MST_IF_SEL, 0, 11),
-+              [F_SCL_FREQ]            = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 30, 31),
-+              [F_DEV_ADDR]            = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 11, 17),
-+              [F_SDA_OUT_SEL]         = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 18, 21),
-+              [F_MEM_ADDR_WIDTH]      = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 9, 10),
-+              [F_DATA_WIDTH]          = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 5, 8),
-+              [F_RD_MODE]             = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 4, 4),
-+              [F_RWOP]                = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 2, 2),
-+              [F_I2C_FAIL]            = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 1, 1),
-+              [F_I2C_TRIG]            = MST_REG_FIELD(RTL9310_I2C_MST_CTRL, 0, 0),
-+              [F_MEM_ADDR]            = MST_REG_FIELD(RTL9310_I2C_MST_MEMADDR_CTRL, 0, 23),
-+      },
-+      .select_scl = rtl9310_i2c_select_scl,
-+      .data_reg = RTL9310_I2C_MST_DATA_CTRL,
-+      .max_nchan = RTL9310_I2C_MUX_NCHAN,
-+};
- static const struct of_device_id i2c_rtl9300_dt_ids[] = {
-       { .compatible = "realtek,rtl9301-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-       { .compatible = "realtek,rtl9302b-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-       { .compatible = "realtek,rtl9302c-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-       { .compatible = "realtek,rtl9303-i2c", .data = (void *) &rtl9300_i2c_drv_data },
-+      { .compatible = "realtek,rtl9310-i2c", .data = (void *) &rtl9310_i2c_drv_data },
-+      { .compatible = "realtek,rtl9311-i2c", .data = (void *) &rtl9310_i2c_drv_data },
-+      { .compatible = "realtek,rtl9312-i2c", .data = (void *) &rtl9310_i2c_drv_data },
-+      { .compatible = "realtek,rtl9313-i2c", .data = (void *) &rtl9310_i2c_drv_data },
-       {}
- };
- MODULE_DEVICE_TABLE(of, i2c_rtl9300_dt_ids);
diff --git a/target/linux/realtek/patches-6.18/020-02-v6.18-timer-rtl-otto-drop-set-counter-function.patch b/target/linux/realtek/patches-6.18/020-02-v6.18-timer-rtl-otto-drop-set-counter-function.patch
deleted file mode 100644 (file)
index 5ee2f07..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From 85e27f218121bdaa8e8afd68674262aa154d2cb4 Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Mon, 4 Aug 2025 04:03:26 -0400
-Subject: clocksource/drivers/timer-rtl-otto: Drop set_counter function
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-The current counter value is a read only register. It will be
-reset when writing a new target timer value with rttm_set_period().
-rttm_set_counter() is essentially a noop. Drop it.
-
-While this makes rttm_start_timer() and rttm_enable_timer() the
-same functions keep both to make the established abstraction layers
-for register and control functions active.
-
-Downstream has already tested and confirmed a patch. See
-https://github.com/openwrt/openwrt/pull/19468
-https://forum.openwrt.org/t/support-for-rtl838x-based-managed-switches/57875/3788
-
-Tested-by: Stephen Howell <howels@allthatwemight.be>
-Tested-by: Bjørn Mork <bjorn@mork.no>
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Link: https://lore.kernel.org/r/20250804080328.2609287-3-markus.stockhausen@gmx.de
-Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
----
- drivers/clocksource/timer-rtl-otto.c | 6 ------
- 1 file changed, 6 deletions(-)
-
---- a/drivers/clocksource/timer-rtl-otto.c
-+++ b/drivers/clocksource/timer-rtl-otto.c
-@@ -56,11 +56,6 @@ struct rttm_cs {
- };
- /* Simple internal register functions */
--static inline void rttm_set_counter(void __iomem *base, unsigned int counter)
--{
--      iowrite32(counter, base + RTTM_CNT);
--}
--
- static inline unsigned int rttm_get_counter(void __iomem *base)
- {
-       return ioread32(base + RTTM_CNT);
-@@ -137,7 +132,6 @@ static void rttm_stop_timer(void __iomem
- static void rttm_start_timer(struct timer_of *to, u32 mode)
- {
--      rttm_set_counter(to->of_base.base, 0);
-       rttm_enable_timer(to->of_base.base, mode, to->of_clk.rate / RTTM_TICKS_PER_SEC);
- }
diff --git a/target/linux/realtek/patches-6.18/021-v6.18-mtd-nand-add-realtek-ecc-engine.patch b/target/linux/realtek/patches-6.18/021-v6.18-mtd-nand-add-realtek-ecc-engine.patch
deleted file mode 100644 (file)
index 7c7811e..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-From 3148d0e5b1c5733d69ec51b70c8280e46488750a Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Fri, 19 Sep 2025 03:52:01 -0400
-Subject: mtd: nand: realtek-ecc: Add Realtek external ECC engine support
-
-The Realtek RTl93xx switch SoC series has a built in ECC controller
-that can provide BCH6 or BCH12 over 512 data and 6 tag bytes. It
-generates 10 (BCH6) or 20 (BCH12) bytes of parity.
-
-This engine will most likely work in conjunction with the Realtek
-spi-mem based NAND controller but can work on its own. Therefore
-the initial implementation will be of type external.
-
-Remark! The engine can support any data blocks that are multiples
-of 512 bytes. For now limit it to data+oob layouts that have been
-analyzed from existing devices. This way it keeps compatibility
-and pre-existing vendor data can be read.
-
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
----
- drivers/mtd/nand/Kconfig       |   8 +
- drivers/mtd/nand/Makefile      |   1 +
- drivers/mtd/nand/ecc-realtek.c | 464 +++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 473 insertions(+)
- create mode 100644 drivers/mtd/nand/ecc-realtek.c
-
---- a/drivers/mtd/nand/Kconfig
-+++ b/drivers/mtd/nand/Kconfig
-@@ -65,6 +65,14 @@ config MTD_NAND_ECC_MEDIATEK
-       help
-         This enables support for the hardware ECC engine from Mediatek.
-+config MTD_NAND_ECC_REALTEK
-+        tristate "Realtek RTL93xx hardware ECC engine"
-+        depends on HAS_IOMEM
-+        depends on MACH_REALTEK_RTL || COMPILE_TEST
-+        select MTD_NAND_ECC
-+        help
-+          This enables support for the hardware ECC engine from Realtek.
-+
- endmenu
- endmenu
---- a/drivers/mtd/nand/Makefile
-+++ b/drivers/mtd/nand/Makefile
-@@ -2,6 +2,7 @@
- nandcore-objs := core.o bbt.o
- obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
-+obj-$(CONFIG_MTD_NAND_ECC_REALTEK) += ecc-realtek.o
- obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
- obj-$(CONFIG_MTD_NAND_MTK_BMT)        += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
- obj-$(CONFIG_SPI_QPIC_SNAND) += qpic_common.o
---- /dev/null
-+++ b/drivers/mtd/nand/ecc-realtek.c
-@@ -0,0 +1,464 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Support for Realtek hardware ECC engine in RTL93xx SoCs
-+ */
-+
-+#include <linux/bitfield.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mutex.h>
-+#include <linux/platform_device.h>
-+#include <linux/regmap.h>
-+
-+/*
-+ * The Realtek ECC engine has two operation modes.
-+ *
-+ * - BCH6  : Generate 10 ECC bytes from 512 data bytes plus 6 free bytes
-+ * - BCH12 : Generate 20 ECC bytes from 512 data bytes plus 6 free bytes
-+ *
-+ * It can run for arbitrary NAND flash chips with different block and OOB sizes. Currently there
-+ * are only two known devices in the wild that have NAND flash and make use of this ECC engine
-+ * (Linksys LGS328C & LGS352C). To keep compatibility with vendor firmware, new modes can only
-+ * be added when new data layouts have been analyzed. For now allow BCH6 on flash with 2048 byte
-+ * blocks and 64 bytes oob.
-+ *
-+ * This driver aligns with kernel ECC naming conventions. Neverthless a short notice on the
-+ * Realtek naming conventions for the different structures in the OOB area.
-+ *
-+ * - BBI      : Bad block indicator. The first two bytes of OOB. Protected by ECC!
-+ * - tag      : 6 User/free bytes. First tag "contains" 2 bytes BBI. Protected by ECC!
-+ * - syndrome : ECC/parity bytes
-+ *
-+ * Altogether this gives currently the following block layout.
-+ *
-+ * +------+------+------+------+-----+------+------+------+------+-----+-----+-----+-----+
-+ * |  512 |  512 |  512 |  512 |   2 |    4 |    6 |    6 |    6 |  10 |  10 |  10 |  10 |
-+ * +------+------+------+------+-----+------+------+------+------+-----+-----+-----+-----+
-+ * | data | data | data | data | BBI | free | free | free | free | ECC | ECC | ECC | ECC |
-+ * +------+------+------+------+-----+------+------+------+------+-----+-----+-----+-----+
-+ */
-+
-+#define RTL_ECC_ALLOWED_PAGE_SIZE     2048
-+#define RTL_ECC_ALLOWED_OOB_SIZE      64
-+#define RTL_ECC_ALLOWED_STRENGTH      6
-+
-+#define RTL_ECC_BLOCK_SIZE            512
-+#define RTL_ECC_FREE_SIZE             6
-+#define RTL_ECC_PARITY_SIZE_BCH6      10
-+#define RTL_ECC_PARITY_SIZE_BCH12     20
-+
-+/*
-+ * The engine is fed with two DMA regions. One for data (always 512 bytes) and one for free bytes
-+ * and parity (either 16 bytes for BCH6 or 26 bytes for BCH12). Start and length of each must be
-+ * aligned to a multiple of 4.
-+ */
-+
-+#define RTL_ECC_DMA_FREE_PARITY_SIZE  ALIGN(RTL_ECC_FREE_SIZE + RTL_ECC_PARITY_SIZE_BCH12, 4)
-+#define RTL_ECC_DMA_SIZE              (RTL_ECC_BLOCK_SIZE + RTL_ECC_DMA_FREE_PARITY_SIZE)
-+
-+#define RTL_ECC_CFG                   0x00
-+#define   RTL_ECC_BCH6                        0
-+#define   RTL_ECC_BCH12                       BIT(28)
-+#define   RTL_ECC_DMA_PRECISE         BIT(12)
-+#define   RTL_ECC_BURST_128           GENMASK(1, 0)
-+#define RTL_ECC_DMA_TRIGGER           0x08
-+#define   RTL_ECC_OP_DECODE           0
-+#define   RTL_ECC_OP_ENCODE           BIT(0)
-+#define RTL_ECC_DMA_START             0x0c
-+#define RTL_ECC_DMA_TAG                       0x10
-+#define RTL_ECC_STATUS                        0x14
-+#define   RTL_ECC_CORR_COUNT          GENMASK(19, 12)
-+#define   RTL_ECC_RESULT              BIT(8)
-+#define   RTL_ECC_ALL_ONE             BIT(4)
-+#define   RTL_ECC_OP_STATUS           BIT(0)
-+
-+struct rtl_ecc_engine {
-+      struct device *dev;
-+      struct nand_ecc_engine engine;
-+      struct mutex lock;
-+      char *buf;
-+      dma_addr_t buf_dma;
-+      struct regmap *regmap;
-+};
-+
-+struct rtl_ecc_ctx {
-+      struct rtl_ecc_engine * rtlc;
-+      struct nand_ecc_req_tweak_ctx req_ctx;
-+      int steps;
-+      int bch_mode;
-+      int strength;
-+      int parity_size;
-+};
-+
-+static const struct regmap_config rtl_ecc_regmap_config = {
-+      .reg_bits       = 32,
-+      .val_bits       = 32,
-+      .reg_stride     = 4,
-+};
-+
-+static inline void *nand_to_ctx(struct nand_device *nand)
-+{
-+      return nand->ecc.ctx.priv;
-+}
-+
-+static inline struct rtl_ecc_engine *nand_to_rtlc(struct nand_device *nand)
-+{
-+      struct nand_ecc_engine *eng = nand->ecc.engine;
-+
-+      return container_of(eng, struct rtl_ecc_engine, engine);
-+}
-+
-+static int rtl_ecc_ooblayout_ecc(struct mtd_info *mtd, int section,
-+                               struct mtd_oob_region *oobregion)
-+{
-+      struct nand_device *nand = mtd_to_nanddev(mtd);
-+      struct rtl_ecc_ctx *ctx = nand_to_ctx(nand);
-+
-+      if (section < 0 || section >= ctx->steps)
-+              return -ERANGE;
-+
-+      oobregion->offset = ctx->steps * RTL_ECC_FREE_SIZE + section * ctx->parity_size;
-+      oobregion->length = ctx->parity_size;
-+
-+      return 0;
-+}
-+
-+static int rtl_ecc_ooblayout_free(struct mtd_info *mtd, int section,
-+                                struct mtd_oob_region *oobregion)
-+{
-+      struct nand_device *nand = mtd_to_nanddev(mtd);
-+      struct rtl_ecc_ctx *ctx = nand_to_ctx(nand);
-+      int bbm;
-+
-+      if (section < 0 || section >= ctx->steps)
-+              return -ERANGE;
-+
-+      /* reserve 2 BBM bytes in first block */
-+      bbm = section ? 0 : 2;
-+      oobregion->offset = section * RTL_ECC_FREE_SIZE + bbm;
-+      oobregion->length = RTL_ECC_FREE_SIZE - bbm;
-+
-+      return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops rtl_ecc_ooblayout_ops = {
-+      .ecc = rtl_ecc_ooblayout_ecc,
-+      .free = rtl_ecc_ooblayout_free,
-+};
-+
-+static void rtl_ecc_kick_engine(struct rtl_ecc_ctx *ctx, int operation)
-+{
-+      struct rtl_ecc_engine *rtlc = ctx->rtlc;
-+
-+      regmap_write(rtlc->regmap, RTL_ECC_CFG,
-+                   ctx->bch_mode | RTL_ECC_BURST_128 | RTL_ECC_DMA_PRECISE);
-+
-+      regmap_write(rtlc->regmap, RTL_ECC_DMA_START, rtlc->buf_dma);
-+      regmap_write(rtlc->regmap, RTL_ECC_DMA_TAG, rtlc->buf_dma + RTL_ECC_BLOCK_SIZE);
-+      regmap_write(rtlc->regmap, RTL_ECC_DMA_TRIGGER, operation);
-+}
-+
-+static int rtl_ecc_wait_for_engine(struct rtl_ecc_ctx *ctx)
-+{
-+      struct rtl_ecc_engine *rtlc = ctx->rtlc;
-+      int ret, status, bitflips;
-+      bool all_one;
-+
-+      /*
-+       * The ECC engine needs 6-8 us to encode/decode a BCH6 syndrome for 512 bytes of data
-+       * and 6 free bytes. In case the NAND area has been erased and all data and oob is
-+       * set to 0xff, decoding takes 30us (reason unknown). Although the engine can trigger
-+       * interrupts when finished, use active polling for now. 12 us maximum wait time has
-+       * proven to be a good tradeoff between performance and overhead.
-+       */
-+
-+      ret = regmap_read_poll_timeout(rtlc->regmap, RTL_ECC_STATUS, status,
-+                                     !(status & RTL_ECC_OP_STATUS), 12, 1000000);
-+      if (ret)
-+              return ret;
-+
-+      ret = FIELD_GET(RTL_ECC_RESULT, status);
-+      all_one = FIELD_GET(RTL_ECC_ALL_ONE, status);
-+      bitflips = FIELD_GET(RTL_ECC_CORR_COUNT, status);
-+
-+      /* For erased blocks (all bits one) error status can be ignored */
-+      if (all_one)
-+              ret = 0;
-+
-+      return ret ? -EBADMSG : bitflips;
-+}
-+
-+static int rtl_ecc_run_engine(struct rtl_ecc_ctx *ctx, char *data, char *free,
-+                            char *parity, int operation)
-+{
-+      struct rtl_ecc_engine *rtlc = ctx->rtlc;
-+      char *buf_parity = rtlc->buf + RTL_ECC_BLOCK_SIZE + RTL_ECC_FREE_SIZE;
-+      char *buf_free = rtlc->buf + RTL_ECC_BLOCK_SIZE;
-+      char *buf_data = rtlc->buf;
-+      int ret;
-+
-+      mutex_lock(&rtlc->lock);
-+
-+      memcpy(buf_data, data, RTL_ECC_BLOCK_SIZE);
-+      memcpy(buf_free, free, RTL_ECC_FREE_SIZE);
-+      memcpy(buf_parity, parity, ctx->parity_size);
-+
-+      dma_sync_single_for_device(rtlc->dev, rtlc->buf_dma, RTL_ECC_DMA_SIZE, DMA_TO_DEVICE);
-+      rtl_ecc_kick_engine(ctx, operation);
-+      ret = rtl_ecc_wait_for_engine(ctx);
-+      dma_sync_single_for_cpu(rtlc->dev, rtlc->buf_dma, RTL_ECC_DMA_SIZE, DMA_FROM_DEVICE);
-+
-+      if (ret >= 0) {
-+              memcpy(data, buf_data, RTL_ECC_BLOCK_SIZE);
-+              memcpy(free, buf_free, RTL_ECC_FREE_SIZE);
-+              memcpy(parity, buf_parity, ctx->parity_size);
-+      }
-+
-+      mutex_unlock(&rtlc->lock);
-+
-+      return ret;
-+}
-+
-+static int rtl_ecc_prepare_io_req(struct nand_device *nand, struct nand_page_io_req *req)
-+{
-+      struct rtl_ecc_engine *rtlc = nand_to_rtlc(nand);
-+      struct rtl_ecc_ctx *ctx = nand_to_ctx(nand);
-+      char *data, *free, *parity;
-+      int ret = 0;
-+
-+      if (req->mode == MTD_OPS_RAW)
-+              return 0;
-+
-+      nand_ecc_tweak_req(&ctx->req_ctx, req);
-+
-+      if (req->type == NAND_PAGE_READ)
-+              return 0;
-+
-+      free = req->oobbuf.in;
-+      data = req->databuf.in;
-+      parity = req->oobbuf.in + ctx->steps * RTL_ECC_FREE_SIZE;
-+
-+      for (int i = 0; i < ctx->steps; i++) {
-+              ret |= rtl_ecc_run_engine(ctx, data, free, parity, RTL_ECC_OP_ENCODE);
-+
-+              free += RTL_ECC_FREE_SIZE;
-+              data += RTL_ECC_BLOCK_SIZE;
-+              parity += ctx->parity_size;
-+      }
-+
-+      if (unlikely(ret))
-+              dev_dbg(rtlc->dev, "ECC calculation failed\n");
-+
-+      return ret ? -EBADMSG : 0;
-+}
-+
-+static int rtl_ecc_finish_io_req(struct nand_device *nand, struct nand_page_io_req *req)
-+{
-+      struct rtl_ecc_engine *rtlc = nand_to_rtlc(nand);
-+      struct rtl_ecc_ctx *ctx = nand_to_ctx(nand);
-+      struct mtd_info *mtd = nanddev_to_mtd(nand);
-+      char *data, *free, *parity;
-+      bool failure = false;
-+      int bitflips = 0;
-+
-+      if (req->mode == MTD_OPS_RAW)
-+              return 0;
-+
-+      if (req->type == NAND_PAGE_WRITE) {
-+              nand_ecc_restore_req(&ctx->req_ctx, req);
-+              return 0;
-+      }
-+
-+      free = req->oobbuf.in;
-+      data = req->databuf.in;
-+      parity = req->oobbuf.in + ctx->steps * RTL_ECC_FREE_SIZE;
-+
-+      for (int i = 0 ; i < ctx->steps; i++) {
-+              int ret = rtl_ecc_run_engine(ctx, data, free, parity, RTL_ECC_OP_DECODE);
-+
-+              if (unlikely(ret < 0))
-+                      /* ECC totally fails for bitflips in erased blocks */
-+                      ret = nand_check_erased_ecc_chunk(data, RTL_ECC_BLOCK_SIZE,
-+                                                        parity, ctx->parity_size,
-+                                                        free, RTL_ECC_FREE_SIZE,
-+                                                        ctx->strength);
-+              if (unlikely(ret < 0)) {
-+                      failure = true;
-+                      mtd->ecc_stats.failed++;
-+              } else {
-+                      mtd->ecc_stats.corrected += ret;
-+                      bitflips = max_t(unsigned int, bitflips, ret);
-+              }
-+
-+              free += RTL_ECC_FREE_SIZE;
-+              data += RTL_ECC_BLOCK_SIZE;
-+              parity += ctx->parity_size;
-+      }
-+
-+      nand_ecc_restore_req(&ctx->req_ctx, req);
-+
-+      if (unlikely(failure))
-+              dev_dbg(rtlc->dev, "ECC correction failed\n");
-+      else if (unlikely(bitflips > 2))
-+              dev_dbg(rtlc->dev, "%d bitflips detected\n", bitflips);
-+
-+      return failure ? -EBADMSG : bitflips;
-+}
-+
-+static int rtl_ecc_check_support(struct nand_device *nand)
-+{
-+      struct mtd_info *mtd = nanddev_to_mtd(nand);
-+      struct device *dev = nand->ecc.engine->dev;
-+
-+      if (mtd->oobsize != RTL_ECC_ALLOWED_OOB_SIZE ||
-+          mtd->writesize != RTL_ECC_ALLOWED_PAGE_SIZE) {
-+              dev_err(dev, "only flash geometry data=%d, oob=%d supported\n",
-+                      RTL_ECC_ALLOWED_PAGE_SIZE, RTL_ECC_ALLOWED_OOB_SIZE);
-+              return -EINVAL;
-+      }
-+
-+      if (nand->ecc.user_conf.algo != NAND_ECC_ALGO_BCH ||
-+          nand->ecc.user_conf.strength != RTL_ECC_ALLOWED_STRENGTH ||
-+          nand->ecc.user_conf.placement != NAND_ECC_PLACEMENT_OOB ||
-+          nand->ecc.user_conf.step_size != RTL_ECC_BLOCK_SIZE) {
-+              dev_err(dev, "only algo=bch, strength=%d, placement=oob, step=%d supported\n",
-+                      RTL_ECC_ALLOWED_STRENGTH, RTL_ECC_BLOCK_SIZE);
-+              return -EINVAL;
-+      }
-+
-+      return 0;
-+}
-+
-+static int rtl_ecc_init_ctx(struct nand_device *nand)
-+{
-+      struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
-+      struct rtl_ecc_engine *rtlc = nand_to_rtlc(nand);
-+      struct mtd_info *mtd = nanddev_to_mtd(nand);
-+      int strength = nand->ecc.user_conf.strength;
-+      struct device *dev = nand->ecc.engine->dev;
-+      struct rtl_ecc_ctx *ctx;
-+      int ret;
-+
-+      ret = rtl_ecc_check_support(nand);
-+      if (ret)
-+              return ret;
-+
-+      ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
-+      if (!ctx)
-+              return -ENOMEM;
-+
-+      nand->ecc.ctx.priv = ctx;
-+      mtd_set_ooblayout(mtd, &rtl_ecc_ooblayout_ops);
-+
-+      conf->algo = NAND_ECC_ALGO_BCH;
-+      conf->strength = strength;
-+      conf->step_size = RTL_ECC_BLOCK_SIZE;
-+      conf->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
-+
-+      ctx->rtlc = rtlc;
-+      ctx->steps = mtd->writesize / RTL_ECC_BLOCK_SIZE;
-+      ctx->strength = strength;
-+      ctx->bch_mode = strength == 6 ? RTL_ECC_BCH6 : RTL_ECC_BCH12;
-+      ctx->parity_size = strength == 6 ? RTL_ECC_PARITY_SIZE_BCH6 : RTL_ECC_PARITY_SIZE_BCH12;
-+
-+      ret = nand_ecc_init_req_tweaking(&ctx->req_ctx, nand);
-+      if (ret)
-+              return ret;
-+
-+      dev_dbg(dev, "using bch%d with geometry data=%dx%d, free=%dx6, parity=%dx%d",
-+              conf->strength, ctx->steps, conf->step_size,
-+              ctx->steps, ctx->steps, ctx->parity_size);
-+
-+      return 0;
-+}
-+
-+static void rtl_ecc_cleanup_ctx(struct nand_device *nand)
-+{
-+      struct rtl_ecc_ctx *ctx = nand_to_ctx(nand);
-+
-+      if (ctx)
-+              nand_ecc_cleanup_req_tweaking(&ctx->req_ctx);
-+}
-+
-+static struct nand_ecc_engine_ops rtl_ecc_engine_ops = {
-+      .init_ctx = rtl_ecc_init_ctx,
-+      .cleanup_ctx = rtl_ecc_cleanup_ctx,
-+      .prepare_io_req = rtl_ecc_prepare_io_req,
-+      .finish_io_req = rtl_ecc_finish_io_req,
-+};
-+
-+static int rtl_ecc_probe(struct platform_device *pdev)
-+{
-+      struct device *dev = &pdev->dev;
-+      struct rtl_ecc_engine *rtlc;
-+      void __iomem *base;
-+      int ret;
-+
-+      rtlc = devm_kzalloc(dev, sizeof(*rtlc), GFP_KERNEL);
-+      if (!rtlc)
-+              return -ENOMEM;
-+
-+      base = devm_platform_ioremap_resource(pdev, 0);
-+      if (IS_ERR(base))
-+              return PTR_ERR(base);
-+
-+      ret = devm_mutex_init(dev, &rtlc->lock);
-+      if (ret)
-+              return ret;
-+
-+      rtlc->regmap = devm_regmap_init_mmio(dev, base, &rtl_ecc_regmap_config);
-+      if (IS_ERR(rtlc->regmap))
-+              return PTR_ERR(rtlc->regmap);
-+
-+      /*
-+       * Focus on simplicity and use a preallocated DMA buffer for data exchange with the
-+       * engine. For now make it a noncoherent memory model as invalidating/flushing caches
-+       * is faster than reading/writing uncached memory on the known architectures.
-+       */
-+
-+      rtlc->buf = dma_alloc_noncoherent(dev, RTL_ECC_DMA_SIZE, &rtlc->buf_dma,
-+                                        DMA_BIDIRECTIONAL, GFP_KERNEL);
-+      if (IS_ERR(rtlc->buf))
-+              return PTR_ERR(rtlc->buf);
-+
-+      rtlc->dev = dev;
-+      rtlc->engine.dev = dev;
-+      rtlc->engine.ops = &rtl_ecc_engine_ops;
-+      rtlc->engine.integration = NAND_ECC_ENGINE_INTEGRATION_EXTERNAL;
-+
-+      nand_ecc_register_on_host_hw_engine(&rtlc->engine);
-+
-+      platform_set_drvdata(pdev, rtlc);
-+
-+      return 0;
-+}
-+
-+static void rtl_ecc_remove(struct platform_device *pdev)
-+{
-+      struct rtl_ecc_engine *rtlc = platform_get_drvdata(pdev);
-+
-+      nand_ecc_unregister_on_host_hw_engine(&rtlc->engine);
-+      dma_free_noncoherent(rtlc->dev, RTL_ECC_DMA_SIZE, rtlc->buf, rtlc->buf_dma,
-+                           DMA_BIDIRECTIONAL);
-+}
-+
-+static const struct of_device_id rtl_ecc_of_ids[] = {
-+      {
-+              .compatible = "realtek,rtl9301-ecc",
-+      },
-+      { /* sentinel */ },
-+};
-+
-+static struct platform_driver rtl_ecc_driver = {
-+      .driver = {
-+              .name = "rtl-nand-ecc-engine",
-+              .of_match_table = rtl_ecc_of_ids,
-+      },
-+      .probe = rtl_ecc_probe,
-+      .remove = rtl_ecc_remove,
-+};
-+module_platform_driver(rtl_ecc_driver);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Markus Stockhausen <markus.stockhausen@gmx.de>");
-+MODULE_DESCRIPTION("Realtek NAND hardware ECC controller");
diff --git a/target/linux/realtek/patches-6.18/302-6.17-irqchip-mips-gic-forced-affinity.patch b/target/linux/realtek/patches-6.18/302-6.17-irqchip-mips-gic-forced-affinity.patch
deleted file mode 100644 (file)
index cf04d60..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 2250db8628a0d8293ad2e0671138b848a185fba1 Mon Sep 17 00:00:00 2001
-From: Markus Stockhausen <markus.stockhausen@gmx.de>
-Date: Sat, 21 Jun 2025 01:49:51 -0400
-Subject: irqchip/mips-gic: Allow forced affinity
-
-Devices of the Realtek MIPS Otto platform use the official rtl-otto-timer
-as clock event generator and CPU clocksource. It is registered for each CPU
-startup via cpuhp_setup_state() and forces the affinity of the clockevent
-interrupts to the appropriate CPU via irq_force_affinity().
-
-On the "smaller" devices with a vendor specific interrupt controller
-(supported by irq-realtek-rtl) the registration works fine. The "larger"
-RTL931x series is based on a MIPS interAptiv dual core with a MIPS GIC
-controller. Interrupt routing setup is cancelled because gic_set_affinity()
-does not accept the current (not yet online) CPU as a target.
-
-Relax the checks by evaluating the force parameter that is provided for
-exactly this purpose like in other drivers. With this the affinity can be
-set as follows:
-
- - force = false: allow to set affinity to any online cpu
- - force = true:  allow to set affinity to any cpu
-
-Co-developed-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
-Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
-Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Link: https://lore.kernel.org/all/20250621054952.380374-1-markus.stockhausen@gmx.de
----
- drivers/irqchip/irq-mips-gic.c | 8 ++++++--
- 1 file changed, 6 insertions(+), 2 deletions(-)
-
---- a/drivers/irqchip/irq-mips-gic.c
-+++ b/drivers/irqchip/irq-mips-gic.c
-@@ -263,7 +263,11 @@ static int gic_set_affinity(struct irq_d
-       unsigned long flags;
-       unsigned int cpu;
--      cpu = cpumask_first_and(cpumask, cpu_online_mask);
-+      if (force)
-+              cpu = cpumask_first(cpumask);
-+      else
-+              cpu = cpumask_first_and(cpumask, cpu_online_mask);
-+
-       if (cpu >= NR_CPUS)
-               return -EINVAL;