From: Greg Kroah-Hartman Date: Mon, 1 Jul 2024 14:04:53 +0000 (+0200) Subject: 6.9-stable patches X-Git-Tag: v4.19.317~91 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f0d856c415f332831bad884f25b3c3d22ef1f7ae;p=thirdparty%2Fkernel%2Fstable-queue.git 6.9-stable patches added patches: iio-accel-fxls8962af-select-iio_buffer-iio_kfifo_buf.patch iio-adc-ad7266-fix-variable-checking-bug.patch iio-chemical-bme680-fix-calibration-data-variable.patch iio-chemical-bme680-fix-overflows-in-compensate-functions.patch iio-chemical-bme680-fix-pressure-value-output.patch iio-chemical-bme680-fix-sensor-data-read-operation.patch iio-humidity-hdc3020-fix-hysteresis-representation.patch net-usb-ax88179_178a-improve-link-status-logs.patch revert-usb-gadget-u_ether-re-attach-netif-device-to-mirror-detachment.patch revert-usb-gadget-u_ether-replace-netif_stop_queue-with-netif_device_detach.patch usb-atm-cxacru-fix-endpoint-checking-in-cxacru_bind.patch usb-dwc3-core-remove-lock-of-otg-mode-during-gadget-suspend-resume-to-avoid-deadlock.patch usb-dwc3-core-workaround-for-csr-read-timeout.patch usb-gadget-aspeed_udc-fix-device-address-configuration.patch usb-gadget-printer-fix-races-against-disable.patch usb-gadget-printer-ss-support.patch usb-musb-da8xx-fix-a-resource-leak-in-probe.patch usb-typec-ucsi-glink-fix-child-node-release-in-probe-function.patch usb-ucsi-stm32-fix-command-completion-handling.patch --- diff --git a/queue-6.9/iio-accel-fxls8962af-select-iio_buffer-iio_kfifo_buf.patch b/queue-6.9/iio-accel-fxls8962af-select-iio_buffer-iio_kfifo_buf.patch new file mode 100644 index 00000000000..b621703fc46 --- /dev/null +++ b/queue-6.9/iio-accel-fxls8962af-select-iio_buffer-iio_kfifo_buf.patch @@ -0,0 +1,35 @@ +From a821d7111e3f7c8869961b606714a299bfe20014 Mon Sep 17 00:00:00 2001 +From: Alexander Sverdlin +Date: Wed, 5 Jun 2024 22:38:06 +0200 +Subject: iio: accel: fxls8962af: select IIO_BUFFER & IIO_KFIFO_BUF + +From: Alexander Sverdlin + +commit a821d7111e3f7c8869961b606714a299bfe20014 upstream. + +Provide missing symbols to the module: +ERROR: modpost: iio_push_to_buffers [drivers/iio/accel/fxls8962af-core.ko] undefined! +ERROR: modpost: devm_iio_kfifo_buffer_setup_ext [drivers/iio/accel/fxls8962af-core.ko] undefined! + +Cc: stable@vger.kernel.org +Fixes: 79e3a5bdd9ef ("iio: accel: fxls8962af: add hw buffered sampling") +Signed-off-by: Alexander Sverdlin +Reviewed-by: Sean Nyekjaer +Link: https://lore.kernel.org/r/20240605203810.2908980-2-alexander.sverdlin@siemens.com +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/accel/Kconfig | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/iio/accel/Kconfig ++++ b/drivers/iio/accel/Kconfig +@@ -330,6 +330,8 @@ config DMARD10 + config FXLS8962AF + tristate + depends on I2C || !I2C # cannot be built-in for modular I2C ++ select IIO_BUFFER ++ select IIO_KFIFO_BUF + + config FXLS8962AF_I2C + tristate "NXP FXLS8962AF/FXLS8964AF Accelerometer I2C Driver" diff --git a/queue-6.9/iio-adc-ad7266-fix-variable-checking-bug.patch b/queue-6.9/iio-adc-ad7266-fix-variable-checking-bug.patch new file mode 100644 index 00000000000..3e0652785d4 --- /dev/null +++ b/queue-6.9/iio-adc-ad7266-fix-variable-checking-bug.patch @@ -0,0 +1,33 @@ +From a2b86132955268b2a1703082fbc2d4832fc001b8 Mon Sep 17 00:00:00 2001 +From: Fernando Yang +Date: Mon, 3 Jun 2024 15:07:54 -0300 +Subject: iio: adc: ad7266: Fix variable checking bug + +From: Fernando Yang + +commit a2b86132955268b2a1703082fbc2d4832fc001b8 upstream. + +The ret variable was not checked after iio_device_release_direct_mode(), +which could possibly cause errors + +Fixes: c70df20e3159 ("iio: adc: ad7266: claim direct mode during sensor read") +Signed-off-by: Fernando Yang +Link: https://lore.kernel.org/r/20240603180757.8560-1-hagisf@usp.br +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/adc/ad7266.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/iio/adc/ad7266.c ++++ b/drivers/iio/adc/ad7266.c +@@ -157,6 +157,8 @@ static int ad7266_read_raw(struct iio_de + ret = ad7266_read_single(st, val, chan->address); + iio_device_release_direct_mode(indio_dev); + ++ if (ret < 0) ++ return ret; + *val = (*val >> 2) & 0xfff; + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, diff --git a/queue-6.9/iio-chemical-bme680-fix-calibration-data-variable.patch b/queue-6.9/iio-chemical-bme680-fix-calibration-data-variable.patch new file mode 100644 index 00000000000..0c4821a8097 --- /dev/null +++ b/queue-6.9/iio-chemical-bme680-fix-calibration-data-variable.patch @@ -0,0 +1,35 @@ +From b47c0fee73a810c4503c4a94ea34858a1d865bba Mon Sep 17 00:00:00 2001 +From: Vasileios Amoiridis +Date: Thu, 6 Jun 2024 23:22:54 +0200 +Subject: iio: chemical: bme680: Fix calibration data variable + +From: Vasileios Amoiridis + +commit b47c0fee73a810c4503c4a94ea34858a1d865bba upstream. + +According to the BME68x Sensor API [1], the h6 calibration +data variable should be an unsigned integer of size 8. + +[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x_defs.h#L789 + +Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor") +Signed-off-by: Vasileios Amoiridis +Link: https://lore.kernel.org/r/20240606212313.207550-3-vassilisamir@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/bme680_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/chemical/bme680_core.c ++++ b/drivers/iio/chemical/bme680_core.c +@@ -38,7 +38,7 @@ struct bme680_calib { + s8 par_h3; + s8 par_h4; + s8 par_h5; +- s8 par_h6; ++ u8 par_h6; + s8 par_h7; + s8 par_gh1; + s16 par_gh2; diff --git a/queue-6.9/iio-chemical-bme680-fix-overflows-in-compensate-functions.patch b/queue-6.9/iio-chemical-bme680-fix-overflows-in-compensate-functions.patch new file mode 100644 index 00000000000..53b57d31f08 --- /dev/null +++ b/queue-6.9/iio-chemical-bme680-fix-overflows-in-compensate-functions.patch @@ -0,0 +1,72 @@ +From fdd478c3ae98c3f13628e110dce9b6cfb0d9b3c8 Mon Sep 17 00:00:00 2001 +From: Vasileios Amoiridis +Date: Thu, 6 Jun 2024 23:22:55 +0200 +Subject: iio: chemical: bme680: Fix overflows in compensate() functions + +From: Vasileios Amoiridis + +commit fdd478c3ae98c3f13628e110dce9b6cfb0d9b3c8 upstream. + +There are cases in the compensate functions of the driver that +there could be overflows of variables due to bit shifting ops. +These implications were initially discussed here [1] and they +were mentioned in log message of Commit 1b3bd8592780 ("iio: +chemical: Add support for Bosch BME680 sensor"). + +[1]: https://lore.kernel.org/linux-iio/20180728114028.3c1bbe81@archlinux/ + +Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor") +Signed-off-by: Vasileios Amoiridis +Link: https://lore.kernel.org/r/20240606212313.207550-4-vassilisamir@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/bme680_core.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/iio/chemical/bme680_core.c ++++ b/drivers/iio/chemical/bme680_core.c +@@ -342,10 +342,10 @@ static s16 bme680_compensate_temp(struct + if (!calib->par_t2) + bme680_read_calib(data, calib); + +- var1 = (adc_temp >> 3) - (calib->par_t1 << 1); ++ var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1); + var2 = (var1 * calib->par_t2) >> 11; + var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; +- var3 = (var3 * (calib->par_t3 << 4)) >> 14; ++ var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14; + data->t_fine = var2 + var3; + calc_temp = (data->t_fine * 5 + 128) >> 8; + +@@ -368,9 +368,9 @@ static u32 bme680_compensate_press(struc + var1 = (data->t_fine >> 1) - 64000; + var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2; + var2 = var2 + (var1 * calib->par_p5 << 1); +- var2 = (var2 >> 2) + (calib->par_p4 << 16); ++ var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16); + var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * +- (calib->par_p3 << 5)) >> 3) + ++ ((s32)calib->par_p3 << 5)) >> 3) + + ((calib->par_p2 * var1) >> 1); + var1 = var1 >> 18; + var1 = ((32768 + var1) * calib->par_p1) >> 15; +@@ -388,7 +388,7 @@ static u32 bme680_compensate_press(struc + var3 = ((press_comp >> 8) * (press_comp >> 8) * + (press_comp >> 8) * calib->par_p10) >> 17; + +- press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4; ++ press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4; + + return press_comp; + } +@@ -414,7 +414,7 @@ static u32 bme680_compensate_humid(struc + (((temp_scaled * ((temp_scaled * calib->par_h5) / 100)) + >> 6) / 100) + (1 << 14))) >> 10; + var3 = var1 * var2; +- var4 = calib->par_h6 << 7; ++ var4 = (s32)calib->par_h6 << 7; + var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4; + var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; + var6 = (var4 * var5) >> 1; diff --git a/queue-6.9/iio-chemical-bme680-fix-pressure-value-output.patch b/queue-6.9/iio-chemical-bme680-fix-pressure-value-output.patch new file mode 100644 index 00000000000..795c29509d9 --- /dev/null +++ b/queue-6.9/iio-chemical-bme680-fix-pressure-value-output.patch @@ -0,0 +1,38 @@ +From ae1f7b93b52095be6776d0f34957b4f35dda44d9 Mon Sep 17 00:00:00 2001 +From: Vasileios Amoiridis +Date: Thu, 6 Jun 2024 23:22:53 +0200 +Subject: iio: chemical: bme680: Fix pressure value output + +From: Vasileios Amoiridis + +commit ae1f7b93b52095be6776d0f34957b4f35dda44d9 upstream. + +The IIO standard units are measured in kPa while the driver +is using hPa. + +Apart from checking the userspace value itself, it is mentioned also +in the Bosch API [1] that the pressure value is in Pascal. + +[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x_defs.h#L742 + +Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor") +Signed-off-by: Vasileios Amoiridis +Link: https://lore.kernel.org/r/20240606212313.207550-2-vassilisamir@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/bme680_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iio/chemical/bme680_core.c ++++ b/drivers/iio/chemical/bme680_core.c +@@ -678,7 +678,7 @@ static int bme680_read_press(struct bme6 + } + + *val = bme680_compensate_press(data, adc_press); +- *val2 = 100; ++ *val2 = 1000; + return IIO_VAL_FRACTIONAL; + } + diff --git a/queue-6.9/iio-chemical-bme680-fix-sensor-data-read-operation.patch b/queue-6.9/iio-chemical-bme680-fix-sensor-data-read-operation.patch new file mode 100644 index 00000000000..c322746a901 --- /dev/null +++ b/queue-6.9/iio-chemical-bme680-fix-sensor-data-read-operation.patch @@ -0,0 +1,138 @@ +From 4241665e6ea063a9c1d734de790121a71db763fc Mon Sep 17 00:00:00 2001 +From: Vasileios Amoiridis +Date: Thu, 6 Jun 2024 23:22:56 +0200 +Subject: iio: chemical: bme680: Fix sensor data read operation + +From: Vasileios Amoiridis + +commit 4241665e6ea063a9c1d734de790121a71db763fc upstream. + +A read operation is happening as follows: + +a) Set sensor to forced mode +b) Sensor measures values and update data registers and sleeps again +c) Read data registers + +In the current implementation the read operation happens immediately +after the sensor is set to forced mode so the sensor does not have +the time to update properly the registers. This leads to the following +2 problems: + +1) The first ever value which is read by the register is always wrong +2) Every read operation, puts the register into forced mode and reads +the data that were calculated in the previous conversion. + +This behaviour was tested in 2 ways: + +1) The internal meas_status_0 register was read before and after every +read operation in order to verify that the data were ready even before +the register was set to forced mode and also to check that after the +forced mode was set the new data were not yet ready. + +2) Physically changing the temperature and measuring the temperature + +This commit adds the waiting time in between the set of the forced mode +and the read of the data. The function is taken from the Bosch BME68x +Sensor API [1]. + +[1]: https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 + +Fixes: 1b3bd8592780 ("iio: chemical: Add support for Bosch BME680 sensor") +Signed-off-by: Vasileios Amoiridis +Link: https://lore.kernel.org/r/20240606212313.207550-5-vassilisamir@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/chemical/bme680.h | 2 + + drivers/iio/chemical/bme680_core.c | 46 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+) + +--- a/drivers/iio/chemical/bme680.h ++++ b/drivers/iio/chemical/bme680.h +@@ -54,7 +54,9 @@ + #define BME680_NB_CONV_MASK GENMASK(3, 0) + + #define BME680_REG_MEAS_STAT_0 0x1D ++#define BME680_NEW_DATA_BIT BIT(7) + #define BME680_GAS_MEAS_BIT BIT(6) ++#define BME680_MEAS_BIT BIT(5) + + /* Calibration Parameters */ + #define BME680_T2_LSB_REG 0x8A +--- a/drivers/iio/chemical/bme680_core.c ++++ b/drivers/iio/chemical/bme680_core.c +@@ -10,6 +10,7 @@ + */ + #include + #include ++#include + #include + #include + #include +@@ -532,6 +533,43 @@ static u8 bme680_oversampling_to_reg(u8 + return ilog2(val) + 1; + } + ++/* ++ * Taken from Bosch BME680 API: ++ * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 ++ */ ++static int bme680_wait_for_eoc(struct bme680_data *data) ++{ ++ struct device *dev = regmap_get_device(data->regmap); ++ unsigned int check; ++ int ret; ++ /* ++ * (Sum of oversampling ratios * time per oversampling) + ++ * TPH measurement + gas measurement + wait transition from forced mode ++ * + heater duration ++ */ ++ int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press + ++ data->oversampling_humid) * 1936) + (477 * 4) + ++ (477 * 5) + 1000 + (data->heater_dur * 1000); ++ ++ usleep_range(wait_eoc_us, wait_eoc_us + 100); ++ ++ ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); ++ if (ret) { ++ dev_err(dev, "failed to read measurement status register.\n"); ++ return ret; ++ } ++ if (check & BME680_MEAS_BIT) { ++ dev_err(dev, "Device measurement cycle incomplete.\n"); ++ return -EBUSY; ++ } ++ if (!(check & BME680_NEW_DATA_BIT)) { ++ dev_err(dev, "No new data available from the device.\n"); ++ return -ENODATA; ++ } ++ ++ return 0; ++} ++ + static int bme680_chip_config(struct bme680_data *data) + { + struct device *dev = regmap_get_device(data->regmap); +@@ -622,6 +660,10 @@ static int bme680_read_temp(struct bme68 + if (ret < 0) + return ret; + ++ ret = bme680_wait_for_eoc(data); ++ if (ret) ++ return ret; ++ + ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB, + &tmp, 3); + if (ret < 0) { +@@ -738,6 +780,10 @@ static int bme680_read_gas(struct bme680 + if (ret < 0) + return ret; + ++ ret = bme680_wait_for_eoc(data); ++ if (ret) ++ return ret; ++ + ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); + if (check & BME680_GAS_MEAS_BIT) { + dev_err(dev, "gas measurement incomplete\n"); diff --git a/queue-6.9/iio-humidity-hdc3020-fix-hysteresis-representation.patch b/queue-6.9/iio-humidity-hdc3020-fix-hysteresis-representation.patch new file mode 100644 index 00000000000..cee3d248d4e --- /dev/null +++ b/queue-6.9/iio-humidity-hdc3020-fix-hysteresis-representation.patch @@ -0,0 +1,423 @@ +From 9547d6a4c65e975e40e203900322342ef7379c52 Mon Sep 17 00:00:00 2001 +From: Dimitri Fedrau +Date: Wed, 5 Jun 2024 21:21:35 +0200 +Subject: iio: humidity: hdc3020: fix hysteresis representation + +From: Dimitri Fedrau + +commit 9547d6a4c65e975e40e203900322342ef7379c52 upstream. + +According to the ABI docs hysteresis values are represented as offsets to +threshold values. Current implementation represents hysteresis values as +absolute values which is wrong. Nevertheless the device stores them as +absolute values and the datasheet refers to them as clear thresholds. Fix +the reading and writing of hysteresis values by including thresholds into +calculations. Hysteresis values that result in threshold clear values +that are out of limits will be truncated. + +To check that the threshold clear values are correct, registers are read +out using i2ctransfer and the corresponding temperature and relative +humidity thresholds are calculated using the formulas in the datasheet. + +Fixes: 3ad0e7e5f0cb ("iio: humidity: hdc3020: add threshold events support") +Signed-off-by: Dimitri Fedrau +Reviewed-by: Javier Carrasco +Link: https://lore.kernel.org/r/20240605192136.38146-1-dima.fedrau@gmail.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/iio/humidity/hdc3020.c | 325 +++++++++++++++++++++++++++++++---------- + 1 file changed, 249 insertions(+), 76 deletions(-) + +--- a/drivers/iio/humidity/hdc3020.c ++++ b/drivers/iio/humidity/hdc3020.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -63,8 +64,10 @@ + + #define HDC3020_CRC8_POLYNOMIAL 0x31 + +-#define HDC3020_MIN_TEMP -40 +-#define HDC3020_MAX_TEMP 125 ++#define HDC3020_MIN_TEMP_MICRO -39872968 ++#define HDC3020_MAX_TEMP_MICRO 124875639 ++#define HDC3020_MAX_TEMP_HYST_MICRO 164748607 ++#define HDC3020_MAX_HUM_MICRO 99220264 + + struct hdc3020_data { + struct i2c_client *client; +@@ -363,6 +366,105 @@ static int hdc3020_write_raw(struct iio_ + return -EINVAL; + } + ++static int hdc3020_thresh_get_temp(u16 thresh) ++{ ++ int temp; ++ ++ /* ++ * Get the temperature threshold from 9 LSBs, shift them to get ++ * the truncated temperature threshold representation and ++ * calculate the threshold according to the formula in the ++ * datasheet. Result is degree celsius scaled by 65535. ++ */ ++ temp = FIELD_GET(HDC3020_THRESH_TEMP_MASK, thresh) << ++ HDC3020_THRESH_TEMP_TRUNC_SHIFT; ++ ++ return -2949075 + (175 * temp); ++} ++ ++static int hdc3020_thresh_get_hum(u16 thresh) ++{ ++ int hum; ++ ++ /* ++ * Get the humidity threshold from 7 MSBs, shift them to get the ++ * truncated humidity threshold representation and calculate the ++ * threshold according to the formula in the datasheet. Result is ++ * percent scaled by 65535. ++ */ ++ hum = FIELD_GET(HDC3020_THRESH_HUM_MASK, thresh) << ++ HDC3020_THRESH_HUM_TRUNC_SHIFT; ++ ++ return hum * 100; ++} ++ ++static u16 hdc3020_thresh_set_temp(int s_temp, u16 curr_thresh) ++{ ++ u64 temp; ++ u16 thresh; ++ ++ /* ++ * Calculate temperature threshold, shift it down to get the ++ * truncated threshold representation in the 9LSBs while keeping ++ * the current humidity threshold in the 7 MSBs. ++ */ ++ temp = (u64)(s_temp + 45000000) * 65535ULL; ++ temp = div_u64(temp, 1000000 * 175) >> HDC3020_THRESH_TEMP_TRUNC_SHIFT; ++ thresh = FIELD_PREP(HDC3020_THRESH_TEMP_MASK, temp); ++ thresh |= (FIELD_GET(HDC3020_THRESH_HUM_MASK, curr_thresh) << ++ HDC3020_THRESH_HUM_TRUNC_SHIFT); ++ ++ return thresh; ++} ++ ++static u16 hdc3020_thresh_set_hum(int s_hum, u16 curr_thresh) ++{ ++ u64 hum; ++ u16 thresh; ++ ++ /* ++ * Calculate humidity threshold, shift it down and up to get the ++ * truncated threshold representation in the 7MSBs while keeping ++ * the current temperature threshold in the 9 LSBs. ++ */ ++ hum = (u64)(s_hum) * 65535ULL; ++ hum = div_u64(hum, 1000000 * 100) >> HDC3020_THRESH_HUM_TRUNC_SHIFT; ++ thresh = FIELD_PREP(HDC3020_THRESH_HUM_MASK, hum); ++ thresh |= FIELD_GET(HDC3020_THRESH_TEMP_MASK, curr_thresh); ++ ++ return thresh; ++} ++ ++static ++int hdc3020_thresh_clr(s64 s_thresh, s64 s_hyst, enum iio_event_direction dir) ++{ ++ s64 s_clr; ++ ++ /* ++ * Include directions when calculation the clear value, ++ * since hysteresis is unsigned by definition and the ++ * clear value is an absolute value which is signed. ++ */ ++ if (dir == IIO_EV_DIR_RISING) ++ s_clr = s_thresh - s_hyst; ++ else ++ s_clr = s_thresh + s_hyst; ++ ++ /* Divide by 65535 to get units of micro */ ++ return div_s64(s_clr, 65535); ++} ++ ++static int _hdc3020_write_thresh(struct hdc3020_data *data, u16 reg, u16 val) ++{ ++ u8 buf[5]; ++ ++ put_unaligned_be16(reg, buf); ++ put_unaligned_be16(val, buf + 2); ++ buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); ++ ++ return hdc3020_write_bytes(data, buf, 5); ++} ++ + static int hdc3020_write_thresh(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, +@@ -371,67 +473,126 @@ static int hdc3020_write_thresh(struct i + int val, int val2) + { + struct hdc3020_data *data = iio_priv(indio_dev); +- u8 buf[5]; +- u64 tmp; +- u16 reg; +- int ret; +- +- /* Supported temperature range is from –40 to 125 degree celsius */ +- if (val < HDC3020_MIN_TEMP || val > HDC3020_MAX_TEMP) +- return -EINVAL; +- +- /* Select threshold register */ +- if (info == IIO_EV_INFO_VALUE) { +- if (dir == IIO_EV_DIR_RISING) +- reg = HDC3020_S_T_RH_THRESH_HIGH; +- else +- reg = HDC3020_S_T_RH_THRESH_LOW; ++ u16 reg, reg_val, reg_thresh_rd, reg_clr_rd, reg_thresh_wr, reg_clr_wr; ++ s64 s_thresh, s_hyst, s_clr; ++ int s_val, thresh, clr, ret; ++ ++ /* Select threshold registers */ ++ if (dir == IIO_EV_DIR_RISING) { ++ reg_thresh_rd = HDC3020_R_T_RH_THRESH_HIGH; ++ reg_thresh_wr = HDC3020_S_T_RH_THRESH_HIGH; ++ reg_clr_rd = HDC3020_R_T_RH_THRESH_HIGH_CLR; ++ reg_clr_wr = HDC3020_S_T_RH_THRESH_HIGH_CLR; + } else { +- if (dir == IIO_EV_DIR_RISING) +- reg = HDC3020_S_T_RH_THRESH_HIGH_CLR; +- else +- reg = HDC3020_S_T_RH_THRESH_LOW_CLR; ++ reg_thresh_rd = HDC3020_R_T_RH_THRESH_LOW; ++ reg_thresh_wr = HDC3020_S_T_RH_THRESH_LOW; ++ reg_clr_rd = HDC3020_R_T_RH_THRESH_LOW_CLR; ++ reg_clr_wr = HDC3020_S_T_RH_THRESH_LOW_CLR; + } + + guard(mutex)(&data->lock); +- ret = hdc3020_read_be16(data, reg); ++ ret = hdc3020_read_be16(data, reg_thresh_rd); + if (ret < 0) + return ret; + ++ thresh = ret; ++ ret = hdc3020_read_be16(data, reg_clr_rd); ++ if (ret < 0) ++ return ret; ++ ++ clr = ret; ++ /* Scale value to include decimal part into calculations */ ++ s_val = (val < 0) ? (val * 1000000 - val2) : (val * 1000000 + val2); + switch (chan->type) { + case IIO_TEMP: +- /* +- * Calculate temperature threshold, shift it down to get the +- * truncated threshold representation in the 9LSBs while keeping +- * the current humidity threshold in the 7 MSBs. +- */ +- tmp = ((u64)(((val + 45) * MICRO) + val2)) * 65535ULL; +- tmp = div_u64(tmp, MICRO * 175); +- val = tmp >> HDC3020_THRESH_TEMP_TRUNC_SHIFT; +- val = FIELD_PREP(HDC3020_THRESH_TEMP_MASK, val); +- val |= (FIELD_GET(HDC3020_THRESH_HUM_MASK, ret) << +- HDC3020_THRESH_HUM_TRUNC_SHIFT); ++ switch (info) { ++ case IIO_EV_INFO_VALUE: ++ s_val = max(s_val, HDC3020_MIN_TEMP_MICRO); ++ s_val = min(s_val, HDC3020_MAX_TEMP_MICRO); ++ reg = reg_thresh_wr; ++ reg_val = hdc3020_thresh_set_temp(s_val, thresh); ++ ret = _hdc3020_write_thresh(data, reg, reg_val); ++ if (ret < 0) ++ return ret; ++ ++ /* Calculate old hysteresis */ ++ s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000; ++ s_clr = (s64)hdc3020_thresh_get_temp(clr) * 1000000; ++ s_hyst = div_s64(abs(s_thresh - s_clr), 65535); ++ /* Set new threshold */ ++ thresh = reg_val; ++ /* Set old hysteresis */ ++ s_val = s_hyst; ++ fallthrough; ++ case IIO_EV_INFO_HYSTERESIS: ++ /* ++ * Function hdc3020_thresh_get_temp returns temperature ++ * in degree celsius scaled by 65535. Scale by 1000000 ++ * to be able to subtract scaled hysteresis value. ++ */ ++ s_thresh = (s64)hdc3020_thresh_get_temp(thresh) * 1000000; ++ /* ++ * Units of s_val are in micro degree celsius, scale by ++ * 65535 to get same units as s_thresh. ++ */ ++ s_val = min(abs(s_val), HDC3020_MAX_TEMP_HYST_MICRO); ++ s_hyst = (s64)s_val * 65535; ++ s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir); ++ s_clr = max(s_clr, HDC3020_MIN_TEMP_MICRO); ++ s_clr = min(s_clr, HDC3020_MAX_TEMP_MICRO); ++ reg = reg_clr_wr; ++ reg_val = hdc3020_thresh_set_temp(s_clr, clr); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } + break; + case IIO_HUMIDITYRELATIVE: +- /* +- * Calculate humidity threshold, shift it down and up to get the +- * truncated threshold representation in the 7MSBs while keeping +- * the current temperature threshold in the 9 LSBs. +- */ +- tmp = ((u64)((val * MICRO) + val2)) * 65535ULL; +- tmp = div_u64(tmp, MICRO * 100); +- val = tmp >> HDC3020_THRESH_HUM_TRUNC_SHIFT; +- val = FIELD_PREP(HDC3020_THRESH_HUM_MASK, val); +- val |= FIELD_GET(HDC3020_THRESH_TEMP_MASK, ret); ++ s_val = (s_val < 0) ? 0 : min(s_val, HDC3020_MAX_HUM_MICRO); ++ switch (info) { ++ case IIO_EV_INFO_VALUE: ++ reg = reg_thresh_wr; ++ reg_val = hdc3020_thresh_set_hum(s_val, thresh); ++ ret = _hdc3020_write_thresh(data, reg, reg_val); ++ if (ret < 0) ++ return ret; ++ ++ /* Calculate old hysteresis */ ++ s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000; ++ s_clr = (s64)hdc3020_thresh_get_hum(clr) * 1000000; ++ s_hyst = div_s64(abs(s_thresh - s_clr), 65535); ++ /* Set new threshold */ ++ thresh = reg_val; ++ /* Try to set old hysteresis */ ++ s_val = min(abs(s_hyst), HDC3020_MAX_HUM_MICRO); ++ fallthrough; ++ case IIO_EV_INFO_HYSTERESIS: ++ /* ++ * Function hdc3020_thresh_get_hum returns relative ++ * humidity in percent scaled by 65535. Scale by 1000000 ++ * to be able to subtract scaled hysteresis value. ++ */ ++ s_thresh = (s64)hdc3020_thresh_get_hum(thresh) * 1000000; ++ /* ++ * Units of s_val are in micro percent, scale by 65535 ++ * to get same units as s_thresh. ++ */ ++ s_hyst = (s64)s_val * 65535; ++ s_clr = hdc3020_thresh_clr(s_thresh, s_hyst, dir); ++ s_clr = max(s_clr, 0); ++ s_clr = min(s_clr, HDC3020_MAX_HUM_MICRO); ++ reg = reg_clr_wr; ++ reg_val = hdc3020_thresh_set_hum(s_clr, clr); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } + break; + default: + return -EOPNOTSUPP; + } + +- put_unaligned_be16(reg, buf); +- put_unaligned_be16(val, buf + 2); +- buf[4] = crc8(hdc3020_crc8_table, buf + 2, 2, CRC8_INIT_VALUE); +- return hdc3020_write_bytes(data, buf, 5); ++ return _hdc3020_write_thresh(data, reg, reg_val); + } + + static int hdc3020_read_thresh(struct iio_dev *indio_dev, +@@ -442,48 +603,60 @@ static int hdc3020_read_thresh(struct ii + int *val, int *val2) + { + struct hdc3020_data *data = iio_priv(indio_dev); +- u16 reg; +- int ret; ++ u16 reg_thresh, reg_clr; ++ int thresh, clr, ret; + +- /* Select threshold register */ +- if (info == IIO_EV_INFO_VALUE) { +- if (dir == IIO_EV_DIR_RISING) +- reg = HDC3020_R_T_RH_THRESH_HIGH; +- else +- reg = HDC3020_R_T_RH_THRESH_LOW; ++ /* Select threshold registers */ ++ if (dir == IIO_EV_DIR_RISING) { ++ reg_thresh = HDC3020_R_T_RH_THRESH_HIGH; ++ reg_clr = HDC3020_R_T_RH_THRESH_HIGH_CLR; + } else { +- if (dir == IIO_EV_DIR_RISING) +- reg = HDC3020_R_T_RH_THRESH_HIGH_CLR; +- else +- reg = HDC3020_R_T_RH_THRESH_LOW_CLR; ++ reg_thresh = HDC3020_R_T_RH_THRESH_LOW; ++ reg_clr = HDC3020_R_T_RH_THRESH_LOW_CLR; + } + + guard(mutex)(&data->lock); +- ret = hdc3020_read_be16(data, reg); ++ ret = hdc3020_read_be16(data, reg_thresh); + if (ret < 0) + return ret; + + switch (chan->type) { + case IIO_TEMP: +- /* +- * Get the temperature threshold from 9 LSBs, shift them to get +- * the truncated temperature threshold representation and +- * calculate the threshold according to the formula in the +- * datasheet. +- */ +- *val = FIELD_GET(HDC3020_THRESH_TEMP_MASK, ret); +- *val = *val << HDC3020_THRESH_TEMP_TRUNC_SHIFT; +- *val = -2949075 + (175 * (*val)); ++ thresh = hdc3020_thresh_get_temp(ret); ++ switch (info) { ++ case IIO_EV_INFO_VALUE: ++ *val = thresh; ++ break; ++ case IIO_EV_INFO_HYSTERESIS: ++ ret = hdc3020_read_be16(data, reg_clr); ++ if (ret < 0) ++ return ret; ++ ++ clr = hdc3020_thresh_get_temp(ret); ++ *val = abs(thresh - clr); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } + *val2 = 65535; + return IIO_VAL_FRACTIONAL; + case IIO_HUMIDITYRELATIVE: +- /* +- * Get the humidity threshold from 7 MSBs, shift them to get the +- * truncated humidity threshold representation and calculate the +- * threshold according to the formula in the datasheet. +- */ +- *val = FIELD_GET(HDC3020_THRESH_HUM_MASK, ret); +- *val = (*val << HDC3020_THRESH_HUM_TRUNC_SHIFT) * 100; ++ thresh = hdc3020_thresh_get_hum(ret); ++ switch (info) { ++ case IIO_EV_INFO_VALUE: ++ *val = thresh; ++ break; ++ case IIO_EV_INFO_HYSTERESIS: ++ ret = hdc3020_read_be16(data, reg_clr); ++ if (ret < 0) ++ return ret; ++ ++ clr = hdc3020_thresh_get_hum(ret); ++ *val = abs(thresh - clr); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } + *val2 = 65535; + return IIO_VAL_FRACTIONAL; + default: diff --git a/queue-6.9/net-usb-ax88179_178a-improve-link-status-logs.patch b/queue-6.9/net-usb-ax88179_178a-improve-link-status-logs.patch new file mode 100644 index 00000000000..8e0701743b1 --- /dev/null +++ b/queue-6.9/net-usb-ax88179_178a-improve-link-status-logs.patch @@ -0,0 +1,57 @@ +From 058722ee350c0bdd664e467156feb2bf5d9cc271 Mon Sep 17 00:00:00 2001 +From: Jose Ignacio Tornos Martinez +Date: Thu, 20 Jun 2024 15:34:31 +0200 +Subject: net: usb: ax88179_178a: improve link status logs + +From: Jose Ignacio Tornos Martinez + +commit 058722ee350c0bdd664e467156feb2bf5d9cc271 upstream. + +Avoid spurious link status logs that may ultimately be wrong; for example, +if the link is set to down with the cable plugged, then the cable is +unplugged and after this the link is set to up, the last new log that is +appearing is incorrectly telling that the link is up. + +In order to avoid errors, show link status logs after link_reset +processing, and in order to avoid spurious as much as possible, only show +the link loss when some link status change is detected. + +cc: stable@vger.kernel.org +Fixes: e2ca90c276e1 ("ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver") +Signed-off-by: Jose Ignacio Tornos Martinez +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/ax88179_178a.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/usb/ax88179_178a.c ++++ b/drivers/net/usb/ax88179_178a.c +@@ -326,7 +326,8 @@ static void ax88179_status(struct usbnet + + if (netif_carrier_ok(dev->net) != link) { + usbnet_link_change(dev, link, 1); +- netdev_info(dev->net, "ax88179 - Link status is: %d\n", link); ++ if (!link) ++ netdev_info(dev->net, "ax88179 - Link status is: 0\n"); + } + } + +@@ -1540,6 +1541,7 @@ static int ax88179_link_reset(struct usb + GMII_PHY_PHYSR, 2, &tmp16); + + if (!(tmp16 & GMII_PHY_PHYSR_LINK)) { ++ netdev_info(dev->net, "ax88179 - Link status is: 0\n"); + return 0; + } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) { + mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ; +@@ -1577,6 +1579,8 @@ static int ax88179_link_reset(struct usb + + netif_carrier_on(dev->net); + ++ netdev_info(dev->net, "ax88179 - Link status is: 1\n"); ++ + return 0; + } + diff --git a/queue-6.9/revert-usb-gadget-u_ether-re-attach-netif-device-to-mirror-detachment.patch b/queue-6.9/revert-usb-gadget-u_ether-re-attach-netif-device-to-mirror-detachment.patch new file mode 100644 index 00000000000..5012ece53da --- /dev/null +++ b/queue-6.9/revert-usb-gadget-u_ether-re-attach-netif-device-to-mirror-detachment.patch @@ -0,0 +1,35 @@ +From 24bf27b92b1c6a322faa88977de2207aa8c26509 Mon Sep 17 00:00:00 2001 +From: Ferry Toth +Date: Thu, 20 Jun 2024 22:46:41 +0200 +Subject: Revert "usb: gadget: u_ether: Re-attach netif device to mirror detachment" + +From: Ferry Toth + +commit 24bf27b92b1c6a322faa88977de2207aa8c26509 upstream. + +This reverts commit 76c945730cdffb572c7767073cc6515fd3f646b4. + +Prerequisite revert for the reverting of the original commit f49449fbc21e. + +Fixes: 76c945730cdf ("usb: gadget: u_ether: Re-attach netif device to mirror detachment") +Fixes: f49449fbc21e ("usb: gadget: u_ether: Replace netif_stop_queue with netif_device_detach") +Reported-by: Ferry Toth +Cc: stable@vger.kernel.org +Signed-off-by: Ferry Toth +Link: https://lore.kernel.org/r/20240620204832.24518-2-ftoth@exalondelft.nl +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/u_ether.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -1163,8 +1163,6 @@ struct net_device *gether_connect(struct + if (netif_running(dev->net)) + eth_start(dev, GFP_ATOMIC); + +- netif_device_attach(dev->net); +- + /* on error, disable any endpoints */ + } else { + (void) usb_ep_disable(link->out_ep); diff --git a/queue-6.9/revert-usb-gadget-u_ether-replace-netif_stop_queue-with-netif_device_detach.patch b/queue-6.9/revert-usb-gadget-u_ether-replace-netif_stop_queue-with-netif_device_detach.patch new file mode 100644 index 00000000000..62c31a77060 --- /dev/null +++ b/queue-6.9/revert-usb-gadget-u_ether-replace-netif_stop_queue-with-netif_device_detach.patch @@ -0,0 +1,44 @@ +From c50814a288dcee687285abc0cf935e9fe8928e59 Mon Sep 17 00:00:00 2001 +From: Ferry Toth +Date: Thu, 20 Jun 2024 22:46:42 +0200 +Subject: Revert "usb: gadget: u_ether: Replace netif_stop_queue with netif_device_detach" + +From: Ferry Toth + +commit c50814a288dcee687285abc0cf935e9fe8928e59 upstream. + +This reverts commit f49449fbc21e7e9550a5203902d69c8ae7dfd918. + +This commit breaks u_ether on some setups (at least Merrifield). The fix +"usb: gadget: u_ether: Re-attach netif device to mirror detachment" party +restores u-ether. However the netif usb: remains up even usb is switched +from device to host mode. This creates problems for user space as the +interface remains in the routing table while not realy present and network +managers (connman) not detecting a network change. + +Various attempts to find the root cause were unsuccesful up to now. Therefore +revert until a solution is found. + +Link: https://lore.kernel.org/linux-usb/20231006141231.7220-1-hgajjar@de.adit-jv.com/ +Reported-by: Andy Shevchenko +Reported-by: Ferry Toth +Fixes: f49449fbc21e ("usb: gadget: u_ether: Replace netif_stop_queue with netif_device_detach") +Cc: stable@vger.kernel.org +Signed-off-by: Ferry Toth +Link: https://lore.kernel.org/r/20240620204832.24518-3-ftoth@exalondelft.nl +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/u_ether.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/function/u_ether.c ++++ b/drivers/usb/gadget/function/u_ether.c +@@ -1200,7 +1200,7 @@ void gether_disconnect(struct gether *li + + DBG(dev, "%s\n", __func__); + +- netif_device_detach(dev->net); ++ netif_stop_queue(dev->net); + netif_carrier_off(dev->net); + + /* disable endpoints, forcing (synchronous) completion diff --git a/queue-6.9/series b/queue-6.9/series index 30580a2ff0a..913c627fa48 100644 --- a/queue-6.9/series +++ b/queue-6.9/series @@ -134,3 +134,22 @@ i2c-testunit-don-t-erase-registers-after-stop.patch i2c-testunit-discard-write-requests-while-old-comman.patch ata-libata-core-fix-null-pointer-dereference-on-erro.patch ata-scsi-libata-core-do-not-leak-memory-for-ata_port.patch +iio-humidity-hdc3020-fix-hysteresis-representation.patch +iio-adc-ad7266-fix-variable-checking-bug.patch +iio-accel-fxls8962af-select-iio_buffer-iio_kfifo_buf.patch +iio-chemical-bme680-fix-pressure-value-output.patch +iio-chemical-bme680-fix-calibration-data-variable.patch +iio-chemical-bme680-fix-overflows-in-compensate-functions.patch +iio-chemical-bme680-fix-sensor-data-read-operation.patch +net-usb-ax88179_178a-improve-link-status-logs.patch +usb-gadget-printer-ss-support.patch +usb-gadget-printer-fix-races-against-disable.patch +usb-musb-da8xx-fix-a-resource-leak-in-probe.patch +usb-atm-cxacru-fix-endpoint-checking-in-cxacru_bind.patch +usb-dwc3-core-remove-lock-of-otg-mode-during-gadget-suspend-resume-to-avoid-deadlock.patch +usb-gadget-aspeed_udc-fix-device-address-configuration.patch +usb-typec-ucsi-glink-fix-child-node-release-in-probe-function.patch +revert-usb-gadget-u_ether-re-attach-netif-device-to-mirror-detachment.patch +revert-usb-gadget-u_ether-replace-netif_stop_queue-with-netif_device_detach.patch +usb-ucsi-stm32-fix-command-completion-handling.patch +usb-dwc3-core-workaround-for-csr-read-timeout.patch diff --git a/queue-6.9/usb-atm-cxacru-fix-endpoint-checking-in-cxacru_bind.patch b/queue-6.9/usb-atm-cxacru-fix-endpoint-checking-in-cxacru_bind.patch new file mode 100644 index 00000000000..455b6c1af54 --- /dev/null +++ b/queue-6.9/usb-atm-cxacru-fix-endpoint-checking-in-cxacru_bind.patch @@ -0,0 +1,88 @@ +From 2eabb655a968b862bc0c31629a09f0fbf3c80d51 Mon Sep 17 00:00:00 2001 +From: Nikita Zhandarovich +Date: Sun, 9 Jun 2024 06:15:46 -0700 +Subject: usb: atm: cxacru: fix endpoint checking in cxacru_bind() + +From: Nikita Zhandarovich + +commit 2eabb655a968b862bc0c31629a09f0fbf3c80d51 upstream. + +Syzbot is still reporting quite an old issue [1] that occurs due to +incomplete checking of present usb endpoints. As such, wrong +endpoints types may be used at urb sumbitting stage which in turn +triggers a warning in usb_submit_urb(). + +Fix the issue by verifying that required endpoint types are present +for both in and out endpoints, taking into account cmd endpoint type. + +Unfortunately, this patch has not been tested on real hardware. + +[1] Syzbot report: +usb 1-1: BOGUS urb xfer, pipe 1 != type 3 +WARNING: CPU: 0 PID: 8667 at drivers/usb/core/urb.c:502 usb_submit_urb+0xed2/0x18a0 drivers/usb/core/urb.c:502 +Modules linked in: +CPU: 0 PID: 8667 Comm: kworker/0:4 Not tainted 5.14.0-rc4-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Workqueue: usb_hub_wq hub_event +RIP: 0010:usb_submit_urb+0xed2/0x18a0 drivers/usb/core/urb.c:502 +... +Call Trace: + cxacru_cm+0x3c0/0x8e0 drivers/usb/atm/cxacru.c:649 + cxacru_card_status+0x22/0xd0 drivers/usb/atm/cxacru.c:760 + cxacru_bind+0x7ac/0x11a0 drivers/usb/atm/cxacru.c:1209 + usbatm_usb_probe+0x321/0x1ae0 drivers/usb/atm/usbatm.c:1055 + cxacru_usb_probe+0xdf/0x1e0 drivers/usb/atm/cxacru.c:1363 + usb_probe_interface+0x315/0x7f0 drivers/usb/core/driver.c:396 + call_driver_probe drivers/base/dd.c:517 [inline] + really_probe+0x23c/0xcd0 drivers/base/dd.c:595 + __driver_probe_device+0x338/0x4d0 drivers/base/dd.c:747 + driver_probe_device+0x4c/0x1a0 drivers/base/dd.c:777 + __device_attach_driver+0x20b/0x2f0 drivers/base/dd.c:894 + bus_for_each_drv+0x15f/0x1e0 drivers/base/bus.c:427 + __device_attach+0x228/0x4a0 drivers/base/dd.c:965 + bus_probe_device+0x1e4/0x290 drivers/base/bus.c:487 + device_add+0xc2f/0x2180 drivers/base/core.c:3354 + usb_set_configuration+0x113a/0x1910 drivers/usb/core/message.c:2170 + usb_generic_driver_probe+0xba/0x100 drivers/usb/core/generic.c:238 + usb_probe_device+0xd9/0x2c0 drivers/usb/core/driver.c:293 + +Reported-and-tested-by: syzbot+00c18ee8497dd3be6ade@syzkaller.appspotmail.com +Fixes: 902ffc3c707c ("USB: cxacru: Use a bulk/int URB to access the command endpoint") +Cc: stable +Signed-off-by: Nikita Zhandarovich +Link: https://lore.kernel.org/r/20240609131546.3932-1-n.zhandarovich@fintech.ru +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/atm/cxacru.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/usb/atm/cxacru.c ++++ b/drivers/usb/atm/cxacru.c +@@ -1131,6 +1131,7 @@ static int cxacru_bind(struct usbatm_dat + struct cxacru_data *instance; + struct usb_device *usb_dev = interface_to_usbdev(intf); + struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; ++ struct usb_endpoint_descriptor *in, *out; + int ret; + + /* instance init */ +@@ -1176,6 +1177,19 @@ static int cxacru_bind(struct usbatm_dat + ret = -ENODEV; + goto fail; + } ++ ++ if (usb_endpoint_xfer_int(&cmd_ep->desc)) ++ ret = usb_find_common_endpoints(intf->cur_altsetting, ++ NULL, NULL, &in, &out); ++ else ++ ret = usb_find_common_endpoints(intf->cur_altsetting, ++ &in, &out, NULL, NULL); ++ ++ if (ret) { ++ usb_err(usbatm_instance, "cxacru_bind: interface has incorrect endpoints\n"); ++ ret = -ENODEV; ++ goto fail; ++ } + + if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { diff --git a/queue-6.9/usb-dwc3-core-remove-lock-of-otg-mode-during-gadget-suspend-resume-to-avoid-deadlock.patch b/queue-6.9/usb-dwc3-core-remove-lock-of-otg-mode-during-gadget-suspend-resume-to-avoid-deadlock.patch new file mode 100644 index 00000000000..a1d4310b48f --- /dev/null +++ b/queue-6.9/usb-dwc3-core-remove-lock-of-otg-mode-during-gadget-suspend-resume-to-avoid-deadlock.patch @@ -0,0 +1,77 @@ +From 7838de15bb700c2898a7d741db9b1f3cbc86c136 Mon Sep 17 00:00:00 2001 +From: Meng Li +Date: Tue, 18 Jun 2024 11:19:18 +0800 +Subject: usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to avoid deadlock + +From: Meng Li + +commit 7838de15bb700c2898a7d741db9b1f3cbc86c136 upstream. + +When config CONFIG_USB_DWC3_DUAL_ROLE is selected, and trigger system +to enter suspend status with below command: +echo mem > /sys/power/state +There will be a deadlock issue occurring. Detailed invoking path as +below: +dwc3_suspend_common() + spin_lock_irqsave(&dwc->lock, flags); <-- 1st + dwc3_gadget_suspend(dwc); + dwc3_gadget_soft_disconnect(dwc); + spin_lock_irqsave(&dwc->lock, flags); <-- 2nd +This issue is exposed by commit c7ebd8149ee5 ("usb: dwc3: gadget: Fix +NULL pointer dereference in dwc3_gadget_suspend") that removes the code +of checking whether dwc->gadget_driver is NULL or not. It causes the +following code is executed and deadlock occurs when trying to get the +spinlock. In fact, the root cause is the commit 5265397f9442("usb: dwc3: +Remove DWC3 locking during gadget suspend/resume") that forgot to remove +the lock of otg mode. So, remove the redundant lock of otg mode during +gadget suspend/resume. + +Fixes: 5265397f9442 ("usb: dwc3: Remove DWC3 locking during gadget suspend/resume") +Cc: Xu Yang +Cc: stable@vger.kernel.org +Signed-off-by: Meng Li +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20240618031918.2585799-1-Meng.Li@windriver.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -2084,7 +2084,6 @@ assert_reset: + + static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) + { +- unsigned long flags; + u32 reg; + + switch (dwc->current_dr_role) { +@@ -2122,9 +2121,7 @@ static int dwc3_suspend_common(struct dw + break; + + if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { +- spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_suspend(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); + synchronize_irq(dwc->irq_gadget); + } + +@@ -2141,7 +2138,6 @@ static int dwc3_suspend_common(struct dw + + static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) + { +- unsigned long flags; + int ret; + u32 reg; + +@@ -2190,9 +2186,7 @@ static int dwc3_resume_common(struct dwc + if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) { + dwc3_otg_host_init(dwc); + } else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) { +- spin_lock_irqsave(&dwc->lock, flags); + dwc3_gadget_resume(dwc); +- spin_unlock_irqrestore(&dwc->lock, flags); + } + + break; diff --git a/queue-6.9/usb-dwc3-core-workaround-for-csr-read-timeout.patch b/queue-6.9/usb-dwc3-core-workaround-for-csr-read-timeout.patch new file mode 100644 index 00000000000..6c5987b6b1d --- /dev/null +++ b/queue-6.9/usb-dwc3-core-workaround-for-csr-read-timeout.patch @@ -0,0 +1,68 @@ +From fc1d1a712b517bbcb383b1f1f7ef478e7d0579f2 Mon Sep 17 00:00:00 2001 +From: Jos Wang +Date: Wed, 19 Jun 2024 19:45:29 +0800 +Subject: usb: dwc3: core: Workaround for CSR read timeout + +From: Jos Wang + +commit fc1d1a712b517bbcb383b1f1f7ef478e7d0579f2 upstream. + +This is a workaround for STAR 4846132, which only affects +DWC_usb31 version2.00a operating in host mode. + +There is a problem in DWC_usb31 version 2.00a operating +in host mode that would cause a CSR read timeout When CSR +read coincides with RAM Clock Gating Entry. By disable +Clock Gating, sacrificing power consumption for normal +operation. + +Cc: stable # 5.10.x: 1e43c86d: usb: dwc3: core: Add DWC31 version 2.00a controller +Signed-off-by: Jos Wang +Acked-by: Thinh Nguyen +Link: https://lore.kernel.org/r/20240619114529.3441-1-joswang1221@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/dwc3/core.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/core.c ++++ b/drivers/usb/dwc3/core.c +@@ -879,12 +879,16 @@ static bool dwc3_core_is_valid(struct dw + + static void dwc3_core_setup_global_control(struct dwc3 *dwc) + { ++ unsigned int power_opt; ++ unsigned int hw_mode; + u32 reg; + + reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg &= ~DWC3_GCTL_SCALEDOWN_MASK; ++ hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); ++ power_opt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1); + +- switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { ++ switch (power_opt) { + case DWC3_GHWPARAMS1_EN_PWROPT_CLK: + /** + * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an +@@ -917,6 +921,20 @@ static void dwc3_core_setup_global_contr + break; + } + ++ /* ++ * This is a workaround for STAR#4846132, which only affects ++ * DWC_usb31 version2.00a operating in host mode. ++ * ++ * There is a problem in DWC_usb31 version 2.00a operating ++ * in host mode that would cause a CSR read timeout When CSR ++ * read coincides with RAM Clock Gating Entry. By disable ++ * Clock Gating, sacrificing power consumption for normal ++ * operation. ++ */ ++ if (power_opt != DWC3_GHWPARAMS1_EN_PWROPT_NO && ++ hw_mode != DWC3_GHWPARAMS0_MODE_GADGET && DWC3_VER_IS(DWC31, 200A)) ++ reg |= DWC3_GCTL_DSBLCLKGTNG; ++ + /* check if current dwc3 is on simulation board */ + if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { + dev_info(dwc->dev, "Running with FPGA optimizations\n"); diff --git a/queue-6.9/usb-gadget-aspeed_udc-fix-device-address-configuration.patch b/queue-6.9/usb-gadget-aspeed_udc-fix-device-address-configuration.patch new file mode 100644 index 00000000000..c67ce81d6b8 --- /dev/null +++ b/queue-6.9/usb-gadget-aspeed_udc-fix-device-address-configuration.patch @@ -0,0 +1,60 @@ +From dba7567c2fbbf10a4de2471cdb0e16e5572dc007 Mon Sep 17 00:00:00 2001 +From: Jeremy Kerr +Date: Thu, 13 Jun 2024 12:20:47 +0800 +Subject: usb: gadget: aspeed_udc: fix device address configuration + +From: Jeremy Kerr + +commit dba7567c2fbbf10a4de2471cdb0e16e5572dc007 upstream. + +In the aspeed UDC setup, we configure the UDC hardware with the assigned +USB device address. + +However, we have an off-by-one in the bitmask, so we're only setting the +lower 6 bits of the address (USB addresses being 7 bits, and the +hardware bitmask being bits 0:6). + +This means that device enumeration fails if the assigned address is +greater than 64: + +[ 344.607255] usb 1-1: new high-speed USB device number 63 using ehci-platform +[ 344.808459] usb 1-1: New USB device found, idVendor=cc00, idProduct=cc00, bcdDevice= 6.10 +[ 344.817684] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 +[ 344.825671] usb 1-1: Product: Test device +[ 344.831075] usb 1-1: Manufacturer: Test vendor +[ 344.836335] usb 1-1: SerialNumber: 00 +[ 349.917181] usb 1-1: USB disconnect, device number 63 +[ 352.036775] usb 1-1: new high-speed USB device number 64 using ehci-platform +[ 352.249432] usb 1-1: device descriptor read/all, error -71 +[ 352.696740] usb 1-1: new high-speed USB device number 65 using ehci-platform +[ 352.909431] usb 1-1: device descriptor read/all, error -71 + +Use the correct mask of 0x7f (rather than 0x3f), and generate this +through the GENMASK macro, so we have numbers that correspond exactly +to the hardware register definition. + +Fixes: 055276c13205 ("usb: gadget: add Aspeed ast2600 udc driver") +Cc: stable@vger.kernel.org +Reviewed-by: Neal Liu +Reviewed-by: Andrew Jeffery +Signed-off-by: Jeremy Kerr +Link: https://lore.kernel.org/r/20240613-aspeed-udc-v2-1-29501ce9cb7a@codeconstruct.com.au +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/aspeed_udc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/usb/gadget/udc/aspeed_udc.c ++++ b/drivers/usb/gadget/udc/aspeed_udc.c +@@ -66,8 +66,8 @@ + #define USB_UPSTREAM_EN BIT(0) + + /* Main config reg */ +-#define UDC_CFG_SET_ADDR(x) ((x) & 0x3f) +-#define UDC_CFG_ADDR_MASK (0x3f) ++#define UDC_CFG_SET_ADDR(x) ((x) & UDC_CFG_ADDR_MASK) ++#define UDC_CFG_ADDR_MASK GENMASK(6, 0) + + /* Interrupt ctrl & status reg */ + #define UDC_IRQ_EP_POOL_NAK BIT(17) diff --git a/queue-6.9/usb-gadget-printer-fix-races-against-disable.patch b/queue-6.9/usb-gadget-printer-fix-races-against-disable.patch new file mode 100644 index 00000000000..f29aba243a5 --- /dev/null +++ b/queue-6.9/usb-gadget-printer-fix-races-against-disable.patch @@ -0,0 +1,140 @@ +From e587a7633dfee8987a999cf253f7c52a8e09276c Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 20 Jun 2024 13:40:26 +0200 +Subject: usb: gadget: printer: fix races against disable + +From: Oliver Neukum + +commit e587a7633dfee8987a999cf253f7c52a8e09276c upstream. + +printer_read() and printer_write() guard against the race +against disable() by checking the dev->interface flag, +which in turn is guarded by a spinlock. +These functions, however, drop the lock on multiple occasions. +This means that the test has to be redone after reacquiring +the lock and before doing IO. + +Add the tests. + +This also addresses CVE-2024-25741 + +Fixes: 7f2ca14d2f9b9 ("usb: gadget: function: printer: Interface is disabled and returns error") +Cc: stable +Signed-off-by: Oliver Neukum +Link: https://lore.kernel.org/r/20240620114039.5767-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_printer.c | 39 +++++++++++++++++++++++--------- + 1 file changed, 29 insertions(+), 10 deletions(-) + +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -450,11 +450,8 @@ printer_read(struct file *fd, char __use + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + +- if (dev->interface < 0) { +- spin_unlock_irqrestore(&dev->lock, flags); +- mutex_unlock(&dev->lock_printer_io); +- return -ENODEV; +- } ++ if (dev->interface < 0) ++ goto out_disabled; + + /* We will use this flag later to check if a printer reset happened + * after we turn interrupts back on. +@@ -462,6 +459,9 @@ printer_read(struct file *fd, char __use + dev->reset_printer = 0; + + setup_rx_reqs(dev); ++ /* this dropped the lock - need to retest */ ++ if (dev->interface < 0) ++ goto out_disabled; + + bytes_copied = 0; + current_rx_req = dev->current_rx_req; +@@ -495,6 +495,8 @@ printer_read(struct file *fd, char __use + wait_event_interruptible(dev->rx_wait, + (likely(!list_empty(&dev->rx_buffers)))); + spin_lock_irqsave(&dev->lock, flags); ++ if (dev->interface < 0) ++ goto out_disabled; + } + + /* We have data to return then copy it to the caller's buffer.*/ +@@ -538,6 +540,9 @@ printer_read(struct file *fd, char __use + return -EAGAIN; + } + ++ if (dev->interface < 0) ++ goto out_disabled; ++ + /* If we not returning all the data left in this RX request + * buffer then adjust the amount of data left in the buffer. + * Othewise if we are done with this RX request buffer then +@@ -567,6 +572,11 @@ printer_read(struct file *fd, char __use + return bytes_copied; + else + return -EAGAIN; ++ ++out_disabled: ++ spin_unlock_irqrestore(&dev->lock, flags); ++ mutex_unlock(&dev->lock_printer_io); ++ return -ENODEV; + } + + static ssize_t +@@ -587,11 +597,8 @@ printer_write(struct file *fd, const cha + mutex_lock(&dev->lock_printer_io); + spin_lock_irqsave(&dev->lock, flags); + +- if (dev->interface < 0) { +- spin_unlock_irqrestore(&dev->lock, flags); +- mutex_unlock(&dev->lock_printer_io); +- return -ENODEV; +- } ++ if (dev->interface < 0) ++ goto out_disabled; + + /* Check if a printer reset happens while we have interrupts on */ + dev->reset_printer = 0; +@@ -614,6 +621,8 @@ printer_write(struct file *fd, const cha + wait_event_interruptible(dev->tx_wait, + (likely(!list_empty(&dev->tx_reqs)))); + spin_lock_irqsave(&dev->lock, flags); ++ if (dev->interface < 0) ++ goto out_disabled; + } + + while (likely(!list_empty(&dev->tx_reqs)) && len) { +@@ -663,6 +672,9 @@ printer_write(struct file *fd, const cha + return -EAGAIN; + } + ++ if (dev->interface < 0) ++ goto out_disabled; ++ + list_add(&req->list, &dev->tx_reqs_active); + + /* here, we unlock, and only unlock, to avoid deadlock. */ +@@ -675,6 +687,8 @@ printer_write(struct file *fd, const cha + mutex_unlock(&dev->lock_printer_io); + return -EAGAIN; + } ++ if (dev->interface < 0) ++ goto out_disabled; + } + + spin_unlock_irqrestore(&dev->lock, flags); +@@ -686,6 +700,11 @@ printer_write(struct file *fd, const cha + return bytes_copied; + else + return -EAGAIN; ++ ++out_disabled: ++ spin_unlock_irqrestore(&dev->lock, flags); ++ mutex_unlock(&dev->lock_printer_io); ++ return -ENODEV; + } + + static int diff --git a/queue-6.9/usb-gadget-printer-ss-support.patch b/queue-6.9/usb-gadget-printer-ss-support.patch new file mode 100644 index 00000000000..3825ba779f2 --- /dev/null +++ b/queue-6.9/usb-gadget-printer-ss-support.patch @@ -0,0 +1,30 @@ +From fd80731e5e9d1402cb2f85022a6abf9b1982ec5f Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 20 Jun 2024 11:37:39 +0200 +Subject: usb: gadget: printer: SS+ support + +From: Oliver Neukum + +commit fd80731e5e9d1402cb2f85022a6abf9b1982ec5f upstream. + +We need to treat super speed plus as super speed, not the default, +which is full speed. + +Signed-off-by: Oliver Neukum +Cc: stable +Link: https://lore.kernel.org/r/20240620093800.28901-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/function/f_printer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/gadget/function/f_printer.c ++++ b/drivers/usb/gadget/function/f_printer.c +@@ -213,6 +213,7 @@ static inline struct usb_endpoint_descri + struct usb_endpoint_descriptor *ss) + { + switch (gadget->speed) { ++ case USB_SPEED_SUPER_PLUS: + case USB_SPEED_SUPER: + return ss; + case USB_SPEED_HIGH: diff --git a/queue-6.9/usb-musb-da8xx-fix-a-resource-leak-in-probe.patch b/queue-6.9/usb-musb-da8xx-fix-a-resource-leak-in-probe.patch new file mode 100644 index 00000000000..09b00235176 --- /dev/null +++ b/queue-6.9/usb-musb-da8xx-fix-a-resource-leak-in-probe.patch @@ -0,0 +1,46 @@ +From de644a4a86be04ed8a43ef8267d0f7d021941c5e Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 17 Jun 2024 12:31:30 +0300 +Subject: usb: musb: da8xx: fix a resource leak in probe() + +From: Dan Carpenter + +commit de644a4a86be04ed8a43ef8267d0f7d021941c5e upstream. + +Call usb_phy_generic_unregister() if of_platform_populate() fails. + +Fixes: d6299b6efbf6 ("usb: musb: Add support of CPPI 4.1 DMA controller to DA8xx") +Cc: stable +Signed-off-by: Dan Carpenter +Link: https://lore.kernel.org/r/69af1b1d-d3f4-492b-bcea-359ca5949f30@moroto.mountain +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/musb/da8xx.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/usb/musb/da8xx.c ++++ b/drivers/usb/musb/da8xx.c +@@ -556,7 +556,7 @@ static int da8xx_probe(struct platform_d + ret = of_platform_populate(pdev->dev.of_node, NULL, + da8xx_auxdata_lookup, &pdev->dev); + if (ret) +- return ret; ++ goto err_unregister_phy; + + pinfo = da8xx_dev_info; + pinfo.parent = &pdev->dev; +@@ -571,9 +571,13 @@ static int da8xx_probe(struct platform_d + ret = PTR_ERR_OR_ZERO(glue->musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device: %d\n", ret); +- usb_phy_generic_unregister(glue->usb_phy); ++ goto err_unregister_phy; + } + ++ return 0; ++ ++err_unregister_phy: ++ usb_phy_generic_unregister(glue->usb_phy); + return ret; + } + diff --git a/queue-6.9/usb-typec-ucsi-glink-fix-child-node-release-in-probe-function.patch b/queue-6.9/usb-typec-ucsi-glink-fix-child-node-release-in-probe-function.patch new file mode 100644 index 00000000000..c0f999dae40 --- /dev/null +++ b/queue-6.9/usb-typec-ucsi-glink-fix-child-node-release-in-probe-function.patch @@ -0,0 +1,52 @@ +From c68942624e254a4e8a65afcd3c17ed95acda5489 Mon Sep 17 00:00:00 2001 +From: Javier Carrasco +Date: Thu, 13 Jun 2024 14:14:48 +0200 +Subject: usb: typec: ucsi: glink: fix child node release in probe function + +From: Javier Carrasco + +commit c68942624e254a4e8a65afcd3c17ed95acda5489 upstream. + +The device_for_each_child_node() macro requires explicit calls to +fwnode_handle_put() in all early exits of the loop if the child node is +not required outside. Otherwise, the child node's refcount is not +decremented and the resource is not released. + +The current implementation of pmic_glink_ucsi_probe() makes use of the +device_for_each_child_node(), but does not release the child node on +early returns. Add the missing calls to fwnode_handle_put(). + +Cc: stable@vger.kernel.org +Fixes: c6165ed2f425 ("usb: ucsi: glink: use the connector orientation GPIO to provide switch events") +Signed-off-by: Javier Carrasco +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240613-ucsi-glink-release-node-v1-1-f7629a56f70a@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi_glink.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/typec/ucsi/ucsi_glink.c ++++ b/drivers/usb/typec/ucsi/ucsi_glink.c +@@ -365,6 +365,7 @@ static int pmic_glink_ucsi_probe(struct + ret = fwnode_property_read_u32(fwnode, "reg", &port); + if (ret < 0) { + dev_err(dev, "missing reg property of %pOFn\n", fwnode); ++ fwnode_handle_put(fwnode); + return ret; + } + +@@ -379,9 +380,11 @@ static int pmic_glink_ucsi_probe(struct + if (!desc) + continue; + +- if (IS_ERR(desc)) ++ if (IS_ERR(desc)) { ++ fwnode_handle_put(fwnode); + return dev_err_probe(dev, PTR_ERR(desc), + "unable to acquire orientation gpio\n"); ++ } + ucsi->port_orientation[port] = desc; + + ucsi->port_switch[port] = fwnode_typec_switch_get(fwnode); diff --git a/queue-6.9/usb-ucsi-stm32-fix-command-completion-handling.patch b/queue-6.9/usb-ucsi-stm32-fix-command-completion-handling.patch new file mode 100644 index 00000000000..db886ead489 --- /dev/null +++ b/queue-6.9/usb-ucsi-stm32-fix-command-completion-handling.patch @@ -0,0 +1,94 @@ +From 8e1ec117efdfd4b2f59f57bd0ad16b4edf5b963f Mon Sep 17 00:00:00 2001 +From: Fabrice Gasnier +Date: Wed, 12 Jun 2024 14:46:56 +0200 +Subject: usb: ucsi: stm32: fix command completion handling + +From: Fabrice Gasnier + +commit 8e1ec117efdfd4b2f59f57bd0ad16b4edf5b963f upstream. + +Sometimes errors are seen, when doing DR swap, like: +[ 24.672481] ucsi-stm32g0-i2c 0-0035: UCSI_GET_PDOS failed (-5) +[ 24.720188] ucsi-stm32g0-i2c 0-0035: ucsi_handle_connector_change: + GET_CONNECTOR_STATUS failed (-5) + +There may be some race, which lead to read CCI, before the command complete +flag is set, hence returning -EIO. Similar fix has been done also in +ucsi_acpi [1]. + +In case of a spurious or otherwise delayed notification it is +possible that CCI still reports the previous completion. The +UCSI spec is aware of this and provides two completion bits in +CCI, one for normal commands and one for acks. As acks and commands +alternate the notification handler can determine if the completion +bit is from the current command. + +To fix this add the ACK_PENDING bit for ucsi_stm32g0 and only complete +commands if the completion bit matches. + +[1] https://lore.kernel.org/lkml/20240121204123.275441-3-lk@c--e.de/ + +Fixes: 72849d4fcee7 ("usb: typec: ucsi: stm32g0: add support for stm32g0 controller") +Signed-off-by: Fabrice Gasnier +Link: https://lore.kernel.org/stable/20240612124656.2305603-1-fabrice.gasnier%40foss.st.com +Cc: stable +Reviewed-by: Heikki Krogerus +Link: https://lore.kernel.org/r/20240612124656.2305603-1-fabrice.gasnier@foss.st.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/typec/ucsi/ucsi_stm32g0.c | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +--- a/drivers/usb/typec/ucsi/ucsi_stm32g0.c ++++ b/drivers/usb/typec/ucsi/ucsi_stm32g0.c +@@ -64,6 +64,7 @@ struct ucsi_stm32g0 { + struct completion complete; + struct device *dev; + unsigned long flags; ++#define ACK_PENDING 2 + const char *fw_name; + struct ucsi *ucsi; + bool suspended; +@@ -395,9 +396,13 @@ static int ucsi_stm32g0_sync_write(struc + size_t len) + { + struct ucsi_stm32g0 *g0 = ucsi_get_drvdata(ucsi); ++ bool ack = UCSI_COMMAND(*(u64 *)val) == UCSI_ACK_CC_CI; + int ret; + +- set_bit(COMMAND_PENDING, &g0->flags); ++ if (ack) ++ set_bit(ACK_PENDING, &g0->flags); ++ else ++ set_bit(COMMAND_PENDING, &g0->flags); + + ret = ucsi_stm32g0_async_write(ucsi, offset, val, len); + if (ret) +@@ -405,9 +410,14 @@ static int ucsi_stm32g0_sync_write(struc + + if (!wait_for_completion_timeout(&g0->complete, msecs_to_jiffies(5000))) + ret = -ETIMEDOUT; ++ else ++ return 0; + + out_clear_bit: +- clear_bit(COMMAND_PENDING, &g0->flags); ++ if (ack) ++ clear_bit(ACK_PENDING, &g0->flags); ++ else ++ clear_bit(COMMAND_PENDING, &g0->flags); + + return ret; + } +@@ -428,8 +438,9 @@ static irqreturn_t ucsi_stm32g0_irq_hand + if (UCSI_CCI_CONNECTOR(cci)) + ucsi_connector_change(g0->ucsi, UCSI_CCI_CONNECTOR(cci)); + +- if (test_bit(COMMAND_PENDING, &g0->flags) && +- cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE)) ++ if (cci & UCSI_CCI_ACK_COMPLETE && test_and_clear_bit(ACK_PENDING, &g0->flags)) ++ complete(&g0->complete); ++ if (cci & UCSI_CCI_COMMAND_COMPLETE && test_and_clear_bit(COMMAND_PENDING, &g0->flags)) + complete(&g0->complete); + + return IRQ_HANDLED;