]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Aug 2025 07:32:52 +0000 (09:32 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Aug 2025 07:32:52 +0000 (09:32 +0200)
added patches:
iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch
iio-imu-inv_icm42600-convert-to-uxx-and-sxx-integer-types.patch
iio-imu-inv_icm42600-switch-timestamp-type-from-int64_t-__aligned-8-to-aligned_s64.patch
iio-imu-inv_icm42600-use-instead-of-memset.patch
iio-light-as73211-ensure-buffer-holes-are-zeroed.patch
iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch
tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch
tracing-remove-unneeded-goto-out-logic.patch
usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch
usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch
usb-xhci-fix-slot_id-resource-race-conflict.patch

12 files changed:
queue-6.6/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch [new file with mode: 0644]
queue-6.6/iio-imu-inv_icm42600-convert-to-uxx-and-sxx-integer-types.patch [new file with mode: 0644]
queue-6.6/iio-imu-inv_icm42600-switch-timestamp-type-from-int64_t-__aligned-8-to-aligned_s64.patch [new file with mode: 0644]
queue-6.6/iio-imu-inv_icm42600-use-instead-of-memset.patch [new file with mode: 0644]
queue-6.6/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch [new file with mode: 0644]
queue-6.6/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch [new file with mode: 0644]
queue-6.6/tracing-remove-unneeded-goto-out-logic.patch [new file with mode: 0644]
queue-6.6/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch [new file with mode: 0644]
queue-6.6/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch [new file with mode: 0644]
queue-6.6/usb-xhci-fix-slot_id-resource-race-conflict.patch [new file with mode: 0644]

diff --git a/queue-6.6/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch b/queue-6.6/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch
new file mode 100644 (file)
index 0000000..659a20a
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-172743-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:40 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:53:27 -0400
+Subject: iio: imu: inv_icm42600: change invalid data error to -EBUSY
+To: stable@vger.kernel.org
+Cc: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andy@kernel.org>, Sean Nyekjaer <sean@geanix.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824135327.2919985-4-sashal@kernel.org>
+
+From: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+
+[ Upstream commit dfdc31e7ccf3ac1d5ec01d5120c71e14745e3dd8 ]
+
+Temperature sensor returns the temperature of the mechanical parts
+of the chip. If both accel and gyro are off, the temperature sensor is
+also automatically turned off and returns invalid data.
+
+In this case, returning -EBUSY error code is better then -EINVAL and
+indicates userspace that it needs to retry reading temperature in
+another context.
+
+Fixes: bc3eb0207fb5 ("iio: imu: inv_icm42600: add temperature sensor support")
+Signed-off-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Reviewed-by: Sean Nyekjaer <sean@geanix.com>
+Link: https://patch.msgid.link/20250808-inv-icm42600-change-temperature-error-code-v1-1-986fbf63b77d@tdk.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
+@@ -32,8 +32,12 @@ static int inv_icm42600_temp_read(struct
+               goto exit;
+       *temp = (s16)be16_to_cpup(raw);
++      /*
++       * Temperature data is invalid if both accel and gyro are off.
++       * Return -EBUSY in this case.
++       */
+       if (*temp == INV_ICM42600_DATA_INVALID)
+-              ret = -EINVAL;
++              ret = -EBUSY;
+ exit:
+       mutex_unlock(&st->lock);
diff --git a/queue-6.6/iio-imu-inv_icm42600-convert-to-uxx-and-sxx-integer-types.patch b/queue-6.6/iio-imu-inv_icm42600-convert-to-uxx-and-sxx-integer-types.patch
new file mode 100644 (file)
index 0000000..9871139
--- /dev/null
@@ -0,0 +1,423 @@
+From stable+bounces-172742-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:39 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:53:26 -0400
+Subject: iio: imu: inv_icm42600: Convert to uXX and sXX integer types
+To: stable@vger.kernel.org
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824135327.2919985-3-sashal@kernel.org>
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit a4135386fa49c2a170b89296da12c4a3be2089d9 ]
+
+The driver code is full of intXX_t and uintXX_t types which is
+not the pattern we use in the IIO subsystem. Switch the driver
+to use kernel internal types for that. No functional changes.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Link: https://patch.msgid.link/20250616090423.575736-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600.h        |    8 ++--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c  |   26 +++++++--------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |   22 ++++++------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |   10 ++---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_core.c   |    6 +--
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c   |   36 ++++++++++-----------
+ drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c   |    6 +--
+ 7 files changed, 57 insertions(+), 57 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h
+@@ -142,11 +142,11 @@ struct inv_icm42600_state {
+       struct inv_icm42600_suspended suspended;
+       struct iio_dev *indio_gyro;
+       struct iio_dev *indio_accel;
+-      uint8_t buffer[2] __aligned(IIO_DMA_MINALIGN);
++      u8 buffer[2] __aligned(IIO_DMA_MINALIGN);
+       struct inv_icm42600_fifo fifo;
+       struct {
+-              int64_t gyro;
+-              int64_t accel;
++              s64 gyro;
++              s64 accel;
+       } timestamp;
+ };
+@@ -369,7 +369,7 @@ const struct iio_mount_matrix *
+ inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev,
+                             const struct iio_chan_spec *chan);
+-uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr);
++u32 inv_icm42600_odr_to_period(enum inv_icm42600_odr odr);
+ int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st,
+                               struct inv_icm42600_sensor_conf *conf,
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -77,7 +77,7 @@ static const struct iio_chan_spec inv_ic
+  */
+ struct inv_icm42600_accel_buffer {
+       struct inv_icm42600_fifo_sensor_data accel;
+-      int16_t temp;
++      s16 temp;
+       aligned_s64 timestamp;
+ };
+@@ -142,7 +142,7 @@ out_unlock:
+ static int inv_icm42600_accel_read_sensor(struct inv_icm42600_state *st,
+                                         struct iio_chan_spec const *chan,
+-                                        int16_t *val)
++                                        s16 *val)
+ {
+       struct device *dev = regmap_get_device(st->map);
+       struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+@@ -182,7 +182,7 @@ static int inv_icm42600_accel_read_senso
+       if (ret)
+               goto exit;
+-      *val = (int16_t)be16_to_cpup(data);
++      *val = (s16)be16_to_cpup(data);
+       if (*val == INV_ICM42600_DATA_INVALID)
+               ret = -EINVAL;
+ exit:
+@@ -359,11 +359,11 @@ static int inv_icm42600_accel_read_offse
+                                         int *val, int *val2)
+ {
+       struct device *dev = regmap_get_device(st->map);
+-      int64_t val64;
+-      int32_t bias;
++      s64 val64;
++      s32 bias;
+       unsigned int reg;
+-      int16_t offset;
+-      uint8_t data[2];
++      s16 offset;
++      u8 data[2];
+       int ret;
+       if (chan->type != IIO_ACCEL)
+@@ -417,7 +417,7 @@ static int inv_icm42600_accel_read_offse
+        * result in micro (1000000)
+        * (offset * 5 * 9.806650 * 1000000) / 10000
+        */
+-      val64 = (int64_t)offset * 5LL * 9806650LL;
++      val64 = (s64)offset * 5LL * 9806650LL;
+       /* for rounding, add + or - divisor (10000) divided by 2 */
+       if (val64 >= 0)
+               val64 += 10000LL / 2LL;
+@@ -435,10 +435,10 @@ static int inv_icm42600_accel_write_offs
+                                          int val, int val2)
+ {
+       struct device *dev = regmap_get_device(st->map);
+-      int64_t val64;
+-      int32_t min, max;
++      s64 val64;
++      s32 min, max;
+       unsigned int reg, regval;
+-      int16_t offset;
++      s16 offset;
+       int ret;
+       if (chan->type != IIO_ACCEL)
+@@ -463,7 +463,7 @@ static int inv_icm42600_accel_write_offs
+             inv_icm42600_accel_calibbias[1];
+       max = inv_icm42600_accel_calibbias[4] * 1000000L +
+             inv_icm42600_accel_calibbias[5];
+-      val64 = (int64_t)val * 1000000LL + (int64_t)val2;
++      val64 = (s64)val * 1000000LL + (s64)val2;
+       if (val64 < min || val64 > max)
+               return -EINVAL;
+@@ -538,7 +538,7 @@ static int inv_icm42600_accel_read_raw(s
+                                      int *val, int *val2, long mask)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      int16_t data;
++      s16 data;
+       int ret;
+       switch (chan->type) {
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
+@@ -26,28 +26,28 @@
+ #define INV_ICM42600_FIFO_HEADER_ODR_GYRO     BIT(0)
+ struct inv_icm42600_fifo_1sensor_packet {
+-      uint8_t header;
++      u8 header;
+       struct inv_icm42600_fifo_sensor_data data;
+-      int8_t temp;
++      s8 temp;
+ } __packed;
+ #define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE         8
+ struct inv_icm42600_fifo_2sensors_packet {
+-      uint8_t header;
++      u8 header;
+       struct inv_icm42600_fifo_sensor_data accel;
+       struct inv_icm42600_fifo_sensor_data gyro;
+-      int8_t temp;
++      s8 temp;
+       __be16 timestamp;
+ } __packed;
+ #define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE                16
+ ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
+-                                      const void **gyro, const int8_t **temp,
++                                      const void **gyro, const s8 **temp,
+                                       const void **timestamp, unsigned int *odr)
+ {
+       const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet;
+       const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet;
+-      uint8_t header = *((const uint8_t *)packet);
++      u8 header = *((const u8 *)packet);
+       /* FIFO empty */
+       if (header & INV_ICM42600_FIFO_HEADER_MSG) {
+@@ -100,7 +100,7 @@ ssize_t inv_icm42600_fifo_decode_packet(
+ void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st)
+ {
+-      uint32_t period_gyro, period_accel, period;
++      u32 period_gyro, period_accel, period;
+       if (st->fifo.en & INV_ICM42600_SENSOR_GYRO)
+               period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr);
+@@ -204,8 +204,8 @@ int inv_icm42600_buffer_update_watermark
+ {
+       size_t packet_size, wm_size;
+       unsigned int wm_gyro, wm_accel, watermark;
+-      uint32_t period_gyro, period_accel, period;
+-      uint32_t latency_gyro, latency_accel, latency;
++      u32 period_gyro, period_accel, period;
++      u32 latency_gyro, latency_accel, latency;
+       bool restore;
+       __le16 raw_wm;
+       int ret;
+@@ -451,7 +451,7 @@ int inv_icm42600_buffer_fifo_read(struct
+       __be16 *raw_fifo_count;
+       ssize_t i, size;
+       const void *accel, *gyro, *timestamp;
+-      const int8_t *temp;
++      const s8 *temp;
+       unsigned int odr;
+       int ret;
+@@ -538,7 +538,7 @@ int inv_icm42600_buffer_hwfifo_flush(str
+                                    unsigned int count)
+ {
+       struct inv_sensors_timestamp *ts;
+-      int64_t gyro_ts, accel_ts;
++      s64 gyro_ts, accel_ts;
+       int ret;
+       gyro_ts = iio_get_time_ns(st->indio_gyro);
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h
+@@ -28,7 +28,7 @@ struct inv_icm42600_state;
+ struct inv_icm42600_fifo {
+       unsigned int on;
+       unsigned int en;
+-      uint32_t period;
++      u32 period;
+       struct {
+               unsigned int gyro;
+               unsigned int accel;
+@@ -39,7 +39,7 @@ struct inv_icm42600_fifo {
+               size_t accel;
+               size_t total;
+       } nb;
+-      uint8_t data[2080] __aligned(IIO_DMA_MINALIGN);
++      u8 data[2080] __aligned(IIO_DMA_MINALIGN);
+ };
+ /* FIFO data packet */
+@@ -50,7 +50,7 @@ struct inv_icm42600_fifo_sensor_data {
+ } __packed;
+ #define INV_ICM42600_FIFO_DATA_INVALID                -32768
+-static inline int16_t inv_icm42600_fifo_get_sensor_data(__be16 d)
++static inline s16 inv_icm42600_fifo_get_sensor_data(__be16 d)
+ {
+       return be16_to_cpu(d);
+ }
+@@ -58,7 +58,7 @@ static inline int16_t inv_icm42600_fifo_
+ static inline bool
+ inv_icm42600_fifo_is_data_valid(const struct inv_icm42600_fifo_sensor_data *s)
+ {
+-      int16_t x, y, z;
++      s16 x, y, z;
+       x = inv_icm42600_fifo_get_sensor_data(s->x);
+       y = inv_icm42600_fifo_get_sensor_data(s->y);
+@@ -73,7 +73,7 @@ inv_icm42600_fifo_is_data_valid(const st
+ }
+ ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
+-                                      const void **gyro, const int8_t **temp,
++                                      const void **gyro, const s8 **temp,
+                                       const void **timestamp, unsigned int *odr);
+ extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops;
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+@@ -56,7 +56,7 @@ const struct regmap_config inv_icm42600_
+ EXPORT_SYMBOL_NS_GPL(inv_icm42600_spi_regmap_config, IIO_ICM42600);
+ struct inv_icm42600_hw {
+-      uint8_t whoami;
++      u8 whoami;
+       const char *name;
+       const struct inv_icm42600_conf *conf;
+ };
+@@ -115,9 +115,9 @@ inv_icm42600_get_mount_matrix(const stru
+       return &st->orientation;
+ }
+-uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)
++u32 inv_icm42600_odr_to_period(enum inv_icm42600_odr odr)
+ {
+-      static uint32_t odr_periods[INV_ICM42600_ODR_NB] = {
++      static u32 odr_periods[INV_ICM42600_ODR_NB] = {
+               /* reserved values */
+               0, 0, 0,
+               /* 8kHz */
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -77,7 +77,7 @@ static const struct iio_chan_spec inv_ic
+  */
+ struct inv_icm42600_gyro_buffer {
+       struct inv_icm42600_fifo_sensor_data gyro;
+-      int16_t temp;
++      s16 temp;
+       aligned_s64 timestamp;
+ };
+@@ -142,7 +142,7 @@ out_unlock:
+ static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st,
+                                        struct iio_chan_spec const *chan,
+-                                       int16_t *val)
++                                       s16 *val)
+ {
+       struct device *dev = regmap_get_device(st->map);
+       struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
+@@ -182,7 +182,7 @@ static int inv_icm42600_gyro_read_sensor
+       if (ret)
+               goto exit;
+-      *val = (int16_t)be16_to_cpup(data);
++      *val = (s16)be16_to_cpup(data);
+       if (*val == INV_ICM42600_DATA_INVALID)
+               ret = -EINVAL;
+ exit:
+@@ -371,11 +371,11 @@ static int inv_icm42600_gyro_read_offset
+                                        int *val, int *val2)
+ {
+       struct device *dev = regmap_get_device(st->map);
+-      int64_t val64;
+-      int32_t bias;
++      s64 val64;
++      s32 bias;
+       unsigned int reg;
+-      int16_t offset;
+-      uint8_t data[2];
++      s16 offset;
++      u8 data[2];
+       int ret;
+       if (chan->type != IIO_ANGL_VEL)
+@@ -429,7 +429,7 @@ static int inv_icm42600_gyro_read_offset
+        * result in nano (1000000000)
+        * (offset * 64 * Pi * 1000000000) / (2048 * 180)
+        */
+-      val64 = (int64_t)offset * 64LL * 3141592653LL;
++      val64 = (s64)offset * 64LL * 3141592653LL;
+       /* for rounding, add + or - divisor (2048 * 180) divided by 2 */
+       if (val64 >= 0)
+               val64 += 2048 * 180 / 2;
+@@ -447,9 +447,9 @@ static int inv_icm42600_gyro_write_offse
+                                         int val, int val2)
+ {
+       struct device *dev = regmap_get_device(st->map);
+-      int64_t val64, min, max;
++      s64 val64, min, max;
+       unsigned int reg, regval;
+-      int16_t offset;
++      s16 offset;
+       int ret;
+       if (chan->type != IIO_ANGL_VEL)
+@@ -470,11 +470,11 @@ static int inv_icm42600_gyro_write_offse
+       }
+       /* inv_icm42600_gyro_calibbias: min - step - max in nano */
+-      min = (int64_t)inv_icm42600_gyro_calibbias[0] * 1000000000LL +
+-            (int64_t)inv_icm42600_gyro_calibbias[1];
+-      max = (int64_t)inv_icm42600_gyro_calibbias[4] * 1000000000LL +
+-            (int64_t)inv_icm42600_gyro_calibbias[5];
+-      val64 = (int64_t)val * 1000000000LL + (int64_t)val2;
++      min = (s64)inv_icm42600_gyro_calibbias[0] * 1000000000LL +
++            (s64)inv_icm42600_gyro_calibbias[1];
++      max = (s64)inv_icm42600_gyro_calibbias[4] * 1000000000LL +
++            (s64)inv_icm42600_gyro_calibbias[5];
++      val64 = (s64)val * 1000000000LL + (s64)val2;
+       if (val64 < min || val64 > max)
+               return -EINVAL;
+@@ -549,7 +549,7 @@ static int inv_icm42600_gyro_read_raw(st
+                                     int *val, int *val2, long mask)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      int16_t data;
++      s16 data;
+       int ret;
+       switch (chan->type) {
+@@ -764,9 +764,9 @@ int inv_icm42600_gyro_parse_fifo(struct
+       ssize_t i, size;
+       unsigned int no;
+       const void *accel, *gyro, *timestamp;
+-      const int8_t *temp;
++      const s8 *temp;
+       unsigned int odr;
+-      int64_t ts_val;
++      s64 ts_val;
+       /* buffer is copied to userspace, zeroing it to avoid any data leak */
+       struct inv_icm42600_gyro_buffer buffer = { };
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c
+@@ -13,7 +13,7 @@
+ #include "inv_icm42600.h"
+ #include "inv_icm42600_temp.h"
+-static int inv_icm42600_temp_read(struct inv_icm42600_state *st, int16_t *temp)
++static int inv_icm42600_temp_read(struct inv_icm42600_state *st, s16 *temp)
+ {
+       struct device *dev = regmap_get_device(st->map);
+       __be16 *raw;
+@@ -31,7 +31,7 @@ static int inv_icm42600_temp_read(struct
+       if (ret)
+               goto exit;
+-      *temp = (int16_t)be16_to_cpup(raw);
++      *temp = (s16)be16_to_cpup(raw);
+       if (*temp == INV_ICM42600_DATA_INVALID)
+               ret = -EINVAL;
+@@ -48,7 +48,7 @@ int inv_icm42600_temp_read_raw(struct ii
+                              int *val, int *val2, long mask)
+ {
+       struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
+-      int16_t temp;
++      s16 temp;
+       int ret;
+       if (chan->type != IIO_TEMP)
diff --git a/queue-6.6/iio-imu-inv_icm42600-switch-timestamp-type-from-int64_t-__aligned-8-to-aligned_s64.patch b/queue-6.6/iio-imu-inv_icm42600-switch-timestamp-type-from-int64_t-__aligned-8-to-aligned_s64.patch
new file mode 100644 (file)
index 0000000..daf8b17
--- /dev/null
@@ -0,0 +1,52 @@
+From stable+bounces-172740-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:34 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:53:24 -0400
+Subject: iio: imu: inv_icm42600: switch timestamp type from int64_t __aligned(8) to aligned_s64
+To: stable@vger.kernel.org
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>, Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824135327.2919985-1-sashal@kernel.org>
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 27e6ddf291b1c05bfcc3534e8212ed6c46447c60 ]
+
+The vast majority of IIO drivers use aligned_s64 for the type of the
+timestamp field.  It is not a bug to use int64_t and until this series
+iio_push_to_buffers_with_timestamp() took and int64_t timestamp, it
+is inconsistent.  This change is to remove that inconsistency and
+ensure there is one obvious choice for future drivers.
+
+Acked-by: Jean-Baptiste Maneyrol <jean-baptiste.maneyrol@tdk.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20241215182912.481706-19-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c |    2 +-
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c  |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -78,7 +78,7 @@ static const struct iio_chan_spec inv_ic
+ struct inv_icm42600_accel_buffer {
+       struct inv_icm42600_fifo_sensor_data accel;
+       int16_t temp;
+-      int64_t timestamp __aligned(8);
++      aligned_s64 timestamp;
+ };
+ #define INV_ICM42600_SCAN_MASK_ACCEL_3AXIS                            \
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -78,7 +78,7 @@ static const struct iio_chan_spec inv_ic
+ struct inv_icm42600_gyro_buffer {
+       struct inv_icm42600_fifo_sensor_data gyro;
+       int16_t temp;
+-      int64_t timestamp __aligned(8);
++      aligned_s64 timestamp;
+ };
+ #define INV_ICM42600_SCAN_MASK_GYRO_3AXIS                             \
diff --git a/queue-6.6/iio-imu-inv_icm42600-use-instead-of-memset.patch b/queue-6.6/iio-imu-inv_icm42600-use-instead-of-memset.patch
new file mode 100644 (file)
index 0000000..decc9ae
--- /dev/null
@@ -0,0 +1,70 @@
+From stable+bounces-172741-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:39 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:53:25 -0400
+Subject: iio: imu: inv_icm42600: use = { } instead of memset()
+To: stable@vger.kernel.org
+Cc: "David Lechner" <dlechner@baylibre.com>, "Nuno Sá" <nuno.sa@analog.com>, "Andy Shevchenko" <andriy.shevchenko@linux.intel.com>, "Jonathan Cameron" <Jonathan.Cameron@huawei.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20250824135327.2919985-2-sashal@kernel.org>
+
+From: David Lechner <dlechner@baylibre.com>
+
+[ Upstream commit 352112e2d9aab6a156c2803ae14eb89a9fd93b7d ]
+
+Use { } instead of memset() to zero-initialize stack memory to simplify
+the code.
+
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://patch.msgid.link/20250611-iio-zero-init-stack-with-instead-of-memset-v1-16-ebb2d0a24302@baylibre.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c |    5 ++---
+ drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c  |    5 ++---
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+@@ -755,7 +755,8 @@ int inv_icm42600_accel_parse_fifo(struct
+       const int8_t *temp;
+       unsigned int odr;
+       int64_t ts_val;
+-      struct inv_icm42600_accel_buffer buffer;
++      /* buffer is copied to userspace, zeroing it to avoid any data leak */
++      struct inv_icm42600_accel_buffer buffer = { };
+       /* parse all fifo packets */
+       for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) {
+@@ -774,8 +775,6 @@ int inv_icm42600_accel_parse_fifo(struct
+                       inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
+                                                       st->fifo.nb.total, no);
+-              /* buffer is copied to userspace, zeroing it to avoid any data leak */
+-              memset(&buffer, 0, sizeof(buffer));
+               memcpy(&buffer.accel, accel, sizeof(buffer.accel));
+               /* convert 8 bits FIFO temperature in high resolution format */
+               buffer.temp = temp ? (*temp * 64) : 0;
+--- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
++++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+@@ -767,7 +767,8 @@ int inv_icm42600_gyro_parse_fifo(struct
+       const int8_t *temp;
+       unsigned int odr;
+       int64_t ts_val;
+-      struct inv_icm42600_gyro_buffer buffer;
++      /* buffer is copied to userspace, zeroing it to avoid any data leak */
++      struct inv_icm42600_gyro_buffer buffer = { };
+       /* parse all fifo packets */
+       for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) {
+@@ -786,8 +787,6 @@ int inv_icm42600_gyro_parse_fifo(struct
+                       inv_sensors_timestamp_apply_odr(ts, st->fifo.period,
+                                                       st->fifo.nb.total, no);
+-              /* buffer is copied to userspace, zeroing it to avoid any data leak */
+-              memset(&buffer, 0, sizeof(buffer));
+               memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro));
+               /* convert 8 bits FIFO temperature in high resolution format */
+               buffer.temp = temp ? (*temp * 64) : 0;
diff --git a/queue-6.6/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch b/queue-6.6/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch
new file mode 100644 (file)
index 0000000..4852fb4
--- /dev/null
@@ -0,0 +1,39 @@
+From stable+bounces-172726-greg=kroah.com@vger.kernel.org Sun Aug 24 15:02:49 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:02:38 -0400
+Subject: iio: light: as73211: Ensure buffer holes are zeroed
+To: stable@vger.kernel.org
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>, Matti Vaittinen <mazziesaccount@gmail.com>, Andy Shevchenko <andy@kernel.org>, Stable@vger.kernel.org, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824130238.2749705-1-sashal@kernel.org>
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 433b99e922943efdfd62b9a8e3ad1604838181f2 ]
+
+Given that the buffer is copied to a kfifo that ultimately user space
+can read, ensure we zero it.
+
+Fixes: 403e5586b52e ("iio: light: as73211: New driver")
+Reviewed-by: Matti Vaittinen <mazziesaccount@gmail.com>
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Link: https://patch.msgid.link/20250802164436.515988-2-jic23@kernel.org
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+[ Adjust context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/light/as73211.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/light/as73211.c
++++ b/drivers/iio/light/as73211.c
+@@ -573,7 +573,7 @@ static irqreturn_t as73211_trigger_handl
+       struct {
+               __le16 chan[4];
+               s64 ts __aligned(8);
+-      } scan;
++      } scan = { };
+       int data_result, ret;
+       mutex_lock(&data->mutex);
diff --git a/queue-6.6/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch b/queue-6.6/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch
new file mode 100644 (file)
index 0000000..4dddf4c
--- /dev/null
@@ -0,0 +1,95 @@
+From stable+bounces-172724-greg=kroah.com@vger.kernel.org Sun Aug 24 15:02:16 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:01:40 -0400
+Subject: iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
+To: stable@vger.kernel.org
+Cc: "David Lechner" <dlechner@baylibre.com>, "Nuno Sá" <nuno.sa@analog.com>, Stable@vger.kernel.org, "Jonathan Cameron" <Jonathan.Cameron@huawei.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20250824130140.2748027-1-sashal@kernel.org>
+
+From: David Lechner <dlechner@baylibre.com>
+
+[ Upstream commit ae5bc07ec9f73a41734270ef3f800c5c8a7e0ad3 ]
+
+Replace using stack-allocated buffers with a DMA-safe buffer for use
+with spi_read(). This allows the driver to be safely used with
+DMA-enabled SPI controllers.
+
+The buffer array is also converted to a struct with a union to make the
+usage of the memory in the buffer more clear and ensure proper alignment.
+
+Fixes: 1f25ca11d84a ("iio: temperature: add support for Maxim thermocouple chips")
+Signed-off-by: David Lechner <dlechner@baylibre.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Link: https://patch.msgid.link/20250721-iio-use-more-iio_declare_buffer_with_ts-3-v2-1-0c68d41ccf6c@baylibre.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+[ iio_push_to_buffers_with_ts() => iio_push_to_buffers_with_timestamp() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/temperature/maxim_thermocouple.c |   26 ++++++++++++++++----------
+ 1 file changed, 16 insertions(+), 10 deletions(-)
+
+--- a/drivers/iio/temperature/maxim_thermocouple.c
++++ b/drivers/iio/temperature/maxim_thermocouple.c
+@@ -12,6 +12,7 @@
+ #include <linux/mutex.h>
+ #include <linux/err.h>
+ #include <linux/spi/spi.h>
++#include <linux/types.h>
+ #include <linux/iio/iio.h>
+ #include <linux/iio/sysfs.h>
+ #include <linux/iio/trigger.h>
+@@ -122,8 +123,15 @@ struct maxim_thermocouple_data {
+       struct spi_device *spi;
+       const struct maxim_thermocouple_chip *chip;
+       char tc_type;
+-
+-      u8 buffer[16] __aligned(IIO_DMA_MINALIGN);
++      /* Buffer for reading up to 2 hardware channels. */
++      struct {
++              union {
++                      __be16 raw16;
++                      __be32 raw32;
++                      __be16 raw[2];
++              };
++              aligned_s64 timestamp;
++      } buffer __aligned(IIO_DMA_MINALIGN);
+ };
+ static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
+@@ -131,18 +139,16 @@ static int maxim_thermocouple_read(struc
+ {
+       unsigned int storage_bytes = data->chip->read_size;
+       unsigned int shift = chan->scan_type.shift + (chan->address * 8);
+-      __be16 buf16;
+-      __be32 buf32;
+       int ret;
+       switch (storage_bytes) {
+       case 2:
+-              ret = spi_read(data->spi, (void *)&buf16, storage_bytes);
+-              *val = be16_to_cpu(buf16);
++              ret = spi_read(data->spi, &data->buffer.raw16, storage_bytes);
++              *val = be16_to_cpu(data->buffer.raw16);
+               break;
+       case 4:
+-              ret = spi_read(data->spi, (void *)&buf32, storage_bytes);
+-              *val = be32_to_cpu(buf32);
++              ret = spi_read(data->spi, &data->buffer.raw32, storage_bytes);
++              *val = be32_to_cpu(data->buffer.raw32);
+               break;
+       default:
+               ret = -EINVAL;
+@@ -167,9 +173,9 @@ static irqreturn_t maxim_thermocouple_tr
+       struct maxim_thermocouple_data *data = iio_priv(indio_dev);
+       int ret;
+-      ret = spi_read(data->spi, data->buffer, data->chip->read_size);
++      ret = spi_read(data->spi, data->buffer.raw, data->chip->read_size);
+       if (!ret) {
+-              iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
++              iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
+                                                  iio_get_time_ns(indio_dev));
+       }
index 3fb55b66a10f2bd0175b608e6ca9ede1e8fb9713..df24b8cab324611951e3f3879af92c66fb5b5b85 100644 (file)
@@ -533,3 +533,14 @@ compiler-remove-__addressable_asm-_str-again.patch
 mmc-sdhci-pci-gli-gl9763e-mask-the-replay-timer-timeout-of-aer.patch
 powerpc-boot-fix-build-with-gcc-15.patch
 tls-fix-handling-of-zero-length-records-on-the-rx_list.patch
+tracing-remove-unneeded-goto-out-logic.patch
+tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch
+iio-light-as73211-ensure-buffer-holes-are-zeroed.patch
+iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch
+iio-imu-inv_icm42600-switch-timestamp-type-from-int64_t-__aligned-8-to-aligned_s64.patch
+iio-imu-inv_icm42600-use-instead-of-memset.patch
+iio-imu-inv_icm42600-convert-to-uxx-and-sxx-integer-types.patch
+iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch
+usb-xhci-fix-slot_id-resource-race-conflict.patch
+usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch
+usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch
diff --git a/queue-6.6/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch b/queue-6.6/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch
new file mode 100644 (file)
index 0000000..b0f6f6b
--- /dev/null
@@ -0,0 +1,142 @@
+From stable+bounces-172737-greg=kroah.com@vger.kernel.org Sun Aug 24 15:39:23 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:39:13 -0400
+Subject: tracing: Limit access to parser->buffer when trace_get_user failed
+To: stable@vger.kernel.org
+Cc: Pu Lehui <pulehui@huawei.com>, "Steven Rostedt (Google)" <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824133913.2897381-2-sashal@kernel.org>
+
+From: Pu Lehui <pulehui@huawei.com>
+
+[ Upstream commit 6a909ea83f226803ea0e718f6e88613df9234d58 ]
+
+When the length of the string written to set_ftrace_filter exceeds
+FTRACE_BUFF_MAX, the following KASAN alarm will be triggered:
+
+BUG: KASAN: slab-out-of-bounds in strsep+0x18c/0x1b0
+Read of size 1 at addr ffff0000d00bd5ba by task ash/165
+
+CPU: 1 UID: 0 PID: 165 Comm: ash Not tainted 6.16.0-g6bcdbd62bd56-dirty
+Hardware name: linux,dummy-virt (DT)
+Call trace:
+ show_stack+0x34/0x50 (C)
+ dump_stack_lvl+0xa0/0x158
+ print_address_description.constprop.0+0x88/0x398
+ print_report+0xb0/0x280
+ kasan_report+0xa4/0xf0
+ __asan_report_load1_noabort+0x20/0x30
+ strsep+0x18c/0x1b0
+ ftrace_process_regex.isra.0+0x100/0x2d8
+ ftrace_regex_release+0x484/0x618
+ __fput+0x364/0xa58
+ ____fput+0x28/0x40
+ task_work_run+0x154/0x278
+ do_notify_resume+0x1f0/0x220
+ el0_svc+0xec/0xf0
+ el0t_64_sync_handler+0xa0/0xe8
+ el0t_64_sync+0x1ac/0x1b0
+
+The reason is that trace_get_user will fail when processing a string
+longer than FTRACE_BUFF_MAX, but not set the end of parser->buffer to 0.
+Then an OOB access will be triggered in ftrace_regex_release->
+ftrace_process_regex->strsep->strpbrk. We can solve this problem by
+limiting access to parser->buffer when trace_get_user failed.
+
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/20250813040232.1344527-1-pulehui@huaweicloud.com
+Fixes: 8c9af478c06b ("ftrace: Handle commands when closing set_ftrace_filter file")
+Signed-off-by: Pu Lehui <pulehui@huawei.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace.c |   18 ++++++++++++------
+ kernel/trace/trace.h |    8 +++++++-
+ 2 files changed, 19 insertions(+), 7 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1661,7 +1661,7 @@ int trace_get_user(struct trace_parser *
+       ret = get_user(ch, ubuf++);
+       if (ret)
+-              return ret;
++              goto fail;
+       read++;
+       cnt--;
+@@ -1675,7 +1675,7 @@ int trace_get_user(struct trace_parser *
+               while (cnt && isspace(ch)) {
+                       ret = get_user(ch, ubuf++);
+                       if (ret)
+-                              return ret;
++                              goto fail;
+                       read++;
+                       cnt--;
+               }
+@@ -1693,12 +1693,14 @@ int trace_get_user(struct trace_parser *
+       while (cnt && !isspace(ch) && ch) {
+               if (parser->idx < parser->size - 1)
+                       parser->buffer[parser->idx++] = ch;
+-              else
+-                      return -EINVAL;
++              else {
++                      ret = -EINVAL;
++                      goto fail;
++              }
+               ret = get_user(ch, ubuf++);
+               if (ret)
+-                      return ret;
++                      goto fail;
+               read++;
+               cnt--;
+       }
+@@ -1713,11 +1715,15 @@ int trace_get_user(struct trace_parser *
+               /* Make sure the parsed string always terminates with '\0'. */
+               parser->buffer[parser->idx] = 0;
+       } else {
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto fail;
+       }
+       *ppos += read;
+       return read;
++fail:
++      trace_parser_fail(parser);
++      return ret;
+ }
+ /* TODO add a seq_buf_to_buffer() */
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -1153,6 +1153,7 @@ bool ftrace_event_is_function(struct tra
+  */
+ struct trace_parser {
+       bool            cont;
++      bool            fail;
+       char            *buffer;
+       unsigned        idx;
+       unsigned        size;
+@@ -1160,7 +1161,7 @@ struct trace_parser {
+ static inline bool trace_parser_loaded(struct trace_parser *parser)
+ {
+-      return (parser->idx != 0);
++      return !parser->fail && parser->idx != 0;
+ }
+ static inline bool trace_parser_cont(struct trace_parser *parser)
+@@ -1174,6 +1175,11 @@ static inline void trace_parser_clear(st
+       parser->idx = 0;
+ }
++static inline void trace_parser_fail(struct trace_parser *parser)
++{
++      parser->fail = true;
++}
++
+ extern int trace_parser_get_init(struct trace_parser *parser, int size);
+ extern void trace_parser_put(struct trace_parser *parser);
+ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
diff --git a/queue-6.6/tracing-remove-unneeded-goto-out-logic.patch b/queue-6.6/tracing-remove-unneeded-goto-out-logic.patch
new file mode 100644 (file)
index 0000000..96f40d8
--- /dev/null
@@ -0,0 +1,149 @@
+From stable+bounces-172736-greg=kroah.com@vger.kernel.org Sun Aug 24 15:39:20 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 09:39:12 -0400
+Subject: tracing: Remove unneeded goto out logic
+To: stable@vger.kernel.org
+Cc: Steven Rostedt <rostedt@goodmis.org>, Masami Hiramatsu <mhiramat@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824133913.2897381-1-sashal@kernel.org>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit c89504a703fb779052213add0e8ed642f4a4f1c8 ]
+
+Several places in the trace.c file there's a goto out where the out is
+simply a return. There's no reason to jump to the out label if it's not
+doing any more logic but simply returning from the function.
+
+Replace the goto outs with a return and remove the out labels.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Link: https://lore.kernel.org/20250801203857.538726745@kernel.org
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace.c |   37 ++++++++++++++-----------------------
+ 1 file changed, 14 insertions(+), 23 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -1661,7 +1661,7 @@ int trace_get_user(struct trace_parser *
+       ret = get_user(ch, ubuf++);
+       if (ret)
+-              goto out;
++              return ret;
+       read++;
+       cnt--;
+@@ -1675,7 +1675,7 @@ int trace_get_user(struct trace_parser *
+               while (cnt && isspace(ch)) {
+                       ret = get_user(ch, ubuf++);
+                       if (ret)
+-                              goto out;
++                              return ret;
+                       read++;
+                       cnt--;
+               }
+@@ -1685,8 +1685,7 @@ int trace_get_user(struct trace_parser *
+               /* only spaces were written */
+               if (isspace(ch) || !ch) {
+                       *ppos += read;
+-                      ret = read;
+-                      goto out;
++                      return read;
+               }
+       }
+@@ -1694,13 +1693,12 @@ int trace_get_user(struct trace_parser *
+       while (cnt && !isspace(ch) && ch) {
+               if (parser->idx < parser->size - 1)
+                       parser->buffer[parser->idx++] = ch;
+-              else {
+-                      ret = -EINVAL;
+-                      goto out;
+-              }
++              else
++                      return -EINVAL;
++
+               ret = get_user(ch, ubuf++);
+               if (ret)
+-                      goto out;
++                      return ret;
+               read++;
+               cnt--;
+       }
+@@ -1715,15 +1713,11 @@ int trace_get_user(struct trace_parser *
+               /* Make sure the parsed string always terminates with '\0'. */
+               parser->buffer[parser->idx] = 0;
+       } else {
+-              ret = -EINVAL;
+-              goto out;
++              return -EINVAL;
+       }
+       *ppos += read;
+-      ret = read;
+-
+-out:
+-      return ret;
++      return read;
+ }
+ /* TODO add a seq_buf_to_buffer() */
+@@ -2211,10 +2205,10 @@ int __init register_tracer(struct tracer
+       mutex_unlock(&trace_types_lock);
+       if (ret || !default_bootup_tracer)
+-              goto out_unlock;
++              return ret;
+       if (strncmp(default_bootup_tracer, type->name, MAX_TRACER_SIZE))
+-              goto out_unlock;
++              return 0;
+       printk(KERN_INFO "Starting tracer '%s'\n", type->name);
+       /* Do we want this tracer to start on bootup? */
+@@ -2226,8 +2220,7 @@ int __init register_tracer(struct tracer
+       /* disable other selftests, since this will break it. */
+       disable_tracing_selftest("running a tracer");
+- out_unlock:
+-      return ret;
++      return 0;
+ }
+ static void tracing_reset_cpu(struct array_buffer *buf, int cpu)
+@@ -8734,11 +8727,10 @@ ftrace_trace_snapshot_callback(struct tr
+  out_reg:
+       ret = tracing_alloc_snapshot_instance(tr);
+       if (ret < 0)
+-              goto out;
++              return ret;
+       ret = register_ftrace_function_probe(glob, tr, ops, count);
+- out:
+       return ret < 0 ? ret : 0;
+ }
+@@ -10344,7 +10336,7 @@ __init static int tracer_alloc_buffers(v
+       BUILD_BUG_ON(TRACE_ITER_LAST_BIT > TRACE_FLAGS_MAX_SIZE);
+       if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL))
+-              goto out;
++              return -ENOMEM;
+       if (!alloc_cpumask_var(&global_trace.tracing_cpumask, GFP_KERNEL))
+               goto out_free_buffer_mask;
+@@ -10455,7 +10447,6 @@ out_free_cpumask:
+       free_cpumask_var(global_trace.tracing_cpumask);
+ out_free_buffer_mask:
+       free_cpumask_var(tracing_buffer_mask);
+-out:
+       return ret;
+ }
diff --git a/queue-6.6/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch b/queue-6.6/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch
new file mode 100644 (file)
index 0000000..7411c50
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-172763-greg=kroah.com@vger.kernel.org Sun Aug 24 20:33:19 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 14:33:12 -0400
+Subject: usb: typec: maxim_contaminant: disable low power mode when reading comparator values
+To: stable@vger.kernel.org
+Cc: Amit Sunil Dhamne <amitsd@google.com>, stable <stable@kernel.org>, Badhri Jagan Sridharan <badhri@google.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824183312.795044-1-sashal@kernel.org>
+
+From: Amit Sunil Dhamne <amitsd@google.com>
+
+[ Upstream commit cabb6c5f4d9e7f49bdf8c0a13c74bd93ee35f45a ]
+
+Low power mode is enabled when reading CC resistance as part of
+`max_contaminant_read_resistance_kohm()` and left in that state.
+However, it's supposed to work with 1uA current source. To read CC
+comparator values current source is changed to 80uA. This causes a storm
+of CC interrupts as it (falsely) detects a potential contaminant. To
+prevent this, disable low power mode current sourcing before reading
+comparator values.
+
+Fixes: 02b332a06397 ("usb: typec: maxim_contaminant: Implement check_contaminant callback")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
+Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
+Rule: add
+Link: https://lore.kernel.org/stable/20250814-fix-upstream-contaminant-v1-1-801ce8089031%40google.com
+Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-1-6c8d6c3adafb@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ adapted macro names from CCLPMODESEL to CCLPMODESEL_MASK ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/maxim_contaminant.c |    6 ++++++
+ drivers/usb/typec/tcpm/tcpci_maxim.h       |    1 +
+ 2 files changed, 7 insertions(+)
+
+--- a/drivers/usb/typec/tcpm/maxim_contaminant.c
++++ b/drivers/usb/typec/tcpm/maxim_contaminant.c
+@@ -5,6 +5,7 @@
+  * USB-C module to reduce wakeups due to contaminants.
+  */
++#include <linux/bitfield.h>
+ #include <linux/device.h>
+ #include <linux/irqreturn.h>
+ #include <linux/module.h>
+@@ -189,6 +190,11 @@ static int max_contaminant_read_comparat
+       if (ret < 0)
+               return ret;
++      /* Disable low power mode */
++      ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL_MASK,
++                               FIELD_PREP(CCLPMODESEL_MASK,
++                                          LOW_POWER_MODE_DISABLE));
++
+       /* Sleep to allow comparators settle */
+       usleep_range(5000, 6000);
+       ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL, TCPC_TCPC_CTRL_ORIENTATION, PLUG_ORNT_CC1);
+--- a/drivers/usb/typec/tcpm/tcpci_maxim.h
++++ b/drivers/usb/typec/tcpm/tcpci_maxim.h
+@@ -21,6 +21,7 @@
+ #define CCOVPDIS                                BIT(6)
+ #define SBURPCTRL                               BIT(5)
+ #define CCLPMODESEL_MASK                        GENMASK(4, 3)
++#define LOW_POWER_MODE_DISABLE                  0
+ #define ULTRA_LOW_POWER_MODE                    BIT(3)
+ #define CCRPCTRL_MASK                           GENMASK(2, 0)
+ #define UA_1_SRC                                1
diff --git a/queue-6.6/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch b/queue-6.6/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch
new file mode 100644 (file)
index 0000000..c27590d
--- /dev/null
@@ -0,0 +1,117 @@
+From stable+bounces-172758-greg=kroah.com@vger.kernel.org Sun Aug 24 18:50:03 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 12:49:53 -0400
+Subject: usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
+To: stable@vger.kernel.org
+Cc: Amit Sunil Dhamne <amitsd@google.com>, stable <stable@kernel.org>, Badhri Jagan Sridharan <badhri@google.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824164953.4152487-1-sashal@kernel.org>
+
+From: Amit Sunil Dhamne <amitsd@google.com>
+
+[ Upstream commit a381c6d6f646226924809d0ad01a9465786da463 ]
+
+Presently in `max_contaminant_is_contaminant()` if there's no
+contaminant detected previously, CC is open & stopped toggling and no
+contaminant is currently present, TCPC.RC would be programmed to do DRP
+toggling. However, it didn't actively look for a connection. This would
+lead to Type-C not detect *any* new connections. Hence, in the above
+situation, re-enable toggling & program TCPC to look for a new
+connection.
+
+Also, return early if TCPC was looking for connection as this indicates
+TCPC has neither detected a potential connection nor a change in
+contaminant state.
+
+In addition, once dry detection is complete (port is dry), restart
+toggling.
+
+Fixes: 02b332a06397e ("usb: typec: maxim_contaminant: Implement check_contaminant callback")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
+Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
+Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-2-6c8d6c3adafb@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/tcpm/maxim_contaminant.c |   48 +++++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+--- a/drivers/usb/typec/tcpm/maxim_contaminant.c
++++ b/drivers/usb/typec/tcpm/maxim_contaminant.c
+@@ -322,6 +322,34 @@ static int max_contaminant_enable_dry_de
+       return 0;
+ }
++static int max_contaminant_enable_toggling(struct max_tcpci_chip *chip)
++{
++      struct regmap *regmap = chip->data.regmap;
++      int ret;
++
++      /* Disable dry detection if enabled. */
++      ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL_MASK,
++                               ULTRA_LOW_POWER_MODE);
++      if (ret)
++              return ret;
++
++      ret = regmap_update_bits(regmap, TCPC_VENDOR_CC_CTRL1, CCCONNDRY, 0);
++      if (ret)
++              return ret;
++
++      ret = max_tcpci_write8(chip, TCPC_ROLE_CTRL, TCPC_ROLE_CTRL_DRP | 0xA);
++      if (ret)
++              return ret;
++
++      ret = regmap_update_bits(regmap, TCPC_TCPC_CTRL,
++                               TCPC_TCPC_CTRL_EN_LK4CONN_ALRT,
++                               TCPC_TCPC_CTRL_EN_LK4CONN_ALRT);
++      if (ret)
++              return ret;
++
++      return max_tcpci_write8(chip, TCPC_COMMAND, TCPC_CMD_LOOK4CONNECTION);
++}
++
+ bool max_contaminant_is_contaminant(struct max_tcpci_chip *chip, bool disconnect_while_debounce)
+ {
+       u8 cc_status, pwr_cntl;
+@@ -335,6 +363,12 @@ bool max_contaminant_is_contaminant(stru
+       if (ret < 0)
+               return false;
++      if (cc_status & TCPC_CC_STATUS_TOGGLING) {
++              if (chip->contaminant_state == DETECTED)
++                      return true;
++              return false;
++      }
++
+       if (chip->contaminant_state == NOT_DETECTED || chip->contaminant_state == SINK) {
+               if (!disconnect_while_debounce)
+                       msleep(100);
+@@ -367,6 +401,12 @@ bool max_contaminant_is_contaminant(stru
+                               max_contaminant_enable_dry_detection(chip);
+                               return true;
+                       }
++
++                      ret = max_contaminant_enable_toggling(chip);
++                      if (ret)
++                              dev_err(chip->dev,
++                                      "Failed to enable toggling, ret=%d",
++                                      ret);
+               }
+               return false;
+       } else if (chip->contaminant_state == DETECTED) {
+@@ -375,6 +415,14 @@ bool max_contaminant_is_contaminant(stru
+                       if (chip->contaminant_state == DETECTED) {
+                               max_contaminant_enable_dry_detection(chip);
+                               return true;
++                      } else {
++                              ret = max_contaminant_enable_toggling(chip);
++                              if (ret) {
++                                      dev_err(chip->dev,
++                                              "Failed to enable toggling, ret=%d",
++                                              ret);
++                                      return true;
++                              }
+                       }
+               }
+       }
diff --git a/queue-6.6/usb-xhci-fix-slot_id-resource-race-conflict.patch b/queue-6.6/usb-xhci-fix-slot_id-resource-race-conflict.patch
new file mode 100644 (file)
index 0000000..8fde09d
--- /dev/null
@@ -0,0 +1,227 @@
+From stable+bounces-172752-greg=kroah.com@vger.kernel.org Sun Aug 24 17:29:16 2025
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Aug 2025 11:29:04 -0400
+Subject: usb: xhci: Fix slot_id resource race conflict
+To: stable@vger.kernel.org
+Cc: Weitao Wang <WeitaoWang-oc@zhaoxin.com>, Mathias Nyman <mathias.nyman@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20250824152904.3382917-1-sashal@kernel.org>
+
+From: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
+
+[ Upstream commit 2eb03376151bb8585caa23ed2673583107bb5193 ]
+
+xHC controller may immediately reuse a slot_id after it's disabled,
+giving it to a new enumerating device before the xhci driver freed
+all resources related to the disabled device.
+
+In such a scenario, device-A with slot_id equal to 1 is disconnecting
+while device-B is enumerating, device-B will fail to enumerate in the
+follow sequence.
+
+1.[device-A] send disable slot command
+2.[device-B] send enable slot command
+3.[device-A] disable slot command completed and wakeup waiting thread
+4.[device-B] enable slot command completed with slot_id equal to 1 and
+            wakeup waiting thread
+5.[device-B] driver checks that slot_id is still in use (by device-A) in
+            xhci_alloc_virt_device, and fail to enumerate due to this
+            conflict
+6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device
+
+To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and
+xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context
+when disable slot command completes successfully. Simultaneously, adjust
+function xhci_free_virt_device to accurately handle device release.
+
+[minor smatch warning and commit message fix -Mathias]
+
+Cc: stable@vger.kernel.org
+Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend")
+Signed-off-by: Weitao Wang <WeitaoWang-oc@zhaoxin.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ Adjust context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/xhci-hub.c  |    3 +--
+ drivers/usb/host/xhci-mem.c  |   22 +++++++++++-----------
+ drivers/usb/host/xhci-ring.c |    9 +++++++--
+ drivers/usb/host/xhci.c      |   21 ++++++++++++++-------
+ drivers/usb/host/xhci.h      |    3 ++-
+ 5 files changed, 35 insertions(+), 23 deletions(-)
+
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -735,8 +735,7 @@ static int xhci_enter_test_mode(struct x
+               if (!xhci->devs[i])
+                       continue;
+-              retval = xhci_disable_slot(xhci, i);
+-              xhci_free_virt_device(xhci, i);
++              retval = xhci_disable_and_free_slot(xhci, i);
+               if (retval)
+                       xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n",
+                                i, retval);
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -849,21 +849,20 @@ free_tts:
+  * will be manipulated by the configure endpoint, allocate device, or update
+  * hub functions while this function is removing the TT entries from the list.
+  */
+-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
++void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
++              int slot_id)
+ {
+-      struct xhci_virt_device *dev;
+       int i;
+       int old_active_eps = 0;
+       /* Slot ID 0 is reserved */
+-      if (slot_id == 0 || !xhci->devs[slot_id])
++      if (slot_id == 0 || !dev)
+               return;
+-      dev = xhci->devs[slot_id];
+-
+-      xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
+-      if (!dev)
+-              return;
++      /* If device ctx array still points to _this_ device, clear it */
++      if (dev->out_ctx &&
++          xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma))
++              xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
+       trace_xhci_free_virt_device(dev);
+@@ -902,8 +901,9 @@ void xhci_free_virt_device(struct xhci_h
+       if (dev->udev && dev->udev->slot_id)
+               dev->udev->slot_id = 0;
+-      kfree(xhci->devs[slot_id]);
+-      xhci->devs[slot_id] = NULL;
++      if (xhci->devs[slot_id] == dev)
++              xhci->devs[slot_id] = NULL;
++      kfree(dev);
+ }
+ /*
+@@ -945,7 +945,7 @@ static void xhci_free_virt_devices_depth
+ out:
+       /* we are now at a leaf device */
+       xhci_debugfs_remove_slot(xhci, slot_id);
+-      xhci_free_virt_device(xhci, slot_id);
++      xhci_free_virt_device(xhci, vdev, slot_id);
+ }
+ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1587,7 +1587,8 @@ static void xhci_handle_cmd_enable_slot(
+               command->slot_id = 0;
+ }
+-static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
++static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id,
++                                      u32 cmd_comp_code)
+ {
+       struct xhci_virt_device *virt_dev;
+       struct xhci_slot_ctx *slot_ctx;
+@@ -1602,6 +1603,10 @@ static void xhci_handle_cmd_disable_slot
+       if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
+               /* Delete default control endpoint resources */
+               xhci_free_device_endpoint_resources(xhci, virt_dev, true);
++      if (cmd_comp_code == COMP_SUCCESS) {
++              xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
++              xhci->devs[slot_id] = NULL;
++      }
+ }
+ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
+@@ -1850,7 +1855,7 @@ static void handle_cmd_completion(struct
+               xhci_handle_cmd_enable_slot(xhci, slot_id, cmd, cmd_comp_code);
+               break;
+       case TRB_DISABLE_SLOT:
+-              xhci_handle_cmd_disable_slot(xhci, slot_id);
++              xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code);
+               break;
+       case TRB_CONFIG_EP:
+               if (!cmd->completion)
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -3760,8 +3760,7 @@ static int xhci_discover_or_reset_device
+                * Obtaining a new device slot to inform the xHCI host that
+                * the USB device has been reset.
+                */
+-              ret = xhci_disable_slot(xhci, udev->slot_id);
+-              xhci_free_virt_device(xhci, udev->slot_id);
++              ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
+               if (!ret) {
+                       ret = xhci_alloc_dev(hcd, udev);
+                       if (ret == 1)
+@@ -3916,7 +3915,7 @@ static void xhci_free_dev(struct usb_hcd
+       xhci_disable_slot(xhci, udev->slot_id);
+       spin_lock_irqsave(&xhci->lock, flags);
+-      xhci_free_virt_device(xhci, udev->slot_id);
++      xhci_free_virt_device(xhci, virt_dev, udev->slot_id);
+       spin_unlock_irqrestore(&xhci->lock, flags);
+ }
+@@ -3965,6 +3964,16 @@ int xhci_disable_slot(struct xhci_hcd *x
+       return 0;
+ }
++int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id)
++{
++      struct xhci_virt_device *vdev = xhci->devs[slot_id];
++      int ret;
++
++      ret = xhci_disable_slot(xhci, slot_id);
++      xhci_free_virt_device(xhci, vdev, slot_id);
++      return ret;
++}
++
+ /*
+  * Checks if we have enough host controller resources for the default control
+  * endpoint.
+@@ -4071,8 +4080,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd,
+       return 1;
+ disable_slot:
+-      xhci_disable_slot(xhci, udev->slot_id);
+-      xhci_free_virt_device(xhci, udev->slot_id);
++      xhci_disable_and_free_slot(xhci, udev->slot_id);
+       return 0;
+ }
+@@ -4208,8 +4216,7 @@ static int xhci_setup_device(struct usb_
+               dev_warn(&udev->dev, "Device not responding to setup %s.\n", act);
+               mutex_unlock(&xhci->mutex);
+-              ret = xhci_disable_slot(xhci, udev->slot_id);
+-              xhci_free_virt_device(xhci, udev->slot_id);
++              ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
+               if (!ret) {
+                       if (xhci_alloc_dev(hcd, udev) == 1)
+                               xhci_setup_addressable_virt_dev(xhci, udev);
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -1798,7 +1798,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhc
+ /* xHCI memory management */
+ void xhci_mem_cleanup(struct xhci_hcd *xhci);
+ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
+-void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
++void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id);
+ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags);
+ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
+ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
+@@ -1895,6 +1895,7 @@ void xhci_reset_bandwidth(struct usb_hcd
+ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
+                          struct usb_tt *tt, gfp_t mem_flags);
+ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
++int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id);
+ int xhci_ext_cap_init(struct xhci_hcd *xhci);
+ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);