aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7981.dtsi6
-rw-r--r--target/linux/mediatek/patches-5.15/810-i2c-mediatek-add-support-for-MT7981-SoC.patch74
-rw-r--r--target/linux/mediatek/patches-5.15/840-v5.16-i2c-mediatek-Reset-the-handshake-signal-between-i2c-.patch74
-rw-r--r--target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch102
-rw-r--r--target/linux/mediatek/patches-5.15/842-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8186.patch45
-rw-r--r--target/linux/mediatek/patches-5.15/843-v5.18-i2c-mediatek-modify-bus-speed-calculation-formula.patch132
-rw-r--r--target/linux/mediatek/patches-5.15/844-v5.18-i2c-mediatek-remove-redundant-null-check.patch41
-rw-r--r--target/linux/mediatek/patches-5.15/845-v5.18-i2c-mt65xx-Simplify-with-clk-bulk.patch234
-rw-r--r--target/linux/mediatek/patches-5.15/846-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8168.patch46
-rw-r--r--target/linux/mediatek/patches-5.15/847-v5.19-i2c-mediatek-Optimize-master_xfer-and-avoid-circular.patch101
-rw-r--r--target/linux/mediatek/patches-5.15/848-v5.19-i2c-mediatek-Fix-an-error-handling-path-in-mtk_i2c_p.patch48
-rw-r--r--target/linux/mediatek/patches-5.15/849-v6.0-i2c-mediatek-add-i2c-compatible-for-MT8188.patch82
-rw-r--r--target/linux/mediatek/patches-5.15/850-v6.0-i2c-move-drivers-from-strlcpy-to-strscpy.patch579
-rw-r--r--target/linux/mediatek/patches-5.15/851-v6.2-i2c-mediatek-add-mt7986-support.patch (renamed from target/linux/mediatek/patches-5.15/803-i2c-busses-add-mt7986-support.patch)24
-rw-r--r--target/linux/mediatek/patches-5.15/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch42
-rw-r--r--target/linux/mediatek/patches-5.15/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch33
-rw-r--r--target/linux/mediatek/patches-5.15/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch47
-rw-r--r--target/linux/mediatek/patches-5.15/855-pending-i2c-mt65xx-add-additional-clocks.patch55
18 files changed, 1684 insertions, 81 deletions
diff --git a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7981.dtsi b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7981.dtsi
index 95b548143b..07a8c06979 100644
--- a/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7981.dtsi
+++ b/target/linux/mediatek/files-5.15/arch/arm64/boot/dts/mediatek/mt7981.dtsi
@@ -317,8 +317,10 @@
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
clock-div = <1>;
clocks = <&infracfg CLK_INFRA_I2C0_CK>,
- <&infracfg CLK_INFRA_AP_DMA_CK>;
- clock-names = "main", "dma";
+ <&infracfg CLK_INFRA_AP_DMA_CK>,
+ <&infracfg CLK_INFRA_I2C_MCK_CK>,
+ <&infracfg CLK_INFRA_I2C_PCK_CK>;
+ clock-names = "main", "dma", "mck", "pck";
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
diff --git a/target/linux/mediatek/patches-5.15/810-i2c-mediatek-add-support-for-MT7981-SoC.patch b/target/linux/mediatek/patches-5.15/810-i2c-mediatek-add-support-for-MT7981-SoC.patch
deleted file mode 100644
index f9ad79c443..0000000000
--- a/target/linux/mediatek/patches-5.15/810-i2c-mediatek-add-support-for-MT7981-SoC.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From bd4f7dae6a1f2fd65bb2112783c92ffe0839bc77 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 28 Feb 2023 23:53:56 +0000
-Subject: [PATCH] i2c: mediatek: add support for MT7981 SoC
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/i2c/busses/i2c-mt65xx.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
-
---- a/drivers/i2c/busses/i2c-mt65xx.c
-+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -202,6 +202,34 @@ static const u16 mt_i2c_regs_v2[] = {
- [OFFSET_DCM_EN] = 0xf88,
- };
-
-+static const u16 mt_i2c_regs_v3[] = {
-+ [OFFSET_DATA_PORT] = 0x0,
-+ [OFFSET_INTR_MASK] = 0x8,
-+ [OFFSET_INTR_STAT] = 0xc,
-+ [OFFSET_CONTROL] = 0x10,
-+ [OFFSET_TRANSFER_LEN] = 0x14,
-+ [OFFSET_TRANSAC_LEN] = 0x18,
-+ [OFFSET_DELAY_LEN] = 0x1c,
-+ [OFFSET_TIMING] = 0x20,
-+ [OFFSET_START] = 0x24,
-+ [OFFSET_EXT_CONF] = 0x28,
-+ [OFFSET_LTIMING] = 0x2c,
-+ [OFFSET_HS] = 0x30,
-+ [OFFSET_IO_CONFIG] = 0x34,
-+ [OFFSET_FIFO_ADDR_CLR] = 0x38,
-+ [OFFSET_SDA_TIMING] = 0x3c,
-+ [OFFSET_TRANSFER_LEN_AUX] = 0x44,
-+ [OFFSET_CLOCK_DIV] = 0x48,
-+ [OFFSET_SOFTRESET] = 0x50,
-+ [OFFSET_SCL_MIS_COMP_POINT] = 0x90,
-+ [OFFSET_SLAVE_ADDR] = 0x94,
-+ [OFFSET_DEBUGSTAT] = 0xe4,
-+ [OFFSET_DEBUGCTRL] = 0xe8,
-+ [OFFSET_FIFO_STAT] = 0xf4,
-+ [OFFSET_FIFO_THRESH] = 0xf8,
-+ [OFFSET_DCM_EN] = 0xf88,
-+};
-+
- struct mtk_i2c_compatible {
- const struct i2c_adapter_quirks *quirks;
- const u16 *regs;
-@@ -365,6 +393,18 @@ static const struct mtk_i2c_compatible m
- .max_dma_support = 32,
- };
-
-+static const struct mtk_i2c_compatible mt7981_compat = {
-+ .regs = mt_i2c_regs_v3,
-+ .pmic_i2c = 0,
-+ .dcm = 0,
-+ .auto_restart = 1,
-+ .aux_len_reg = 1,
-+ .timing_adjust = 1,
-+ .dma_sync = 1,
-+ .ltiming_adjust = 1,
-+ .max_dma_support = 33
-+};
-+
- static const struct mtk_i2c_compatible mt7986_compat = {
- .quirks = &mt7622_i2c_quirks,
- .regs = mt_i2c_regs_v1,
-@@ -424,6 +464,7 @@ static const struct of_device_id mtk_i2c
- { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
- { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
- { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
-+ { .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },
- { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
- { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
- { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
diff --git a/target/linux/mediatek/patches-5.15/840-v5.16-i2c-mediatek-Reset-the-handshake-signal-between-i2c-.patch b/target/linux/mediatek/patches-5.15/840-v5.16-i2c-mediatek-Reset-the-handshake-signal-between-i2c-.patch
new file mode 100644
index 0000000000..8b01196409
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/840-v5.16-i2c-mediatek-Reset-the-handshake-signal-between-i2c-.patch
@@ -0,0 +1,74 @@
+From 95e4dfbf33dc0a0843ba20db811f7ea271235e1e Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Sun, 10 Oct 2021 15:05:12 +0800
+Subject: [PATCH 01/16] i2c: mediatek: Reset the handshake signal between i2c
+ and dma
+
+Due to changes in the hardware design of the handshaking signal
+between i2c and dma, it is necessary to reset the handshaking
+signal before each transfer to ensure that the multi-msgs can
+be transferred correctly.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -15,6 +15,7 @@
+ #include <linux/init.h>
+ #include <linux/interrupt.h>
+ #include <linux/io.h>
++#include <linux/iopoll.h>
+ #include <linux/kernel.h>
+ #include <linux/mm.h>
+ #include <linux/module.h>
+@@ -49,6 +50,8 @@
+ #define I2C_RD_TRANAC_VALUE 0x0001
+ #define I2C_SCL_MIS_COMP_VALUE 0x0000
+ #define I2C_CHN_CLR_FLAG 0x0000
++#define I2C_RELIABILITY 0x0010
++#define I2C_DMAACK_ENABLE 0x0008
+
+ #define I2C_DMA_CON_TX 0x0000
+ #define I2C_DMA_CON_RX 0x0001
+@@ -851,6 +854,7 @@ static int mtk_i2c_do_transfer(struct mt
+ u16 restart_flag = 0;
+ u16 dma_sync = 0;
+ u32 reg_4g_mode;
++ u32 reg_dma_reset;
+ u8 *dma_rd_buf = NULL;
+ u8 *dma_wr_buf = NULL;
+ dma_addr_t rpaddr = 0;
+@@ -864,6 +868,28 @@ static int mtk_i2c_do_transfer(struct mt
+
+ reinit_completion(&i2c->msg_complete);
+
++ if (i2c->dev_comp->apdma_sync &&
++ i2c->op != I2C_MASTER_WRRD && num > 1) {
++ mtk_i2c_writew(i2c, 0x00, OFFSET_DEBUGCTRL);
++ writel(I2C_DMA_HANDSHAKE_RST | I2C_DMA_WARM_RST,
++ i2c->pdmabase + OFFSET_RST);
++
++ ret = readw_poll_timeout(i2c->pdmabase + OFFSET_RST,
++ reg_dma_reset,
++ !(reg_dma_reset & I2C_DMA_WARM_RST),
++ 0, 100);
++ if (ret) {
++ dev_err(i2c->dev, "DMA warm reset timeout\n");
++ return -ETIMEDOUT;
++ }
++
++ writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST);
++ mtk_i2c_writew(i2c, I2C_HANDSHAKE_RST, OFFSET_SOFTRESET);
++ mtk_i2c_writew(i2c, I2C_CHN_CLR_FLAG, OFFSET_SOFTRESET);
++ mtk_i2c_writew(i2c, I2C_RELIABILITY | I2C_DMAACK_ENABLE,
++ OFFSET_DEBUGCTRL);
++ }
++
+ control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) &
+ ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
+ if ((i2c->speed_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) || (left_num >= 1))
diff --git a/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch b/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch
new file mode 100644
index 0000000000..a2d2521c77
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/841-v5.16-i2c-mediatek-Dump-i2c-dma-register-when-a-timeout-oc.patch
@@ -0,0 +1,102 @@
+From 5b8e29e566e086ef9b5b9ea0d054370a295e1d05 Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Sun, 10 Oct 2021 15:05:13 +0800
+Subject: [PATCH 02/16] i2c: mediatek: Dump i2c/dma register when a timeout
+ occurs
+
+When a timeout error occurs in i2c transter, it is usually related
+to the i2c/dma IP hardware configuration. Therefore, the purpose of
+this patch is to dump the key register values of i2c/dma when a
+timeout occurs in i2c for debugging.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 54 +++++++++++++++++++++++++++++++++
+ 1 file changed, 54 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -130,6 +130,7 @@ enum I2C_REGS_OFFSET {
+ OFFSET_HS,
+ OFFSET_SOFTRESET,
+ OFFSET_DCM_EN,
++ OFFSET_MULTI_DMA,
+ OFFSET_PATH_DIR,
+ OFFSET_DEBUGSTAT,
+ OFFSET_DEBUGCTRL,
+@@ -197,6 +198,7 @@ static const u16 mt_i2c_regs_v2[] = {
+ [OFFSET_TRANSFER_LEN_AUX] = 0x44,
+ [OFFSET_CLOCK_DIV] = 0x48,
+ [OFFSET_SOFTRESET] = 0x50,
++ [OFFSET_MULTI_DMA] = 0x8c,
+ [OFFSET_SCL_MIS_COMP_POINT] = 0x90,
+ [OFFSET_DEBUGSTAT] = 0xe4,
+ [OFFSET_DEBUGCTRL] = 0xe8,
+@@ -845,6 +847,57 @@ static int mtk_i2c_set_speed(struct mtk_
+ return 0;
+ }
+
++static void i2c_dump_register(struct mtk_i2c *i2c)
++{
++ dev_dbg(i2c->dev, "SLAVE_ADDR: 0x%x, INTR_MASK: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_SLAVE_ADDR),
++ mtk_i2c_readw(i2c, OFFSET_INTR_MASK));
++ dev_dbg(i2c->dev, "INTR_STAT: 0x%x, CONTROL: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_INTR_STAT),
++ mtk_i2c_readw(i2c, OFFSET_CONTROL));
++ dev_dbg(i2c->dev, "TRANSFER_LEN: 0x%x, TRANSAC_LEN: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN),
++ mtk_i2c_readw(i2c, OFFSET_TRANSAC_LEN));
++ dev_dbg(i2c->dev, "DELAY_LEN: 0x%x, HTIMING: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_DELAY_LEN),
++ mtk_i2c_readw(i2c, OFFSET_TIMING));
++ dev_dbg(i2c->dev, "START: 0x%x, EXT_CONF: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_START),
++ mtk_i2c_readw(i2c, OFFSET_EXT_CONF));
++ dev_dbg(i2c->dev, "HS: 0x%x, IO_CONFIG: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_HS),
++ mtk_i2c_readw(i2c, OFFSET_IO_CONFIG));
++ dev_dbg(i2c->dev, "DCM_EN: 0x%x, TRANSFER_LEN_AUX: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_DCM_EN),
++ mtk_i2c_readw(i2c, OFFSET_TRANSFER_LEN_AUX));
++ dev_dbg(i2c->dev, "CLOCK_DIV: 0x%x, FIFO_STAT: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_CLOCK_DIV),
++ mtk_i2c_readw(i2c, OFFSET_FIFO_STAT));
++ dev_dbg(i2c->dev, "DEBUGCTRL : 0x%x, DEBUGSTAT: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_DEBUGCTRL),
++ mtk_i2c_readw(i2c, OFFSET_DEBUGSTAT));
++ if (i2c->dev_comp->regs == mt_i2c_regs_v2) {
++ dev_dbg(i2c->dev, "LTIMING: 0x%x, MULTI_DMA: 0x%x\n",
++ mtk_i2c_readw(i2c, OFFSET_LTIMING),
++ mtk_i2c_readw(i2c, OFFSET_MULTI_DMA));
++ }
++ dev_dbg(i2c->dev, "\nDMA_INT_FLAG: 0x%x, DMA_INT_EN: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_INT_FLAG),
++ readl(i2c->pdmabase + OFFSET_INT_EN));
++ dev_dbg(i2c->dev, "DMA_EN: 0x%x, DMA_CON: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_EN),
++ readl(i2c->pdmabase + OFFSET_CON));
++ dev_dbg(i2c->dev, "DMA_TX_MEM_ADDR: 0x%x, DMA_RX_MEM_ADDR: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_TX_MEM_ADDR),
++ readl(i2c->pdmabase + OFFSET_RX_MEM_ADDR));
++ dev_dbg(i2c->dev, "DMA_TX_LEN: 0x%x, DMA_RX_LEN: 0x%x\n",
++ readl(i2c->pdmabase + OFFSET_TX_LEN),
++ readl(i2c->pdmabase + OFFSET_RX_LEN));
++ dev_dbg(i2c->dev, "DMA_TX_4G_MODE: 0x%x, DMA_RX_4G_MODE: 0x%x",
++ readl(i2c->pdmabase + OFFSET_TX_4G_MODE),
++ readl(i2c->pdmabase + OFFSET_RX_4G_MODE));
++}
++
+ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs,
+ int num, int left_num)
+ {
+@@ -1075,6 +1128,7 @@ static int mtk_i2c_do_transfer(struct mt
+
+ if (ret == 0) {
+ dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr);
++ i2c_dump_register(i2c);
+ mtk_i2c_init_hw(i2c);
+ return -ETIMEDOUT;
+ }
diff --git a/target/linux/mediatek/patches-5.15/842-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8186.patch b/target/linux/mediatek/patches-5.15/842-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8186.patch
new file mode 100644
index 0000000000..184fe94ff8
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/842-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8186.patch
@@ -0,0 +1,45 @@
+From 83630e3c6147bf7bb18a18f3d5a99462464f450b Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Tue, 25 Jan 2022 19:04:13 +0800
+Subject: [PATCH 03/16] i2c: mediatek: Add i2c compatible for Mediatek MT8186
+
+Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
+MT8186 doesn't need handshake signal witch apdma.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -397,6 +397,19 @@ static const struct mtk_i2c_compatible m
+ .max_dma_support = 33,
+ };
+
++static const struct mtk_i2c_compatible mt8186_compat = {
++ .regs = mt_i2c_regs_v2,
++ .pmic_i2c = 0,
++ .dcm = 0,
++ .auto_restart = 1,
++ .aux_len_reg = 1,
++ .timing_adjust = 1,
++ .dma_sync = 0,
++ .ltiming_adjust = 1,
++ .apdma_sync = 0,
++ .max_dma_support = 36,
++};
++
+ static const struct mtk_i2c_compatible mt8192_compat = {
+ .quirks = &mt8183_i2c_quirks,
+ .regs = mt_i2c_regs_v2,
+@@ -418,6 +431,7 @@ static const struct of_device_id mtk_i2c
+ { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
+ { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
+ { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
++ { .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat },
+ { .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat },
+ {}
+ };
diff --git a/target/linux/mediatek/patches-5.15/843-v5.18-i2c-mediatek-modify-bus-speed-calculation-formula.patch b/target/linux/mediatek/patches-5.15/843-v5.18-i2c-mediatek-modify-bus-speed-calculation-formula.patch
new file mode 100644
index 0000000000..0ace4a6701
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/843-v5.18-i2c-mediatek-modify-bus-speed-calculation-formula.patch
@@ -0,0 +1,132 @@
+From f606aab3f1a49d723d66e14e545f6ca45005bda6 Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Thu, 17 Feb 2022 20:22:43 +0800
+Subject: [PATCH 04/16] i2c: mediatek: modify bus speed calculation formula
+
+When clock-div is 0 or greater than 1, the bus speed
+calculated by the old speed calculation formula will be
+larger than the target speed. So we update the formula.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 51 ++++++++++++++++++++++++++-------
+ 1 file changed, 41 insertions(+), 10 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -67,11 +67,12 @@
+
+ #define MAX_SAMPLE_CNT_DIV 8
+ #define MAX_STEP_CNT_DIV 64
+-#define MAX_CLOCK_DIV 256
++#define MAX_CLOCK_DIV_8BITS 256
++#define MAX_CLOCK_DIV_5BITS 32
+ #define MAX_HS_STEP_CNT_DIV 8
+-#define I2C_STANDARD_MODE_BUFFER (1000 / 2)
+-#define I2C_FAST_MODE_BUFFER (300 / 2)
+-#define I2C_FAST_MODE_PLUS_BUFFER (20 / 2)
++#define I2C_STANDARD_MODE_BUFFER (1000 / 3)
++#define I2C_FAST_MODE_BUFFER (300 / 3)
++#define I2C_FAST_MODE_PLUS_BUFFER (20 / 3)
+
+ #define I2C_CONTROL_RS (0x1 << 1)
+ #define I2C_CONTROL_DMA_EN (0x1 << 2)
+@@ -604,6 +605,31 @@ static int mtk_i2c_max_step_cnt(unsigned
+ return MAX_STEP_CNT_DIV;
+ }
+
++static int mtk_i2c_get_clk_div_restri(struct mtk_i2c *i2c,
++ unsigned int sample_cnt)
++{
++ int clk_div_restri = 0;
++
++ if (i2c->dev_comp->ltiming_adjust == 0)
++ return 0;
++
++ if (sample_cnt == 1) {
++ if (i2c->ac_timing.inter_clk_div == 0)
++ clk_div_restri = 0;
++ else
++ clk_div_restri = 1;
++ } else {
++ if (i2c->ac_timing.inter_clk_div == 0)
++ clk_div_restri = -1;
++ else if (i2c->ac_timing.inter_clk_div == 1)
++ clk_div_restri = 0;
++ else
++ clk_div_restri = 1;
++ }
++
++ return clk_div_restri;
++}
++
+ /*
+ * Check and Calculate i2c ac-timing
+ *
+@@ -732,6 +758,7 @@ static int mtk_i2c_calculate_speed(struc
+ unsigned int best_mul;
+ unsigned int cnt_mul;
+ int ret = -EINVAL;
++ int clk_div_restri = 0;
+
+ if (target_speed > I2C_MAX_HIGH_SPEED_MODE_FREQ)
+ target_speed = I2C_MAX_HIGH_SPEED_MODE_FREQ;
+@@ -749,7 +776,8 @@ static int mtk_i2c_calculate_speed(struc
+ * optimizing for sample_cnt * step_cnt being minimal
+ */
+ for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) {
+- step_cnt = DIV_ROUND_UP(opt_div, sample_cnt);
++ clk_div_restri = mtk_i2c_get_clk_div_restri(i2c, sample_cnt);
++ step_cnt = DIV_ROUND_UP(opt_div + clk_div_restri, sample_cnt);
+ cnt_mul = step_cnt * sample_cnt;
+ if (step_cnt > max_step_cnt)
+ continue;
+@@ -763,7 +791,7 @@ static int mtk_i2c_calculate_speed(struc
+ best_mul = cnt_mul;
+ base_sample_cnt = sample_cnt;
+ base_step_cnt = step_cnt;
+- if (best_mul == opt_div)
++ if (best_mul == (opt_div + clk_div_restri))
+ break;
+ }
+ }
+@@ -774,7 +802,8 @@ static int mtk_i2c_calculate_speed(struc
+ sample_cnt = base_sample_cnt;
+ step_cnt = base_step_cnt;
+
+- if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
++ if ((clk_src / (2 * (sample_cnt * step_cnt - clk_div_restri))) >
++ target_speed) {
+ /* In this case, hardware can't support such
+ * low i2c_bus_freq
+ */
+@@ -803,13 +832,16 @@ static int mtk_i2c_set_speed(struct mtk_
+ target_speed = i2c->speed_hz;
+ parent_clk /= i2c->clk_src_div;
+
+- if (i2c->dev_comp->timing_adjust)
+- max_clk_div = MAX_CLOCK_DIV;
++ if (i2c->dev_comp->timing_adjust && i2c->dev_comp->ltiming_adjust)
++ max_clk_div = MAX_CLOCK_DIV_5BITS;
++ else if (i2c->dev_comp->timing_adjust)
++ max_clk_div = MAX_CLOCK_DIV_8BITS;
+ else
+ max_clk_div = 1;
+
+ for (clk_div = 1; clk_div <= max_clk_div; clk_div++) {
+ clk_src = parent_clk / clk_div;
++ i2c->ac_timing.inter_clk_div = clk_div - 1;
+
+ if (target_speed > I2C_MAX_FAST_MODE_PLUS_FREQ) {
+ /* Set master code speed register */
+@@ -856,7 +888,6 @@ static int mtk_i2c_set_speed(struct mtk_
+ break;
+ }
+
+- i2c->ac_timing.inter_clk_div = clk_div - 1;
+
+ return 0;
+ }
diff --git a/target/linux/mediatek/patches-5.15/844-v5.18-i2c-mediatek-remove-redundant-null-check.patch b/target/linux/mediatek/patches-5.15/844-v5.18-i2c-mediatek-remove-redundant-null-check.patch
new file mode 100644
index 0000000000..8f3c965a8d
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/844-v5.18-i2c-mediatek-remove-redundant-null-check.patch
@@ -0,0 +1,41 @@
+From eb4a2ae019815946f574cd9f8209e12bdcd8fd34 Mon Sep 17 00:00:00 2001
+From: Xu Wang <vulab@iscas.ac.cn>
+Date: Wed, 30 Sep 2020 08:42:33 +0000
+Subject: [PATCH 05/16] i2c: mediatek: remove redundant null check
+
+Because clk_disable_unprepare already checked NULL clock parameter,
+so the additional checks are unnecessary, just remove it
+
+Signed-off-by: Xu Wang <vulab@iscas.ac.cn>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -476,8 +476,7 @@ static int mtk_i2c_clock_enable(struct m
+ return 0;
+
+ err_arb:
+- if (i2c->have_pmic)
+- clk_disable_unprepare(i2c->clk_pmic);
++ clk_disable_unprepare(i2c->clk_pmic);
+ err_pmic:
+ clk_disable_unprepare(i2c->clk_main);
+ err_main:
+@@ -488,11 +487,9 @@ err_main:
+
+ static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
+ {
+- if (i2c->clk_arb)
+- clk_disable_unprepare(i2c->clk_arb);
++ clk_disable_unprepare(i2c->clk_arb);
+
+- if (i2c->have_pmic)
+- clk_disable_unprepare(i2c->clk_pmic);
++ clk_disable_unprepare(i2c->clk_pmic);
+
+ clk_disable_unprepare(i2c->clk_main);
+ clk_disable_unprepare(i2c->clk_dma);
diff --git a/target/linux/mediatek/patches-5.15/845-v5.18-i2c-mt65xx-Simplify-with-clk-bulk.patch b/target/linux/mediatek/patches-5.15/845-v5.18-i2c-mt65xx-Simplify-with-clk-bulk.patch
new file mode 100644
index 0000000000..71d083f31a
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/845-v5.18-i2c-mt65xx-Simplify-with-clk-bulk.patch
@@ -0,0 +1,234 @@
+From cc6faa5e0772296d815fd298c231277d47308a6a Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Thu, 3 Mar 2022 10:15:47 +0100
+Subject: [PATCH 06/16] i2c: mt65xx: Simplify with clk-bulk
+
+Since depending on the SoC or specific bus functionality some clocks
+may be optional, we cannot get the benefit of using devm_clk_bulk_get()
+but, by migrating to clk-bulk, we are able to remove the custom functions
+mtk_i2c_clock_enable() and mtk_i2c_clock_disable(), increasing common
+APIs usage, hence (lightly) decreasing kernel footprint.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 124 +++++++++++++-------------------
+ 1 file changed, 51 insertions(+), 73 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -86,6 +86,27 @@
+
+ #define I2C_DRV_NAME "i2c-mt65xx"
+
++/**
++ * enum i2c_mt65xx_clks - Clocks enumeration for MT65XX I2C
++ *
++ * @I2C_MT65XX_CLK_MAIN: main clock for i2c bus
++ * @I2C_MT65XX_CLK_DMA: DMA clock for i2c via DMA
++ * @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC
++ * @I2C_MT65XX_CLK_ARB: Arbitrator clock for i2c
++ * @I2C_MT65XX_CLK_MAX: Number of supported clocks
++ */
++enum i2c_mt65xx_clks {
++ I2C_MT65XX_CLK_MAIN = 0,
++ I2C_MT65XX_CLK_DMA,
++ I2C_MT65XX_CLK_PMIC,
++ I2C_MT65XX_CLK_ARB,
++ I2C_MT65XX_CLK_MAX
++};
++
++static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = {
++ "main", "dma", "pmic", "arb"
++};
++
+ enum DMA_REGS_OFFSET {
+ OFFSET_INT_FLAG = 0x0,
+ OFFSET_INT_EN = 0x04,
+@@ -244,10 +265,7 @@ struct mtk_i2c {
+ /* set in i2c probe */
+ void __iomem *base; /* i2c base addr */
+ void __iomem *pdmabase; /* dma base address*/
+- struct clk *clk_main; /* main clock for i2c bus */
+- struct clk *clk_dma; /* DMA clock for i2c via DMA */
+- struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */
+- struct clk *clk_arb; /* Arbitrator clock for i2c */
++ struct clk_bulk_data clocks[I2C_MT65XX_CLK_MAX]; /* clocks for i2c */
+ bool have_pmic; /* can use i2c pins from PMIC */
+ bool use_push_pull; /* IO config push-pull mode */
+
+@@ -449,52 +467,6 @@ static void mtk_i2c_writew(struct mtk_i2
+ writew(val, i2c->base + i2c->dev_comp->regs[reg]);
+ }
+
+-static int mtk_i2c_clock_enable(struct mtk_i2c *i2c)
+-{
+- int ret;
+-
+- ret = clk_prepare_enable(i2c->clk_dma);
+- if (ret)
+- return ret;
+-
+- ret = clk_prepare_enable(i2c->clk_main);
+- if (ret)
+- goto err_main;
+-
+- if (i2c->have_pmic) {
+- ret = clk_prepare_enable(i2c->clk_pmic);
+- if (ret)
+- goto err_pmic;
+- }
+-
+- if (i2c->clk_arb) {
+- ret = clk_prepare_enable(i2c->clk_arb);
+- if (ret)
+- goto err_arb;
+- }
+-
+- return 0;
+-
+-err_arb:
+- clk_disable_unprepare(i2c->clk_pmic);
+-err_pmic:
+- clk_disable_unprepare(i2c->clk_main);
+-err_main:
+- clk_disable_unprepare(i2c->clk_dma);
+-
+- return ret;
+-}
+-
+-static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
+-{
+- clk_disable_unprepare(i2c->clk_arb);
+-
+- clk_disable_unprepare(i2c->clk_pmic);
+-
+- clk_disable_unprepare(i2c->clk_main);
+- clk_disable_unprepare(i2c->clk_dma);
+-}
+-
+ static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
+ {
+ u16 control_reg;
+@@ -1191,7 +1163,7 @@ static int mtk_i2c_transfer(struct i2c_a
+ int left_num = num;
+ struct mtk_i2c *i2c = i2c_get_adapdata(adap);
+
+- ret = mtk_i2c_clock_enable(i2c);
++ ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+ if (ret)
+ return ret;
+
+@@ -1245,7 +1217,7 @@ static int mtk_i2c_transfer(struct i2c_a
+ ret = num;
+
+ err_exit:
+- mtk_i2c_clock_disable(i2c);
++ clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
+ return ret;
+ }
+
+@@ -1323,9 +1295,8 @@ static int mtk_i2c_probe(struct platform
+ {
+ int ret = 0;
+ struct mtk_i2c *i2c;
+- struct clk *clk;
+ struct resource *res;
+- int irq;
++ int i, irq, speed_clk;
+
+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+@@ -1371,35 +1342,42 @@ static int mtk_i2c_probe(struct platform
+ if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
+ return -EINVAL;
+
+- i2c->clk_main = devm_clk_get(&pdev->dev, "main");
+- if (IS_ERR(i2c->clk_main)) {
++ /* Fill in clk-bulk IDs */
++ for (i = 0; i < I2C_MT65XX_CLK_MAX; i++)
++ i2c->clocks[i].id = i2c_mt65xx_clk_ids[i];
++
++ /* Get clocks one by one, some may be optional */
++ i2c->clocks[I2C_MT65XX_CLK_MAIN].clk = devm_clk_get(&pdev->dev, "main");
++ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk)) {
+ dev_err(&pdev->dev, "cannot get main clock\n");
+- return PTR_ERR(i2c->clk_main);
++ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk);
+ }
+
+- i2c->clk_dma = devm_clk_get(&pdev->dev, "dma");
+- if (IS_ERR(i2c->clk_dma)) {
++ i2c->clocks[I2C_MT65XX_CLK_DMA].clk = devm_clk_get(&pdev->dev, "dma");
++ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk)) {
+ dev_err(&pdev->dev, "cannot get dma clock\n");
+- return PTR_ERR(i2c->clk_dma);
++ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk);
+ }
+
+- i2c->clk_arb = devm_clk_get(&pdev->dev, "arb");
+- if (IS_ERR(i2c->clk_arb))
+- i2c->clk_arb = NULL;
++ i2c->clocks[I2C_MT65XX_CLK_ARB].clk = devm_clk_get_optional(&pdev->dev, "arb");
++ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
++ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
+
+- clk = i2c->clk_main;
+ if (i2c->have_pmic) {
+- i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic");
+- if (IS_ERR(i2c->clk_pmic)) {
++ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
++ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
+ dev_err(&pdev->dev, "cannot get pmic clock\n");
+- return PTR_ERR(i2c->clk_pmic);
++ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
+ }
+- clk = i2c->clk_pmic;
++ speed_clk = I2C_MT65XX_CLK_PMIC;
++ } else {
++ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
++ speed_clk = I2C_MT65XX_CLK_MAIN;
+ }
+
+ strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
+
+- ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
++ ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to set the speed.\n");
+ return -EINVAL;
+@@ -1414,13 +1392,13 @@ static int mtk_i2c_probe(struct platform
+ }
+ }
+
+- ret = mtk_i2c_clock_enable(i2c);
++ ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+ if (ret) {
+ dev_err(&pdev->dev, "clock enable failed!\n");
+ return ret;
+ }
+ mtk_i2c_init_hw(i2c);
+- mtk_i2c_clock_disable(i2c);
++ clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
+
+ ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
+ IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
+@@ -1465,7 +1443,7 @@ static int mtk_i2c_resume_noirq(struct d
+ int ret;
+ struct mtk_i2c *i2c = dev_get_drvdata(dev);
+
+- ret = mtk_i2c_clock_enable(i2c);
++ ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+ if (ret) {
+ dev_err(dev, "clock enable failed!\n");
+ return ret;
+@@ -1473,7 +1451,7 @@ static int mtk_i2c_resume_noirq(struct d
+
+ mtk_i2c_init_hw(i2c);
+
+- mtk_i2c_clock_disable(i2c);
++ clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
+
+ i2c_mark_adapter_resumed(&i2c->adap);
+
diff --git a/target/linux/mediatek/patches-5.15/846-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8168.patch b/target/linux/mediatek/patches-5.15/846-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8168.patch
new file mode 100644
index 0000000000..fe5be94fca
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/846-v5.18-i2c-mediatek-Add-i2c-compatible-for-Mediatek-MT8168.patch
@@ -0,0 +1,46 @@
+From de054c03f90b3ea22bc346fbf78ac716df192b2d Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Mon, 7 Mar 2022 11:36:49 +0800
+Subject: [PATCH 07/16] i2c: mediatek: Add i2c compatible for Mediatek MT8168
+
+Add i2c compatible for MT8168. Compare to MT2712 i2c controller,
+MT8168 need to synchronize signal with dma.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -389,6 +389,19 @@ static const struct mtk_i2c_compatible m
+ .max_dma_support = 32,
+ };
+
++static const struct mtk_i2c_compatible mt8168_compat = {
++ .regs = mt_i2c_regs_v1,
++ .pmic_i2c = 0,
++ .dcm = 1,
++ .auto_restart = 1,
++ .aux_len_reg = 1,
++ .timing_adjust = 1,
++ .dma_sync = 1,
++ .ltiming_adjust = 0,
++ .apdma_sync = 0,
++ .max_dma_support = 33,
++};
++
+ static const struct mtk_i2c_compatible mt8173_compat = {
+ .regs = mt_i2c_regs_v1,
+ .pmic_i2c = 0,
+@@ -448,6 +461,7 @@ static const struct of_device_id mtk_i2c
+ { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
+ { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
+ { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
++ { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
+ { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
+ { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
+ { .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat },
diff --git a/target/linux/mediatek/patches-5.15/847-v5.19-i2c-mediatek-Optimize-master_xfer-and-avoid-circular.patch b/target/linux/mediatek/patches-5.15/847-v5.19-i2c-mediatek-Optimize-master_xfer-and-avoid-circular.patch
new file mode 100644
index 0000000000..5c4ce40765
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/847-v5.19-i2c-mediatek-Optimize-master_xfer-and-avoid-circular.patch
@@ -0,0 +1,101 @@
+From 2831f9a53ec3a16012d2d23590e3ebad6084b763 Mon Sep 17 00:00:00 2001
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Date: Mon, 11 Apr 2022 15:21:07 +0200
+Subject: [PATCH 08/16] i2c: mediatek: Optimize master_xfer() and avoid
+ circular locking
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Especially (but not only) during probe, it may happen that multiple
+devices are communicating via i2c (or multiple i2c busses) and
+sometimes while others are probing asynchronously.
+For example, a Cr50 TPM may be filling entropy (or userspace may be
+reading random data) while the rt5682 (i2c) codec driver reads/sets
+some registers, like while getting/setting a clock's rate, which
+happens both during probe and during system operation.
+
+In this driver, the mtk_i2c_transfer() function (which is the i2c
+.master_xfer() callback) was granularly managing the clocks by
+performing a clk_bulk_prepare_enable() to start them and its inverse.
+This is not only creating possible circular locking dependencies in
+the some cases (like former explanation), but it's also suboptimal,
+as clk_core prepare/unprepare operations are using mutex locking,
+which creates a bit of unwanted overhead (for example, i2c trackpads
+will call master_xfer() every few milliseconds!).
+
+With this commit, we avoid both the circular locking and additional
+overhead by changing how we handle the clocks in this driver:
+- Prepare the clocks during probe (and PM resume)
+- Enable/disable clocks in mtk_i2c_transfer()
+- Unprepare the clocks only for driver removal (and PM suspend)
+
+For the sake of providing a full explanation: during probe, the
+clocks are not only prepared but also enabled, as this is needed
+for some hardware initialization but, after that, we are disabling
+but not unpreparing them, leaving an expected state for the
+aforementioned clock handling strategy.
+
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1177,7 +1177,7 @@ static int mtk_i2c_transfer(struct i2c_a
+ int left_num = num;
+ struct mtk_i2c *i2c = i2c_get_adapdata(adap);
+
+- ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
++ ret = clk_bulk_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+ if (ret)
+ return ret;
+
+@@ -1231,7 +1231,7 @@ static int mtk_i2c_transfer(struct i2c_a
+ ret = num;
+
+ err_exit:
+- clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
++ clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+ return ret;
+ }
+
+@@ -1412,7 +1412,7 @@ static int mtk_i2c_probe(struct platform
+ return ret;
+ }
+ mtk_i2c_init_hw(i2c);
+- clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
++ clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+
+ ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
+ IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
+@@ -1439,6 +1439,8 @@ static int mtk_i2c_remove(struct platfor
+
+ i2c_del_adapter(&i2c->adap);
+
++ clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
++
+ return 0;
+ }
+
+@@ -1448,6 +1450,7 @@ static int mtk_i2c_suspend_noirq(struct
+ struct mtk_i2c *i2c = dev_get_drvdata(dev);
+
+ i2c_mark_adapter_suspended(&i2c->adap);
++ clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
+
+ return 0;
+ }
+@@ -1465,7 +1468,7 @@ static int mtk_i2c_resume_noirq(struct d
+
+ mtk_i2c_init_hw(i2c);
+
+- clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
++ clk_bulk_disable(I2C_MT65XX_CLK_MAX, i2c->clocks);
+
+ i2c_mark_adapter_resumed(&i2c->adap);
+
diff --git a/target/linux/mediatek/patches-5.15/848-v5.19-i2c-mediatek-Fix-an-error-handling-path-in-mtk_i2c_p.patch b/target/linux/mediatek/patches-5.15/848-v5.19-i2c-mediatek-Fix-an-error-handling-path-in-mtk_i2c_p.patch
new file mode 100644
index 0000000000..354f12e214
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/848-v5.19-i2c-mediatek-Fix-an-error-handling-path-in-mtk_i2c_p.patch
@@ -0,0 +1,48 @@
+From 6f3a5814c7aaea4176e0ac8b1ec6dc0a65aa2808 Mon Sep 17 00:00:00 2001
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Date: Sun, 22 May 2022 14:22:07 +0200
+Subject: [PATCH 09/16] i2c: mediatek: Fix an error handling path in
+ mtk_i2c_probe()
+
+The clsk are prepared, enabled, then disabled. So if an error occurs after
+the disable step, they are still prepared.
+
+Add an error handling path to unprepare the clks in such a case, as already
+done in the .remove function.
+
+Fixes: 8b4fc246c3ff ("i2c: mediatek: Optimize master_xfer() and avoid circular locking")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1420,17 +1420,22 @@ static int mtk_i2c_probe(struct platform
+ if (ret < 0) {
+ dev_err(&pdev->dev,
+ "Request I2C IRQ %d fail\n", irq);
+- return ret;
++ goto err_bulk_unprepare;
+ }
+
+ i2c_set_adapdata(&i2c->adap, i2c);
+ ret = i2c_add_adapter(&i2c->adap);
+ if (ret)
+- return ret;
++ goto err_bulk_unprepare;
+
+ platform_set_drvdata(pdev, i2c);
+
+ return 0;
++
++err_bulk_unprepare:
++ clk_bulk_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
++
++ return ret;
+ }
+
+ static int mtk_i2c_remove(struct platform_device *pdev)
diff --git a/target/linux/mediatek/patches-5.15/849-v6.0-i2c-mediatek-add-i2c-compatible-for-MT8188.patch b/target/linux/mediatek/patches-5.15/849-v6.0-i2c-mediatek-add-i2c-compatible-for-MT8188.patch
new file mode 100644
index 0000000000..744aa96ed0
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/849-v6.0-i2c-mediatek-add-i2c-compatible-for-MT8188.patch
@@ -0,0 +1,82 @@
+From 94c7f8af2c0a399c8aa66f2522b60c5784b5be6c Mon Sep 17 00:00:00 2001
+From: Kewei Xu <kewei.xu@mediatek.com>
+Date: Sat, 6 Aug 2022 18:02:49 +0800
+Subject: [PATCH 10/16] i2c: mediatek: add i2c compatible for MT8188
+
+Add i2c compatible for MT8188 and added mt_i2c_regs_v3[], since
+MT8188 i2c OFFSET_SLAVE_ADDR register changed from 0x04 to 0x94.
+
+Signed-off-by: Kewei Xu <kewei.xu@mediatek.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Qii Wang <qii.wang@mediatek.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 43 +++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -229,6 +229,35 @@ static const u16 mt_i2c_regs_v2[] = {
+ [OFFSET_DCM_EN] = 0xf88,
+ };
+
++static const u16 mt_i2c_regs_v3[] = {
++ [OFFSET_DATA_PORT] = 0x0,
++ [OFFSET_INTR_MASK] = 0x8,
++ [OFFSET_INTR_STAT] = 0xc,
++ [OFFSET_CONTROL] = 0x10,
++ [OFFSET_TRANSFER_LEN] = 0x14,
++ [OFFSET_TRANSAC_LEN] = 0x18,
++ [OFFSET_DELAY_LEN] = 0x1c,
++ [OFFSET_TIMING] = 0x20,
++ [OFFSET_START] = 0x24,
++ [OFFSET_EXT_CONF] = 0x28,
++ [OFFSET_LTIMING] = 0x2c,
++ [OFFSET_HS] = 0x30,
++ [OFFSET_IO_CONFIG] = 0x34,
++ [OFFSET_FIFO_ADDR_CLR] = 0x38,
++ [OFFSET_SDA_TIMING] = 0x3c,
++ [OFFSET_TRANSFER_LEN_AUX] = 0x44,
++ [OFFSET_CLOCK_DIV] = 0x48,
++ [OFFSET_SOFTRESET] = 0x50,
++ [OFFSET_MULTI_DMA] = 0x8c,
++ [OFFSET_SCL_MIS_COMP_POINT] = 0x90,
++ [OFFSET_SLAVE_ADDR] = 0x94,
++ [OFFSET_DEBUGSTAT] = 0xe4,
++ [OFFSET_DEBUGCTRL] = 0xe8,
++ [OFFSET_FIFO_STAT] = 0xf4,
++ [OFFSET_FIFO_THRESH] = 0xf8,
++ [OFFSET_DCM_EN] = 0xf88,
++};
++
+ struct mtk_i2c_compatible {
+ const struct i2c_adapter_quirks *quirks;
+ const u16 *regs;
+@@ -442,6 +471,19 @@ static const struct mtk_i2c_compatible m
+ .max_dma_support = 36,
+ };
+
++static const struct mtk_i2c_compatible mt8188_compat = {
++ .regs = mt_i2c_regs_v3,
++ .pmic_i2c = 0,
++ .dcm = 0,
++ .auto_restart = 1,
++ .aux_len_reg = 1,
++ .timing_adjust = 1,
++ .dma_sync = 0,
++ .ltiming_adjust = 1,
++ .apdma_sync = 1,
++ .max_dma_support = 36,
++};
++
+ static const struct mtk_i2c_compatible mt8192_compat = {
+ .quirks = &mt8183_i2c_quirks,
+ .regs = mt_i2c_regs_v2,
+@@ -465,6 +507,7 @@ static const struct of_device_id mtk_i2c
+ { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
+ { .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
+ { .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat },
++ { .compatible = "mediatek,mt8188-i2c", .data = &mt8188_compat },
+ { .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat },
+ {}
+ };
diff --git a/target/linux/mediatek/patches-5.15/850-v6.0-i2c-move-drivers-from-strlcpy-to-strscpy.patch b/target/linux/mediatek/patches-5.15/850-v6.0-i2c-move-drivers-from-strlcpy-to-strscpy.patch
new file mode 100644
index 0000000000..506689965d
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/850-v6.0-i2c-move-drivers-from-strlcpy-to-strscpy.patch
@@ -0,0 +1,579 @@
+From 2f4ca256a98cc19787b7c861109dd1150a21b0bf Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Date: Thu, 11 Aug 2022 09:10:30 +0200
+Subject: [PATCH 11/16] i2c: move drivers from strlcpy to strscpy
+
+Follow the advice of the below link and prefer 'strscpy'. Conversion is
+easy because no driver used the return value and has been done with a
+simple sed invocation.
+
+Link: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw@mail.gmail.com/
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-altera.c | 2 +-
+ drivers/i2c/busses/i2c-aspeed.c | 2 +-
+ drivers/i2c/busses/i2c-au1550.c | 2 +-
+ drivers/i2c/busses/i2c-axxia.c | 2 +-
+ drivers/i2c/busses/i2c-bcm-kona.c | 2 +-
+ drivers/i2c/busses/i2c-cbus-gpio.c | 2 +-
+ drivers/i2c/busses/i2c-cht-wc.c | 2 +-
+ drivers/i2c/busses/i2c-cros-ec-tunnel.c | 2 +-
+ drivers/i2c/busses/i2c-davinci.c | 2 +-
+ drivers/i2c/busses/i2c-digicolor.c | 2 +-
+ drivers/i2c/busses/i2c-eg20t.c | 2 +-
+ drivers/i2c/busses/i2c-emev2.c | 2 +-
+ drivers/i2c/busses/i2c-exynos5.c | 2 +-
+ drivers/i2c/busses/i2c-gpio.c | 2 +-
+ drivers/i2c/busses/i2c-highlander.c | 2 +-
+ drivers/i2c/busses/i2c-hix5hd2.c | 2 +-
+ drivers/i2c/busses/i2c-i801.c | 4 ++--
+ drivers/i2c/busses/i2c-ibm_iic.c | 2 +-
+ drivers/i2c/busses/i2c-icy.c | 2 +-
+ drivers/i2c/busses/i2c-imx-lpi2c.c | 2 +-
+ drivers/i2c/busses/i2c-lpc2k.c | 2 +-
+ drivers/i2c/busses/i2c-meson.c | 2 +-
+ drivers/i2c/busses/i2c-mt65xx.c | 2 +-
+ drivers/i2c/busses/i2c-mt7621.c | 2 +-
+ drivers/i2c/busses/i2c-mv64xxx.c | 2 +-
+ drivers/i2c/busses/i2c-mxs.c | 2 +-
+ drivers/i2c/busses/i2c-nvidia-gpu.c | 2 +-
+ drivers/i2c/busses/i2c-omap.c | 2 +-
+ drivers/i2c/busses/i2c-opal.c | 4 ++--
+ drivers/i2c/busses/i2c-parport.c | 2 +-
+ drivers/i2c/busses/i2c-pxa.c | 2 +-
+ drivers/i2c/busses/i2c-qcom-geni.c | 2 +-
+ drivers/i2c/busses/i2c-qup.c | 2 +-
+ drivers/i2c/busses/i2c-rcar.c | 2 +-
+ drivers/i2c/busses/i2c-riic.c | 2 +-
+ drivers/i2c/busses/i2c-rk3x.c | 2 +-
+ drivers/i2c/busses/i2c-s3c2410.c | 2 +-
+ drivers/i2c/busses/i2c-sh_mobile.c | 2 +-
+ drivers/i2c/busses/i2c-simtec.c | 2 +-
+ drivers/i2c/busses/i2c-taos-evm.c | 2 +-
+ drivers/i2c/busses/i2c-tegra-bpmp.c | 2 +-
+ drivers/i2c/busses/i2c-tegra.c | 2 +-
+ drivers/i2c/busses/i2c-uniphier-f.c | 2 +-
+ drivers/i2c/busses/i2c-uniphier.c | 2 +-
+ drivers/i2c/busses/i2c-versatile.c | 2 +-
+ drivers/i2c/busses/i2c-wmt.c | 2 +-
+ 46 files changed, 48 insertions(+), 48 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-altera.c
++++ b/drivers/i2c/busses/i2c-altera.c
+@@ -447,7 +447,7 @@ static int altr_i2c_probe(struct platfor
+ mutex_unlock(&idev->isr_mutex);
+
+ i2c_set_adapdata(&idev->adapter, idev);
+- strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
++ strscpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
+ idev->adapter.owner = THIS_MODULE;
+ idev->adapter.algo = &altr_i2c_algo;
+ idev->adapter.dev.parent = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-aspeed.c
++++ b/drivers/i2c/busses/i2c-aspeed.c
+@@ -1024,7 +1024,7 @@ static int aspeed_i2c_probe_bus(struct p
+ bus->adap.algo = &aspeed_i2c_algo;
+ bus->adap.dev.parent = &pdev->dev;
+ bus->adap.dev.of_node = pdev->dev.of_node;
+- strlcpy(bus->adap.name, pdev->name, sizeof(bus->adap.name));
++ strscpy(bus->adap.name, pdev->name, sizeof(bus->adap.name));
+ i2c_set_adapdata(&bus->adap, bus);
+
+ bus->dev = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-au1550.c
++++ b/drivers/i2c/busses/i2c-au1550.c
+@@ -321,7 +321,7 @@ i2c_au1550_probe(struct platform_device
+ priv->adap.algo = &au1550_algo;
+ priv->adap.algo_data = priv;
+ priv->adap.dev.parent = &pdev->dev;
+- strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));
++ strscpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));
+
+ /* Now, set up the PSC for SMBus PIO mode. */
+ i2c_au1550_setup(priv);
+--- a/drivers/i2c/busses/i2c-axxia.c
++++ b/drivers/i2c/busses/i2c-axxia.c
+@@ -783,7 +783,7 @@ static int axxia_i2c_probe(struct platfo
+ }
+
+ i2c_set_adapdata(&idev->adapter, idev);
+- strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
++ strscpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
+ idev->adapter.owner = THIS_MODULE;
+ idev->adapter.algo = &axxia_i2c_algo;
+ idev->adapter.bus_recovery_info = &axxia_i2c_recovery_info;
+--- a/drivers/i2c/busses/i2c-bcm-kona.c
++++ b/drivers/i2c/busses/i2c-bcm-kona.c
+@@ -849,7 +849,7 @@ static int bcm_kona_i2c_probe(struct pla
+ adap = &dev->adapter;
+ i2c_set_adapdata(adap, dev);
+ adap->owner = THIS_MODULE;
+- strlcpy(adap->name, "Broadcom I2C adapter", sizeof(adap->name));
++ strscpy(adap->name, "Broadcom I2C adapter", sizeof(adap->name));
+ adap->algo = &bcm_algo;
+ adap->dev.parent = &pdev->dev;
+ adap->dev.of_node = pdev->dev.of_node;
+--- a/drivers/i2c/busses/i2c-cbus-gpio.c
++++ b/drivers/i2c/busses/i2c-cbus-gpio.c
+@@ -245,7 +245,7 @@ static int cbus_i2c_probe(struct platfor
+ adapter->nr = pdev->id;
+ adapter->timeout = HZ;
+ adapter->algo = &cbus_i2c_algo;
+- strlcpy(adapter->name, "CBUS I2C adapter", sizeof(adapter->name));
++ strscpy(adapter->name, "CBUS I2C adapter", sizeof(adapter->name));
+
+ spin_lock_init(&chost->lock);
+ chost->dev = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-cht-wc.c
++++ b/drivers/i2c/busses/i2c-cht-wc.c
+@@ -334,7 +334,7 @@ static int cht_wc_i2c_adap_i2c_probe(str
+ adap->adapter.class = I2C_CLASS_HWMON;
+ adap->adapter.algo = &cht_wc_i2c_adap_algo;
+ adap->adapter.lock_ops = &cht_wc_i2c_adap_lock_ops;
+- strlcpy(adap->adapter.name, "PMIC I2C Adapter",
++ strscpy(adap->adapter.name, "PMIC I2C Adapter",
+ sizeof(adap->adapter.name));
+ adap->adapter.dev.parent = &pdev->dev;
+
+--- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c
++++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
+@@ -267,7 +267,7 @@ static int ec_i2c_probe(struct platform_
+ bus->dev = dev;
+
+ bus->adap.owner = THIS_MODULE;
+- strlcpy(bus->adap.name, "cros-ec-i2c-tunnel", sizeof(bus->adap.name));
++ strscpy(bus->adap.name, "cros-ec-i2c-tunnel", sizeof(bus->adap.name));
+ bus->adap.algo = &ec_i2c_algorithm;
+ bus->adap.algo_data = bus;
+ bus->adap.dev.parent = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-davinci.c
++++ b/drivers/i2c/busses/i2c-davinci.c
+@@ -847,7 +847,7 @@ static int davinci_i2c_probe(struct plat
+ i2c_set_adapdata(adap, dev);
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_DEPRECATED;
+- strlcpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
++ strscpy(adap->name, "DaVinci I2C adapter", sizeof(adap->name));
+ adap->algo = &i2c_davinci_algo;
+ adap->dev.parent = &pdev->dev;
+ adap->timeout = DAVINCI_I2C_TIMEOUT;
+--- a/drivers/i2c/busses/i2c-digicolor.c
++++ b/drivers/i2c/busses/i2c-digicolor.c
+@@ -322,7 +322,7 @@ static int dc_i2c_probe(struct platform_
+ if (ret < 0)
+ return ret;
+
+- strlcpy(i2c->adap.name, "Conexant Digicolor I2C adapter",
++ strscpy(i2c->adap.name, "Conexant Digicolor I2C adapter",
+ sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &dc_i2c_algorithm;
+--- a/drivers/i2c/busses/i2c-eg20t.c
++++ b/drivers/i2c/busses/i2c-eg20t.c
+@@ -773,7 +773,7 @@ static int pch_i2c_probe(struct pci_dev
+
+ pch_adap->owner = THIS_MODULE;
+ pch_adap->class = I2C_CLASS_HWMON;
+- strlcpy(pch_adap->name, KBUILD_MODNAME, sizeof(pch_adap->name));
++ strscpy(pch_adap->name, KBUILD_MODNAME, sizeof(pch_adap->name));
+ pch_adap->algo = &pch_algorithm;
+ pch_adap->algo_data = &adap_info->pch_data[i];
+
+--- a/drivers/i2c/busses/i2c-emev2.c
++++ b/drivers/i2c/busses/i2c-emev2.c
+@@ -371,7 +371,7 @@ static int em_i2c_probe(struct platform_
+ if (IS_ERR(priv->base))
+ return PTR_ERR(priv->base);
+
+- strlcpy(priv->adap.name, "EMEV2 I2C", sizeof(priv->adap.name));
++ strscpy(priv->adap.name, "EMEV2 I2C", sizeof(priv->adap.name));
+
+ priv->sclk = devm_clk_get(&pdev->dev, "sclk");
+ if (IS_ERR(priv->sclk))
+--- a/drivers/i2c/busses/i2c-exynos5.c
++++ b/drivers/i2c/busses/i2c-exynos5.c
+@@ -751,7 +751,7 @@ static int exynos5_i2c_probe(struct plat
+ if (of_property_read_u32(np, "clock-frequency", &i2c->op_clock))
+ i2c->op_clock = I2C_MAX_STANDARD_MODE_FREQ;
+
+- strlcpy(i2c->adap.name, "exynos5-i2c", sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, "exynos5-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &exynos5_i2c_algorithm;
+ i2c->adap.retries = 3;
+--- a/drivers/i2c/busses/i2c-gpio.c
++++ b/drivers/i2c/busses/i2c-gpio.c
+@@ -436,7 +436,7 @@ static int i2c_gpio_probe(struct platfor
+
+ adap->owner = THIS_MODULE;
+ if (np)
+- strlcpy(adap->name, dev_name(dev), sizeof(adap->name));
++ strscpy(adap->name, dev_name(dev), sizeof(adap->name));
+ else
+ snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id);
+
+--- a/drivers/i2c/busses/i2c-highlander.c
++++ b/drivers/i2c/busses/i2c-highlander.c
+@@ -402,7 +402,7 @@ static int highlander_i2c_probe(struct p
+ i2c_set_adapdata(adap, dev);
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_HWMON;
+- strlcpy(adap->name, "HL FPGA I2C adapter", sizeof(adap->name));
++ strscpy(adap->name, "HL FPGA I2C adapter", sizeof(adap->name));
+ adap->algo = &highlander_i2c_algo;
+ adap->dev.parent = &pdev->dev;
+ adap->nr = pdev->id;
+--- a/drivers/i2c/busses/i2c-hix5hd2.c
++++ b/drivers/i2c/busses/i2c-hix5hd2.c
+@@ -423,7 +423,7 @@ static int hix5hd2_i2c_probe(struct plat
+ }
+ clk_prepare_enable(priv->clk);
+
+- strlcpy(priv->adap.name, "hix5hd2-i2c", sizeof(priv->adap.name));
++ strscpy(priv->adap.name, "hix5hd2-i2c", sizeof(priv->adap.name));
+ priv->dev = &pdev->dev;
+ priv->adap.owner = THIS_MODULE;
+ priv->adap.algo = &hix5hd2_i2c_algorithm;
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -1111,7 +1111,7 @@ static void dmi_check_onboard_device(u8
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = dmi_devices[i].i2c_addr;
+- strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
++ strscpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
+ i2c_new_client_device(adap, &info);
+ break;
+ }
+@@ -1267,7 +1267,7 @@ static void register_dell_lis3lv02d_i2c_
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = dell_lis3lv02d_devices[i].i2c_addr;
+- strlcpy(info.type, "lis3lv02d", I2C_NAME_SIZE);
++ strscpy(info.type, "lis3lv02d", I2C_NAME_SIZE);
+ i2c_new_client_device(&priv->adapter, &info);
+ }
+
+--- a/drivers/i2c/busses/i2c-ibm_iic.c
++++ b/drivers/i2c/busses/i2c-ibm_iic.c
+@@ -738,7 +738,7 @@ static int iic_probe(struct platform_dev
+ adap = &dev->adap;
+ adap->dev.parent = &ofdev->dev;
+ adap->dev.of_node = of_node_get(np);
+- strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
++ strscpy(adap->name, "IBM IIC", sizeof(adap->name));
+ i2c_set_adapdata(adap, dev);
+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+ adap->algo = &iic_algo;
+--- a/drivers/i2c/busses/i2c-icy.c
++++ b/drivers/i2c/busses/i2c-icy.c
+@@ -141,7 +141,7 @@ static int icy_probe(struct zorro_dev *z
+ i2c->adapter.owner = THIS_MODULE;
+ /* i2c->adapter.algo assigned by i2c_pcf_add_bus() */
+ i2c->adapter.algo_data = algo_data;
+- strlcpy(i2c->adapter.name, "ICY I2C Zorro adapter",
++ strscpy(i2c->adapter.name, "ICY I2C Zorro adapter",
+ sizeof(i2c->adapter.name));
+
+ if (!devm_request_mem_region(&z->dev,
+--- a/drivers/i2c/busses/i2c-imx-lpi2c.c
++++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
+@@ -564,7 +564,7 @@ static int lpi2c_imx_probe(struct platfo
+ lpi2c_imx->adapter.algo = &lpi2c_imx_algo;
+ lpi2c_imx->adapter.dev.parent = &pdev->dev;
+ lpi2c_imx->adapter.dev.of_node = pdev->dev.of_node;
+- strlcpy(lpi2c_imx->adapter.name, pdev->name,
++ strscpy(lpi2c_imx->adapter.name, pdev->name,
+ sizeof(lpi2c_imx->adapter.name));
+
+ lpi2c_imx->clk = devm_clk_get(&pdev->dev, NULL);
+--- a/drivers/i2c/busses/i2c-lpc2k.c
++++ b/drivers/i2c/busses/i2c-lpc2k.c
+@@ -417,7 +417,7 @@ static int i2c_lpc2k_probe(struct platfo
+
+ i2c_set_adapdata(&i2c->adap, i2c);
+ i2c->adap.owner = THIS_MODULE;
+- strlcpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name));
+ i2c->adap.algo = &i2c_lpc2k_algorithm;
+ i2c->adap.dev.parent = &pdev->dev;
+ i2c->adap.dev.of_node = pdev->dev.of_node;
+--- a/drivers/i2c/busses/i2c-meson.c
++++ b/drivers/i2c/busses/i2c-meson.c
+@@ -451,7 +451,7 @@ static int meson_i2c_probe(struct platfo
+ return ret;
+ }
+
+- strlcpy(i2c->adap.name, "Meson I2C adapter",
++ strscpy(i2c->adap.name, "Meson I2C adapter",
+ sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &meson_i2c_algorithm;
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1432,7 +1432,7 @@ static int mtk_i2c_probe(struct platform
+ speed_clk = I2C_MT65XX_CLK_MAIN;
+ }
+
+- strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
+
+ ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
+ if (ret) {
+--- a/drivers/i2c/busses/i2c-mt7621.c
++++ b/drivers/i2c/busses/i2c-mt7621.c
+@@ -315,7 +315,7 @@ static int mtk_i2c_probe(struct platform
+ adap->dev.parent = &pdev->dev;
+ i2c_set_adapdata(adap, i2c);
+ adap->dev.of_node = pdev->dev.of_node;
+- strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
++ strscpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
+
+ platform_set_drvdata(pdev, i2c);
+
+--- a/drivers/i2c/busses/i2c-mv64xxx.c
++++ b/drivers/i2c/busses/i2c-mv64xxx.c
+@@ -989,7 +989,7 @@ mv64xxx_i2c_probe(struct platform_device
+ if (IS_ERR(drv_data->reg_base))
+ return PTR_ERR(drv_data->reg_base);
+
+- strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
++ strscpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
+ sizeof(drv_data->adapter.name));
+
+ init_waitqueue_head(&drv_data->waitq);
+--- a/drivers/i2c/busses/i2c-mxs.c
++++ b/drivers/i2c/busses/i2c-mxs.c
+@@ -838,7 +838,7 @@ static int mxs_i2c_probe(struct platform
+ return err;
+
+ adap = &i2c->adapter;
+- strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
++ strscpy(adap->name, "MXS I2C adapter", sizeof(adap->name));
+ adap->owner = THIS_MODULE;
+ adap->algo = &mxs_i2c_algo;
+ adap->quirks = &mxs_i2c_quirks;
+--- a/drivers/i2c/busses/i2c-nvidia-gpu.c
++++ b/drivers/i2c/busses/i2c-nvidia-gpu.c
+@@ -319,7 +319,7 @@ static int gpu_i2c_probe(struct pci_dev
+
+ i2c_set_adapdata(&i2cd->adapter, i2cd);
+ i2cd->adapter.owner = THIS_MODULE;
+- strlcpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter",
++ strscpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter",
+ sizeof(i2cd->adapter.name));
+ i2cd->adapter.algo = &gpu_i2c_algorithm;
+ i2cd->adapter.quirks = &gpu_i2c_quirks;
+--- a/drivers/i2c/busses/i2c-omap.c
++++ b/drivers/i2c/busses/i2c-omap.c
+@@ -1488,7 +1488,7 @@ omap_i2c_probe(struct platform_device *p
+ i2c_set_adapdata(adap, omap);
+ adap->owner = THIS_MODULE;
+ adap->class = I2C_CLASS_DEPRECATED;
+- strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
++ strscpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
+ adap->algo = &omap_i2c_algo;
+ adap->quirks = &omap_i2c_quirks;
+ adap->dev.parent = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-opal.c
++++ b/drivers/i2c/busses/i2c-opal.c
+@@ -220,9 +220,9 @@ static int i2c_opal_probe(struct platfor
+ adapter->dev.of_node = of_node_get(pdev->dev.of_node);
+ pname = of_get_property(pdev->dev.of_node, "ibm,port-name", NULL);
+ if (pname)
+- strlcpy(adapter->name, pname, sizeof(adapter->name));
++ strscpy(adapter->name, pname, sizeof(adapter->name));
+ else
+- strlcpy(adapter->name, "opal", sizeof(adapter->name));
++ strscpy(adapter->name, "opal", sizeof(adapter->name));
+
+ platform_set_drvdata(pdev, adapter);
+ rc = i2c_add_adapter(adapter);
+--- a/drivers/i2c/busses/i2c-parport.c
++++ b/drivers/i2c/busses/i2c-parport.c
+@@ -308,7 +308,7 @@ static void i2c_parport_attach(struct pa
+ /* Fill the rest of the structure */
+ adapter->adapter.owner = THIS_MODULE;
+ adapter->adapter.class = I2C_CLASS_HWMON;
+- strlcpy(adapter->adapter.name, "Parallel port adapter",
++ strscpy(adapter->adapter.name, "Parallel port adapter",
+ sizeof(adapter->adapter.name));
+ adapter->algo_data = parport_algo_data;
+ /* Slow down if we can't sense SCL */
+--- a/drivers/i2c/busses/i2c-pxa.c
++++ b/drivers/i2c/busses/i2c-pxa.c
+@@ -1403,7 +1403,7 @@ static int i2c_pxa_probe(struct platform
+ spin_lock_init(&i2c->lock);
+ init_waitqueue_head(&i2c->wait);
+
+- strlcpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, "pxa_i2c-i2c", sizeof(i2c->adap.name));
+
+ i2c->clk = devm_clk_get(&dev->dev, NULL);
+ if (IS_ERR(i2c->clk)) {
+--- a/drivers/i2c/busses/i2c-qcom-geni.c
++++ b/drivers/i2c/busses/i2c-qcom-geni.c
+@@ -577,7 +577,7 @@ static int geni_i2c_probe(struct platfor
+ i2c_set_adapdata(&gi2c->adap, gi2c);
+ gi2c->adap.dev.parent = dev;
+ gi2c->adap.dev.of_node = dev->of_node;
+- strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
++ strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name));
+
+ ret = geni_icc_get(&gi2c->se, "qup-memory");
+ if (ret)
+--- a/drivers/i2c/busses/i2c-qup.c
++++ b/drivers/i2c/busses/i2c-qup.c
+@@ -1878,7 +1878,7 @@ nodma:
+ qup->adap.dev.of_node = pdev->dev.of_node;
+ qup->is_last = true;
+
+- strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
++ strscpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
+
+ pm_runtime_set_autosuspend_delay(qup->dev, MSEC_PER_SEC);
+ pm_runtime_use_autosuspend(qup->dev);
+--- a/drivers/i2c/busses/i2c-rcar.c
++++ b/drivers/i2c/busses/i2c-rcar.c
+@@ -1059,7 +1059,7 @@ static int rcar_i2c_probe(struct platfor
+ adap->bus_recovery_info = &rcar_i2c_bri;
+ adap->quirks = &rcar_i2c_quirks;
+ i2c_set_adapdata(adap, priv);
+- strlcpy(adap->name, pdev->name, sizeof(adap->name));
++ strscpy(adap->name, pdev->name, sizeof(adap->name));
+
+ /* Init DMA */
+ sg_init_table(&priv->sg, 1);
+--- a/drivers/i2c/busses/i2c-riic.c
++++ b/drivers/i2c/busses/i2c-riic.c
+@@ -447,7 +447,7 @@ static int riic_i2c_probe(struct platfor
+
+ adap = &riic->adapter;
+ i2c_set_adapdata(adap, riic);
+- strlcpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
++ strscpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
+ adap->owner = THIS_MODULE;
+ adap->algo = &riic_algo;
+ adap->dev.parent = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-rk3x.c
++++ b/drivers/i2c/busses/i2c-rk3x.c
+@@ -1240,7 +1240,7 @@ static int rk3x_i2c_probe(struct platfor
+ /* use common interface to get I2C timing properties */
+ i2c_parse_fw_timings(&pdev->dev, &i2c->t, true);
+
+- strlcpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, "rk3x-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &rk3x_i2c_algorithm;
+ i2c->adap.retries = 3;
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -1076,7 +1076,7 @@ static int s3c24xx_i2c_probe(struct plat
+ else
+ s3c24xx_i2c_parse_dt(pdev->dev.of_node, i2c);
+
+- strlcpy(i2c->adap.name, "s3c2410-i2c", sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, "s3c2410-i2c", sizeof(i2c->adap.name));
+ i2c->adap.owner = THIS_MODULE;
+ i2c->adap.algo = &s3c24xx_i2c_algorithm;
+ i2c->adap.retries = 2;
+--- a/drivers/i2c/busses/i2c-sh_mobile.c
++++ b/drivers/i2c/busses/i2c-sh_mobile.c
+@@ -930,7 +930,7 @@ static int sh_mobile_i2c_probe(struct pl
+ adap->nr = dev->id;
+ adap->dev.of_node = dev->dev.of_node;
+
+- strlcpy(adap->name, dev->name, sizeof(adap->name));
++ strscpy(adap->name, dev->name, sizeof(adap->name));
+
+ spin_lock_init(&pd->lock);
+ init_waitqueue_head(&pd->wait);
+--- a/drivers/i2c/busses/i2c-simtec.c
++++ b/drivers/i2c/busses/i2c-simtec.c
+@@ -99,7 +99,7 @@ static int simtec_i2c_probe(struct platf
+ pd->adap.algo_data = &pd->bit;
+ pd->adap.dev.parent = &dev->dev;
+
+- strlcpy(pd->adap.name, "Simtec I2C", sizeof(pd->adap.name));
++ strscpy(pd->adap.name, "Simtec I2C", sizeof(pd->adap.name));
+
+ pd->bit.data = pd;
+ pd->bit.setsda = simtec_i2c_setsda;
+--- a/drivers/i2c/busses/i2c-taos-evm.c
++++ b/drivers/i2c/busses/i2c-taos-evm.c
+@@ -239,7 +239,7 @@ static int taos_connect(struct serio *se
+ dev_err(&serio->dev, "TAOS EVM identification failed\n");
+ goto exit_close;
+ }
+- strlcpy(adapter->name, name, sizeof(adapter->name));
++ strscpy(adapter->name, name, sizeof(adapter->name));
+
+ /* Turn echo off for better performance */
+ taos->state = TAOS_STATE_EOFF;
+--- a/drivers/i2c/busses/i2c-tegra-bpmp.c
++++ b/drivers/i2c/busses/i2c-tegra-bpmp.c
+@@ -305,7 +305,7 @@ static int tegra_bpmp_i2c_probe(struct p
+
+ i2c_set_adapdata(&i2c->adapter, i2c);
+ i2c->adapter.owner = THIS_MODULE;
+- strlcpy(i2c->adapter.name, "Tegra BPMP I2C adapter",
++ strscpy(i2c->adapter.name, "Tegra BPMP I2C adapter",
+ sizeof(i2c->adapter.name));
+ i2c->adapter.algo = &tegra_bpmp_i2c_algo;
+ i2c->adapter.dev.parent = &pdev->dev;
+--- a/drivers/i2c/busses/i2c-tegra.c
++++ b/drivers/i2c/busses/i2c-tegra.c
+@@ -1799,7 +1799,7 @@ static int tegra_i2c_probe(struct platfo
+ if (i2c_dev->hw->supports_bus_clear)
+ i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
+
+- strlcpy(i2c_dev->adapter.name, dev_name(i2c_dev->dev),
++ strscpy(i2c_dev->adapter.name, dev_name(i2c_dev->dev),
+ sizeof(i2c_dev->adapter.name));
+
+ err = i2c_add_numbered_adapter(&i2c_dev->adapter);
+--- a/drivers/i2c/busses/i2c-uniphier-f.c
++++ b/drivers/i2c/busses/i2c-uniphier-f.c
+@@ -564,7 +564,7 @@ static int uniphier_fi2c_probe(struct pl
+ priv->adap.algo = &uniphier_fi2c_algo;
+ priv->adap.dev.parent = dev;
+ priv->adap.dev.of_node = dev->of_node;
+- strlcpy(priv->adap.name, "UniPhier FI2C", sizeof(priv->adap.name));
++ strscpy(priv->adap.name, "UniPhier FI2C", sizeof(priv->adap.name));
+ priv->adap.bus_recovery_info = &uniphier_fi2c_bus_recovery_info;
+ i2c_set_adapdata(&priv->adap, priv);
+ platform_set_drvdata(pdev, priv);
+--- a/drivers/i2c/busses/i2c-uniphier.c
++++ b/drivers/i2c/busses/i2c-uniphier.c
+@@ -358,7 +358,7 @@ static int uniphier_i2c_probe(struct pla
+ priv->adap.algo = &uniphier_i2c_algo;
+ priv->adap.dev.parent = dev;
+ priv->adap.dev.of_node = dev->of_node;
+- strlcpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name));
++ strscpy(priv->adap.name, "UniPhier I2C", sizeof(priv->adap.name));
+ priv->adap.bus_recovery_info = &uniphier_i2c_bus_recovery_info;
+ i2c_set_adapdata(&priv->adap, priv);
+ platform_set_drvdata(pdev, priv);
+--- a/drivers/i2c/busses/i2c-versatile.c
++++ b/drivers/i2c/busses/i2c-versatile.c
+@@ -79,7 +79,7 @@ static int i2c_versatile_probe(struct pl
+ writel(SCL | SDA, i2c->base + I2C_CONTROLS);
+
+ i2c->adap.owner = THIS_MODULE;
+- strlcpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name));
++ strscpy(i2c->adap.name, "Versatile I2C adapter", sizeof(i2c->adap.name));
+ i2c->adap.algo_data = &i2c->algo;
+ i2c->adap.dev.parent = &dev->dev;
+ i2c->adap.dev.of_node = dev->dev.of_node;
+--- a/drivers/i2c/busses/i2c-wmt.c
++++ b/drivers/i2c/busses/i2c-wmt.c
+@@ -413,7 +413,7 @@ static int wmt_i2c_probe(struct platform
+
+ adap = &i2c_dev->adapter;
+ i2c_set_adapdata(adap, i2c_dev);
+- strlcpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
++ strscpy(adap->name, "WMT I2C adapter", sizeof(adap->name));
+ adap->owner = THIS_MODULE;
+ adap->algo = &wmt_i2c_algo;
+ adap->dev.parent = &pdev->dev;
diff --git a/target/linux/mediatek/patches-5.15/803-i2c-busses-add-mt7986-support.patch b/target/linux/mediatek/patches-5.15/851-v6.2-i2c-mediatek-add-mt7986-support.patch
index 1860a6da01..4c398c59f9 100644
--- a/target/linux/mediatek/patches-5.15/803-i2c-busses-add-mt7986-support.patch
+++ b/target/linux/mediatek/patches-5.15/851-v6.2-i2c-mediatek-add-mt7986-support.patch
@@ -1,7 +1,21 @@
+From 11f9a0f4e51887ad7b4a2898a368fcd0c2984e89 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Sun, 9 Oct 2022 12:16:31 +0200
+Subject: [PATCH 12/16] i2c: mediatek: add mt7986 support
+
+Add i2c support for MT7986 SoC.
+
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
-@@ -365,6 +365,19 @@ static const struct mtk_i2c_compatible m
- .max_dma_support = 32,
+@@ -431,6 +431,19 @@ static const struct mtk_i2c_compatible m
+ .max_dma_support = 33,
};
+static const struct mtk_i2c_compatible mt7986_compat = {
@@ -11,20 +25,20 @@
+ .dcm = 1,
+ .auto_restart = 1,
+ .aux_len_reg = 1,
-+ .max_dma_support = 32,
+ .timing_adjust = 0,
+ .dma_sync = 1,
+ .ltiming_adjust = 0,
++ .max_dma_support = 32,
+};
+
static const struct mtk_i2c_compatible mt8173_compat = {
.regs = mt_i2c_regs_v1,
.pmic_i2c = 0,
-@@ -411,6 +424,7 @@ static const struct of_device_id mtk_i2c
+@@ -503,6 +516,7 @@ static const struct of_device_id mtk_i2c
{ .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
{ .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
+ { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
+ { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
- { .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat },
diff --git a/target/linux/mediatek/patches-5.15/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch b/target/linux/mediatek/patches-5.15/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch
new file mode 100644
index 0000000000..18c66cdac5
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/852-v6.3-i2c-mt65xx-Use-devm_platform_get_and_ioremap_resourc.patch
@@ -0,0 +1,42 @@
+From 98204ccafd45a8a6109ff2d60e2c179b95d92578 Mon Sep 17 00:00:00 2001
+From: ye xingchen <ye.xingchen@zte.com.cn>
+Date: Thu, 19 Jan 2023 17:19:58 +0800
+Subject: [PATCH 13/16] i2c: mt65xx: Use
+ devm_platform_get_and_ioremap_resource()
+
+Convert platform_get_resource(), devm_ioremap_resource() to a single
+call to devm_platform_get_and_ioremap_resource(), as this is exactly
+what this function does.
+
+Signed-off-by: ye xingchen <ye.xingchen@zte.com.cn>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1366,20 +1366,17 @@ static int mtk_i2c_probe(struct platform
+ {
+ int ret = 0;
+ struct mtk_i2c *i2c;
+- struct resource *res;
+ int i, irq, speed_clk;
+
+ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
+ if (!i2c)
+ return -ENOMEM;
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- i2c->base = devm_ioremap_resource(&pdev->dev, res);
++ i2c->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+ if (IS_ERR(i2c->base))
+ return PTR_ERR(i2c->base);
+
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- i2c->pdmabase = devm_ioremap_resource(&pdev->dev, res);
++ i2c->pdmabase = devm_platform_get_and_ioremap_resource(pdev, 1, NULL);
+ if (IS_ERR(i2c->pdmabase))
+ return PTR_ERR(i2c->pdmabase);
+
diff --git a/target/linux/mediatek/patches-5.15/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch b/target/linux/mediatek/patches-5.15/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch
new file mode 100644
index 0000000000..d000d53522
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/853-v6.3-i2c-mt65xx-drop-of_match_ptr-for-ID-table.patch
@@ -0,0 +1,33 @@
+From 8106fa2e0ae6082833fe1df97829c46c0183eaea Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Sat, 11 Mar 2023 12:16:54 +0100
+Subject: [PATCH 14/16] i2c: mt65xx: drop of_match_ptr for ID table
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The driver can match only via the DT table so the table should be always
+used and the of_match_ptr does not have any sense (this also allows ACPI
+matching via PRP0001, even though it might not be relevant here).
+
+ drivers/i2c/busses/i2c-mt65xx.c:514:34: error: ‘mtk_i2c_of_match’ defined but not used [-Werror=unused-const-variable=]
+
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Guenter Roeck <groeck@chromium.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -1546,7 +1546,7 @@ static struct platform_driver mtk_i2c_dr
+ .driver = {
+ .name = I2C_DRV_NAME,
+ .pm = &mtk_i2c_pm,
+- .of_match_table = of_match_ptr(mtk_i2c_of_match),
++ .of_match_table = mtk_i2c_of_match,
+ },
+ };
+
diff --git a/target/linux/mediatek/patches-5.15/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch b/target/linux/mediatek/patches-5.15/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch
new file mode 100644
index 0000000000..e0973741e2
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/854-v6.4-i2c-mediatek-add-support-for-MT7981-SoC.patch
@@ -0,0 +1,47 @@
+From f69f3d662ba3bf999c36d9ac1e684540c4487bc3 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 10 Apr 2023 17:19:38 +0100
+Subject: [PATCH 15/16] i2c: mediatek: add support for MT7981 SoC
+
+Add support for the I2C units found in the MediaTek MT7981 and MT7988
+SoCs. Just like other recent MediaTek I2C units that also uses v3
+register offsets (which differ from v2 only by OFFSET_SLAVE_ADDR being
+0x94 instead of 0x4).
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -431,6 +431,18 @@ static const struct mtk_i2c_compatible m
+ .max_dma_support = 33,
+ };
+
++static const struct mtk_i2c_compatible mt7981_compat = {
++ .regs = mt_i2c_regs_v3,
++ .pmic_i2c = 0,
++ .dcm = 0,
++ .auto_restart = 1,
++ .aux_len_reg = 1,
++ .timing_adjust = 1,
++ .dma_sync = 1,
++ .ltiming_adjust = 1,
++ .max_dma_support = 33
++};
++
+ static const struct mtk_i2c_compatible mt7986_compat = {
+ .quirks = &mt7622_i2c_quirks,
+ .regs = mt_i2c_regs_v1,
+@@ -516,6 +528,7 @@ static const struct of_device_id mtk_i2c
+ { .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
+ { .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
+ { .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
++ { .compatible = "mediatek,mt7981-i2c", .data = &mt7981_compat },
+ { .compatible = "mediatek,mt7986-i2c", .data = &mt7986_compat },
+ { .compatible = "mediatek,mt8168-i2c", .data = &mt8168_compat },
+ { .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
diff --git a/target/linux/mediatek/patches-5.15/855-pending-i2c-mt65xx-add-additional-clocks.patch b/target/linux/mediatek/patches-5.15/855-pending-i2c-mt65xx-add-additional-clocks.patch
new file mode 100644
index 0000000000..1ed8d1a96a
--- /dev/null
+++ b/target/linux/mediatek/patches-5.15/855-pending-i2c-mt65xx-add-additional-clocks.patch
@@ -0,0 +1,55 @@
+From 94bf61df9201195d6d8ce82e299fb231b31fbaae Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 26 May 2023 10:29:45 +0100
+Subject: [PATCH] i2c: mt65xx: add additional clocks
+
+On MT7981 additional clocks are required when accessing I2C registers.
+Add MCK and PCK optional clocks to i2c-mt65xx driver so we don't have
+to always have them enabled, but really only if I2C is used.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/i2c/busses/i2c-mt65xx.c
++++ b/drivers/i2c/busses/i2c-mt65xx.c
+@@ -93,6 +93,8 @@
+ * @I2C_MT65XX_CLK_DMA: DMA clock for i2c via DMA
+ * @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC
+ * @I2C_MT65XX_CLK_ARB: Arbitrator clock for i2c
++ * @I2C_MT65XX_CLK_MCK: MCK clock for i2c
++ * @I2C_MT65XX_CLK_PCK: PCK clock for i2c
+ * @I2C_MT65XX_CLK_MAX: Number of supported clocks
+ */
+ enum i2c_mt65xx_clks {
+@@ -100,11 +102,13 @@ enum i2c_mt65xx_clks {
+ I2C_MT65XX_CLK_DMA,
+ I2C_MT65XX_CLK_PMIC,
+ I2C_MT65XX_CLK_ARB,
++ I2C_MT65XX_CLK_MCK,
++ I2C_MT65XX_CLK_PCK,
+ I2C_MT65XX_CLK_MAX
+ };
+
+ static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = {
+- "main", "dma", "pmic", "arb"
++ "main", "dma", "pmic", "arb", "mck", "pck"
+ };
+
+ enum DMA_REGS_OFFSET {
+@@ -1444,6 +1448,14 @@ static int mtk_i2c_probe(struct platform
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
+ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
+
++ i2c->clocks[I2C_MT65XX_CLK_MCK].clk = devm_clk_get_optional(&pdev->dev, "mck");
++ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MCK].clk))
++ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MCK].clk);
++
++ i2c->clocks[I2C_MT65XX_CLK_PCK].clk = devm_clk_get_optional(&pdev->dev, "pck");
++ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PCK].clk))
++ return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PCK].clk);
++
+ if (i2c->have_pmic) {
+ i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
+ if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {