--- /dev/null
+From d4735576c05db246da76b009066b2473fed6a64d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Oct 2024 07:22:46 +0000
+Subject: cgroup: Fix potential overflow issue when checking max_depth
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiu Jianfeng <xiujianfeng@huawei.com>
+
+[ Upstream commit 3cc4e13bb1617f6a13e5e6882465984148743cf4 ]
+
+cgroup.max.depth is the maximum allowed descent depth below the current
+cgroup. If the actual descent depth is equal or larger, an attempt to
+create a new child cgroup will fail. However due to the cgroup->max_depth
+is of int type and having the default value INT_MAX, the condition
+'level > cgroup->max_depth' will never be satisfied, and it will cause
+an overflow of the level after it reaches to INT_MAX.
+
+Fix it by starting the level from 0 and using '>=' instead.
+
+It's worth mentioning that this issue is unlikely to occur in reality,
+as it's impossible to have a depth of INT_MAX hierarchy, but should be
+be avoided logically.
+
+Fixes: 1a926e0bbab8 ("cgroup: implement hierarchy limits")
+Signed-off-by: Xiu Jianfeng <xiujianfeng@huawei.com>
+Reviewed-by: Michal Koutný <mkoutny@suse.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/cgroup.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index 660817c125e73..b927f0623ac77 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -5697,7 +5697,7 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent)
+ {
+ struct cgroup *cgroup;
+ int ret = false;
+- int level = 1;
++ int level = 0;
+
+ lockdep_assert_held(&cgroup_mutex);
+
+@@ -5705,7 +5705,7 @@ static bool cgroup_check_hierarchy_limits(struct cgroup *parent)
+ if (cgroup->nr_descendants >= cgroup->max_descendants)
+ goto fail;
+
+- if (level > cgroup->max_depth)
++ if (level >= cgroup->max_depth)
+ goto fail;
+
+ level++;
+--
+2.43.0
+
--- /dev/null
+From b9e0446c858ccc3a2230a09caa6eb9f9679732a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Oct 2024 12:37:06 -0700
+Subject: Input: xpad - add support for 8BitDo Ultimate 2C Wireless Controller
+
+From: Stefan Kerkmann <s.kerkmann@pengutronix.de>
+
+[ Upstream commit ea330429a04b383bd319c66261a5eca4798801e4 ]
+
+This XBOX360 compatible gamepad uses the new product id 0x310a under the
+8BitDo's vendor id 0x2dc8. The change was tested using the gamepad in a
+wired and wireless dongle configuration.
+
+Signed-off-by: Stefan Kerkmann <s.kerkmann@pengutronix.de>
+Link: https://lore.kernel.org/r/20241015-8bitdo_2c_ultimate_wireless-v1-1-9c9f9db2e995@pengutronix.de
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/joystick/xpad.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index ebe243b79d819..0cfcad8348a6d 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -373,6 +373,7 @@ static const struct xpad_device {
+ { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE },
+ { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
+ { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
++ { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 },
+ { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
+ { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
+ { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
+--
+2.43.0
+
--- /dev/null
+From 4bc4ff508ec519a3eacb6845938eee9e4a17fbf2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 8 Feb 2024 11:13:17 -0800
+Subject: Input: xpad - sort xpad_device by vendor and product ID
+
+From: Brenton Simpson <appsforartists@google.com>
+
+[ Upstream commit 18970d4f6317a3595cc592c3c7815f63d1818932 ]
+
+This helps making sure there are no duplicate entries in the tables.
+
+Signed-off-by: Brenton Simpson <appsforartists@google.com>
+Link: https://lore.kernel.org/r/20240130231903.293265-1-appsforartists@google.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Stable-dep-of: ea330429a04b ("Input: xpad - add support for 8BitDo Ultimate 2C Wireless Controller")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/input/joystick/xpad.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index 1cb47488375be..ebe243b79d819 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -127,6 +127,7 @@ static const struct xpad_device {
+ u8 mapping;
+ u8 xtype;
+ } xpad_device[] = {
++ /* Please keep this list sorted by vendor and product ID. */
+ { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
+ { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 },
+ { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 },
+@@ -152,9 +153,9 @@ static const struct xpad_device {
+ { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE },
+- { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE },
+ { 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
+ { 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
++ { 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE },
+ { 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", MAP_PROFILE_BUTTON, XTYPE_XBOXONE },
+ { 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE },
+ { 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 },
+@@ -343,7 +344,6 @@ static const struct xpad_device {
+ { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
+ { 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
+ { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
+- { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
+@@ -358,9 +358,9 @@ static const struct xpad_device {
+ { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
+- { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
++ { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+ { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x561a, "PowerA FUSION Controller", 0, XTYPE_XBOXONE },
+ { 0x24c6, 0x5b00, "ThrustMaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
+@@ -373,6 +373,7 @@ static const struct xpad_device {
+ { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE },
+ { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
+ { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
++ { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
+ { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
+ { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
+ { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
+@@ -470,6 +471,10 @@ static const signed short xpad_btn_paddles[] = {
+ { XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) }
+
+ static const struct usb_device_id xpad_table[] = {
++ /*
++ * Please keep this list sorted by vendor ID. Note that there are 2
++ * macros - XPAD_XBOX360_VENDOR and XPAD_XBOXONE_VENDOR.
++ */
+ { USB_INTERFACE_INFO('X', 'B', 0) }, /* Xbox USB-IF not-approved class */
+ XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 controller */
+ XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */
+--
+2.43.0
+
--- /dev/null
+thermal-core-make-thermal_zone_device_unregister-ret.patch
+thermal-core-rework-thermal-zone-availability-check.patch
+thermal-core-free-tzp-copy-along-with-the-thermal-zo.patch
+input-xpad-sort-xpad_device-by-vendor-and-product-id.patch
+input-xpad-add-support-for-8bitdo-ultimate-2c-wirele.patch
+cgroup-fix-potential-overflow-issue-when-checking-ma.patch
+spi-geni-qcom-fix-boot-warning-related-to-pm_runtime.patch
--- /dev/null
+From f46f45078afc5b60ea6090dfc4d25c0cfe4713ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Oct 2024 02:16:15 +0300
+Subject: spi: geni-qcom: Fix boot warning related to pm_runtime and devres
+
+From: Georgi Djakov <djakov@kernel.org>
+
+[ Upstream commit d0ccf760a405d243a49485be0a43bd5b66ed17e2 ]
+
+During boot, users sometimes observe the following warning:
+
+[7.841431] WARNING: CPU: 4 PID: 492 at
+drivers/interconnect/core.c:685 __icc_enable
+(drivers/interconnect/core.c:685 (discriminator 7))
+[..]
+[7.841541] Call trace:
+[7.841542] __icc_enable (drivers/interconnect/core.c:685 (discriminator 7))
+[7.841545] icc_disable (drivers/interconnect/core.c:708)
+[7.841547] geni_icc_disable (drivers/soc/qcom/qcom-geni-se.c:862)
+[7.841553] spi_geni_runtime_suspend+0x3c/0x4c spi_geni_qcom
+
+This occurs when the spi-geni driver receives an -EPROBE_DEFER error
+from spi_geni_grab_gpi_chan(), causing devres to start releasing all
+resources as shown below:
+
+[7.138679] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_icc_release (8 bytes)
+[7.138751] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_icc_release (8 bytes)
+[7.138827] geni_spi 880000.spi: DEVRES REL ffff800081443800 pm_runtime_disable_action (16 bytes)
+[7.139494] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_pm_opp_config_release (16 bytes)
+[7.139512] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_spi_release_controller (8 bytes)
+[7.139516] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_clk_release (16 bytes)
+[7.139519] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_ioremap_release (8 bytes)
+[7.139524] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_region_release (24 bytes)
+[7.139527] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_kzalloc_release (22 bytes)
+[7.139530] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_pinctrl_release (8 bytes)
+[7.139539] geni_spi 880000.spi: DEVRES REL ffff800081443800 devm_kzalloc_release (40 bytes)
+
+The issue here is that pm_runtime_disable_action() results in a call to
+spi_geni_runtime_suspend(), which attempts to suspend the device and
+disable an interconnect path that devm_icc_release() has just released.
+
+Resolve this by calling geni_icc_get() before enabling runtime PM. This
+approach ensures that when devres releases resources in reverse order,
+it will start with pm_runtime_disable_action(), suspending the device,
+and then proceed to free the remaining resources.
+
+Reported-by: Naresh Kamboju <naresh.kamboju@linaro.org>
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Closes: https://lore.kernel.org/r/CA+G9fYtsjFtddG8i+k-SpV8U6okL0p4zpsTiwGfNH5GUA8dWAA@mail.gmail.com
+Fixes: 89e362c883c6 ("spi: geni-qcom: Undo runtime PM changes at driver exit time")
+Signed-off-by: Georgi Djakov <djakov@kernel.org>
+Link: https://patch.msgid.link/20241008231615.430073-1-djakov@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-geni-qcom.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
+index 7401ed3b9acd4..6a3b41dbfa701 100644
+--- a/drivers/spi/spi-geni-qcom.c
++++ b/drivers/spi/spi-geni-qcom.c
+@@ -1108,6 +1108,11 @@ static int spi_geni_probe(struct platform_device *pdev)
+ init_completion(&mas->tx_reset_done);
+ init_completion(&mas->rx_reset_done);
+ spin_lock_init(&mas->lock);
++
++ ret = geni_icc_get(&mas->se, NULL);
++ if (ret)
++ return ret;
++
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 250);
+ ret = devm_pm_runtime_enable(dev);
+@@ -1117,9 +1122,6 @@ static int spi_geni_probe(struct platform_device *pdev)
+ if (device_property_read_bool(&pdev->dev, "spi-slave"))
+ spi->slave = true;
+
+- ret = geni_icc_get(&mas->se, NULL);
+- if (ret)
+- return ret;
+ /* Set the bus quota to a reasonable value for register access */
+ mas->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(CORE_2X_50_MHZ);
+ mas->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW;
+--
+2.43.0
+
--- /dev/null
+From 8e9ca18dc4ca285c1afba8e9bce91504a56f252e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 14:27:28 +0200
+Subject: thermal: core: Free tzp copy along with the thermal zone
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 827a07525c099f54d3b15110408824541ec66b3c ]
+
+The object pointed to by tz->tzp may still be accessed after being
+freed in thermal_zone_device_unregister(), so move the freeing of it
+to the point after the removal completion has been completed at which
+it cannot be accessed any more.
+
+Fixes: 3d439b1a2ad3 ("thermal/core: Alloc-copy-free the thermal zone parameters structure")
+Cc: 6.8+ <stable@vger.kernel.org> # 6.8+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://patch.msgid.link/4623516.LvFx2qVVIh@rjwysocki.net
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 69b89a71f44eb..d7ac7eef680e1 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -1484,14 +1484,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
+ ida_destroy(&tz->ida);
+
+ device_del(&tz->device);
+-
+- kfree(tz->tzp);
+-
+ put_device(&tz->device);
+
+ thermal_notify_tz_delete(tz_id);
+
+ wait_for_completion(&tz->removal);
++ kfree(tz->tzp);
+ kfree(tz);
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
+--
+2.43.0
+
--- /dev/null
+From 230be0d45ef53a4be99d4594c2b9b81e103dbcca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Dec 2023 20:13:44 +0100
+Subject: thermal: core: Make thermal_zone_device_unregister() return after
+ freeing the zone
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit 4649620d9404d3aceb25891c24bab77143e3f21c ]
+
+Make thermal_zone_device_unregister() wait until all of the references
+to the given thermal zone object have been dropped and free it before
+returning.
+
+This guarantees that when thermal_zone_device_unregister() returns,
+there is no leftover activity regarding the thermal zone in question
+which is required by some of its callers (for instance, modular driver
+code that wants to know when it is safe to let the module go away).
+
+Subsequently, this will allow some confusing device_is_registered()
+checks to be dropped from the thermal sysfs and core code.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-and-tested-by: Lukasz Luba <lukasz.luba@arm.com>
+Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Stable-dep-of: 827a07525c09 ("thermal: core: Free tzp copy along with the thermal zone")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 6 +++++-
+ include/linux/thermal.h | 2 ++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index dee3022539cf7..5a9068e8f050d 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -800,7 +800,7 @@ static void thermal_release(struct device *dev)
+ tz = to_thermal_zone(dev);
+ thermal_zone_destroy_device_groups(tz);
+ mutex_destroy(&tz->lock);
+- kfree(tz);
++ complete(&tz->removal);
+ } else if (!strncmp(dev_name(dev), "cooling_device",
+ sizeof("cooling_device") - 1)) {
+ cdev = to_cooling_device(dev);
+@@ -1294,6 +1294,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ INIT_LIST_HEAD(&tz->thermal_instances);
+ ida_init(&tz->ida);
+ mutex_init(&tz->lock);
++ init_completion(&tz->removal);
+ id = ida_alloc(&thermal_tz_ida, GFP_KERNEL);
+ if (id < 0) {
+ result = id;
+@@ -1480,6 +1481,9 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
+ put_device(&tz->device);
+
+ thermal_notify_tz_delete(tz_id);
++
++ wait_for_completion(&tz->removal);
++ kfree(tz);
+ }
+ EXPORT_SYMBOL_GPL(thermal_zone_device_unregister);
+
+diff --git a/include/linux/thermal.h b/include/linux/thermal.h
+index 4012f440bfdcc..2e9d18ba46531 100644
+--- a/include/linux/thermal.h
++++ b/include/linux/thermal.h
+@@ -115,6 +115,7 @@ struct thermal_cooling_device {
+ * @id: unique id number for each thermal zone
+ * @type: the thermal zone device type
+ * @device: &struct device for this thermal zone
++ * @removal: removal completion
+ * @trip_temp_attrs: attributes for trip points for sysfs: trip temperature
+ * @trip_type_attrs: attributes for trip points for sysfs: trip type
+ * @trip_hyst_attrs: attributes for trip points for sysfs: trip hysteresis
+@@ -156,6 +157,7 @@ struct thermal_zone_device {
+ int id;
+ char type[THERMAL_NAME_LENGTH];
+ struct device device;
++ struct completion removal;
+ struct attribute_group trips_attribute_group;
+ struct thermal_attr *trip_temp_attrs;
+ struct thermal_attr *trip_type_attrs;
+--
+2.43.0
+
--- /dev/null
+From 05caa50b4d3148008633699147da42f5450dd531 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Dec 2023 20:20:00 +0100
+Subject: thermal: core: Rework thermal zone availability check
+
+From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+
+[ Upstream commit b38aa87f67931e23ebc32c0ca00a86dfa4688719 ]
+
+In order to avoid running __thermal_zone_device_update() for thermal
+zones going away, the thermal zone lock is held around device_del()
+in thermal_zone_device_unregister() and thermal_zone_device_update()
+passes the given thermal zone device to device_is_registered().
+This allows thermal_zone_device_update() to skip the
+__thermal_zone_device_update() if device_del() has already run for
+the thermal zone at hand.
+
+However, instead of looking at driver core internals, the thermal
+subsystem may as well rely on its own data structures for this
+purpose. Namely, if the thermal zone is not present in
+thermal_tz_list, it can be regarded as unavailable, which in fact is
+already the case in thermal_zone_device_unregister(). Accordingly,
+the device_is_registered() check in thermal_zone_device_update() can
+be replaced with checking whether or not the node list_head in struct
+thermal_zone_device is empty, in which case it is not there in
+thermal_tz_list.
+
+To make this work, though, it is necessary to initialize tz->node
+in thermal_zone_device_register_with_trips() before registering the
+thermal zone device and it needs to be added to thermal_tz_list and
+deleted from it under its zone lock.
+
+After the above modifications, the zone lock does not need to be
+held around device_del() in thermal_zone_device_unregister() any more.
+
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Reviewed-and-tested-by: Lukasz Luba <lukasz.luba@arm.com>
+Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Stable-dep-of: 827a07525c09 ("thermal: core: Free tzp copy along with the thermal zone")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/thermal/thermal_core.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c
+index 5a9068e8f050d..69b89a71f44eb 100644
+--- a/drivers/thermal/thermal_core.c
++++ b/drivers/thermal/thermal_core.c
+@@ -487,11 +487,16 @@ int thermal_zone_device_is_enabled(struct thermal_zone_device *tz)
+ return tz->mode == THERMAL_DEVICE_ENABLED;
+ }
+
++static bool thermal_zone_is_present(struct thermal_zone_device *tz)
++{
++ return !list_empty(&tz->node);
++}
++
+ void thermal_zone_device_update(struct thermal_zone_device *tz,
+ enum thermal_notify_event event)
+ {
+ mutex_lock(&tz->lock);
+- if (device_is_registered(&tz->device))
++ if (thermal_zone_is_present(tz))
+ __thermal_zone_device_update(tz, event);
+ mutex_unlock(&tz->lock);
+ }
+@@ -1292,6 +1297,7 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ }
+
+ INIT_LIST_HEAD(&tz->thermal_instances);
++ INIT_LIST_HEAD(&tz->node);
+ ida_init(&tz->ida);
+ mutex_init(&tz->lock);
+ init_completion(&tz->removal);
+@@ -1365,7 +1371,9 @@ thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *t
+ }
+
+ mutex_lock(&thermal_list_lock);
++ mutex_lock(&tz->lock);
+ list_add_tail(&tz->node, &thermal_tz_list);
++ mutex_unlock(&tz->lock);
+ mutex_unlock(&thermal_list_lock);
+
+ /* Bind cooling devices for this zone */
+@@ -1455,7 +1463,10 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
+ mutex_unlock(&thermal_list_lock);
+ return;
+ }
++
++ mutex_lock(&tz->lock);
+ list_del(&tz->node);
++ mutex_unlock(&tz->lock);
+
+ /* Unbind all cdevs associated with 'this' thermal zone */
+ list_for_each_entry(cdev, &thermal_cdev_list, node)
+@@ -1472,9 +1483,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
+ ida_free(&thermal_tz_ida, tz->id);
+ ida_destroy(&tz->ida);
+
+- mutex_lock(&tz->lock);
+ device_del(&tz->device);
+- mutex_unlock(&tz->lock);
+
+ kfree(tz->tzp);
+
+--
+2.43.0
+