From: Sasha Levin Date: Sat, 14 Jun 2025 13:34:10 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v6.6.94~68 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8aba60d99a9819c95834ecaec66c013c6bc5b0a2;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/arm64-dts-ti-k3-am65-main-add-missing-taps-to-sdhci0.patch b/queue-5.15/arm64-dts-ti-k3-am65-main-add-missing-taps-to-sdhci0.patch new file mode 100644 index 0000000000..58d3e770f3 --- /dev/null +++ b/queue-5.15/arm64-dts-ti-k3-am65-main-add-missing-taps-to-sdhci0.patch @@ -0,0 +1,41 @@ +From f5e8a681bfd9fc22f739af6dea664c4382996e60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Apr 2025 12:30:08 -0500 +Subject: arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0 + +From: Judith Mendez + +[ 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 +Reviewed-by: Moteen Shah +Link: https://lore.kernel.org/r/20250429173009.33994-1-jm@ti.com +Signed-off-by: Nishanth Menon +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/arm64-dts-ti-k3-am65-main-drop-deprecated-ti-otap-de.patch b/queue-5.15/arm64-dts-ti-k3-am65-main-drop-deprecated-ti-otap-de.patch new file mode 100644 index 0000000000..b7e9ec02ce --- /dev/null +++ b/queue-5.15/arm64-dts-ti-k3-am65-main-drop-deprecated-ti-otap-de.patch @@ -0,0 +1,38 @@ +From ba94e50a86cefb225586153449b7387623651a5a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Link: https://lore.kernel.org/r/20230607132043.3932726-3-nm@ti.com +Signed-off-by: Vignesh Raghavendra +Stable-dep-of: f55c9f087cc2 ("arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/arm64-dts-ti-k3-am65-main-fix-sdhci-node-properties.patch b/queue-5.15/arm64-dts-ti-k3-am65-main-fix-sdhci-node-properties.patch new file mode 100644 index 0000000000..ee8e1a5c32 --- /dev/null +++ b/queue-5.15/arm64-dts-ti-k3-am65-main-fix-sdhci-node-properties.patch @@ -0,0 +1,83 @@ +From 4079a2619a8509d5662bc6db6cab5f570f6d6bf5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Apr 2024 10:17:28 -0500 +Subject: arm64: dts: ti: k3-am65-main: Fix sdhci node properties + +From: Judith Mendez + +[ 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 +Link: https://lore.kernel.org/r/20240423151732.3541894-2-jm@ti.com +Signed-off-by: Nishanth Menon +Stable-dep-of: f55c9f087cc2 ("arm64: dts: ti: k3-am65-main: Add missing taps to sdhci0") +Signed-off-by: Sasha Levin +--- + 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 = ; + 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 = ; ++ 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 + diff --git a/queue-5.15/input-synaptics-rmi-fix-crash-with-unsupported-versi.patch b/queue-5.15/input-synaptics-rmi-fix-crash-with-unsupported-versi.patch new file mode 100644 index 0000000000..20fc6f0057 --- /dev/null +++ b/queue-5.15/input-synaptics-rmi-fix-crash-with-unsupported-versi.patch @@ -0,0 +1,262 @@ +From 73256b033455e801ff67869aeeafd79229f526e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +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 +Signed-off-by: Sasha Levin +--- + 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 + #include + #include +@@ -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 + diff --git a/queue-5.15/input-synaptics-rmi4-convert-to-use-sysfs_emit-apis.patch b/queue-5.15/input-synaptics-rmi4-convert-to-use-sysfs_emit-apis.patch new file mode 100644 index 0000000000..31b0232e9e --- /dev/null +++ b/queue-5.15/input-synaptics-rmi4-convert-to-use-sysfs_emit-apis.patch @@ -0,0 +1,68 @@ +From b83cb138db6a0a21d1cc22c96d9f3c2b3654de4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 08:56:06 -0700 +Subject: Input: synaptics-rmi4 - convert to use sysfs_emit() APIs + +From: zhang songyi + +[ 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 +Signed-off-by: zhang songyi +Link: https://lore.kernel.org/r/20220927070936.258300-1-zhang.songyi@zte.com.cn +Signed-off-by: Dmitry Torokhov +Stable-dep-of: ca39500f6af9 ("Input: synaptics-rmi - fix crash with unsupported versions of F34") +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/pmdomain-core-fix-error-checking-in-genpd_dev_pm_att.patch b/queue-5.15/pmdomain-core-fix-error-checking-in-genpd_dev_pm_att.patch new file mode 100644 index 0000000000..2cd6d4c509 --- /dev/null +++ b/queue-5.15/pmdomain-core-fix-error-checking-in-genpd_dev_pm_att.patch @@ -0,0 +1,43 @@ +From d73d0c447d96b599105d8511d72324c0d2b74dff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/aBxPQ8AI8N5v-7rL@stanley.mountain +Signed-off-by: Ulf Hansson +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/serial-sh-sci-check-if-tx-data-was-written-to-device.patch b/queue-5.15/serial-sh-sci-check-if-tx-data-was-written-to-device.patch new file mode 100644 index 0000000000..1339cc8bf4 --- /dev/null +++ b/queue-5.15/serial-sh-sci-check-if-tx-data-was-written-to-device.patch @@ -0,0 +1,155 @@ +From 34b3cd60328392c8e91960e8bf9f8f3284e464b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +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 +Link: https://lore.kernel.org/r/20241125115856.513642-1-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Greg Kroah-Hartman +[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 +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/serial-sh-sci-clean-sci_ports-0-after-at-earlycon-ex.patch b/queue-5.15/serial-sh-sci-clean-sci_ports-0-after-at-earlycon-ex.patch new file mode 100644 index 0000000000..c719a3997f --- /dev/null +++ b/queue-5.15/serial-sh-sci-clean-sci_ports-0-after-at-earlycon-ex.patch @@ -0,0 +1,125 @@ +From 15ab33e0891dbfd5a45d7f83d98e996aae624b27 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 08:01:30 +0300 +Subject: serial: sh-sci: Clean sci_ports[0] after at earlycon exit + +From: Claudiu Beznea + +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 +Link: https://lore.kernel.org/r/20250116182249.3828577-5-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Claudiu Beznea +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/serial-sh-sci-increment-the-runtime-usage-counter-fo.patch b/queue-5.15/serial-sh-sci-increment-the-runtime-usage-counter-fo.patch new file mode 100644 index 0000000000..6e8fc4b155 --- /dev/null +++ b/queue-5.15/serial-sh-sci-increment-the-runtime-usage-counter-fo.patch @@ -0,0 +1,92 @@ +From 7490534c6dbc7e68d073ebe9ee1ea6a3383f4b13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +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 +Link: https://lore.kernel.org/r/20250116182249.3828577-6-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Claudiu Beznea +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/serial-sh-sci-move-runtime-pm-enable-to-sci_probe_si.patch b/queue-5.15/serial-sh-sci-move-runtime-pm-enable-to-sci_probe_si.patch new file mode 100644 index 0000000000..d57e97c353 --- /dev/null +++ b/queue-5.15/serial-sh-sci-move-runtime-pm-enable-to-sci_probe_si.patch @@ -0,0 +1,93 @@ +From e02e0f90b6639a4c75ce8464c7e7cb0caaacfda9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 08:01:29 +0300 +Subject: serial: sh-sci: Move runtime PM enable to sci_probe_single() + +From: Claudiu Beznea + +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 +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20250116182249.3828577-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Claudiu Beznea +Signed-off-by: Sasha Levin +--- + 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 + diff --git a/queue-5.15/series b/queue-5.15/series index 48679ba62c..af57ba85fc 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -128,3 +128,13 @@ wireguard-device-enable-threaded-napi.patch 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