--- /dev/null
+From ca39500f6af9cfe6823dc5aa8fbaed788d6e35b2 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 5 May 2025 15:49:59 -0700
+Subject: Input: synaptics-rmi - fix crash with unsupported versions of F34
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit ca39500f6af9cfe6823dc5aa8fbaed788d6e35b2 upstream.
+
+Sysfs interface for updating firmware for RMI devices is available even
+when F34 probe fails. The code checks for presence of F34 "container"
+pointer and then tries to use the function data attached to the
+sub-device. F34 assigns the function data early, before it knows if
+probe will succeed, leaving behind a stale pointer.
+
+Fix this by expanding checks to not only test for presence of F34
+"container" but also check if there is driver data assigned to the
+sub-device, and call dev_set_drvdata() only after we are certain that
+probe is successful.
+
+This is not a complete fix, since F34 will be freed during firmware
+update, so there is still a race when fetching and accessing this
+pointer. This race will be addressed in follow-up changes.
+
+Reported-by: Hanno Böck <hanno@hboeck.de>
+Fixes: 29fd0ec2bdbe ("Input: synaptics-rmi4 - add support for F34 device reflash")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/aBlAl6sGulam-Qcx@google.com
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/rmi4/rmi_f34.c | 133 ++++++++++++++++++++++++-------------------
+ 1 file changed, 75 insertions(+), 58 deletions(-)
+
+--- a/drivers/input/rmi4/rmi_f34.c
++++ b/drivers/input/rmi4/rmi_f34.c
+@@ -4,6 +4,7 @@
+ * Copyright (C) 2016 Zodiac Inflight Innovations
+ */
+
++#include "linux/device.h"
+ #include <linux/kernel.h>
+ #include <linux/rmi.h>
+ #include <linux/firmware.h>
+@@ -298,39 +299,30 @@ out:
+ 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);
++ fn = data->f34_container;
++ if (!fn)
++ 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]);
+- }
++ f34 = dev_get_drvdata(&fn->dev);
++ if (!f34)
++ return -ENODEV;
+
+- return 0;
++ 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_
+ 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 rm
+
+ 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_stat
+ 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_
+ .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_func
+ 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,11 +577,33 @@ static int rmi_f34_probe(struct rmi_func
+ 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)
+ {
--- /dev/null
+From f0d17942ea3edec191f1c0fc0d2cd7feca8de2f0 Mon Sep 17 00:00:00 2001
+From: Vicki Pfau <vi@endrift.com>
+Date: Tue, 13 May 2025 15:59:48 -0700
+Subject: Input: xpad - add more controllers
+
+From: Vicki Pfau <vi@endrift.com>
+
+commit f0d17942ea3edec191f1c0fc0d2cd7feca8de2f0 upstream.
+
+Adds support for a revision of the Turtle Beach Recon Wired Controller,
+the Turtle Beach Stealth Ultra, and the PowerA Wired Controller.
+
+Signed-off-by: Vicki Pfau <vi@endrift.com>
+Link: https://lore.kernel.org/r/20250513225950.2719387-1-vi@endrift.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/input/joystick/xpad.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -289,6 +289,8 @@ static const struct xpad_device {
+ { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
+ { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
+ { 0x10f5, 0x7005, "Turtle Beach Recon Controller", 0, XTYPE_XBOXONE },
++ { 0x10f5, 0x7008, "Turtle Beach Recon Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
++ { 0x10f5, 0x7073, "Turtle Beach Stealth Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
+ { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
+ { 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 },
+ { 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 },
+@@ -353,6 +355,7 @@ static const struct xpad_device {
+ { 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
+ { 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, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
+ { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
+ { 0x2345, 0xe00b, "Machenike G5 Pro Controller", 0, XTYPE_XBOX360 },
+ { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },