--- /dev/null
+From f5e8a681bfd9fc22f739af6dea664c4382996e60 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 29 Apr 2025 12:30:08 -0500
+Subject: arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0
+
+From: Judith Mendez <jm@ti.com>
+
+[ Upstream commit f55c9f087cc2e2252d44ffd9d58def2066fc176e ]
+
+For am65x, add missing ITAPDLYSEL values for Default Speed and High
+Speed SDR modes to sdhci0 node according to the device datasheet [0].
+
+[0] https://www.ti.com/lit/gpn/am6548
+
+Fixes: eac99d38f861 ("arm64: dts: ti: k3-am654-main: Update otap-del-sel values")
+Cc: stable@vger.kernel.org
+Signed-off-by: Judith Mendez <jm@ti.com>
+Reviewed-by: Moteen Shah <m-shah@ti.com>
+Link: https://lore.kernel.org/r/20250429173009.33994-1-jm@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index 1d43d1b529b39..ccd14a2e97a9c 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -273,6 +273,8 @@ sdhci0: mmc@4f80000 {
+ ti,otap-del-sel-ddr50 = <0x5>;
+ ti,otap-del-sel-ddr52 = <0x5>;
+ ti,otap-del-sel-hs200 = <0x5>;
++ ti,itap-del-sel-legacy = <0xa>;
++ ti,itap-del-sel-mmc-hs = <0x1>;
+ ti,itap-del-sel-ddr52 = <0x0>;
+ dma-coherent;
+ };
+--
+2.39.5
+
--- /dev/null
+From ba94e50a86cefb225586153449b7387623651a5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 7 Jun 2023 08:20:42 -0500
+Subject: arm64: dts: ti: k3-am65-main: Drop deprecated ti,otap-del-sel
+ property
+
+From: Nishanth Menon <nm@ti.com>
+
+[ Upstream commit 2b9bb988742d1794e78d4297a99658f38477eedd ]
+
+ti,otap-del-sel has been deprecated in favor of ti,otap-del-sel-legacy.
+
+Drop the duplicate and misleading ti,otap-del-sel property.
+
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Link: https://lore.kernel.org/r/20230607132043.3932726-3-nm@ti.com
+Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
+Stable-dep-of: f55c9f087cc2 ("arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index b729d2dee209e..b81ee1f2aecd2 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -294,7 +294,6 @@ sdhci1: mmc@4fa0000 {
+ ti,otap-del-sel-ddr52 = <0x4>;
+ ti,otap-del-sel-hs200 = <0x7>;
+ ti,clkbuf-sel = <0x7>;
+- ti,otap-del-sel = <0x2>;
+ ti,trm-icp = <0x8>;
+ dma-coherent;
+ };
+--
+2.39.5
+
--- /dev/null
+From 4079a2619a8509d5662bc6db6cab5f570f6d6bf5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Apr 2024 10:17:28 -0500
+Subject: arm64: dts: ti: k3-am65-main: Fix sdhci node properties
+
+From: Judith Mendez <jm@ti.com>
+
+[ Upstream commit 8ffe9cb889f2b831a9d5bbb1f7ad42d30e31170f ]
+
+Update otap-del-sel properties as per datasheet [0].
+
+Add missing clkbuf-sel and itap-del-sel values also as per
+datasheet [0].
+
+Move clkbuf-sel and ti,trm-icp above the otap-del-sel properties
+so the sdhci nodes could be more uniform across platforms.
+
+[0] https://www.ti.com/lit/ds/symlink/am6548.pdf
+
+Fixes: eac99d38f861 ("arm64: dts: ti: k3-am654-main: Update otap-del-sel values")
+Fixes: d7600d070fb0 ("arm64: dts: ti: k3-am65-main: Add support for sdhci1")
+Signed-off-by: Judith Mendez <jm@ti.com>
+Link: https://lore.kernel.org/r/20240423151732.3541894-2-jm@ti.com
+Signed-off-by: Nishanth Menon <nm@ti.com>
+Stable-dep-of: f55c9f087cc2 ("arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+index b81ee1f2aecd2..1d43d1b529b39 100644
+--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
++++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+@@ -261,6 +261,8 @@ sdhci0: mmc@4f80000 {
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
++ ti,clkbuf-sel = <0x7>;
++ ti,trm-icp = <0x8>;
+ ti,otap-del-sel-legacy = <0x0>;
+ ti,otap-del-sel-mmc-hs = <0x0>;
+ ti,otap-del-sel-sd-hs = <0x0>;
+@@ -271,8 +273,7 @@ sdhci0: mmc@4f80000 {
+ ti,otap-del-sel-ddr50 = <0x5>;
+ ti,otap-del-sel-ddr52 = <0x5>;
+ ti,otap-del-sel-hs200 = <0x5>;
+- ti,otap-del-sel-hs400 = <0x0>;
+- ti,trm-icp = <0x8>;
++ ti,itap-del-sel-ddr52 = <0x0>;
+ dma-coherent;
+ };
+
+@@ -283,18 +284,22 @@ sdhci1: mmc@4fa0000 {
+ clocks = <&k3_clks 48 0>, <&k3_clks 48 1>;
+ clock-names = "clk_ahb", "clk_xin";
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
++ ti,clkbuf-sel = <0x7>;
++ ti,trm-icp = <0x8>;
+ ti,otap-del-sel-legacy = <0x0>;
+ ti,otap-del-sel-mmc-hs = <0x0>;
+ ti,otap-del-sel-sd-hs = <0x0>;
+- ti,otap-del-sel-sdr12 = <0x0>;
+- ti,otap-del-sel-sdr25 = <0x0>;
++ ti,otap-del-sel-sdr12 = <0xf>;
++ ti,otap-del-sel-sdr25 = <0xf>;
+ ti,otap-del-sel-sdr50 = <0x8>;
+ ti,otap-del-sel-sdr104 = <0x7>;
+ ti,otap-del-sel-ddr50 = <0x4>;
+ ti,otap-del-sel-ddr52 = <0x4>;
+ ti,otap-del-sel-hs200 = <0x7>;
+- ti,clkbuf-sel = <0x7>;
+- ti,trm-icp = <0x8>;
++ ti,itap-del-sel-legacy = <0xa>;
++ ti,itap-del-sel-sd-hs = <0x1>;
++ ti,itap-del-sel-sdr12 = <0xa>;
++ ti,itap-del-sel-sdr25 = <0x1>;
+ dma-coherent;
+ };
+
+--
+2.39.5
+
--- /dev/null
+From 73256b033455e801ff67869aeeafd79229f526e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 May 2025 15:49:59 -0700
+Subject: Input: synaptics-rmi - fix crash with unsupported versions of F34
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+[ Upstream commit ca39500f6af9cfe6823dc5aa8fbaed788d6e35b2 ]
+
+Sysfs interface for updating firmware for RMI devices is available even
+when F34 probe fails. The code checks for presence of F34 "container"
+pointer and then tries to use the function data attached to the
+sub-device. F34 assigns the function data early, before it knows if
+probe will succeed, leaving behind a stale pointer.
+
+Fix this by expanding checks to not only test for presence of F34
+"container" but also check if there is driver data assigned to the
+sub-device, and call dev_set_drvdata() only after we are certain that
+probe is successful.
+
+This is not a complete fix, since F34 will be freed during firmware
+update, so there is still a race when fetching and accessing this
+pointer. This race will be addressed in follow-up changes.
+
+Reported-by: Hanno Böck <hanno@hboeck.de>
+Fixes: 29fd0ec2bdbe ("Input: synaptics-rmi4 - add support for F34 device reflash")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/aBlAl6sGulam-Qcx@google.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/rmi4/rmi_f34.c | 135 ++++++++++++++++++++---------------
+ 1 file changed, 76 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
+index c26808f10827a..c93a8ccd87c73 100644
+--- a/drivers/input/rmi4/rmi_f34.c
++++ b/drivers/input/rmi4/rmi_f34.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2016 Zodiac Inflight Innovations
+ */
+
++#include "linux/device.h"
+ #include <linux/kernel.h>
+ #include <linux/rmi.h>
+ #include <linux/firmware.h>
+@@ -298,39 +299,30 @@ static int rmi_f34_update_firmware(struct f34_data *f34,
+ return ret;
+ }
+
+-static int rmi_f34_status(struct rmi_function *fn)
+-{
+- struct f34_data *f34 = dev_get_drvdata(&fn->dev);
+-
+- /*
+- * The status is the percentage complete, or once complete,
+- * zero for success or a negative return code.
+- */
+- return f34->update_status;
+-}
+-
+ static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
+ struct device_attribute *dattr,
+ char *buf)
+ {
+ struct rmi_driver_data *data = dev_get_drvdata(dev);
+- struct rmi_function *fn = data->f34_container;
++ struct rmi_function *fn;
+ struct f34_data *f34;
+
+- if (fn) {
+- f34 = dev_get_drvdata(&fn->dev);
+-
+- if (f34->bl_version == 5)
+- return sysfs_emit(buf, "%c%c\n",
+- f34->bootloader_id[0],
+- f34->bootloader_id[1]);
+- else
+- return sysfs_emit(buf, "V%d.%d\n",
+- f34->bootloader_id[1],
+- f34->bootloader_id[0]);
+- }
++ fn = data->f34_container;
++ if (!fn)
++ return -ENODEV;
+
+- return 0;
++ f34 = dev_get_drvdata(&fn->dev);
++ if (!f34)
++ return -ENODEV;
++
++ if (f34->bl_version == 5)
++ return sysfs_emit(buf, "%c%c\n",
++ f34->bootloader_id[0],
++ f34->bootloader_id[1]);
++ else
++ return sysfs_emit(buf, "V%d.%d\n",
++ f34->bootloader_id[1],
++ f34->bootloader_id[0]);
+ }
+
+ static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
+@@ -343,13 +335,16 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev,
+ struct rmi_function *fn = data->f34_container;
+ struct f34_data *f34;
+
+- if (fn) {
+- f34 = dev_get_drvdata(&fn->dev);
++ fn = data->f34_container;
++ if (!fn)
++ return -ENODEV;
+
+- return sysfs_emit(buf, "%s\n", f34->configuration_id);
+- }
++ f34 = dev_get_drvdata(&fn->dev);
++ if (!f34)
++ return -ENODEV;
+
+- return 0;
++
++ return sysfs_emit(buf, "%s\n", f34->configuration_id);
+ }
+
+ static DEVICE_ATTR(configuration_id, 0444,
+@@ -365,10 +360,14 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
+
+ if (!data->f34_container) {
+ dev_warn(dev, "%s: No F34 present!\n", __func__);
+- return -EINVAL;
++ return -ENODEV;
+ }
+
+ f34 = dev_get_drvdata(&data->f34_container->dev);
++ if (!f34) {
++ dev_warn(dev, "%s: No valid F34 present!\n", __func__);
++ return -ENODEV;
++ }
+
+ if (f34->bl_version == 7) {
+ if (data->pdt_props & HAS_BSR) {
+@@ -494,10 +493,18 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
+ char *buf)
+ {
+ struct rmi_driver_data *data = dev_get_drvdata(dev);
+- int update_status = 0;
++ struct f34_data *f34;
++ int update_status = -ENODEV;
+
+- if (data->f34_container)
+- update_status = rmi_f34_status(data->f34_container);
++ /*
++ * The status is the percentage complete, or once complete,
++ * zero for success or a negative return code.
++ */
++ if (data->f34_container) {
++ f34 = dev_get_drvdata(&data->f34_container->dev);
++ if (f34)
++ update_status = f34->update_status;
++ }
+
+ return sysfs_emit(buf, "%d\n", update_status);
+ }
+@@ -517,33 +524,21 @@ static const struct attribute_group rmi_firmware_attr_group = {
+ .attrs = rmi_firmware_attrs,
+ };
+
+-static int rmi_f34_probe(struct rmi_function *fn)
++static int rmi_f34v5_probe(struct f34_data *f34)
+ {
+- struct f34_data *f34;
+- unsigned char f34_queries[9];
++ struct rmi_function *fn = f34->fn;
++ u8 f34_queries[9];
+ bool has_config_id;
+- u8 version = fn->fd.function_version;
+- int ret;
+-
+- f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
+- if (!f34)
+- return -ENOMEM;
+-
+- f34->fn = fn;
+- dev_set_drvdata(&fn->dev, f34);
+-
+- /* v5 code only supported version 0, try V7 probe */
+- if (version > 0)
+- return rmi_f34v7_probe(f34);
++ int error;
+
+ f34->bl_version = 5;
+
+- ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
+- f34_queries, sizeof(f34_queries));
+- if (ret) {
++ error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
++ f34_queries, sizeof(f34_queries));
++ if (error) {
+ dev_err(&fn->dev, "%s: Failed to query properties\n",
+ __func__);
+- return ret;
++ return error;
+ }
+
+ snprintf(f34->bootloader_id, sizeof(f34->bootloader_id),
+@@ -569,11 +564,11 @@ static int rmi_f34_probe(struct rmi_function *fn)
+ f34->v5.config_blocks);
+
+ if (has_config_id) {
+- ret = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
+- f34_queries, sizeof(f34_queries));
+- if (ret) {
++ error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
++ f34_queries, sizeof(f34_queries));
++ if (error) {
+ dev_err(&fn->dev, "Failed to read F34 config ID\n");
+- return ret;
++ return error;
+ }
+
+ snprintf(f34->configuration_id, sizeof(f34->configuration_id),
+@@ -582,12 +577,34 @@ static int rmi_f34_probe(struct rmi_function *fn)
+ f34_queries[2], f34_queries[3]);
+
+ rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Configuration ID: %s\n",
+- f34->configuration_id);
++ f34->configuration_id);
+ }
+
+ return 0;
+ }
+
++static int rmi_f34_probe(struct rmi_function *fn)
++{
++ struct f34_data *f34;
++ u8 version = fn->fd.function_version;
++ int error;
++
++ f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
++ if (!f34)
++ return -ENOMEM;
++
++ f34->fn = fn;
++
++ /* v5 code only supported version 0 */
++ error = version == 0 ? rmi_f34v5_probe(f34) : rmi_f34v7_probe(f34);
++ if (error)
++ return error;
++
++ dev_set_drvdata(&fn->dev, f34);
++
++ return 0;
++}
++
+ int rmi_f34_create_sysfs(struct rmi_device *rmi_dev)
+ {
+ return sysfs_create_group(&rmi_dev->dev.kobj, &rmi_firmware_attr_group);
+--
+2.39.5
+
--- /dev/null
+From b83cb138db6a0a21d1cc22c96d9f3c2b3654de4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Sep 2022 08:56:06 -0700
+Subject: Input: synaptics-rmi4 - convert to use sysfs_emit() APIs
+
+From: zhang songyi <zhang.songyi@zte.com.cn>
+
+[ Upstream commit 9dedc915937c33302df7fcab01c45e7936d6195a ]
+
+Follow the advice of the Documentation/filesystems/sysfs.rst and show()
+should only use sysfs_emit() or sysfs_emit_at() when formatting the value
+to be returned to user space.
+
+Reported-by: Zeal Robot <zealci@zte.com.cn>
+Signed-off-by: zhang songyi <zhang.songyi@zte.com.cn>
+Link: https://lore.kernel.org/r/20220927070936.258300-1-zhang.songyi@zte.com.cn
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Stable-dep-of: ca39500f6af9 ("Input: synaptics-rmi - fix crash with unsupported versions of F34")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/rmi4/rmi_f34.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
+index e5dca9868f87f..c26808f10827a 100644
+--- a/drivers/input/rmi4/rmi_f34.c
++++ b/drivers/input/rmi4/rmi_f34.c
+@@ -321,13 +321,13 @@ static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
+ f34 = dev_get_drvdata(&fn->dev);
+
+ if (f34->bl_version == 5)
+- return scnprintf(buf, PAGE_SIZE, "%c%c\n",
+- f34->bootloader_id[0],
+- f34->bootloader_id[1]);
++ return sysfs_emit(buf, "%c%c\n",
++ f34->bootloader_id[0],
++ f34->bootloader_id[1]);
+ else
+- return scnprintf(buf, PAGE_SIZE, "V%d.%d\n",
+- f34->bootloader_id[1],
+- f34->bootloader_id[0]);
++ return sysfs_emit(buf, "V%d.%d\n",
++ f34->bootloader_id[1],
++ f34->bootloader_id[0]);
+ }
+
+ return 0;
+@@ -346,7 +346,7 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev,
+ if (fn) {
+ f34 = dev_get_drvdata(&fn->dev);
+
+- return scnprintf(buf, PAGE_SIZE, "%s\n", f34->configuration_id);
++ return sysfs_emit(buf, "%s\n", f34->configuration_id);
+ }
+
+ return 0;
+@@ -499,7 +499,7 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
+ if (data->f34_container)
+ update_status = rmi_f34_status(data->f34_container);
+
+- return scnprintf(buf, PAGE_SIZE, "%d\n", update_status);
++ return sysfs_emit(buf, "%d\n", update_status);
+ }
+
+ static DEVICE_ATTR(update_fw_status, 0444,
+--
+2.39.5
+
--- /dev/null
+From d73d0c447d96b599105d8511d72324c0d2b74dff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 May 2025 09:29:23 +0300
+Subject: pmdomain: core: Fix error checking in genpd_dev_pm_attach_by_id()
+
+From: Dan Carpenter <dan.carpenter@linaro.org>
+
+[ Upstream commit 0f5757667ec0aaf2456c3b76fcf0c6c3ea3591fe ]
+
+The error checking for of_count_phandle_with_args() does not handle
+negative error codes correctly. The problem is that "index" is a u32 so
+in the condition "if (index >= num_domains)" negative error codes stored
+in "num_domains" are type promoted to very high positive values and
+"index" is always going to be valid.
+
+Test for negative error codes first and then test if "index" is valid.
+
+Fixes: 3ccf3f0cd197 ("PM / Domains: Enable genpd_dev_pm_attach_by_id|name() for single PM domain")
+Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/aBxPQ8AI8N5v-7rL@stanley.mountain
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/power/domain.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
+index fda0a5e50a2d9..005ece1a658e5 100644
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2773,7 +2773,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev,
+ /* Verify that the index is within a valid range. */
+ num_domains = of_count_phandle_with_args(dev->of_node, "power-domains",
+ "#power-domain-cells");
+- if (index >= num_domains)
++ if (num_domains < 0 || index >= num_domains)
+ return NULL;
+
+ /* Allocate and register device on the genpd bus. */
+--
+2.39.5
+
--- /dev/null
+From 34b3cd60328392c8e91960e8bf9f8f3284e464b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 08:01:28 +0300
+Subject: serial: sh-sci: Check if TX data was written to device in .tx_empty()
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 7cc0e0a43a91052477c2921f924a37d9c3891f0c upstream.
+
+On the Renesas RZ/G3S, when doing suspend to RAM, the uart_suspend_port()
+is called. The uart_suspend_port() calls 3 times the
+struct uart_port::ops::tx_empty() before shutting down the port.
+
+According to the documentation, the struct uart_port::ops::tx_empty()
+API tests whether the transmitter FIFO and shifter for the port is
+empty.
+
+The Renesas RZ/G3S SCIFA IP reports the number of data units stored in the
+transmit FIFO through the FDR (FIFO Data Count Register). The data units
+in the FIFOs are written in the shift register and transmitted from there.
+The TEND bit in the Serial Status Register reports if the data was
+transmitted from the shift register.
+
+In the previous code, in the tx_empty() API implemented by the sh-sci
+driver, it is considered that the TX is empty if the hardware reports the
+TEND bit set and the number of data units in the FIFO is zero.
+
+According to the HW manual, the TEND bit has the following meaning:
+
+0: Transmission is in the waiting state or in progress.
+1: Transmission is completed.
+
+It has been noticed that when opening the serial device w/o using it and
+then switch to a power saving mode, the tx_empty() call in the
+uart_port_suspend() function fails, leading to the "Unable to drain
+transmitter" message being printed on the console. This is because the
+TEND=0 if nothing has been transmitted and the FIFOs are empty. As the
+TEND=0 has double meaning (waiting state, in progress) we can't
+determined the scenario described above.
+
+Add a software workaround for this. This sets a variable if any data has
+been sent on the serial console (when using PIO) or if the DMA callback has
+been called (meaning something has been transmitted). In the tx_empty()
+API the status of the DMA transaction is also checked and if it is
+completed or in progress the code falls back in checking the hardware
+registers instead of relying on the software variable.
+
+Fixes: 73a19e4c0301 ("serial: sh-sci: Add DMA support.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20241125115856.513642-1-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[claudiu.beznea: fixed conflict by:
+ - keeping serial_port_out() instead of sci_port_out() in
+ sci_transmit_chars()
+ - keeping !uart_circ_empty(xmit) condition in sci_dma_tx_complete(),
+ after s->tx_occurred = true; assignement]
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sh-sci.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index eb9c1e991024a..a276efa103192 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -157,6 +157,7 @@ struct sci_port {
+
+ bool has_rtscts;
+ bool autorts;
++ bool tx_occurred;
+ };
+
+ #define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
+@@ -807,6 +808,7 @@ static void sci_transmit_chars(struct uart_port *port)
+ {
+ struct circ_buf *xmit = &port->state->xmit;
+ unsigned int stopped = uart_tx_stopped(port);
++ struct sci_port *s = to_sci_port(port);
+ unsigned short status;
+ unsigned short ctrl;
+ int count;
+@@ -838,6 +840,7 @@ static void sci_transmit_chars(struct uart_port *port)
+ }
+
+ serial_port_out(port, SCxTDR, c);
++ s->tx_occurred = true;
+
+ port->icount.tx++;
+ } while (--count > 0);
+@@ -1202,6 +1205,8 @@ static void sci_dma_tx_complete(void *arg)
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
++ s->tx_occurred = true;
++
+ if (!uart_circ_empty(xmit)) {
+ s->cookie_tx = 0;
+ schedule_work(&s->work_tx);
+@@ -1684,6 +1689,19 @@ static void sci_flush_buffer(struct uart_port *port)
+ s->cookie_tx = -EINVAL;
+ }
+ }
++
++static void sci_dma_check_tx_occurred(struct sci_port *s)
++{
++ struct dma_tx_state state;
++ enum dma_status status;
++
++ if (!s->chan_tx)
++ return;
++
++ status = dmaengine_tx_status(s->chan_tx, s->cookie_tx, &state);
++ if (status == DMA_COMPLETE || status == DMA_IN_PROGRESS)
++ s->tx_occurred = true;
++}
+ #else /* !CONFIG_SERIAL_SH_SCI_DMA */
+ static inline void sci_request_dma(struct uart_port *port)
+ {
+@@ -1693,6 +1711,10 @@ static inline void sci_free_dma(struct uart_port *port)
+ {
+ }
+
++static void sci_dma_check_tx_occurred(struct sci_port *s)
++{
++}
++
+ #define sci_flush_buffer NULL
+ #endif /* !CONFIG_SERIAL_SH_SCI_DMA */
+
+@@ -2005,6 +2027,12 @@ static unsigned int sci_tx_empty(struct uart_port *port)
+ {
+ unsigned short status = serial_port_in(port, SCxSR);
+ unsigned short in_tx_fifo = sci_txfill(port);
++ struct sci_port *s = to_sci_port(port);
++
++ sci_dma_check_tx_occurred(s);
++
++ if (!s->tx_occurred)
++ return TIOCSER_TEMT;
+
+ return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
+ }
+@@ -2175,6 +2203,7 @@ static int sci_startup(struct uart_port *port)
+
+ dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
+
++ s->tx_occurred = false;
+ sci_request_dma(port);
+
+ ret = sci_request_irq(s);
+--
+2.39.5
+
--- /dev/null
+From 15ab33e0891dbfd5a45d7f83d98e996aae624b27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 08:01:30 +0300
+Subject: serial: sh-sci: Clean sci_ports[0] after at earlycon exit
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 5f1017069933489add0c08659673443c9905659e upstream.
+
+The early_console_setup() function initializes sci_ports[0].port with an
+object of type struct uart_port obtained from the struct earlycon_device
+passed as an argument to early_console_setup().
+
+Later, during serial port probing, the serial port used as earlycon
+(e.g., port A) might be remapped to a different position in the sci_ports[]
+array, and a different serial port (e.g., port B) might be assigned to slot
+0. For example:
+
+sci_ports[0] = port B
+sci_ports[X] = port A
+
+In this scenario, the new port mapped at index zero (port B) retains the
+data associated with the earlycon configuration. Consequently, after the
+Linux boot process, any access to the serial port now mapped to
+sci_ports[0] (port B) will block the original earlycon port (port A).
+
+To address this, introduce an early_console_exit() function to clean up
+sci_ports[0] when earlycon is exited.
+
+To prevent the cleanup of sci_ports[0] while the serial device is still
+being used by earlycon, introduce the struct sci_port::probing flag and
+account for it in early_console_exit().
+
+Fixes: 0b0cced19ab1 ("serial: sh-sci: Add CONFIG_SERIAL_EARLYCON support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20250116182249.3828577-5-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sh-sci.c | 32 ++++++++++++++++++++++++++++++--
+ 1 file changed, 30 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index a24fcd702f6cd..534b9840eb796 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -166,6 +166,7 @@ static struct sci_port sci_ports[SCI_NPORTS];
+ static unsigned long sci_ports_in_use;
+ static struct uart_driver sci_uart_driver;
+ static bool sci_uart_earlycon;
++static bool sci_uart_earlycon_dev_probing;
+
+ static inline struct sci_port *
+ to_sci_port(struct uart_port *uart)
+@@ -3284,7 +3285,8 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev,
+ static int sci_probe_single(struct platform_device *dev,
+ unsigned int index,
+ struct plat_sci_port *p,
+- struct sci_port *sciport)
++ struct sci_port *sciport,
++ struct resource *sci_res)
+ {
+ int ret;
+
+@@ -3331,6 +3333,14 @@ static int sci_probe_single(struct platform_device *dev,
+ sciport->port.flags |= UPF_HARD_FLOW;
+ }
+
++ if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
++ /*
++ * Skip cleanup the sci_port[0] in early_console_exit(), this
++ * port is the same as the earlycon one.
++ */
++ sci_uart_earlycon_dev_probing = true;
++ }
++
+ return uart_add_one_port(&sci_uart_driver, &sciport->port);
+ }
+
+@@ -3389,7 +3399,7 @@ static int sci_probe(struct platform_device *dev)
+
+ platform_set_drvdata(dev, sp);
+
+- ret = sci_probe_single(dev, dev_id, p, sp);
++ ret = sci_probe_single(dev, dev_id, p, sp, res);
+ if (ret)
+ return ret;
+
+@@ -3472,6 +3482,22 @@ sh_early_platform_init_buffer("earlyprintk", &sci_driver,
+ #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON
+ static struct plat_sci_port port_cfg;
+
++static int early_console_exit(struct console *co)
++{
++ struct sci_port *sci_port = &sci_ports[0];
++
++ /*
++ * Clean the slot used by earlycon. A new SCI device might
++ * map to this slot.
++ */
++ if (!sci_uart_earlycon_dev_probing) {
++ memset(sci_port, 0, sizeof(*sci_port));
++ sci_uart_earlycon = false;
++ }
++
++ return 0;
++}
++
+ static int __init early_console_setup(struct earlycon_device *device,
+ int type)
+ {
+@@ -3491,6 +3517,8 @@ static int __init early_console_setup(struct earlycon_device *device,
+ SCSCR_RE | SCSCR_TE | port_cfg.scscr);
+
+ device->con->write = serial_console_write;
++ device->con->exit = early_console_exit;
++
+ return 0;
+ }
+ static int __init sci_early_console_setup(struct earlycon_device *device,
+--
+2.39.5
+
--- /dev/null
+From 7490534c6dbc7e68d073ebe9ee1ea6a3383f4b13 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 08:01:31 +0300
+Subject: serial: sh-sci: Increment the runtime usage counter for the earlycon
+ device
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 651dee03696e1dfde6d9a7e8664bbdcd9a10ea7f upstream.
+
+In the sh-sci driver, serial ports are mapped to the sci_ports[] array,
+with earlycon mapped at index zero.
+
+The uart_add_one_port() function eventually calls __device_attach(),
+which, in turn, calls pm_request_idle(). The identified code path is as
+follows:
+
+uart_add_one_port() ->
+ serial_ctrl_register_port() ->
+ serial_core_register_port() ->
+ serial_core_port_device_add() ->
+ serial_base_port_add() ->
+ device_add() ->
+ bus_probe_device() ->
+ device_initial_probe() ->
+ __device_attach() ->
+ // ...
+ if (dev->p->dead) {
+ // ...
+ } else if (dev->driver) {
+ // ...
+ } else {
+ // ...
+ pm_request_idle(dev);
+ // ...
+ }
+
+The earlycon device clocks are enabled by the bootloader. However, the
+pm_request_idle() call in __device_attach() disables the SCI port clocks
+while earlycon is still active.
+
+The earlycon write function, serial_console_write(), calls
+sci_poll_put_char() via serial_console_putchar(). If the SCI port clocks
+are disabled, writing to earlycon may sometimes cause the SR.TDFE bit to
+remain unset indefinitely, causing the while loop in sci_poll_put_char()
+to never exit. On single-core SoCs, this can result in the system being
+blocked during boot when this issue occurs.
+
+To resolve this, increment the runtime PM usage counter for the earlycon
+SCI device before registering the UART port.
+
+Fixes: 0b0cced19ab1 ("serial: sh-sci: Add CONFIG_SERIAL_EARLYCON support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20250116182249.3828577-6-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sh-sci.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index 534b9840eb796..aa4f0803c8d3e 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -3334,6 +3334,22 @@ static int sci_probe_single(struct platform_device *dev,
+ }
+
+ if (sci_uart_earlycon && sci_ports[0].port.mapbase == sci_res->start) {
++ /*
++ * In case:
++ * - this is the earlycon port (mapped on index 0 in sci_ports[]) and
++ * - it now maps to an alias other than zero and
++ * - the earlycon is still alive (e.g., "earlycon keep_bootcon" is
++ * available in bootargs)
++ *
++ * we need to avoid disabling clocks and PM domains through the runtime
++ * PM APIs called in __device_attach(). For this, increment the runtime
++ * PM reference counter (the clocks and PM domains were already enabled
++ * by the bootloader). Otherwise the earlycon may access the HW when it
++ * has no clocks enabled leading to failures (infinite loop in
++ * sci_poll_put_char()).
++ */
++ pm_runtime_get_noresume(&dev->dev);
++
+ /*
+ * Skip cleanup the sci_port[0] in early_console_exit(), this
+ * port is the same as the earlycon one.
+--
+2.39.5
+
--- /dev/null
+From e02e0f90b6639a4c75ce8464c7e7cb0caaacfda9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 11 Jun 2025 08:01:29 +0300
+Subject: serial: sh-sci: Move runtime PM enable to sci_probe_single()
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+commit 239f11209e5f282e16f5241b99256e25dd0614b6 upstream.
+
+Relocate the runtime PM enable operation to sci_probe_single(). This change
+prepares the codebase for upcoming fixes.
+
+While at it, replace the existing logic with a direct call to
+devm_pm_runtime_enable() and remove sci_cleanup_single(). The
+devm_pm_runtime_enable() function automatically handles disabling runtime
+PM during driver removal.
+
+Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Link: https://lore.kernel.org/r/20250116182249.3828577-3-claudiu.beznea.uj@bp.renesas.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sh-sci.c | 24 ++++++------------------
+ 1 file changed, 6 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
+index a276efa103192..a24fcd702f6cd 100644
+--- a/drivers/tty/serial/sh-sci.c
++++ b/drivers/tty/serial/sh-sci.c
+@@ -2993,10 +2993,6 @@ static int sci_init_single(struct platform_device *dev,
+ ret = sci_init_clocks(sci_port, &dev->dev);
+ if (ret < 0)
+ return ret;
+-
+- port->dev = &dev->dev;
+-
+- pm_runtime_enable(&dev->dev);
+ }
+
+ port->type = p->type;
+@@ -3026,11 +3022,6 @@ static int sci_init_single(struct platform_device *dev,
+ return 0;
+ }
+
+-static void sci_cleanup_single(struct sci_port *port)
+-{
+- pm_runtime_disable(port->port.dev);
+-}
+-
+ #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) || \
+ defined(CONFIG_SERIAL_SH_SCI_EARLYCON)
+ static void serial_console_putchar(struct uart_port *port, int ch)
+@@ -3188,8 +3179,6 @@ static int sci_remove(struct platform_device *dev)
+ sci_ports_in_use &= ~BIT(port->port.line);
+ uart_remove_one_port(&sci_uart_driver, &port->port);
+
+- sci_cleanup_single(port);
+-
+ if (port->port.fifosize > 1)
+ device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger);
+ if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF)
+@@ -3324,6 +3313,11 @@ static int sci_probe_single(struct platform_device *dev,
+ if (ret)
+ return ret;
+
++ sciport->port.dev = &dev->dev;
++ ret = devm_pm_runtime_enable(&dev->dev);
++ if (ret)
++ return ret;
++
+ sciport->gpios = mctrl_gpio_init(&sciport->port, 0);
+ if (IS_ERR(sciport->gpios))
+ return PTR_ERR(sciport->gpios);
+@@ -3337,13 +3331,7 @@ static int sci_probe_single(struct platform_device *dev,
+ sciport->port.flags |= UPF_HARD_FLOW;
+ }
+
+- ret = uart_add_one_port(&sci_uart_driver, &sciport->port);
+- if (ret) {
+- sci_cleanup_single(sciport);
+- return ret;
+- }
+-
+- return 0;
++ return uart_add_one_port(&sci_uart_driver, &sciport->port);
+ }
+
+ static int sci_probe(struct platform_device *dev)
+--
+2.39.5
+
seg6-fix-validation-of-nexthop-addresses.patch
fix-propagation-graph-breakage-by-move_mount_set_gro.patch
do_change_type-refuse-to-operate-on-unmounted-not-ou.patch
+pmdomain-core-fix-error-checking-in-genpd_dev_pm_att.patch
+input-synaptics-rmi4-convert-to-use-sysfs_emit-apis.patch
+input-synaptics-rmi-fix-crash-with-unsupported-versi.patch
+arm64-dts-ti-k3-am65-main-drop-deprecated-ti-otap-de.patch
+arm64-dts-ti-k3-am65-main-fix-sdhci-node-properties.patch
+arm64-dts-ti-k3-am65-main-add-missing-taps-to-sdhci0.patch
+serial-sh-sci-check-if-tx-data-was-written-to-device.patch
+serial-sh-sci-move-runtime-pm-enable-to-sci_probe_si.patch
+serial-sh-sci-clean-sci_ports-0-after-at-earlycon-ex.patch
+serial-sh-sci-increment-the-runtime-usage-counter-fo.patch