From: Greg Kroah-Hartman Date: Mon, 5 Jan 2026 10:42:58 +0000 (+0100) Subject: 6.12-stable patches X-Git-Tag: v6.12.64~37 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e283363a82de737ae3984b70552af088a9dccaa;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch leds-leds-cros_ec-skip-leds-without-color-components.patch leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch leds-leds-lp50xx-enable-chip-before-any-communication.patch leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch media-rc-st_rc-fix-reset-control-resource-leak.patch media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch powerpc-mm-fix-mprotect-on-book3s-32-bit.patch --- diff --git a/queue-6.12/arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch b/queue-6.12/arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch new file mode 100644 index 0000000000..5d4b446d65 --- /dev/null +++ b/queue-6.12/arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch @@ -0,0 +1,62 @@ +From 51f89c488f2ecc020f82bfedd77482584ce8027a Mon Sep 17 00:00:00 2001 +From: Siddharth Vadapalli +Date: Wed, 19 Nov 2025 21:31:05 +0530 +Subject: arm64: dts: ti: k3-j721e-sk: Fix pinmux for pin Y1 used by power regulator + +From: Siddharth Vadapalli + +commit 51f89c488f2ecc020f82bfedd77482584ce8027a upstream. + +The SoC pin Y1 is incorrectly defined in the WKUP Pinmux device-tree node +(pinctrl@4301c000) leading to the following silent failure: + + pinctrl-single 4301c000.pinctrl: mux offset out of range: 0x1dc (0x178) + +According to the datasheet for the J721E SoC [0], the pin Y1 belongs to the +MAIN Pinmux device-tree node (pinctrl@11c000). This is confirmed by the +address of the pinmux register for it on page 142 of the datasheet which is +0x00011C1DC. + +Hence fix it. + +[0]: https://www.ti.com/lit/ds/symlink/tda4vm.pdf + +Fixes: 97b67cc102dc ("arm64: dts: ti: k3-j721e-sk: Add DT nodes for power regulators") +Cc: stable@vger.kernel.org +Signed-off-by: Siddharth Vadapalli +Reviewed-by: Yemike Abhilash Chandra +Link: https://patch.msgid.link/20251119160148.2752616-1-s-vadapalli@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/ti/k3-j721e-sk.dts | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/arch/arm64/boot/dts/ti/k3-j721e-sk.dts ++++ b/arch/arm64/boot/dts/ti/k3-j721e-sk.dts +@@ -572,6 +572,12 @@ + J721E_IOPAD(0x234, PIN_INPUT, 7) /* (U3) EXT_REFCLK1.GPIO1_12 */ + >; + }; ++ ++ vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { ++ pinctrl-single,pins = < ++ J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ ++ >; ++ }; + }; + + &wkup_pmx0 { +@@ -633,12 +639,6 @@ + >; + }; + +- vdd_sd_dv_pins_default: vdd-sd-dv-default-pins { +- pinctrl-single,pins = < +- J721E_IOPAD(0x1dc, PIN_OUTPUT, 7) /* (Y1) SPI1_CLK.GPIO0_118 */ +- >; +- }; +- + wkup_uart0_pins_default: wkup-uart0-default-pins { + pinctrl-single,pins = < + J721E_WKUP_IOPAD(0xa0, PIN_INPUT, 0) /* (J29) WKUP_UART0_RXD */ diff --git a/queue-6.12/block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch b/queue-6.12/block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch new file mode 100644 index 0000000000..f75fa44ed0 --- /dev/null +++ b/queue-6.12/block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch @@ -0,0 +1,57 @@ +From 552c1149af7ac0cffab6fccd13feeaf816dd1f53 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Thu, 4 Dec 2025 19:59:52 +0900 +Subject: block: Clear BLK_ZONE_WPLUG_PLUGGED when aborting plugged BIOs + +From: Damien Le Moal + +commit 552c1149af7ac0cffab6fccd13feeaf816dd1f53 upstream. + +Commit fe0418eb9bd6 ("block: Prevent potential deadlocks in zone write +plug error recovery") added a WARN check in disk_put_zone_wplug() to +verify that when the last reference to a zone write plug is dropped, +this zone write plug does not have the BLK_ZONE_WPLUG_PLUGGED flag set, +that is, that it is not plugged. + +However, the function disk_zone_wplug_abort(), which is called for zone +reset and zone finish operations, does not clear this flag after +emptying a zone write plug BIO list. This can result in the +disk_put_zone_wplug() warning to trigger if the user (erroneously as +that is bad pratcice) issues zone reset or zone finish operations while +the target zone still has plugged BIOs. + +Modify disk_put_zone_wplug() to clear the BLK_ZONE_WPLUG_PLUGGED flag. +And while at it, also add a lockdep annotation to ensure that this +function is called with the zone write plug spinlock held. + +Fixes: fe0418eb9bd6 ("block: Prevent potential deadlocks in zone write plug error recovery") +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Reviewed-by: Niklas Cassel +Reviewed-by: Johannes Thumshirn +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-zoned.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/block/blk-zoned.c ++++ b/block/blk-zoned.c +@@ -621,6 +621,8 @@ static void disk_zone_wplug_abort(struct + { + struct bio *bio; + ++ lockdep_assert_held(&zwplug->lock); ++ + if (bio_list_empty(&zwplug->bio_list)) + return; + +@@ -628,6 +630,8 @@ static void disk_zone_wplug_abort(struct + zwplug->disk->disk_name, zwplug->zone_no); + while ((bio = bio_list_pop(&zwplug->bio_list))) + blk_zone_wplug_bio_io_error(zwplug, bio); ++ ++ zwplug->flags &= ~BLK_ZONE_WPLUG_PLUGGED; + } + + /* diff --git a/queue-6.12/clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch b/queue-6.12/clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch new file mode 100644 index 0000000000..4a528027ea --- /dev/null +++ b/queue-6.12/clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch @@ -0,0 +1,59 @@ +From cf33f0b7df13685234ccea7be7bfe316b60db4db Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Mon, 24 Nov 2025 12:11:06 -0700 +Subject: clk: samsung: exynos-clkout: Assign .num before accessing .hws + +From: Nathan Chancellor + +commit cf33f0b7df13685234ccea7be7bfe316b60db4db upstream. + +Commit f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with +__counted_by") annotated the hws member of 'struct clk_hw_onecell_data' +with __counted_by, which informs the bounds sanitizer (UBSAN_BOUNDS) +about the number of elements in .hws[], so that it can warn when .hws[] +is accessed out of bounds. As noted in that change, the __counted_by +member must be initialized with the number of elements before the first +array access happens, otherwise there will be a warning from each access +prior to the initialization because the number of elements is zero. This +occurs in exynos_clkout_probe() due to .num being assigned after .hws[] +has been accessed: + + UBSAN: array-index-out-of-bounds in drivers/clk/samsung/clk-exynos-clkout.c:178:18 + index 0 is out of range for type 'clk_hw *[*]' + +Move the .num initialization to before the first access of .hws[], +clearing up the warning. + +Cc: stable@vger.kernel.org +Fixes: f316cdff8d67 ("clk: Annotate struct clk_hw_onecell_data with __counted_by") +Reported-by: Jochen Sprickerhof +Closes: https://lore.kernel.org/aSIYDN5eyKFKoXKL@eldamar.lan/ +Tested-by: Jochen Sprickerhof +Signed-off-by: Nathan Chancellor +Reviewed-by: Kees Cook +Reviewed-by: Sam Protsenko +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman +--- + drivers/clk/samsung/clk-exynos-clkout.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/samsung/clk-exynos-clkout.c ++++ b/drivers/clk/samsung/clk-exynos-clkout.c +@@ -174,6 +174,7 @@ static int exynos_clkout_probe(struct pl + clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT; + clkout->mux.lock = &clkout->slock; + ++ clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; + clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout", + parent_names, parent_count, &clkout->mux.hw, + &clk_mux_ops, NULL, NULL, &clkout->gate.hw, +@@ -184,7 +185,6 @@ static int exynos_clkout_probe(struct pl + goto err_unmap; + } + +- clkout->data.num = EXYNOS_CLKOUT_NR_CLKS; + ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data); + if (ret) + goto err_clk_unreg; diff --git a/queue-6.12/fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch b/queue-6.12/fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch new file mode 100644 index 0000000000..bcb4268b5e --- /dev/null +++ b/queue-6.12/fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch @@ -0,0 +1,54 @@ +From 1650a1b6cb1ae6cb99bb4fce21b30ebdf9fc238e Mon Sep 17 00:00:00 2001 +From: Shengming Hu +Date: Wed, 26 Nov 2025 17:33:31 +0800 +Subject: fgraph: Check ftrace_pids_enabled on registration for early filtering + +From: Shengming Hu + +commit 1650a1b6cb1ae6cb99bb4fce21b30ebdf9fc238e upstream. + +When registering ftrace_graph, check if ftrace_pids_enabled is active. +If enabled, assign entryfunc to fgraph_pid_func to ensure filtering +is performed before executing the saved original entry function. + +Cc: stable@vger.kernel.org +Cc: +Cc: +Cc: +Cc: +Cc: +Cc: +Link: https://patch.msgid.link/20251126173331679XGVF98NLhyLJRdtNkVZ6w@zte.com.cn +Fixes: df3ec5da6a1e7 ("function_graph: Add pid tracing back to function graph tracer") +Signed-off-by: Shengming Hu +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/fgraph.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/kernel/trace/fgraph.c ++++ b/kernel/trace/fgraph.c +@@ -1286,6 +1286,13 @@ int register_ftrace_graph(struct fgraph_ + + ftrace_graph_active++; + ++ /* Always save the function, and reset at unregistering */ ++ gops->saved_func = gops->entryfunc; ++#ifdef CONFIG_DYNAMIC_FTRACE ++ if (ftrace_pids_enabled(&gops->ops)) ++ gops->entryfunc = fgraph_pid_func; ++#endif ++ + if (ftrace_graph_active == 2) + ftrace_graph_disable_direct(true); + +@@ -1305,8 +1312,6 @@ int register_ftrace_graph(struct fgraph_ + } else { + init_task_vars(gops->idx); + } +- /* Always save the function, and reset at unregistering */ +- gops->saved_func = gops->entryfunc; + + ret = ftrace_startup_subops(&graph_ops, &gops->ops, command); + if (!ret) diff --git a/queue-6.12/fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch b/queue-6.12/fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch new file mode 100644 index 0000000000..71f3aa7ee5 --- /dev/null +++ b/queue-6.12/fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch @@ -0,0 +1,43 @@ +From b5d6d3f73d0bac4a7e3a061372f6da166fc6ee5c Mon Sep 17 00:00:00 2001 +From: Shengming Hu +Date: Wed, 26 Nov 2025 17:29:26 +0800 +Subject: fgraph: Initialize ftrace_ops->private for function graph ops + +From: Shengming Hu + +commit b5d6d3f73d0bac4a7e3a061372f6da166fc6ee5c upstream. + +The ftrace_pids_enabled(op) check relies on op->private being properly +initialized, but fgraph_ops's underlying ftrace_ops->private was left +uninitialized. This caused ftrace_pids_enabled() to always return false, +effectively disabling PID filtering for function graph tracing. + +Fix this by copying src_ops->private to dst_ops->private in +fgraph_init_ops(), ensuring PID filter state is correctly propagated. + +Cc: stable@vger.kernel.org +Cc: +Cc: +Cc: +Cc: +Cc: +Cc: +Fixes: c132be2c4fcc1 ("function_graph: Have the instances use their own ftrace_ops for filtering") +Link: https://patch.msgid.link/20251126172926004y3hC8QyU4WFOjBkU_UxLC@zte.com.cn +Signed-off-by: Shengming Hu +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/fgraph.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/trace/fgraph.c ++++ b/kernel/trace/fgraph.c +@@ -943,6 +943,7 @@ void fgraph_init_ops(struct ftrace_ops * + mutex_init(&dst_ops->local_hash.regex_lock); + INIT_LIST_HEAD(&dst_ops->subop_list); + dst_ops->flags |= FTRACE_OPS_FL_INITIALIZED; ++ dst_ops->private = src_ops->private; + } + #endif + } diff --git a/queue-6.12/leds-leds-cros_ec-skip-leds-without-color-components.patch b/queue-6.12/leds-leds-cros_ec-skip-leds-without-color-components.patch new file mode 100644 index 0000000000..0a8d0a5854 --- /dev/null +++ b/queue-6.12/leds-leds-cros_ec-skip-leds-without-color-components.patch @@ -0,0 +1,62 @@ +From 4dbf066d965cd3299fb396f1375d10423c9c625c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Tue, 28 Oct 2025 16:31:03 +0100 +Subject: leds: leds-cros_ec: Skip LEDs without color components +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit 4dbf066d965cd3299fb396f1375d10423c9c625c upstream. + +A user reports that on their Lenovo Corsola Magneton with EC firmware +steelix-15194.270.0 the driver probe fails with EINVAL. It turns out +that the power LED does not contain any color components as indicated +by the following "ectool led power query" output: + +Brightness range for LED 1: + red : 0x0 + green : 0x0 + blue : 0x0 + yellow : 0x0 + white : 0x0 + amber : 0x0 + +The LED also does not react to commands sent manually through ectool and +is generally non-functional. + +Instead of failing the probe for all LEDs managed by the EC when one +without color components is encountered, silently skip those. + +Cc: stable@vger.kernel.org +Fixes: 8d6ce6f3ec9d ("leds: Add ChromeOS EC driver") +Signed-off-by: Thomas Weißschuh +Link: https://patch.msgid.link/20251028-cros_ec-leds-no-colors-v1-1-ebe13a02022a@weissschuh.net +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/leds-cros_ec.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/leds/leds-cros_ec.c ++++ b/drivers/leds/leds-cros_ec.c +@@ -155,9 +155,6 @@ static int cros_ec_led_count_subleds(str + } + } + +- if (!num_subleds) +- return -EINVAL; +- + *max_brightness = common_range; + return num_subleds; + } +@@ -202,6 +199,8 @@ static int cros_ec_led_probe_one(struct + &priv->led_mc_cdev.led_cdev.max_brightness); + if (num_subleds < 0) + return num_subleds; ++ if (num_subleds == 0) ++ return 0; /* LED without any colors, skip */ + + priv->cros_ec = cros_ec; + priv->led_id = id; diff --git a/queue-6.12/leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch b/queue-6.12/leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch new file mode 100644 index 0000000000..63af823f99 --- /dev/null +++ b/queue-6.12/leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch @@ -0,0 +1,61 @@ +From 26fe74d598c32e7bc6f150edfc4aa43e1bee55db Mon Sep 17 00:00:00 2001 +From: Christian Hitz +Date: Wed, 8 Oct 2025 14:32:21 +0200 +Subject: leds: leds-lp50xx: Allow LED 0 to be added to module bank + +From: Christian Hitz + +commit 26fe74d598c32e7bc6f150edfc4aa43e1bee55db upstream. + +led_banks contains LED module number(s) that should be grouped into the +module bank. led_banks is 0-initialized. +By checking the led_banks entries for 0, un-set entries are detected. +But a 0-entry also indicates that LED module 0 should be grouped into the +module bank. + +By only iterating over the available entries no check for unused entries +is required and LED module 0 can be added to bank. + +Cc: stable@vger.kernel.org +Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver") +Signed-off-by: Christian Hitz +Reviewed-by: Jacek Anaszewski +Link: https://patch.msgid.link/20251008123222.1117331-1-christian@klarinett.li +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/leds-lp50xx.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/leds/leds-lp50xx.c ++++ b/drivers/leds/leds-lp50xx.c +@@ -343,17 +343,15 @@ out: + return ret; + } + +-static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[]) ++static int lp50xx_set_banks(struct lp50xx *priv, u32 led_banks[], int num_leds) + { + u8 led_config_lo, led_config_hi; + u32 bank_enable_mask = 0; + int ret; + int i; + +- for (i = 0; i < priv->chip_info->max_modules; i++) { +- if (led_banks[i]) +- bank_enable_mask |= (1 << led_banks[i]); +- } ++ for (i = 0; i < num_leds; i++) ++ bank_enable_mask |= (1 << led_banks[i]); + + led_config_lo = bank_enable_mask; + led_config_hi = bank_enable_mask >> 8; +@@ -407,7 +405,7 @@ static int lp50xx_probe_leds(struct fwno + return ret; + } + +- ret = lp50xx_set_banks(priv, led_banks); ++ ret = lp50xx_set_banks(priv, led_banks, num_leds); + if (ret) { + dev_err(priv->dev, "Cannot setup banked LEDs\n"); + return ret; diff --git a/queue-6.12/leds-leds-lp50xx-enable-chip-before-any-communication.patch b/queue-6.12/leds-leds-lp50xx-enable-chip-before-any-communication.patch new file mode 100644 index 0000000000..3fa64a548b --- /dev/null +++ b/queue-6.12/leds-leds-lp50xx-enable-chip-before-any-communication.patch @@ -0,0 +1,150 @@ +From 434959618c47efe9e5f2e20f4a850caac4f6b823 Mon Sep 17 00:00:00 2001 +From: Christian Hitz +Date: Tue, 28 Oct 2025 16:51:40 +0100 +Subject: leds: leds-lp50xx: Enable chip before any communication +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Christian Hitz + +commit 434959618c47efe9e5f2e20f4a850caac4f6b823 upstream. + +If a GPIO is used to control the chip's enable pin, it needs to be pulled +high before any i2c communication is attempted. + +Currently, the enable GPIO handling is not correct. + +Assume the enable GPIO is low when the probe function is entered. In this +case the device is in SHUTDOWN mode and does not react to i2c commands. + +During probe the following sequence happens: + 1. The call to lp50xx_reset() on line 548 has no effect as i2c is not + possible yet. + 2. Then - on line 552 - lp50xx_enable_disable() is called. As + "priv->enable_gpio“ has not yet been initialized, setting the GPIO has + no effect. Also the i2c enable command is not executed as the device + is still in SHUTDOWN. + 3. On line 556 the call to lp50xx_probe_dt() finally parses the rest of + the DT and the configured priv->enable_gpio is set up. + +As a result the device is still in SHUTDOWN mode and not ready for +operation. + +Split lp50xx_enable_disable() into distinct enable and disable functions +to enforce correct ordering between enable_gpio manipulations and i2c +commands. +Read enable_gpio configuration from DT before attempting to manipulate +enable_gpio. +Add delays to observe correct wait timing after manipulating enable_gpio +and before any i2c communication. + +Cc: stable@vger.kernel.org +Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver") +Signed-off-by: Christian Hitz +Link: https://patch.msgid.link/20251028155141.1603193-1-christian@klarinett.li +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/leds-lp50xx.c | 55 ++++++++++++++++++++++++++++++++------------- + 1 file changed, 40 insertions(+), 15 deletions(-) + +--- a/drivers/leds/leds-lp50xx.c ++++ b/drivers/leds/leds-lp50xx.c +@@ -52,6 +52,12 @@ + + #define LP50XX_SW_RESET 0xff + #define LP50XX_CHIP_EN BIT(6) ++#define LP50XX_CHIP_DISABLE 0x00 ++#define LP50XX_START_TIME_US 500 ++#define LP50XX_RESET_TIME_US 3 ++ ++#define LP50XX_EN_GPIO_LOW 0 ++#define LP50XX_EN_GPIO_HIGH 1 + + /* There are 3 LED outputs per bank */ + #define LP50XX_LEDS_PER_MODULE 3 +@@ -371,19 +377,42 @@ static int lp50xx_reset(struct lp50xx *p + return regmap_write(priv->regmap, priv->chip_info->reset_reg, LP50XX_SW_RESET); + } + +-static int lp50xx_enable_disable(struct lp50xx *priv, int enable_disable) ++static int lp50xx_enable(struct lp50xx *priv) + { + int ret; + +- ret = gpiod_direction_output(priv->enable_gpio, enable_disable); ++ if (priv->enable_gpio) { ++ ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_HIGH); ++ if (ret) ++ return ret; ++ ++ udelay(LP50XX_START_TIME_US); ++ } ++ ++ ret = lp50xx_reset(priv); + if (ret) + return ret; + +- if (enable_disable) +- return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); +- else +- return regmap_write(priv->regmap, LP50XX_DEV_CFG0, 0); ++ return regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_EN); ++} + ++static int lp50xx_disable(struct lp50xx *priv) ++{ ++ int ret; ++ ++ ret = regmap_write(priv->regmap, LP50XX_DEV_CFG0, LP50XX_CHIP_DISABLE); ++ if (ret) ++ return ret; ++ ++ if (priv->enable_gpio) { ++ ret = gpiod_direction_output(priv->enable_gpio, LP50XX_EN_GPIO_LOW); ++ if (ret) ++ return ret; ++ ++ udelay(LP50XX_RESET_TIME_US); ++ } ++ ++ return 0; + } + + static int lp50xx_probe_leds(struct fwnode_handle *child, struct lp50xx *priv, +@@ -448,6 +477,10 @@ static int lp50xx_probe_dt(struct lp50xx + return dev_err_probe(priv->dev, PTR_ERR(priv->enable_gpio), + "Failed to get enable GPIO\n"); + ++ ret = lp50xx_enable(priv); ++ if (ret) ++ return ret; ++ + priv->regulator = devm_regulator_get(priv->dev, "vled"); + if (IS_ERR(priv->regulator)) + priv->regulator = NULL; +@@ -554,14 +587,6 @@ static int lp50xx_probe(struct i2c_clien + return ret; + } + +- ret = lp50xx_reset(led); +- if (ret) +- return ret; +- +- ret = lp50xx_enable_disable(led, 1); +- if (ret) +- return ret; +- + return lp50xx_probe_dt(led); + } + +@@ -570,7 +595,7 @@ static void lp50xx_remove(struct i2c_cli + struct lp50xx *led = i2c_get_clientdata(client); + int ret; + +- ret = lp50xx_enable_disable(led, 0); ++ ret = lp50xx_disable(led); + if (ret) + dev_err(led->dev, "Failed to disable chip\n"); + diff --git a/queue-6.12/leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch b/queue-6.12/leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch new file mode 100644 index 0000000000..a2cf3dd917 --- /dev/null +++ b/queue-6.12/leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch @@ -0,0 +1,32 @@ +From 5246e3673eeeccb4f5bf4f42375dd495d465ac15 Mon Sep 17 00:00:00 2001 +From: Christian Hitz +Date: Wed, 22 Oct 2025 08:33:04 +0200 +Subject: leds: leds-lp50xx: LP5009 supports 3 modules for a total of 9 LEDs + +From: Christian Hitz + +commit 5246e3673eeeccb4f5bf4f42375dd495d465ac15 upstream. + +LP5009 supports 9 LED outputs that are grouped into 3 modules. + +Cc: stable@vger.kernel.org +Fixes: 242b81170fb8 ("leds: lp50xx: Add the LP50XX family of the RGB LED driver") +Signed-off-by: Christian Hitz +Link: https://patch.msgid.link/20251022063305.972190-1-christian@klarinett.li +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/leds/leds-lp50xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/leds/leds-lp50xx.c ++++ b/drivers/leds/leds-lp50xx.c +@@ -56,7 +56,7 @@ + /* There are 3 LED outputs per bank */ + #define LP50XX_LEDS_PER_MODULE 3 + +-#define LP5009_MAX_LED_MODULES 2 ++#define LP5009_MAX_LED_MODULES 3 + #define LP5012_MAX_LED_MODULES 4 + #define LP5018_MAX_LED_MODULES 6 + #define LP5024_MAX_LED_MODULES 8 diff --git a/queue-6.12/media-rc-st_rc-fix-reset-control-resource-leak.patch b/queue-6.12/media-rc-st_rc-fix-reset-control-resource-leak.patch new file mode 100644 index 0000000000..9b061e9377 --- /dev/null +++ b/queue-6.12/media-rc-st_rc-fix-reset-control-resource-leak.patch @@ -0,0 +1,39 @@ +From 1240abf4b71f632f0117b056e22488e4d9808938 Mon Sep 17 00:00:00 2001 +From: Haotian Zhang +Date: Fri, 31 Oct 2025 14:03:32 +0800 +Subject: media: rc: st_rc: Fix reset control resource leak + +From: Haotian Zhang + +commit 1240abf4b71f632f0117b056e22488e4d9808938 upstream. + +The driver calls reset_control_get_optional_exclusive() but never calls +reset_control_put() in error paths or in the remove function. This causes +a resource leak when probe fails after successfully acquiring the reset +control, or when the driver is unloaded. + +Switch to devm_reset_control_get_optional_exclusive() to automatically +manage the reset control resource. + +Fixes: a4b80242d046 ("media: st-rc: explicitly request exclusive reset control") +Cc: stable@vger.kernel.org +Signed-off-by: Haotian Zhang +Reviewed-by: Patrice Chotard +Signed-off-by: Sean Young +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/rc/st_rc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/rc/st_rc.c ++++ b/drivers/media/rc/st_rc.c +@@ -284,7 +284,7 @@ static int st_rc_probe(struct platform_d + else + rc_dev->rx_base = rc_dev->base; + +- rc_dev->rstc = reset_control_get_optional_exclusive(dev, NULL); ++ rc_dev->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(rc_dev->rstc)) { + ret = PTR_ERR(rc_dev->rstc); + goto err; diff --git a/queue-6.12/media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch b/queue-6.12/media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch new file mode 100644 index 0000000000..c3128bae57 --- /dev/null +++ b/queue-6.12/media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch @@ -0,0 +1,235 @@ +From 19c286b755072a22a063052f530a6b1fac8a1f63 Mon Sep 17 00:00:00 2001 +From: Nicolas Dufresne +Date: Mon, 22 Sep 2025 14:43:38 -0400 +Subject: media: verisilicon: Fix CPU stalls on G2 bus error + +From: Nicolas Dufresne + +commit 19c286b755072a22a063052f530a6b1fac8a1f63 upstream. + +In some seek stress tests, we are getting IRQ from the G2 decoder where +the dec_bus_int and the dec_e bits are high, meaning the decoder is +still running despite the error. + +Fix this by reworking the IRQ handler to only finish the job once we +have reached completion and move the software reset to when our software +watchdog triggers. + +This way, we let the hardware continue on errors when it did not self +reset and in worse case scenario the hardware timeout will +automatically stop it. The actual error will be fixed in a follow up +patch. + +Fixes: 3385c514ecc5a ("media: hantro: Convert imx8m_vpu_g2_irq to helper") +Cc: stable@vger.kernel.org +Reviewed-by: Benjamin Gaignard +Signed-off-by: Nicolas Dufresne +Signed-off-by: Hans Verkuil +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/platform/verisilicon/hantro_g2.c | 84 ++++++++++++---- + drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c | 2 + drivers/media/platform/verisilicon/hantro_g2_regs.h | 13 ++ + drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c | 2 + drivers/media/platform/verisilicon/hantro_hw.h | 1 + drivers/media/platform/verisilicon/imx8m_vpu_hw.c | 2 + 6 files changed, 83 insertions(+), 21 deletions(-) + +--- a/drivers/media/platform/verisilicon/hantro_g2.c ++++ b/drivers/media/platform/verisilicon/hantro_g2.c +@@ -5,43 +5,93 @@ + * Copyright (C) 2021 Collabora Ltd, Andrzej Pietrasiewicz + */ + ++#include + #include "hantro_hw.h" + #include "hantro_g2_regs.h" + + #define G2_ALIGN 16 + +-void hantro_g2_check_idle(struct hantro_dev *vpu) ++static bool hantro_g2_active(struct hantro_ctx *ctx) + { +- int i; ++ struct hantro_dev *vpu = ctx->dev; ++ u32 status; ++ ++ status = vdpu_read(vpu, G2_REG_INTERRUPT); ++ ++ return (status & G2_REG_INTERRUPT_DEC_E); ++} + +- for (i = 0; i < 3; i++) { +- u32 status; ++/** ++ * hantro_g2_reset: ++ * @ctx: the hantro context ++ * ++ * Emulates a reset using Hantro abort function. Failing this procedure would ++ * results in programming a running IP which leads to CPU hang. ++ * ++ * Using a hard reset procedure instead is prefferred. ++ */ ++void hantro_g2_reset(struct hantro_ctx *ctx) ++{ ++ struct hantro_dev *vpu = ctx->dev; ++ u32 status; + +- /* Make sure the VPU is idle */ +- status = vdpu_read(vpu, G2_REG_INTERRUPT); +- if (status & G2_REG_INTERRUPT_DEC_E) { +- dev_warn(vpu->dev, "device still running, aborting"); +- status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS; +- vdpu_write(vpu, status, G2_REG_INTERRUPT); +- } ++ status = vdpu_read(vpu, G2_REG_INTERRUPT); ++ if (status & G2_REG_INTERRUPT_DEC_E) { ++ dev_warn_ratelimited(vpu->dev, "device still running, aborting"); ++ status |= G2_REG_INTERRUPT_DEC_ABORT_E | G2_REG_INTERRUPT_DEC_IRQ_DIS; ++ vdpu_write(vpu, status, G2_REG_INTERRUPT); ++ ++ do { ++ mdelay(1); ++ } while (hantro_g2_active(ctx)); + } + } + + irqreturn_t hantro_g2_irq(int irq, void *dev_id) + { + struct hantro_dev *vpu = dev_id; +- enum vb2_buffer_state state; + u32 status; + + status = vdpu_read(vpu, G2_REG_INTERRUPT); +- state = (status & G2_REG_INTERRUPT_DEC_RDY_INT) ? +- VB2_BUF_STATE_DONE : VB2_BUF_STATE_ERROR; + +- vdpu_write(vpu, 0, G2_REG_INTERRUPT); +- vdpu_write(vpu, G2_REG_CONFIG_DEC_CLK_GATE_E, G2_REG_CONFIG); ++ if (!(status & G2_REG_INTERRUPT_DEC_IRQ)) ++ return IRQ_NONE; ++ ++ hantro_reg_write(vpu, &g2_dec_irq, 0); ++ hantro_reg_write(vpu, &g2_dec_int_stat, 0); ++ hantro_reg_write(vpu, &g2_clk_gate_e, 1); ++ ++ if (status & G2_REG_INTERRUPT_DEC_RDY_INT) { ++ hantro_irq_done(vpu, VB2_BUF_STATE_DONE); ++ return IRQ_HANDLED; ++ } ++ ++ if (status & G2_REG_INTERRUPT_DEC_ABORT_INT) { ++ /* disabled on abort, though lets be safe and handle it */ ++ dev_warn_ratelimited(vpu->dev, "decode operation aborted."); ++ return IRQ_HANDLED; ++ } ++ ++ if (status & G2_REG_INTERRUPT_DEC_LAST_SLICE_INT) ++ dev_warn_ratelimited(vpu->dev, "not all macroblocks were decoded."); ++ ++ if (status & G2_REG_INTERRUPT_DEC_BUS_INT) ++ dev_warn_ratelimited(vpu->dev, "bus error detected."); ++ ++ if (status & G2_REG_INTERRUPT_DEC_ERROR_INT) ++ dev_warn_ratelimited(vpu->dev, "decode error detected."); + +- hantro_irq_done(vpu, state); ++ if (status & G2_REG_INTERRUPT_DEC_TIMEOUT) ++ dev_warn_ratelimited(vpu->dev, "frame decode timed out."); ++ ++ /** ++ * If the decoding haven't stopped, let it continue. The hardware timeout ++ * will trigger if it is trully stuck. ++ */ ++ if (status & G2_REG_INTERRUPT_DEC_E) ++ return IRQ_HANDLED; + ++ hantro_irq_done(vpu, VB2_BUF_STATE_ERROR); + return IRQ_HANDLED; + } + +--- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c ++++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c +@@ -582,8 +582,6 @@ int hantro_g2_hevc_dec_run(struct hantro + struct hantro_dev *vpu = ctx->dev; + int ret; + +- hantro_g2_check_idle(vpu); +- + /* Prepare HEVC decoder context. */ + ret = hantro_hevc_dec_prepare_run(ctx); + if (ret) +--- a/drivers/media/platform/verisilicon/hantro_g2_regs.h ++++ b/drivers/media/platform/verisilicon/hantro_g2_regs.h +@@ -22,7 +22,14 @@ + #define G2_REG_VERSION G2_SWREG(0) + + #define G2_REG_INTERRUPT G2_SWREG(1) ++#define G2_REG_INTERRUPT_DEC_LAST_SLICE_INT BIT(19) ++#define G2_REG_INTERRUPT_DEC_TIMEOUT BIT(18) ++#define G2_REG_INTERRUPT_DEC_ERROR_INT BIT(16) ++#define G2_REG_INTERRUPT_DEC_BUF_INT BIT(14) ++#define G2_REG_INTERRUPT_DEC_BUS_INT BIT(13) + #define G2_REG_INTERRUPT_DEC_RDY_INT BIT(12) ++#define G2_REG_INTERRUPT_DEC_ABORT_INT BIT(11) ++#define G2_REG_INTERRUPT_DEC_IRQ BIT(8) + #define G2_REG_INTERRUPT_DEC_ABORT_E BIT(5) + #define G2_REG_INTERRUPT_DEC_IRQ_DIS BIT(4) + #define G2_REG_INTERRUPT_DEC_E BIT(0) +@@ -35,6 +42,9 @@ + #define BUS_WIDTH_128 2 + #define BUS_WIDTH_256 3 + ++#define g2_dec_int_stat G2_DEC_REG(1, 11, 0xf) ++#define g2_dec_irq G2_DEC_REG(1, 8, 0x1) ++ + #define g2_strm_swap G2_DEC_REG(2, 28, 0xf) + #define g2_strm_swap_old G2_DEC_REG(2, 27, 0x1f) + #define g2_pic_swap G2_DEC_REG(2, 22, 0x1f) +@@ -225,6 +235,9 @@ + #define vp9_filt_level_seg5 G2_DEC_REG(19, 8, 0x3f) + #define vp9_quant_seg5 G2_DEC_REG(19, 0, 0xff) + ++#define g2_timemout_override_e G2_DEC_REG(45, 31, 0x1) ++#define g2_timemout_cycles G2_DEC_REG(45, 0, 0x7fffffff) ++ + #define hevc_cur_poc_00 G2_DEC_REG(46, 24, 0xff) + #define hevc_cur_poc_01 G2_DEC_REG(46, 16, 0xff) + #define hevc_cur_poc_02 G2_DEC_REG(46, 8, 0xff) +--- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c ++++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +@@ -893,8 +893,6 @@ int hantro_g2_vp9_dec_run(struct hantro_ + struct vb2_v4l2_buffer *dst; + int ret; + +- hantro_g2_check_idle(ctx->dev); +- + ret = start_prepare_run(ctx, &decode_params); + if (ret) { + hantro_end_prepare_run(ctx); +--- a/drivers/media/platform/verisilicon/hantro_hw.h ++++ b/drivers/media/platform/verisilicon/hantro_hw.h +@@ -583,6 +583,7 @@ void hantro_g2_vp9_dec_done(struct hantr + int hantro_vp9_dec_init(struct hantro_ctx *ctx); + void hantro_vp9_dec_exit(struct hantro_ctx *ctx); + void hantro_g2_check_idle(struct hantro_dev *vpu); ++void hantro_g2_reset(struct hantro_ctx *ctx); + irqreturn_t hantro_g2_irq(int irq, void *dev_id); + + #endif /* HANTRO_HW_H_ */ +--- a/drivers/media/platform/verisilicon/imx8m_vpu_hw.c ++++ b/drivers/media/platform/verisilicon/imx8m_vpu_hw.c +@@ -312,11 +312,13 @@ static const struct hantro_codec_ops imx + static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = { + [HANTRO_MODE_HEVC_DEC] = { + .run = hantro_g2_hevc_dec_run, ++ .reset = hantro_g2_reset, + .init = hantro_hevc_dec_init, + .exit = hantro_hevc_dec_exit, + }, + [HANTRO_MODE_VP9_DEC] = { + .run = hantro_g2_vp9_dec_run, ++ .reset = hantro_g2_reset, + .done = hantro_g2_vp9_dec_done, + .init = hantro_vp9_dec_init, + .exit = hantro_vp9_dec_exit, diff --git a/queue-6.12/mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch b/queue-6.12/mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch new file mode 100644 index 0000000000..33c52a0540 --- /dev/null +++ b/queue-6.12/mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch @@ -0,0 +1,35 @@ +From ccb7cd3218e48665f3c7e19eede0da5f069c323d Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 25 Sep 2025 17:02:19 +0200 +Subject: mfd: altera-sysmgr: Fix device leak on sysmgr regmap lookup + +From: Johan Hovold + +commit ccb7cd3218e48665f3c7e19eede0da5f069c323d upstream. + +Make sure to drop the reference taken to the sysmgr platform device when +retrieving its driver data. + +Note that holding a reference to a device does not prevent its driver +data from going away. + +Fixes: f36e789a1f8d ("mfd: altera-sysmgr: Add SOCFPGA System Manager") +Cc: stable@vger.kernel.org # 5.2 +Signed-off-by: Johan Hovold +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mfd/altera-sysmgr.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/mfd/altera-sysmgr.c ++++ b/drivers/mfd/altera-sysmgr.c +@@ -117,6 +117,8 @@ struct regmap *altr_sysmgr_regmap_lookup + + sysmgr = dev_get_drvdata(dev); + ++ put_device(dev); ++ + return sysmgr->regmap; + } + EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle); diff --git a/queue-6.12/mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch b/queue-6.12/mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch new file mode 100644 index 0000000000..5765234609 --- /dev/null +++ b/queue-6.12/mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch @@ -0,0 +1,81 @@ +From 2bac49bad1f3553cc3b3bfb22cc194e9bd9e8427 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Thu, 23 Oct 2025 12:19:40 +0200 +Subject: mfd: max77620: Fix potential IRQ chip conflict when probing two devices + +From: Krzysztof Kozlowski + +commit 2bac49bad1f3553cc3b3bfb22cc194e9bd9e8427 upstream. + +MAX77620 is most likely always a single device on the board, however +nothing stops board designers to have two of them, thus same device +driver could probe twice. Or user could manually try to probing second +time. + +Device driver is not ready for that case, because it allocates +statically 'struct regmap_irq_chip' as non-const and stores during +probe in 'irq_drv_data' member a pointer to per-probe state +container ('struct max77620_chip'). devm_regmap_add_irq_chip() does not +make a copy of 'struct regmap_irq_chip' but store the pointer. + +Second probe - either successful or failure - would overwrite the +'irq_drv_data' from previous device probe, so interrupts would be +executed in a wrong context. + +Cc: stable@vger.kernel.org +Fixes: 3df140d11c6d ("mfd: max77620: Mask/unmask interrupt before/after servicing it") +Signed-off-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20251023101939.67991-2-krzysztof.kozlowski@linaro.org +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mfd/max77620.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/mfd/max77620.c ++++ b/drivers/mfd/max77620.c +@@ -253,7 +253,7 @@ static int max77620_irq_global_unmask(vo + return ret; + } + +-static struct regmap_irq_chip max77620_top_irq_chip = { ++static const struct regmap_irq_chip max77620_top_irq_chip = { + .name = "max77620-top", + .irqs = max77620_top_irqs, + .num_irqs = ARRAY_SIZE(max77620_top_irqs), +@@ -497,6 +497,7 @@ static int max77620_probe(struct i2c_cli + const struct i2c_device_id *id = i2c_client_get_device_id(client); + const struct regmap_config *rmap_config; + struct max77620_chip *chip; ++ struct regmap_irq_chip *chip_desc; + const struct mfd_cell *mfd_cells; + int n_mfd_cells; + bool pm_off; +@@ -507,6 +508,14 @@ static int max77620_probe(struct i2c_cli + return -ENOMEM; + + i2c_set_clientdata(client, chip); ++ ++ chip_desc = devm_kmemdup(&client->dev, &max77620_top_irq_chip, ++ sizeof(max77620_top_irq_chip), ++ GFP_KERNEL); ++ if (!chip_desc) ++ return -ENOMEM; ++ chip_desc->irq_drv_data = chip; ++ + chip->dev = &client->dev; + chip->chip_irq = client->irq; + chip->chip_id = (enum max77620_chip_id)id->driver_data; +@@ -543,11 +552,9 @@ static int max77620_probe(struct i2c_cli + if (ret < 0) + return ret; + +- max77620_top_irq_chip.irq_drv_data = chip; + ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq, + IRQF_ONESHOT | IRQF_SHARED, 0, +- &max77620_top_irq_chip, +- &chip->top_irq_data); ++ chip_desc, &chip->top_irq_data); + if (ret < 0) { + dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret); + return ret; diff --git a/queue-6.12/pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch b/queue-6.12/pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch new file mode 100644 index 0000000000..121849551b --- /dev/null +++ b/queue-6.12/pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch @@ -0,0 +1,88 @@ +From 894f475f88e06c0f352c829849560790dbdedbe5 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Wed, 19 Nov 2025 09:50:01 +0100 +Subject: PCI/PM: Reinstate clearing state_saved in legacy and !PM codepaths + +From: Lukas Wunner + +commit 894f475f88e06c0f352c829849560790dbdedbe5 upstream. + +When a PCI device is suspended, it is normally the PCI core's job to save +Config Space and put the device into a low power state. However drivers +are allowed to assume these responsibilities. When they do, the PCI core +can tell by looking at the state_saved flag in struct pci_dev: The flag +is cleared before commencing the suspend sequence and it is set when +pci_save_state() is called. If the PCI core finds the flag set late in +the suspend sequence, it refrains from calling pci_save_state() itself. + +But there are two corner cases where the PCI core neglects to clear the +flag before commencing the suspend sequence: + +* If a driver has legacy PCI PM callbacks, pci_legacy_suspend() neglects + to clear the flag. The (stale) flag is subsequently queried by + pci_legacy_suspend() itself and pci_legacy_suspend_late(). + +* If a device has no driver or its driver has no PCI PM callbacks, + pci_pm_freeze() neglects to clear the flag. The (stale) flag is + subsequently queried by pci_pm_freeze_noirq(). + +The flag may be set prior to suspend if the device went through error +recovery: Drivers commonly invoke pci_restore_state() + pci_save_state() +to restore Config Space after reset. + +The flag may also be set if drivers call pci_save_state() on probe to +allow for recovery from subsequent errors. + +The result is that pci_legacy_suspend_late() and pci_pm_freeze_noirq() +don't call pci_save_state() and so the state that will be restored on +resume is the one recorded on last error recovery or on probe, not the one +that the device had on suspend. If the two states happen to be identical, +there's no problem. + +Reinstate clearing the flag in pci_legacy_suspend() and pci_pm_freeze(). +The two functions used to do that until commit 4b77b0a2ba27 ("PCI: Clear +saved_state after the state has been restored") deemed it unnecessary +because it assumed that it's sufficient to clear the flag on resume in +pci_restore_state(). The commit seemingly did not take into account that +pci_save_state() and pci_restore_state() are not only used by power +management code, but also for error recovery. + +Devices without driver or whose driver has no PCI PM callbacks may be in +runtime suspend when pci_pm_freeze() is called. Their state has already +been saved, so don't clear the flag to skip a pointless pci_save_state() +in pci_pm_freeze_noirq(). + +None of the drivers with legacy PCI PM callbacks seem to use runtime PM, +so clear the flag unconditionally in their case. + +Fixes: 4b77b0a2ba27 ("PCI: Clear saved_state after the state has been restored") +Signed-off-by: Lukas Wunner +Signed-off-by: Bjorn Helgaas +Reviewed-by: Rafael J. Wysocki (Intel) +Cc: stable@vger.kernel.org # v2.6.32+ +Link: https://patch.msgid.link/094f2aad64418710daf0940112abe5a0afdc6bce.1763483367.git.lukas@wunner.de +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci-driver.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/pci/pci-driver.c ++++ b/drivers/pci/pci-driver.c +@@ -635,6 +635,8 @@ static int pci_legacy_suspend(struct dev + struct pci_dev *pci_dev = to_pci_dev(dev); + struct pci_driver *drv = pci_dev->driver; + ++ pci_dev->state_saved = false; ++ + if (drv && drv->suspend) { + pci_power_t prev = pci_dev->current_state; + int error; +@@ -1039,6 +1041,8 @@ static int pci_pm_freeze(struct device * + + if (!pm) { + pci_pm_default_suspend(pci_dev); ++ if (!pm_runtime_suspended(dev)) ++ pci_dev->state_saved = false; + return 0; + } + diff --git a/queue-6.12/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch b/queue-6.12/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch new file mode 100644 index 0000000000..edbb5c3aff --- /dev/null +++ b/queue-6.12/powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch @@ -0,0 +1,323 @@ +From 00312419f0863964625d6dcda8183f96849412c6 Mon Sep 17 00:00:00 2001 +From: Donet Tom +Date: Thu, 30 Oct 2025 20:27:26 +0530 +Subject: powerpc/64s/slb: Fix SLB multihit issue during SLB preload +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Donet Tom + +commit 00312419f0863964625d6dcda8183f96849412c6 upstream. + +On systems using the hash MMU, there is a software SLB preload cache that +mirrors the entries loaded into the hardware SLB buffer. This preload +cache is subject to periodic eviction — typically after every 256 context +switches — to remove old entry. + +To optimize performance, the kernel skips switch_mmu_context() in +switch_mm_irqs_off() when the prev and next mm_struct are the same. +However, on hash MMU systems, this can lead to inconsistencies between +the hardware SLB and the software preload cache. + +If an SLB entry for a process is evicted from the software cache on one +CPU, and the same process later runs on another CPU without executing +switch_mmu_context(), the hardware SLB may retain stale entries. If the +kernel then attempts to reload that entry, it can trigger an SLB +multi-hit error. + +The following timeline shows how stale SLB entries are created and can +cause a multi-hit error when a process moves between CPUs without a +MMU context switch. + +CPU 0 CPU 1 +----- ----- +Process P +exec swapper/1 + load_elf_binary + begin_new_exc + activate_mm + switch_mm_irqs_off + switch_mmu_context + switch_slb + /* + * This invalidates all + * the entries in the HW + * and setup the new HW + * SLB entries as per the + * preload cache. + */ +context_switch +sched_migrate_task migrates process P to cpu-1 + +Process swapper/0 context switch (to process P) +(uses mm_struct of Process P) switch_mm_irqs_off() + switch_slb + load_slb++ + /* + * load_slb becomes 0 here + * and we evict an entry from + * the preload cache with + * preload_age(). We still + * keep HW SLB and preload + * cache in sync, that is + * because all HW SLB entries + * anyways gets evicted in + * switch_slb during SLBIA. + * We then only add those + * entries back in HW SLB, + * which are currently + * present in preload_cache + * (after eviction). + */ + load_elf_binary continues... + setup_new_exec() + slb_setup_new_exec() + + sched_switch event + sched_migrate_task migrates + process P to cpu-0 + +context_switch from swapper/0 to Process P + switch_mm_irqs_off() + /* + * Since both prev and next mm struct are same we don't call + * switch_mmu_context(). This will cause the HW SLB and SW preload + * cache to go out of sync in preload_new_slb_context. Because there + * was an SLB entry which was evicted from both HW and preload cache + * on cpu-1. Now later in preload_new_slb_context(), when we will try + * to add the same preload entry again, we will add this to the SW + * preload cache and then will add it to the HW SLB. Since on cpu-0 + * this entry was never invalidated, hence adding this entry to the HW + * SLB will cause a SLB multi-hit error. + */ +load_elf_binary continues... + START_THREAD + start_thread + preload_new_slb_context + /* + * This tries to add a new EA to preload cache which was earlier + * evicted from both cpu-1 HW SLB and preload cache. This caused the + * HW SLB of cpu-0 to go out of sync with the SW preload cache. The + * reason for this was, that when we context switched back on CPU-0, + * we should have ideally called switch_mmu_context() which will + * bring the HW SLB entries on CPU-0 in sync with SW preload cache + * entries by setting up the mmu context properly. But we didn't do + * that since the prev mm_struct running on cpu-0 was same as the + * next mm_struct (which is true for swapper / kernel threads). So + * now when we try to add this new entry into the HW SLB of cpu-0, + * we hit a SLB multi-hit error. + */ + +WARNING: CPU: 0 PID: 1810970 at arch/powerpc/mm/book3s64/slb.c:62 +assert_slb_presence+0x2c/0x50(48 results) 02:47:29 [20157/42149] +Modules linked in: +CPU: 0 UID: 0 PID: 1810970 Comm: dd Not tainted 6.16.0-rc3-dirty #12 +VOLUNTARY +Hardware name: IBM pSeries (emulated by qemu) POWER8 (architected) +0x4d0200 0xf000004 of:SLOF,HEAD hv:linux,kvm pSeries +NIP: c00000000015426c LR: c0000000001543b4 CTR: 0000000000000000 +REGS: c0000000497c77e0 TRAP: 0700 Not tainted (6.16.0-rc3-dirty) +MSR: 8000000002823033 CR: 28888482 XER: 00000000 +CFAR: c0000000001543b0 IRQMASK: 3 +<...> +NIP [c00000000015426c] assert_slb_presence+0x2c/0x50 +LR [c0000000001543b4] slb_insert_entry+0x124/0x390 +Call Trace: + 0x7fffceb5ffff (unreliable) + preload_new_slb_context+0x100/0x1a0 + start_thread+0x26c/0x420 + load_elf_binary+0x1b04/0x1c40 + bprm_execve+0x358/0x680 + do_execveat_common+0x1f8/0x240 + sys_execve+0x58/0x70 + system_call_exception+0x114/0x300 + system_call_common+0x160/0x2c4 + +>From the above analysis, during early exec the hardware SLB is cleared, +and entries from the software preload cache are reloaded into hardware +by switch_slb. However, preload_new_slb_context and slb_setup_new_exec +also attempt to load some of the same entries, which can trigger a +multi-hit. In most cases, these additional preloads simply hit existing +entries and add nothing new. Removing these functions avoids redundant +preloads and eliminates the multi-hit issue. This patch removes these +two functions. + +We tested process switching performance using the context_switch +benchmark on POWER9/hash, and observed no regression. + +Without this patch: 129041 ops/sec +With this patch: 129341 ops/sec + +We also measured SLB faults during boot, and the counts are essentially +the same with and without this patch. + +SLB faults without this patch: 19727 +SLB faults with this patch: 19786 + +Fixes: 5434ae74629a ("powerpc/64s/hash: Add a SLB preload cache") +cc: stable@vger.kernel.org +Suggested-by: Nicholas Piggin +Signed-off-by: Donet Tom +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/0ac694ae683494fe8cadbd911a1a5018d5d3c541.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/book3s/64/mmu-hash.h | 1 + arch/powerpc/kernel/process.c | 5 - + arch/powerpc/mm/book3s64/internal.h | 2 + arch/powerpc/mm/book3s64/mmu_context.c | 2 + arch/powerpc/mm/book3s64/slb.c | 88 -------------------------- + 5 files changed, 98 deletions(-) + +--- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h ++++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h +@@ -524,7 +524,6 @@ void slb_save_contents(struct slb_entry + void slb_dump_contents(struct slb_entry *slb_ptr); + + extern void slb_vmalloc_update(void); +-void preload_new_slb_context(unsigned long start, unsigned long sp); + + #ifdef CONFIG_PPC_64S_HASH_MMU + void slb_set_size(u16 size); +--- a/arch/powerpc/kernel/process.c ++++ b/arch/powerpc/kernel/process.c +@@ -1897,8 +1897,6 @@ int copy_thread(struct task_struct *p, c + return 0; + } + +-void preload_new_slb_context(unsigned long start, unsigned long sp); +- + /* + * Set up a thread for executing a new program + */ +@@ -1906,9 +1904,6 @@ void start_thread(struct pt_regs *regs, + { + #ifdef CONFIG_PPC64 + unsigned long load_addr = regs->gpr[2]; /* saved by ELF_PLAT_INIT */ +- +- if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !radix_enabled()) +- preload_new_slb_context(start, sp); + #endif + + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM +--- a/arch/powerpc/mm/book3s64/internal.h ++++ b/arch/powerpc/mm/book3s64/internal.h +@@ -24,8 +24,6 @@ static inline bool stress_hpt(void) + + void hpt_do_stress(unsigned long ea, unsigned long hpte_group); + +-void slb_setup_new_exec(void); +- + void exit_lazy_flush_tlb(struct mm_struct *mm, bool always_flush); + + #endif /* ARCH_POWERPC_MM_BOOK3S64_INTERNAL_H */ +--- a/arch/powerpc/mm/book3s64/mmu_context.c ++++ b/arch/powerpc/mm/book3s64/mmu_context.c +@@ -150,8 +150,6 @@ static int hash__init_new_context(struct + void hash__setup_new_exec(void) + { + slice_setup_new_exec(); +- +- slb_setup_new_exec(); + } + #else + static inline int hash__init_new_context(struct mm_struct *mm) +--- a/arch/powerpc/mm/book3s64/slb.c ++++ b/arch/powerpc/mm/book3s64/slb.c +@@ -328,94 +328,6 @@ static void preload_age(struct thread_in + ti->slb_preload_tail = (ti->slb_preload_tail + 1) % SLB_PRELOAD_NR; + } + +-void slb_setup_new_exec(void) +-{ +- struct thread_info *ti = current_thread_info(); +- struct mm_struct *mm = current->mm; +- unsigned long exec = 0x10000000; +- +- WARN_ON(irqs_disabled()); +- +- /* +- * preload cache can only be used to determine whether a SLB +- * entry exists if it does not start to overflow. +- */ +- if (ti->slb_preload_nr + 2 > SLB_PRELOAD_NR) +- return; +- +- hard_irq_disable(); +- +- /* +- * We have no good place to clear the slb preload cache on exec, +- * flush_thread is about the earliest arch hook but that happens +- * after we switch to the mm and have already preloaded the SLBEs. +- * +- * For the most part that's probably okay to use entries from the +- * previous exec, they will age out if unused. It may turn out to +- * be an advantage to clear the cache before switching to it, +- * however. +- */ +- +- /* +- * preload some userspace segments into the SLB. +- * Almost all 32 and 64bit PowerPC executables are linked at +- * 0x10000000 so it makes sense to preload this segment. +- */ +- if (!is_kernel_addr(exec)) { +- if (preload_add(ti, exec)) +- slb_allocate_user(mm, exec); +- } +- +- /* Libraries and mmaps. */ +- if (!is_kernel_addr(mm->mmap_base)) { +- if (preload_add(ti, mm->mmap_base)) +- slb_allocate_user(mm, mm->mmap_base); +- } +- +- /* see switch_slb */ +- asm volatile("isync" : : : "memory"); +- +- local_irq_enable(); +-} +- +-void preload_new_slb_context(unsigned long start, unsigned long sp) +-{ +- struct thread_info *ti = current_thread_info(); +- struct mm_struct *mm = current->mm; +- unsigned long heap = mm->start_brk; +- +- WARN_ON(irqs_disabled()); +- +- /* see above */ +- if (ti->slb_preload_nr + 3 > SLB_PRELOAD_NR) +- return; +- +- hard_irq_disable(); +- +- /* Userspace entry address. */ +- if (!is_kernel_addr(start)) { +- if (preload_add(ti, start)) +- slb_allocate_user(mm, start); +- } +- +- /* Top of stack, grows down. */ +- if (!is_kernel_addr(sp)) { +- if (preload_add(ti, sp)) +- slb_allocate_user(mm, sp); +- } +- +- /* Bottom of heap, grows up. */ +- if (heap && !is_kernel_addr(heap)) { +- if (preload_add(ti, heap)) +- slb_allocate_user(mm, heap); +- } +- +- /* see switch_slb */ +- asm volatile("isync" : : : "memory"); +- +- local_irq_enable(); +-} +- + static void slb_cache_slbie_kernel(unsigned int index) + { + unsigned long slbie_data = get_paca()->slb_cache[index]; diff --git a/queue-6.12/powerpc-mm-fix-mprotect-on-book3s-32-bit.patch b/queue-6.12/powerpc-mm-fix-mprotect-on-book3s-32-bit.patch new file mode 100644 index 0000000000..e5473d190f --- /dev/null +++ b/queue-6.12/powerpc-mm-fix-mprotect-on-book3s-32-bit.patch @@ -0,0 +1,75 @@ +From 78fc63ffa7813e33681839bb33826c24195f0eb7 Mon Sep 17 00:00:00 2001 +From: Dave Vasilevsky +Date: Sun, 16 Nov 2025 01:40:46 -0500 +Subject: powerpc, mm: Fix mprotect on book3s 32-bit + +From: Dave Vasilevsky + +commit 78fc63ffa7813e33681839bb33826c24195f0eb7 upstream. + +On 32-bit book3s with hash-MMUs, tlb_flush() was a no-op. This was +unnoticed because all uses until recently were for unmaps, and thus +handled by __tlb_remove_tlb_entry(). + +After commit 4a18419f71cd ("mm/mprotect: use mmu_gather") in kernel 5.19, +tlb_gather_mmu() started being used for mprotect as well. This caused +mprotect to simply not work on these machines: + + int *ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + *ptr = 1; // force HPTE to be created + mprotect(ptr, 4096, PROT_READ); + *ptr = 2; // should segfault, but succeeds + +Fixed by making tlb_flush() actually flush TLB pages. This finally +agrees with the behaviour of boot3s64's tlb_flush(). + +Fixes: 4a18419f71cd ("mm/mprotect: use mmu_gather") +Cc: stable@vger.kernel.org +Reviewed-by: Christophe Leroy +Reviewed-by: Ritesh Harjani (IBM) +Signed-off-by: Dave Vasilevsky +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20251116-vasi-mprotect-g3-v3-1-59a9bd33ba00@vasilevsky.ca +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/book3s/32/tlbflush.h | 5 ++++- + arch/powerpc/mm/book3s32/tlb.c | 9 +++++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/include/asm/book3s/32/tlbflush.h ++++ b/arch/powerpc/include/asm/book3s/32/tlbflush.h +@@ -11,6 +11,7 @@ + void hash__flush_tlb_mm(struct mm_struct *mm); + void hash__flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); + void hash__flush_range(struct mm_struct *mm, unsigned long start, unsigned long end); ++void hash__flush_gather(struct mmu_gather *tlb); + + #ifdef CONFIG_SMP + void _tlbie(unsigned long address); +@@ -29,7 +30,9 @@ void _tlbia(void); + static inline void tlb_flush(struct mmu_gather *tlb) + { + /* 603 needs to flush the whole TLB here since it doesn't use a hash table. */ +- if (!mmu_has_feature(MMU_FTR_HPTE_TABLE)) ++ if (mmu_has_feature(MMU_FTR_HPTE_TABLE)) ++ hash__flush_gather(tlb); ++ else + _tlbia(); + } + +--- a/arch/powerpc/mm/book3s32/tlb.c ++++ b/arch/powerpc/mm/book3s32/tlb.c +@@ -105,3 +105,12 @@ void hash__flush_tlb_page(struct vm_area + flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1); + } + EXPORT_SYMBOL(hash__flush_tlb_page); ++ ++void hash__flush_gather(struct mmu_gather *tlb) ++{ ++ if (tlb->fullmm || tlb->need_flush_all) ++ hash__flush_tlb_mm(tlb->mm); ++ else ++ hash__flush_range(tlb->mm, tlb->start, tlb->end); ++} ++EXPORT_SYMBOL(hash__flush_gather); diff --git a/queue-6.12/series b/queue-6.12/series index 426bb2f0fe..d0dd2d1358 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -365,3 +365,19 @@ iommu-sun50i-fix-device-leak-on-of_xlate.patch iommu-tegra-fix-device-leak-on-probe_device.patch iommu-disable-sva-when-config_x86-is-set.patch hid-logitech-dj-remove-duplicate-error-logging.patch +fgraph-initialize-ftrace_ops-private-for-function-graph-ops.patch +fgraph-check-ftrace_pids_enabled-on-registration-for-early-filtering.patch +pci-pm-reinstate-clearing-state_saved-in-legacy-and-pm-codepaths.patch +arm64-dts-ti-k3-j721e-sk-fix-pinmux-for-pin-y1-used-by-power-regulator.patch +powerpc-mm-fix-mprotect-on-book3s-32-bit.patch +powerpc-64s-slb-fix-slb-multihit-issue-during-slb-preload.patch +leds-leds-cros_ec-skip-leds-without-color-components.patch +leds-leds-lp50xx-allow-led-0-to-be-added-to-module-bank.patch +leds-leds-lp50xx-lp5009-supports-3-modules-for-a-total-of-9-leds.patch +leds-leds-lp50xx-enable-chip-before-any-communication.patch +block-clear-blk_zone_wplug_plugged-when-aborting-plugged-bios.patch +clk-samsung-exynos-clkout-assign-.num-before-accessing-.hws.patch +mfd-altera-sysmgr-fix-device-leak-on-sysmgr-regmap-lookup.patch +mfd-max77620-fix-potential-irq-chip-conflict-when-probing-two-devices.patch +media-rc-st_rc-fix-reset-control-resource-leak.patch +media-verisilicon-fix-cpu-stalls-on-g2-bus-error.patch