From: Greg Kroah-Hartman Date: Mon, 25 Aug 2025 07:32:52 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v5.4.297~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c7d118850a6ac1f7ae64b97378808c85fddf508e;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches 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 --- 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 index 0000000000..659a20adf5 --- /dev/null +++ b/queue-6.6/iio-imu-inv_icm42600-change-invalid-data-error-to-ebusy.patch @@ -0,0 +1,49 @@ +From stable+bounces-172743-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:40 2025 +From: Sasha Levin +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 , Andy Shevchenko , Sean Nyekjaer , Jonathan Cameron , Sasha Levin +Message-ID: <20250824135327.2919985-4-sashal@kernel.org> + +From: Jean-Baptiste Maneyrol + +[ 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 +Cc: stable@vger.kernel.org +Reviewed-by: Andy Shevchenko +Reviewed-by: Sean Nyekjaer +Link: https://patch.msgid.link/20250808-inv-icm42600-change-temperature-error-code-v1-1-986fbf63b77d@tdk.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..9871139d78 --- /dev/null +++ b/queue-6.6/iio-imu-inv_icm42600-convert-to-uxx-and-sxx-integer-types.patch @@ -0,0 +1,423 @@ +From stable+bounces-172742-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:39 2025 +From: Sasha Levin +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 , Jean-Baptiste Maneyrol , Jonathan Cameron , Sasha Levin +Message-ID: <20250824135327.2919985-3-sashal@kernel.org> + +From: Andy Shevchenko + +[ 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 +Acked-by: Jean-Baptiste Maneyrol +Link: https://patch.msgid.link/20250616090423.575736-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..daf8b17610 --- /dev/null +++ b/queue-6.6/iio-imu-inv_icm42600-switch-timestamp-type-from-int64_t-__aligned-8-to-aligned_s64.patch @@ -0,0 +1,52 @@ +From stable+bounces-172740-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:34 2025 +From: Sasha Levin +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 , Jean-Baptiste Maneyrol , Andy Shevchenko , Sasha Levin +Message-ID: <20250824135327.2919985-1-sashal@kernel.org> + +From: Jonathan Cameron + +[ 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 +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20241215182912.481706-19-jic23@kernel.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..decc9ae6d0 --- /dev/null +++ b/queue-6.6/iio-imu-inv_icm42600-use-instead-of-memset.patch @@ -0,0 +1,70 @@ +From stable+bounces-172741-greg=kroah.com@vger.kernel.org Sun Aug 24 15:53:39 2025 +From: Sasha Levin +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" , "Nuno Sá" , "Andy Shevchenko" , "Jonathan Cameron" , "Sasha Levin" +Message-ID: <20250824135327.2919985-2-sashal@kernel.org> + +From: David Lechner + +[ Upstream commit 352112e2d9aab6a156c2803ae14eb89a9fd93b7d ] + +Use { } instead of memset() to zero-initialize stack memory to simplify +the code. + +Signed-off-by: David Lechner +Reviewed-by: Nuno Sá +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20250611-iio-zero-init-stack-with-instead-of-memset-v1-16-ebb2d0a24302@baylibre.com +Signed-off-by: Jonathan Cameron +Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4852fb407b --- /dev/null +++ b/queue-6.6/iio-light-as73211-ensure-buffer-holes-are-zeroed.patch @@ -0,0 +1,39 @@ +From stable+bounces-172726-greg=kroah.com@vger.kernel.org Sun Aug 24 15:02:49 2025 +From: Sasha Levin +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 , Matti Vaittinen , Andy Shevchenko , Stable@vger.kernel.org, Sasha Levin +Message-ID: <20250824130238.2749705-1-sashal@kernel.org> + +From: Jonathan Cameron + +[ 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 +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20250802164436.515988-2-jic23@kernel.org +Cc: +Signed-off-by: Jonathan Cameron +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..4dddf4c503 --- /dev/null +++ b/queue-6.6/iio-temperature-maxim_thermocouple-use-dma-safe-buffer-for-spi_read.patch @@ -0,0 +1,95 @@ +From stable+bounces-172724-greg=kroah.com@vger.kernel.org Sun Aug 24 15:02:16 2025 +From: Sasha Levin +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" , "Nuno Sá" , Stable@vger.kernel.org, "Jonathan Cameron" , "Sasha Levin" +Message-ID: <20250824130140.2748027-1-sashal@kernel.org> + +From: David Lechner + +[ 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 +Reviewed-by: Nuno Sá +Link: https://patch.msgid.link/20250721-iio-use-more-iio_declare_buffer_with_ts-3-v2-1-0c68d41ccf6c@baylibre.com +Cc: +Signed-off-by: Jonathan Cameron +[ iio_push_to_buffers_with_ts() => iio_push_to_buffers_with_timestamp() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include ++#include + #include + #include + #include +@@ -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)); + } + diff --git a/queue-6.6/series b/queue-6.6/series index 3fb55b66a1..df24b8cab3 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -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 index 0000000000..b0f6f6b131 --- /dev/null +++ b/queue-6.6/tracing-limit-access-to-parser-buffer-when-trace_get_user-failed.patch @@ -0,0 +1,142 @@ +From stable+bounces-172737-greg=kroah.com@vger.kernel.org Sun Aug 24 15:39:23 2025 +From: Sasha Levin +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 , "Steven Rostedt (Google)" , Sasha Levin +Message-ID: <20250824133913.2897381-2-sashal@kernel.org> + +From: Pu Lehui + +[ 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 +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..96f40d8ca8 --- /dev/null +++ b/queue-6.6/tracing-remove-unneeded-goto-out-logic.patch @@ -0,0 +1,149 @@ +From stable+bounces-172736-greg=kroah.com@vger.kernel.org Sun Aug 24 15:39:20 2025 +From: Sasha Levin +Date: Sun, 24 Aug 2025 09:39:12 -0400 +Subject: tracing: Remove unneeded goto out logic +To: stable@vger.kernel.org +Cc: Steven Rostedt , Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Sasha Levin +Message-ID: <20250824133913.2897381-1-sashal@kernel.org> + +From: Steven Rostedt + +[ 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 +Cc: Mark Rutland +Cc: Mathieu Desnoyers +Cc: Andrew Morton +Link: https://lore.kernel.org/20250801203857.538726745@kernel.org +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..7411c50262 --- /dev/null +++ b/queue-6.6/usb-typec-maxim_contaminant-disable-low-power-mode-when-reading-comparator-values.patch @@ -0,0 +1,68 @@ +From stable+bounces-172763-greg=kroah.com@vger.kernel.org Sun Aug 24 20:33:19 2025 +From: Sasha Levin +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 , stable , Badhri Jagan Sridharan , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250824183312.795044-1-sashal@kernel.org> + +From: Amit Sunil Dhamne + +[ 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 +Signed-off-by: Amit Sunil Dhamne +Reviewed-by: Badhri Jagan Sridharan +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 +[ adapted macro names from CCLPMODESEL to CCLPMODESEL_MASK ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 + #include + #include + #include +@@ -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 index 0000000000..c27590de98 --- /dev/null +++ b/queue-6.6/usb-typec-maxim_contaminant-re-enable-cc-toggle-if-cc-is-open-and-port-is-clean.patch @@ -0,0 +1,117 @@ +From stable+bounces-172758-greg=kroah.com@vger.kernel.org Sun Aug 24 18:50:03 2025 +From: Sasha Levin +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 , stable , Badhri Jagan Sridharan , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250824164953.4152487-1-sashal@kernel.org> + +From: Amit Sunil Dhamne + +[ 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 +Signed-off-by: Amit Sunil Dhamne +Reviewed-by: Badhri Jagan Sridharan +Link: https://lore.kernel.org/r/20250815-fix-upstream-contaminant-v2-2-6c8d6c3adafb@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 0000000000..8fde09d732 --- /dev/null +++ b/queue-6.6/usb-xhci-fix-slot_id-resource-race-conflict.patch @@ -0,0 +1,227 @@ +From stable+bounces-172752-greg=kroah.com@vger.kernel.org Sun Aug 24 17:29:16 2025 +From: Sasha Levin +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 , Mathias Nyman , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20250824152904.3382917-1-sashal@kernel.org> + +From: Weitao Wang + +[ 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 +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20250819125844.2042452-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +[ Adjust context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + 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);