]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Fri, 26 Jan 2024 14:04:46 +0000 (09:04 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 26 Jan 2024 14:04:46 +0000 (09:04 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
16 files changed:
queue-5.10/dmaengine-fix-null-pointer-in-channel-unregistration.patch [new file with mode: 0644]
queue-5.10/iio-adc-ad7091r-allow-users-to-configure-device-even.patch [new file with mode: 0644]
queue-5.10/iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch [new file with mode: 0644]
queue-5.10/iio-adc-ad7091r-set-alert-bit-in-config-register.patch [new file with mode: 0644]
queue-5.10/pci-mediatek-clear-interrupt-status-before-dispatchi.patch [new file with mode: 0644]
queue-5.10/serial-sc16is7xx-add-check-for-unsupported-spi-modes.patch [new file with mode: 0644]
queue-5.10/serial-sc16is7xx-set-safe-default-spi-clock-frequenc.patch [new file with mode: 0644]
queue-5.10/series [new file with mode: 0644]
queue-5.10/spi-introduce-spi_mode_x_mask-macro.patch [new file with mode: 0644]
queue-5.10/units-add-the-hz-macros.patch [new file with mode: 0644]
queue-5.10/units-change-from-l-to-ul.patch [new file with mode: 0644]
queue-5.10/usb-cdns3-fix-incorrect-calculation-of-ep_buf_size-w.patch [new file with mode: 0644]
queue-5.10/usb-cdns3-fix-iso-transfer-error-when-mult-is-not-ze.patch [new file with mode: 0644]
queue-5.10/usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-si.patch [new file with mode: 0644]
queue-5.10/usb-cdns3-fix-uvc-failure-work-since-sg-support-enab.patch [new file with mode: 0644]
queue-5.10/usb-cdns3-fixes-for-sparse-warnings.patch [new file with mode: 0644]

diff --git a/queue-5.10/dmaengine-fix-null-pointer-in-channel-unregistration.patch b/queue-5.10/dmaengine-fix-null-pointer-in-channel-unregistration.patch
new file mode 100644 (file)
index 0000000..3da70de
--- /dev/null
@@ -0,0 +1,55 @@
+From 5fe2a657d52838ff9d15c741b90418759c69698a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 17:04:52 +0100
+Subject: dmaengine: fix NULL pointer in channel unregistration function
+
+From: Amelie Delaunay <amelie.delaunay@foss.st.com>
+
+[ Upstream commit f5c24d94512f1b288262beda4d3dcb9629222fc7 ]
+
+__dma_async_device_channel_register() can fail. In case of failure,
+chan->local is freed (with free_percpu()), and chan->local is nullified.
+When dma_async_device_unregister() is called (because of managed API or
+intentionally by DMA controller driver), channels are unconditionally
+unregistered, leading to this NULL pointer:
+[    1.318693] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d0
+[...]
+[    1.484499] Call trace:
+[    1.486930]  device_del+0x40/0x394
+[    1.490314]  device_unregister+0x20/0x7c
+[    1.494220]  __dma_async_device_channel_unregister+0x68/0xc0
+
+Look at dma_async_device_register() function error path, channel device
+unregistration is done only if chan->local is not NULL.
+
+Then add the same condition at the beginning of
+__dma_async_device_channel_unregister() function, to avoid NULL pointer
+issue whatever the API used to reach this function.
+
+Fixes: d2fb0a043838 ("dmaengine: break out channel registration")
+Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Link: https://lore.kernel.org/r/20231213160452.2598073-1-amelie.delaunay@foss.st.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/dma/dmaengine.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
+index 4ec7bb58c195..9559ebd61f3b 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -1108,6 +1108,9 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_register);
+ static void __dma_async_device_channel_unregister(struct dma_device *device,
+                                                 struct dma_chan *chan)
+ {
++      if (chan->local == NULL)
++              return;
++
+       WARN_ONCE(!device->device_release && chan->client_count,
+                 "%s called while %d clients hold a reference\n",
+                 __func__, chan->client_count);
+-- 
+2.43.0
+
diff --git a/queue-5.10/iio-adc-ad7091r-allow-users-to-configure-device-even.patch b/queue-5.10/iio-adc-ad7091r-allow-users-to-configure-device-even.patch
new file mode 100644 (file)
index 0000000..eb762fa
--- /dev/null
@@ -0,0 +1,295 @@
+From 6c4a55b6120e770562168020493c34310ded1a9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 17:26:01 -0300
+Subject: iio: adc: ad7091r: Allow users to configure device events
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+[ Upstream commit 020e71c7ffc25dfe29ed9be6c2d39af7bd7f661f ]
+
+AD7091R-5 devices are supported by the ad7091r-5 driver together with
+the ad7091r-base driver. Those drivers declared iio events for notifying
+user space when ADC readings fall bellow the thresholds of low limit
+registers or above the values set in high limit registers.
+However, to configure iio events and their thresholds, a set of callback
+functions must be implemented and those were not present until now.
+The consequence of trying to configure ad7091r-5 events without the
+proper callback functions was a null pointer dereference in the kernel
+because the pointers to the callback functions were not set.
+
+Implement event configuration callbacks allowing users to read/write
+event thresholds and enable/disable event generation.
+
+Since the event spec structs are generic to AD7091R devices, also move
+those from the ad7091r-5 driver the base driver so they can be reused
+when support for ad7091r-2/-4/-8 be added.
+
+Fixes: ca69300173b6 ("iio: adc: Add support for AD7091R5 ADC")
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/59552d3548dabd56adc3107b7b4869afee2b0c3c.1703013352.git.marcelo.schmitt1@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 156 +++++++++++++++++++++++++++++++++
+ drivers/iio/adc/ad7091r-base.h |   6 ++
+ drivers/iio/adc/ad7091r5.c     |  28 +-----
+ 3 files changed, 166 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
+index ad089c0ff953..9ddda08918db 100644
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -6,6 +6,7 @@
+  */
+ #include <linux/bitops.h>
++#include <linux/bitfield.h>
+ #include <linux/iio/events.h>
+ #include <linux/iio/iio.h>
+ #include <linux/interrupt.h>
+@@ -50,6 +51,27 @@ struct ad7091r_state {
+       struct mutex lock; /*lock to prevent concurent reads */
+ };
++const struct iio_event_spec ad7091r_events[] = {
++      {
++              .type = IIO_EV_TYPE_THRESH,
++              .dir = IIO_EV_DIR_RISING,
++              .mask_separate = BIT(IIO_EV_INFO_VALUE) |
++                               BIT(IIO_EV_INFO_ENABLE),
++      },
++      {
++              .type = IIO_EV_TYPE_THRESH,
++              .dir = IIO_EV_DIR_FALLING,
++              .mask_separate = BIT(IIO_EV_INFO_VALUE) |
++                               BIT(IIO_EV_INFO_ENABLE),
++      },
++      {
++              .type = IIO_EV_TYPE_THRESH,
++              .dir = IIO_EV_DIR_EITHER,
++              .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
++      },
++};
++EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R);
++
+ static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
+ {
+       int ret, conf;
+@@ -169,8 +191,142 @@ static int ad7091r_read_raw(struct iio_dev *iio_dev,
+       return ret;
+ }
++static int ad7091r_read_event_config(struct iio_dev *indio_dev,
++                                   const struct iio_chan_spec *chan,
++                                   enum iio_event_type type,
++                                   enum iio_event_direction dir)
++{
++      struct ad7091r_state *st = iio_priv(indio_dev);
++      int val, ret;
++
++      switch (dir) {
++      case IIO_EV_DIR_RISING:
++              ret = regmap_read(st->map,
++                                AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++                                &val);
++              if (ret)
++                      return ret;
++              return val != AD7091R_HIGH_LIMIT;
++      case IIO_EV_DIR_FALLING:
++              ret = regmap_read(st->map,
++                                AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++                                &val);
++              if (ret)
++                      return ret;
++              return val != AD7091R_LOW_LIMIT;
++      default:
++              return -EINVAL;
++      }
++}
++
++static int ad7091r_write_event_config(struct iio_dev *indio_dev,
++                                    const struct iio_chan_spec *chan,
++                                    enum iio_event_type type,
++                                    enum iio_event_direction dir, int state)
++{
++      struct ad7091r_state *st = iio_priv(indio_dev);
++
++      if (state) {
++              return regmap_set_bits(st->map, AD7091R_REG_CONF,
++                                     AD7091R_REG_CONF_ALERT_EN);
++      } else {
++              /*
++               * Set thresholds either to 0 or to 2^12 - 1 as appropriate to
++               * prevent alerts and thus disable event generation.
++               */
++              switch (dir) {
++              case IIO_EV_DIR_RISING:
++                      return regmap_write(st->map,
++                                          AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++                                          AD7091R_HIGH_LIMIT);
++              case IIO_EV_DIR_FALLING:
++                      return regmap_write(st->map,
++                                          AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++                                          AD7091R_LOW_LIMIT);
++              default:
++                      return -EINVAL;
++              }
++      }
++}
++
++static int ad7091r_read_event_value(struct iio_dev *indio_dev,
++                                  const struct iio_chan_spec *chan,
++                                  enum iio_event_type type,
++                                  enum iio_event_direction dir,
++                                  enum iio_event_info info, int *val, int *val2)
++{
++      struct ad7091r_state *st = iio_priv(indio_dev);
++      int ret;
++
++      switch (info) {
++      case IIO_EV_INFO_VALUE:
++              switch (dir) {
++              case IIO_EV_DIR_RISING:
++                      ret = regmap_read(st->map,
++                                        AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++                                        val);
++                      if (ret)
++                              return ret;
++                      return IIO_VAL_INT;
++              case IIO_EV_DIR_FALLING:
++                      ret = regmap_read(st->map,
++                                        AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++                                        val);
++                      if (ret)
++                              return ret;
++                      return IIO_VAL_INT;
++              default:
++                      return -EINVAL;
++              }
++      case IIO_EV_INFO_HYSTERESIS:
++              ret = regmap_read(st->map,
++                                AD7091R_REG_CH_HYSTERESIS(chan->channel),
++                                val);
++              if (ret)
++                      return ret;
++              return IIO_VAL_INT;
++      default:
++              return -EINVAL;
++      }
++}
++
++static int ad7091r_write_event_value(struct iio_dev *indio_dev,
++                                   const struct iio_chan_spec *chan,
++                                   enum iio_event_type type,
++                                   enum iio_event_direction dir,
++                                   enum iio_event_info info, int val, int val2)
++{
++      struct ad7091r_state *st = iio_priv(indio_dev);
++
++      switch (info) {
++      case IIO_EV_INFO_VALUE:
++              switch (dir) {
++              case IIO_EV_DIR_RISING:
++                      return regmap_write(st->map,
++                                          AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++                                          val);
++              case IIO_EV_DIR_FALLING:
++                      return regmap_write(st->map,
++                                          AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++                                          val);
++              default:
++                      return -EINVAL;
++              }
++      case IIO_EV_INFO_HYSTERESIS:
++              return regmap_write(st->map,
++                                  AD7091R_REG_CH_HYSTERESIS(chan->channel),
++                                  val);
++      default:
++              return -EINVAL;
++      }
++}
++
+ static const struct iio_info ad7091r_info = {
+       .read_raw = ad7091r_read_raw,
++      .read_event_config = &ad7091r_read_event_config,
++      .write_event_config = &ad7091r_write_event_config,
++      .read_event_value = &ad7091r_read_event_value,
++      .write_event_value = &ad7091r_write_event_value,
+ };
+ static irqreturn_t ad7091r_event_handler(int irq, void *private)
+diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h
+index 509748aef9b1..7a78976a2f80 100644
+--- a/drivers/iio/adc/ad7091r-base.h
++++ b/drivers/iio/adc/ad7091r-base.h
+@@ -8,6 +8,10 @@
+ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
++/* AD7091R_REG_CH_LIMIT */
++#define AD7091R_HIGH_LIMIT            0xFFF
++#define AD7091R_LOW_LIMIT             0x0
++
+ struct device;
+ struct ad7091r_state;
+@@ -17,6 +21,8 @@ struct ad7091r_chip_info {
+       unsigned int vref_mV;
+ };
++extern const struct iio_event_spec ad7091r_events[3];
++
+ extern const struct regmap_config ad7091r_regmap_config;
+ int ad7091r_probe(struct device *dev, const char *name,
+diff --git a/drivers/iio/adc/ad7091r5.c b/drivers/iio/adc/ad7091r5.c
+index 9665679c3ea6..e60511460786 100644
+--- a/drivers/iio/adc/ad7091r5.c
++++ b/drivers/iio/adc/ad7091r5.c
+@@ -12,26 +12,6 @@
+ #include "ad7091r-base.h"
+-static const struct iio_event_spec ad7091r5_events[] = {
+-      {
+-              .type = IIO_EV_TYPE_THRESH,
+-              .dir = IIO_EV_DIR_RISING,
+-              .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+-                               BIT(IIO_EV_INFO_ENABLE),
+-      },
+-      {
+-              .type = IIO_EV_TYPE_THRESH,
+-              .dir = IIO_EV_DIR_FALLING,
+-              .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+-                               BIT(IIO_EV_INFO_ENABLE),
+-      },
+-      {
+-              .type = IIO_EV_TYPE_THRESH,
+-              .dir = IIO_EV_DIR_EITHER,
+-              .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+-      },
+-};
+-
+ #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \
+       .type = IIO_VOLTAGE, \
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+@@ -44,10 +24,10 @@ static const struct iio_event_spec ad7091r5_events[] = {
+       .scan_type.realbits = bits, \
+ }
+ static const struct iio_chan_spec ad7091r5_channels_irq[] = {
+-      AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+-      AD7091R_CHANNEL(1, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+-      AD7091R_CHANNEL(2, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+-      AD7091R_CHANNEL(3, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
++      AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++      AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++      AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++      AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
+ };
+ static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
+-- 
+2.43.0
+
diff --git a/queue-5.10/iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch b/queue-5.10/iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch
new file mode 100644 (file)
index 0000000..c901a09
--- /dev/null
@@ -0,0 +1,67 @@
+From 0c4e0cbd5462851c26964c6515deaa4f12823eea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Dec 2023 17:26:27 -0300
+Subject: iio: adc: ad7091r: Enable internal vref if external vref is not
+ supplied
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+[ Upstream commit e71c5c89bcb165a02df35325aa13d1ee40112401 ]
+
+The ADC needs a voltage reference to work correctly.
+Users can provide an external voltage reference or use the chip internal
+reference to operate the ADC.
+The availability of an in chip reference for the ADC saves the user from
+having to supply an external voltage reference, which makes the external
+reference an optional property as described in the device tree
+documentation.
+Though, to use the internal reference, it must be enabled by writing to
+the configuration register.
+Enable AD7091R internal voltage reference if no external vref is supplied.
+
+Fixes: 260442cc5be4 ("iio: adc: ad7091r5: Add scale and external VREF support")
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/b865033fa6a4fc4bf2b4a98ec51a6144e0f64f77.1703013352.git.marcelo.schmitt1@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 7 +++++++
+ drivers/iio/adc/ad7091r-base.h | 2 ++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
+index 9ddda08918db..f345542e69a0 100644
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -405,7 +405,14 @@ int ad7091r_probe(struct device *dev, const char *name,
+       if (IS_ERR(st->vref)) {
+               if (PTR_ERR(st->vref) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
++
+               st->vref = NULL;
++              /* Enable internal vref */
++              ret = regmap_set_bits(st->map, AD7091R_REG_CONF,
++                                    AD7091R_REG_CONF_INT_VREF);
++              if (ret)
++                      return dev_err_probe(st->dev, ret,
++                                           "Error on enable internal reference\n");
+       } else {
+               ret = regulator_enable(st->vref);
+               if (ret)
+diff --git a/drivers/iio/adc/ad7091r-base.h b/drivers/iio/adc/ad7091r-base.h
+index 7a78976a2f80..b9e1c8bf3440 100644
+--- a/drivers/iio/adc/ad7091r-base.h
++++ b/drivers/iio/adc/ad7091r-base.h
+@@ -8,6 +8,8 @@
+ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
++#define AD7091R_REG_CONF_INT_VREF     BIT(0)
++
+ /* AD7091R_REG_CH_LIMIT */
+ #define AD7091R_HIGH_LIMIT            0xFFF
+ #define AD7091R_LOW_LIMIT             0x0
+-- 
+2.43.0
+
diff --git a/queue-5.10/iio-adc-ad7091r-set-alert-bit-in-config-register.patch b/queue-5.10/iio-adc-ad7091r-set-alert-bit-in-config-register.patch
new file mode 100644 (file)
index 0000000..f4bae9e
--- /dev/null
@@ -0,0 +1,53 @@
+From 9b660eb0b6de395facd2eb3e0ff9f734e3d037fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 16 Dec 2023 14:46:37 -0300
+Subject: iio: adc: ad7091r: Set alert bit in config register
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+[ Upstream commit 149694f5e79b0c7a36ceb76e7c0d590db8f151c1 ]
+
+The ad7091r-base driver sets up an interrupt handler for firing events
+when inputs are either above or below a certain threshold.
+However, for the interrupt signal to come from the device it must be
+configured to enable the ALERT/BUSY/GPO pin to be used as ALERT, which
+was not being done until now.
+Enable interrupt signals on the ALERT/BUSY/GPO pin by setting the proper
+bit in the configuration register.
+
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/e8da2ee98d6df88318b14baf3dc9630e20218418.1702746240.git.marcelo.schmitt1@gmail.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 020e71c7ffc2 ("iio: adc: ad7091r: Allow users to configure device events")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/iio/adc/ad7091r-base.c b/drivers/iio/adc/ad7091r-base.c
+index 811f04448d8d..ad089c0ff953 100644
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -28,6 +28,7 @@
+ #define AD7091R_REG_RESULT_CONV_RESULT(x)   ((x) & 0xfff)
+ /* AD7091R_REG_CONF */
++#define AD7091R_REG_CONF_ALERT_EN   BIT(4)
+ #define AD7091R_REG_CONF_AUTO   BIT(8)
+ #define AD7091R_REG_CONF_CMD    BIT(10)
+@@ -232,6 +233,11 @@ int ad7091r_probe(struct device *dev, const char *name,
+       iio_dev->channels = chip_info->channels;
+       if (irq) {
++              ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
++                                       AD7091R_REG_CONF_ALERT_EN, BIT(4));
++              if (ret)
++                      return ret;
++
+               ret = devm_request_threaded_irq(dev, irq, NULL,
+                               ad7091r_event_handler,
+                               IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev);
+-- 
+2.43.0
+
diff --git a/queue-5.10/pci-mediatek-clear-interrupt-status-before-dispatchi.patch b/queue-5.10/pci-mediatek-clear-interrupt-status-before-dispatchi.patch
new file mode 100644 (file)
index 0000000..c5e737d
--- /dev/null
@@ -0,0 +1,65 @@
+From 1e8c1ccf867e4ec682f8419b123ba5b8d2db291f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 17:49:23 +0800
+Subject: PCI: mediatek: Clear interrupt status before dispatching handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: qizhong cheng <qizhong.cheng@mediatek.com>
+
+[ Upstream commit 4e11c29873a8a296a20f99b3e03095e65ebf897d ]
+
+We found a failure when using the iperf tool during WiFi performance
+testing, where some MSIs were received while clearing the interrupt
+status, and these MSIs cannot be serviced.
+
+The interrupt status can be cleared even if the MSI status remains pending.
+As such, given the edge-triggered interrupt type, its status should be
+cleared before being dispatched to the handler of the underling device.
+
+[kwilczynski: commit log, code comment wording]
+Link: https://lore.kernel.org/linux-pci/20231211094923.31967-1-jianjun.wang@mediatek.com
+Fixes: 43e6409db64d ("PCI: mediatek: Add MSI support for MT2712 and MT7622")
+Signed-off-by: qizhong cheng <qizhong.cheng@mediatek.com>
+Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com>
+Signed-off-by: Krzysztof WilczyÅ„ski <kwilczynski@kernel.org>
+[bhelgaas: rewrap comment]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-mediatek.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
+index 23548b517e4b..ea91d63c8be1 100644
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -620,14 +620,20 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
+               if (status & MSI_STATUS){
+                       unsigned long imsi_status;
++                      /*
++                       * The interrupt status can be cleared even if the
++                       * MSI status remains pending. As such, given the
++                       * edge-triggered interrupt type, its status should
++                       * be cleared before being dispatched to the
++                       * handler of the underlying device.
++                       */
++                      writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
+                       while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
+                               for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) {
+                                       virq = irq_find_mapping(port->inner_domain, bit);
+                                       generic_handle_irq(virq);
+                               }
+                       }
+-                      /* Clear MSI interrupt status */
+-                      writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
+               }
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/serial-sc16is7xx-add-check-for-unsupported-spi-modes.patch b/queue-5.10/serial-sc16is7xx-add-check-for-unsupported-spi-modes.patch
new file mode 100644 (file)
index 0000000..1eeaf62
--- /dev/null
@@ -0,0 +1,55 @@
+From 89830b9732103c0559741baaebb85f53bf1b0cc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 18:18:09 -0500
+Subject: serial: sc16is7xx: add check for unsupported SPI modes during probe
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+[ Upstream commit 6d710b769c1f5f0d55c9ad9bb49b7dce009ec103 ]
+
+The original comment is confusing because it implies that variants other
+than the SC16IS762 supports other SPI modes beside SPI_MODE_0.
+
+Extract from datasheet:
+    The SC16IS762 differs from the SC16IS752 in that it supports SPI clock
+    speeds up to 15 Mbit/s instead of the 4 Mbit/s supported by the
+    SC16IS752... In all other aspects, the SC16IS762 is functionally and
+    electrically the same as the SC16IS752.
+
+The same is also true of the SC16IS760 variant versus the SC16IS740 and
+SC16IS750 variants.
+
+For all variants, only SPI mode 0 is supported.
+
+Change comment and abort probing if the specified SPI mode is not
+SPI_MODE_0.
+
+Fixes: 2c837a8a8f9f ("sc16is7xx: spi interface is added")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231221231823.2327894-3-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sc16is7xx.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
+index dfaca09de79b..31e0c5c3ddea 100644
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -1450,7 +1450,10 @@ static int sc16is7xx_spi_probe(struct spi_device *spi)
+       /* Setup SPI bus */
+       spi->bits_per_word      = 8;
+-      /* only supports mode 0 on SC16IS762 */
++      /* For all variants, only mode 0 is supported */
++      if ((spi->mode & SPI_MODE_X_MASK) != SPI_MODE_0)
++              return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n");
++
+       spi->mode               = spi->mode ? : SPI_MODE_0;
+       spi->max_speed_hz       = spi->max_speed_hz ? : 4 * HZ_PER_MHZ;
+       ret = spi_setup(spi);
+-- 
+2.43.0
+
diff --git a/queue-5.10/serial-sc16is7xx-set-safe-default-spi-clock-frequenc.patch b/queue-5.10/serial-sc16is7xx-set-safe-default-spi-clock-frequenc.patch
new file mode 100644 (file)
index 0000000..0916a07
--- /dev/null
@@ -0,0 +1,50 @@
+From 45d0c9653b8cebf9ba4e690d7ff96168b9d3a7d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 18:18:10 -0500
+Subject: serial: sc16is7xx: set safe default SPI clock frequency
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+[ Upstream commit 3ef79cd1412236d884ab0c46b4d1921380807b48 ]
+
+15 MHz is supported only by 76x variants.
+
+If the SPI clock frequency is not specified, use a safe default clock value
+of 4 MHz that is supported by all variants.
+
+Also use HZ_PER_MHZ macro to improve readability.
+
+Fixes: 2c837a8a8f9f ("sc16is7xx: spi interface is added")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231221231823.2327894-4-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/sc16is7xx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
+index fd9be81bcfd8..dfaca09de79b 100644
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -24,6 +24,7 @@
+ #include <linux/tty_flip.h>
+ #include <linux/spi/spi.h>
+ #include <linux/uaccess.h>
++#include <linux/units.h>
+ #include <uapi/linux/sched/types.h>
+ #define SC16IS7XX_NAME                        "sc16is7xx"
+@@ -1451,7 +1452,7 @@ static int sc16is7xx_spi_probe(struct spi_device *spi)
+       spi->bits_per_word      = 8;
+       /* only supports mode 0 on SC16IS762 */
+       spi->mode               = spi->mode ? : SPI_MODE_0;
+-      spi->max_speed_hz       = spi->max_speed_hz ? : 15000000;
++      spi->max_speed_hz       = spi->max_speed_hz ? : 4 * HZ_PER_MHZ;
+       ret = spi_setup(spi);
+       if (ret)
+               return ret;
+-- 
+2.43.0
+
diff --git a/queue-5.10/series b/queue-5.10/series
new file mode 100644 (file)
index 0000000..4d55e3b
--- /dev/null
@@ -0,0 +1,15 @@
+usb-cdns3-fixes-for-sparse-warnings.patch
+usb-cdns3-fix-uvc-failure-work-since-sg-support-enab.patch
+usb-cdns3-fix-incorrect-calculation-of-ep_buf_size-w.patch
+usb-cdns3-fix-iso-transfer-error-when-mult-is-not-ze.patch
+usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-si.patch
+pci-mediatek-clear-interrupt-status-before-dispatchi.patch
+units-change-from-l-to-ul.patch
+units-add-the-hz-macros.patch
+serial-sc16is7xx-set-safe-default-spi-clock-frequenc.patch
+spi-introduce-spi_mode_x_mask-macro.patch
+serial-sc16is7xx-add-check-for-unsupported-spi-modes.patch
+iio-adc-ad7091r-set-alert-bit-in-config-register.patch
+iio-adc-ad7091r-allow-users-to-configure-device-even.patch
+iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch
+dmaengine-fix-null-pointer-in-channel-unregistration.patch
diff --git a/queue-5.10/spi-introduce-spi_mode_x_mask-macro.patch b/queue-5.10/spi-introduce-spi_mode_x_mask-macro.patch
new file mode 100644 (file)
index 0000000..6924843
--- /dev/null
@@ -0,0 +1,46 @@
+From 3a309252807fbe50554efe7891c46d550058ff7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 27 Oct 2020 10:57:23 +0100
+Subject: spi: introduce SPI_MODE_X_MASK macro
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit 029b42d8519cef70c4fb5fcaccd08f1053ed2bf0 ]
+
+Provide a macro to filter all SPI_MODE_0,1,2,3 mode in one run.
+
+The latest SPI framework will parse the devicetree in following call
+sequence: of_register_spi_device() -> of_spi_parse_dt()
+So, driver do not need to pars the devicetree and will get prepared
+flags in the probe.
+
+On one hand it is good far most drivers. On other hand some drivers need to
+filter flags provide by SPI framework and apply know to work flags. This drivers
+may use SPI_MODE_X_MASK to filter MODE flags and set own, known flags:
+  spi->flags &= ~SPI_MODE_X_MASK;
+  spi->flags |= SPI_MODE_0;
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://lore.kernel.org/r/20201027095724.18654-2-o.rempel@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 6d710b769c1f ("serial: sc16is7xx: add check for unsupported SPI modes during probe")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/spi/spi.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
+index e1d88630ff24..ab7747549d23 100644
+--- a/include/linux/spi/spi.h
++++ b/include/linux/spi/spi.h
+@@ -171,6 +171,7 @@ struct spi_device {
+ #define       SPI_MODE_1      (0|SPI_CPHA)
+ #define       SPI_MODE_2      (SPI_CPOL|0)
+ #define       SPI_MODE_3      (SPI_CPOL|SPI_CPHA)
++#define       SPI_MODE_X_MASK (SPI_CPOL|SPI_CPHA)
+ #define       SPI_CS_HIGH     0x04                    /* chipselect active high? */
+ #define       SPI_LSB_FIRST   0x08                    /* per-word bits-on-wire */
+ #define       SPI_3WIRE       0x10                    /* SI/SO signals shared */
+-- 
+2.43.0
+
diff --git a/queue-5.10/units-add-the-hz-macros.patch b/queue-5.10/units-add-the-hz-macros.patch
new file mode 100644 (file)
index 0000000..5c8b013
--- /dev/null
@@ -0,0 +1,57 @@
+From 619eef7ee7b5c9d9febe20a01842acd2d876d45b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Sep 2021 19:57:48 -0700
+Subject: units: add the HZ macros
+
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+
+[ Upstream commit e2c77032fcbe515194107994d12cd72ddb77b022 ]
+
+The macros for the unit conversion for frequency are duplicated in
+different places.
+
+Provide these macros in the 'units' header, so they can be reused.
+
+Link: https://lkml.kernel.org/r/20210816114732.1834145-3-daniel.lezcano@linaro.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Reviewed-by: Christian Eggers <ceggers@arri.de>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Chanwoo Choi <cw00.choi@samsung.com>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Cc: Jonathan Cameron <jic23@kernel.org>
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Lukasz Luba <lukasz.luba@arm.com>
+Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
+Cc: Peter Meerwald <pmeerw@pmeerw.net>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 3ef79cd14122 ("serial: sc16is7xx: set safe default SPI clock frequency")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/units.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/include/linux/units.h b/include/linux/units.h
+index 62149b5082e1..b61e3f6d5099 100644
+--- a/include/linux/units.h
++++ b/include/linux/units.h
+@@ -20,6 +20,10 @@
+ #define PICO  1000000000000ULL
+ #define FEMTO 1000000000000000ULL
++#define HZ_PER_KHZ            1000UL
++#define KHZ_PER_MHZ           1000UL
++#define HZ_PER_MHZ            1000000UL
++
+ #define MILLIWATT_PER_WATT    1000UL
+ #define MICROWATT_PER_MILLIWATT       1000UL
+ #define MICROWATT_PER_WATT    1000000UL
+-- 
+2.43.0
+
diff --git a/queue-5.10/units-change-from-l-to-ul.patch b/queue-5.10/units-change-from-l-to-ul.patch
new file mode 100644 (file)
index 0000000..28f73b7
--- /dev/null
@@ -0,0 +1,71 @@
+From 30cbe45e8be7b0b52c75e17cb018db67b6010ae8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Sep 2021 19:57:44 -0700
+Subject: units: change from 'L' to 'UL'
+
+From: Daniel Lezcano <daniel.lezcano@linaro.org>
+
+[ Upstream commit c9221919a2d2df5741ab074dfec5bdfc6f1e043b ]
+
+Patch series "Add Hz macros", v3.
+
+There are multiple definitions of the HZ_PER_MHZ or HZ_PER_KHZ in the
+different drivers.  Instead of duplicating this definition again and
+again, add one in the units.h header to be reused in all the place the
+redefiniton occurs.
+
+At the same time, change the type of the Watts, as they can not be
+negative.
+
+This patch (of 10):
+
+The users of the macros are safe to be assigned with an unsigned instead
+of signed as the variables using them are themselves unsigned.
+
+Link: https://lkml.kernel.org/r/20210816114732.1834145-1-daniel.lezcano@linaro.org
+Link: https://lkml.kernel.org/r/20210816114732.1834145-2-daniel.lezcano@linaro.org
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Jonathan Cameron <jic23@kernel.org>
+Cc: Christian Eggers <ceggers@arri.de>
+Cc: Lukasz Luba <lukasz.luba@arm.com>
+Cc: MyungJoo Ham <myungjoo.ham@samsung.com>
+Cc: Kyungmin Park <kyungmin.park@samsung.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Peter Meerwald <pmeerw@pmeerw.net>
+Cc: Zhang Rui <rui.zhang@intel.com>
+Cc: Guenter Roeck <linux@roeck-us.net>
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+Cc: "Rafael J. Wysocki" <rafael@kernel.org>
+Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
+Cc: Chanwoo Choi <cw00.choi@samsung.com>
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: 3ef79cd14122 ("serial: sc16is7xx: set safe default SPI clock frequency")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/units.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/units.h b/include/linux/units.h
+index 3457179f7116..62149b5082e1 100644
+--- a/include/linux/units.h
++++ b/include/linux/units.h
+@@ -20,9 +20,9 @@
+ #define PICO  1000000000000ULL
+ #define FEMTO 1000000000000000ULL
+-#define MILLIWATT_PER_WATT    1000L
+-#define MICROWATT_PER_MILLIWATT       1000L
+-#define MICROWATT_PER_WATT    1000000L
++#define MILLIWATT_PER_WATT    1000UL
++#define MICROWATT_PER_MILLIWATT       1000UL
++#define MICROWATT_PER_WATT    1000000UL
+ #define ABSOLUTE_ZERO_MILLICELSIUS -273150
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-cdns3-fix-incorrect-calculation-of-ep_buf_size-w.patch b/queue-5.10/usb-cdns3-fix-incorrect-calculation-of-ep_buf_size-w.patch
new file mode 100644 (file)
index 0000000..ff92ebc
--- /dev/null
@@ -0,0 +1,55 @@
+From aead52baf21e5a4b42540c9de395cb055f177f97 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Jul 2023 19:00:15 -0400
+Subject: usb: cdns3: fix incorrect calculation of ep_buf_size when more than
+ one config
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit 2627335a1329a0d39d8d277994678571c4f21800 ]
+
+Previously, the cdns3_gadget_check_config() function in the cdns3 driver
+mistakenly calculated the ep_buf_size by considering only one
+configuration's endpoint information because "claimed" will be clear after
+call usb_gadget_check_config().
+
+The fix involves checking the private flags EP_CLAIMED instead of relying
+on the "claimed" flag.
+
+Fixes: dce49449e04f ("usb: cdns3: allocate TX FIFO size according to composite EP number")
+Cc: stable <stable@kernel.org>
+Reported-by: Ravi Gunasekaran <r-gunasekaran@ti.com>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Tested-by: Ravi Gunasekaran <r-gunasekaran@ti.com>
+Link: https://lore.kernel.org/r/20230707230015.494999-2-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 92f02efa1d86 ("usb: cdns3: fix iso transfer error when mult is not zero")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/gadget.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
+index 575180a59ad4..ee64c4ab8dd2 100644
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -3030,12 +3030,14 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget)
+ static int cdns3_gadget_check_config(struct usb_gadget *gadget)
+ {
+       struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget);
++      struct cdns3_endpoint *priv_ep;
+       struct usb_ep *ep;
+       int n_in = 0;
+       int total;
+       list_for_each_entry(ep, &gadget->ep_list, ep_list) {
+-              if (ep->claimed && (ep->address & USB_DIR_IN))
++              priv_ep = ep_to_cdns3_ep(ep);
++              if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN))
+                       n_in++;
+       }
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-cdns3-fix-iso-transfer-error-when-mult-is-not-ze.patch b/queue-5.10/usb-cdns3-fix-iso-transfer-error-when-mult-is-not-ze.patch
new file mode 100644 (file)
index 0000000..bf4b68e
--- /dev/null
@@ -0,0 +1,180 @@
+From e23d833d5044217a5b2f6b2ca936279619fda4ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Dec 2023 10:38:14 -0500
+Subject: usb: cdns3: fix iso transfer error when mult is not zero
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit 92f02efa1d86d7dcaef7f38a5fe3396c4e88a93c ]
+
+ISO basic transfer is
+       ITP(SOF) Package_0 Package_1 ... Package_n
+
+CDNS3 DMA start dma transfer from memmory to internal FIFO when get SOF,
+controller will transfer data to usb bus from internal FIFO when get IN
+token.
+
+According USB spec defination:
+       Maximum number of packets = (bMaxBurst + 1) * (Mult + 1)
+
+Internal memory should be the same as (bMaxBurst + 1) * (Mult + 1). DMA
+don't fetch data advance when ISO transfer, so only reserve
+(bMaxBurst + 1) * (Mult + 1) internal memory for ISO transfer.
+
+Need save Mult and bMaxBurst information and set it into EP_CFG register,
+otherwise only 1 package is sent by controller, other package will be
+lost.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231224153816.1664687-3-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/gadget.c | 59 +++++++++++++++++++++++---------------
+ drivers/usb/cdns3/gadget.h |  3 ++
+ 2 files changed, 39 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
+index ee64c4ab8dd2..118c9402bb60 100644
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -2063,11 +2063,10 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
+       bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC);
+       struct cdns3_device *priv_dev = priv_ep->cdns3_dev;
+       u32 bEndpointAddress = priv_ep->num | priv_ep->dir;
+-      u32 max_packet_size = 0;
+-      u8 maxburst = 0;
++      u32 max_packet_size = priv_ep->wMaxPacketSize;
++      u8 maxburst = priv_ep->bMaxBurst;
+       u32 ep_cfg = 0;
+       u8 buffering;
+-      u8 mult = 0;
+       int ret;
+       buffering = priv_dev->ep_buf_size - 1;
+@@ -2089,8 +2088,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
+               break;
+       default:
+               ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC);
+-              mult = priv_dev->ep_iso_burst - 1;
+-              buffering = mult + 1;
++              buffering = (priv_ep->bMaxBurst + 1) * (priv_ep->mult + 1) - 1;
+       }
+       switch (priv_dev->gadget.speed) {
+@@ -2101,17 +2099,8 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
+               max_packet_size = is_iso_ep ? 1024 : 512;
+               break;
+       case USB_SPEED_SUPER:
+-              /* It's limitation that driver assumes in driver. */
+-              mult = 0;
+-              max_packet_size = 1024;
+-              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
+-                      maxburst = priv_dev->ep_iso_burst - 1;
+-                      buffering = (mult + 1) *
+-                                  (maxburst + 1);
+-
+-                      if (priv_ep->interval > 1)
+-                              buffering++;
+-              } else {
++              if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) {
++                      max_packet_size = 1024;
+                       maxburst = priv_dev->ep_buf_size - 1;
+               }
+               break;
+@@ -2140,7 +2129,6 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
+       if (priv_dev->dev_ver < DEV_VER_V2)
+               priv_ep->trb_burst_size = 16;
+-      mult = min_t(u8, mult, EP_CFG_MULT_MAX);
+       buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
+       maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);
+@@ -2174,7 +2162,7 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
+       }
+       ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) |
+-                EP_CFG_MULT(mult) |
++                EP_CFG_MULT(priv_ep->mult) |                  /* must match EP setting */
+                 EP_CFG_BUFFERING(buffering) |
+                 EP_CFG_MAXBURST(maxburst);
+@@ -2264,6 +2252,13 @@ usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget,
+       priv_ep->type = usb_endpoint_type(desc);
+       priv_ep->flags |= EP_CLAIMED;
+       priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0;
++      priv_ep->wMaxPacketSize =  usb_endpoint_maxp(desc);
++      priv_ep->mult = USB_EP_MAXP_MULT(priv_ep->wMaxPacketSize);
++      priv_ep->wMaxPacketSize &= USB_ENDPOINT_MAXP_MASK;
++      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && comp_desc) {
++              priv_ep->mult =  USB_SS_MULT(comp_desc->bmAttributes) - 1;
++              priv_ep->bMaxBurst = comp_desc->bMaxBurst;
++      }
+       spin_unlock_irqrestore(&priv_dev->lock, flags);
+       return &priv_ep->endpoint;
+@@ -3033,22 +3028,40 @@ static int cdns3_gadget_check_config(struct usb_gadget *gadget)
+       struct cdns3_endpoint *priv_ep;
+       struct usb_ep *ep;
+       int n_in = 0;
++      int iso = 0;
++      int out = 1;
+       int total;
++      int n;
+       list_for_each_entry(ep, &gadget->ep_list, ep_list) {
+               priv_ep = ep_to_cdns3_ep(ep);
+-              if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN))
+-                      n_in++;
++              if (!(priv_ep->flags & EP_CLAIMED))
++                      continue;
++
++              n = (priv_ep->mult + 1) * (priv_ep->bMaxBurst + 1);
++              if (ep->address & USB_DIR_IN) {
++                      /*
++                       * ISO transfer: DMA start move data when get ISO, only transfer
++                       * data as min(TD size, iso). No benefit for allocate bigger
++                       * internal memory than 'iso'.
++                       */
++                      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
++                              iso += n;
++                      else
++                              n_in++;
++              } else {
++                      if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
++                              out = max_t(int, out, n);
++              }
+       }
+       /* 2KB are reserved for EP0, 1KB for out*/
+-      total = 2 + n_in + 1;
++      total = 2 + n_in + out + iso;
+       if (total > priv_dev->onchip_buffers)
+               return -ENOMEM;
+-      priv_dev->ep_buf_size = priv_dev->ep_iso_burst =
+-                      (priv_dev->onchip_buffers - 2) / (n_in + 1);
++      priv_dev->ep_buf_size = (priv_dev->onchip_buffers - 2 - iso) / (n_in + out);
+       return 0;
+ }
+diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h
+index 32825477edd3..aeb2211228c1 100644
+--- a/drivers/usb/cdns3/gadget.h
++++ b/drivers/usb/cdns3/gadget.h
+@@ -1167,6 +1167,9 @@ struct cdns3_endpoint {
+       u8                      dir;
+       u8                      num;
+       u8                      type;
++      u8                      mult;
++      u8                      bMaxBurst;
++      u16                     wMaxPacketSize;
+       int                     interval;
+       int                     free_trbs;
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-si.patch b/queue-5.10/usb-cdns3-fix-uvc-fail-when-dma-cross-4k-boundery-si.patch
new file mode 100644 (file)
index 0000000..d1dd19b
--- /dev/null
@@ -0,0 +1,91 @@
+From 05aad0082bf48fcac8be321c53eb97c3815ad73b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Dec 2023 10:38:15 -0500
+Subject: usb: cdns3: Fix uvc fail when DMA cross 4k boundery since sg enabled
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit 40c304109e866a7dc123661a5c8ca72f6b5e14e0 ]
+
+Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but
+still met problem when do ISO transfer if sg enabled.
+
+Data pattern likes below when sg enabled, package size is 1k and mult is 2
+       [UVC Header(8B) ] [data(3k - 8)] ...
+
+The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error
+happen position as below pattern:
+       0xd000: wrong
+       0xe000: wrong
+       0xf000: correct
+       0x10000: wrong
+       0x11000: wrong
+       0x12000: correct
+       ...
+
+To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according
+to start DMA address's alignment.
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231224153816.1664687-4-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/gadget.c | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
+index 118c9402bb60..8a1f0a636848 100644
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -1119,6 +1119,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+       u32 togle_pcs = 1;
+       int sg_iter = 0;
+       int num_trb_req;
++      int trb_burst;
+       int num_trb;
+       int address;
+       u32 control;
+@@ -1241,7 +1242,36 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+                       total_tdl += DIV_ROUND_UP(length,
+                                              priv_ep->endpoint.maxpacket);
+-              trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) |
++              trb_burst = priv_ep->trb_burst_size;
++
++              /*
++               * Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but still
++               * met problem when do ISO transfer if sg enabled.
++               *
++               * Data pattern likes below when sg enabled, package size is 1k and mult is 2
++               *       [UVC Header(8B) ] [data(3k - 8)] ...
++               *
++               * The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error happen
++               * as below pattern:
++               *      0xd000: wrong
++               *      0xe000: wrong
++               *      0xf000: correct
++               *      0x10000: wrong
++               *      0x11000: wrong
++               *      0x12000: correct
++               *      ...
++               *
++               * But it is still unclear about why error have not happen below 0xd000, it should
++               * cross 4k bounder. But anyway, the below code can fix this problem.
++               *
++               * To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according to 16.
++               */
++              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_dev->dev_ver <= DEV_VER_V2)
++                      if (ALIGN_DOWN(trb->buffer, SZ_4K) !=
++                          ALIGN_DOWN(trb->buffer + length, SZ_4K))
++                              trb_burst = 16;
++
++              trb->length |= cpu_to_le32(TRB_BURST_LEN(trb_burst) |
+                                       TRB_LEN(length));
+               pcs = priv_ep->pcs ? TRB_CYCLE : 0;
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-cdns3-fix-uvc-failure-work-since-sg-support-enab.patch b/queue-5.10/usb-cdns3-fix-uvc-failure-work-since-sg-support-enab.patch
new file mode 100644 (file)
index 0000000..a44a01d
--- /dev/null
@@ -0,0 +1,159 @@
+From a333a132b7738e81197e1a6a82b54b832bed1590 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Dec 2023 10:38:13 -0500
+Subject: usb: cdns3: fix uvc failure work since sg support enabled
+
+From: Frank Li <Frank.Li@nxp.com>
+
+[ Upstream commit 1b8be5ecff26201bafb0a554c74e91571299fb94 ]
+
+When IP version >= DEV_VER_V2, gadget:sg_supported is true. So uvc gadget
+function driver will use sg to equeue data, first is 8bytes header, the
+second is 1016bytes data.
+
+    cdns3_prepare_trb: ep2in: trb 0000000000ac755f, dma buf: 0xbf455000, size: 8, burst: 128 ctrl: 0x00000415 (C=1, T=0, ISP, CHAIN, Normal)
+    cdns3_prepare_trb: ep2in: trb 00000000a574e693, dma buf: 0xc0200fe0, size: 1016, burst: 128 ctrl: 0x00000405 (C=1, T=0, ISP, Normal)
+
+But cdns3_ep_run_transfer() can't correctly handle this case, which only
+support one TRB for ISO transfer.
+
+The controller requires duplicate the TD for each SOF if priv_ep->interval
+is not 1. DMA will read data from DDR to internal FIFO when get SOF. Send
+data to bus when receive IN token. DMA always refill FIFO when get SOF
+regardless host send IN token or not. If host send IN token later, some
+frames data will be lost.
+
+Fixed it by below major steps:
+
+1. Calculate numembers of TRB base on sg_nums and priv_ep->interval.
+2. Remove CHAIN flags for each end TRB of TD when duplicate TD.
+3. The controller requires LINK TRB must be first TRB of TD. When check
+there are not enough TRBs lefts, just fill LINK TRB for left TRBs.
+
+.... CHAIN_TRB DATA_TRB, CHAIN_TRB DATA_TRB,  LINK_TRB ... LINK_TRB
+                                                           ^End of TRB List
+
+Cc:  <stable@vger.kernel.org>
+Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver")
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Link: https://lore.kernel.org/r/20231224153816.1664687-2-Frank.Li@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/gadget.c | 51 ++++++++++++++++++++++++++++++--------
+ 1 file changed, 40 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
+index 82b6fd2bc890..575180a59ad4 100644
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -1118,6 +1118,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+       dma_addr_t trb_dma;
+       u32 togle_pcs = 1;
+       int sg_iter = 0;
++      int num_trb_req;
+       int num_trb;
+       int address;
+       u32 control;
+@@ -1126,15 +1127,13 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+       struct scatterlist *s = NULL;
+       bool sg_supported = !!(request->num_mapped_sgs);
++      num_trb_req = sg_supported ? request->num_mapped_sgs : 1;
++
++      /* ISO transfer require each SOF have a TD, each TD include some TRBs */
+       if (priv_ep->type == USB_ENDPOINT_XFER_ISOC)
+-              num_trb = priv_ep->interval;
++              num_trb = priv_ep->interval * num_trb_req;
+       else
+-              num_trb = sg_supported ? request->num_mapped_sgs : 1;
+-
+-      if (num_trb > priv_ep->free_trbs) {
+-              priv_ep->flags |= EP_RING_FULL;
+-              return -ENOBUFS;
+-      }
++              num_trb = num_trb_req;
+       priv_req = to_cdns3_request(request);
+       address = priv_ep->endpoint.desc->bEndpointAddress;
+@@ -1183,14 +1182,31 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+               link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) |
+                                   TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit);
++
++              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) {
++                      /*
++                       * ISO require LINK TRB must be first one of TD.
++                       * Fill LINK TRBs for left trb space to simply software process logic.
++                       */
++                      while (priv_ep->enqueue) {
++                              *trb = *link_trb;
++                              trace_cdns3_prepare_trb(priv_ep, trb);
++
++                              cdns3_ep_inc_enq(priv_ep);
++                              trb = priv_ep->trb_pool + priv_ep->enqueue;
++                              priv_req->trb = trb;
++                      }
++              }
++      }
++
++      if (num_trb > priv_ep->free_trbs) {
++              priv_ep->flags |= EP_RING_FULL;
++              return -ENOBUFS;
+       }
+       if (priv_dev->dev_ver <= DEV_VER_V2)
+               togle_pcs = cdns3_wa1_update_guard(priv_ep, trb);
+-      if (sg_supported)
+-              s = request->sg;
+-
+       /* set incorrect Cycle Bit for first trb*/
+       control = priv_ep->pcs ? 0 : TRB_CYCLE;
+       trb->length = 0;
+@@ -1208,6 +1224,9 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+       do {
+               u32 length;
++              if (!(sg_iter % num_trb_req) && sg_supported)
++                      s = request->sg;
++
+               /* fill TRB */
+               control |= TRB_TYPE(TRB_NORMAL);
+               if (sg_supported) {
+@@ -1249,7 +1268,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+               if (sg_supported) {
+                       trb->control |= cpu_to_le32(TRB_ISP);
+                       /* Don't set chain bit for last TRB */
+-                      if (sg_iter < num_trb - 1)
++                      if ((sg_iter % num_trb_req) < num_trb_req - 1)
+                               trb->control |= cpu_to_le32(TRB_CHAIN);
+                       s = sg_next(s);
+@@ -1507,6 +1526,12 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
+               /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */
+               while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) {
++
++                      /* ISO ep_traddr may stop at LINK TRB */
++                      if (priv_ep->dequeue == cdns3_get_dma_pos(priv_dev, priv_ep) &&
++                          priv_ep->type == USB_ENDPOINT_XFER_ISOC)
++                              break;
++
+                       trace_cdns3_complete_trb(priv_ep, trb);
+                       cdns3_ep_inc_deq(priv_ep);
+                       trb = priv_ep->trb_pool + priv_ep->dequeue;
+@@ -1539,6 +1564,10 @@ static void cdns3_transfer_completed(struct cdns3_device *priv_dev,
+                       }
+                       if (request_handled) {
++                              /* TRBs are duplicated by priv_ep->interval time for ISO IN */
++                              if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_ep->dir)
++                                      request->actual /= priv_ep->interval;
++
+                               cdns3_gadget_giveback(priv_ep, priv_req, 0);
+                               request_handled = false;
+                               transfer_end = false;
+-- 
+2.43.0
+
diff --git a/queue-5.10/usb-cdns3-fixes-for-sparse-warnings.patch b/queue-5.10/usb-cdns3-fixes-for-sparse-warnings.patch
new file mode 100644 (file)
index 0000000..ca7a39f
--- /dev/null
@@ -0,0 +1,85 @@
+From 2bd3a8a5cfa4b169ccf0085b39c468668cc18892 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Dec 2020 12:04:33 +0100
+Subject: usb: cdns3: Fixes for sparse warnings
+
+From: Pawel Laszczak <pawell@cadence.com>
+
+[ Upstream commit fba8701baed76eac00b84b59f09f6a077f24c534 ]
+
+Patch fixes the following warnings:
+cdns3-gadget.c:1203: sparse: warning: incorrect type
+                     in assignment (different base types)
+cdns3-gadget.c:1203: sparse:  expected restricted __le32 [usertype] length
+cdns3-gadget.c:1203: sparse:  got unsigned long
+cdns3-gadget.c:1250: sparse: warning: invalid assignment: |=
+cdns3-gadget.c:1250: sparse:  left side has type restricted __le32
+cdns3-gadget.c:1250: sparse:  right side has type unsigned long
+cdns3-gadget.c:1253: sparse: warning: invalid assignment: |=
+cdns3-gadget.c:1253: sparse:  left side has type restricted __le32
+cdns3-gadget.c:1253: sparse:  right side has type unsigned long
+cdns3-ep0.c:367: sparse: warning: restricted __le16 degrades to integer
+cdns3-ep0.c:792: sparse: warning: symbol 'cdns3_gadget_ep0_ops' was not
+                                  declared. Should it be static?
+
+Reported-by: kernel test robot <lkp@intel.com>
+Signed-off-by: Pawel Laszczak <pawell@cadence.com>
+Signed-off-by: Peter Chen <peter.chen@nxp.com>
+Stable-dep-of: 1b8be5ecff26 ("usb: cdns3: fix uvc failure work since sg support enabled")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/cdns3/ep0.c    | 4 ++--
+ drivers/usb/cdns3/gadget.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c
+index 30d3516c7f98..4241c513b9f6 100644
+--- a/drivers/usb/cdns3/ep0.c
++++ b/drivers/usb/cdns3/ep0.c
+@@ -364,7 +364,7 @@ static int cdns3_ep0_feature_handle_endpoint(struct cdns3_device *priv_dev,
+       if (le16_to_cpu(ctrl->wValue) != USB_ENDPOINT_HALT)
+               return -EINVAL;
+-      if (!(ctrl->wIndex & ~USB_DIR_IN))
++      if (!(le16_to_cpu(ctrl->wIndex) & ~USB_DIR_IN))
+               return 0;
+       index = cdns3_ep_addr_to_index(le16_to_cpu(ctrl->wIndex));
+@@ -790,7 +790,7 @@ int cdns3_gadget_ep_set_wedge(struct usb_ep *ep)
+       return 0;
+ }
+-const struct usb_ep_ops cdns3_gadget_ep0_ops = {
++static const struct usb_ep_ops cdns3_gadget_ep0_ops = {
+       .enable = cdns3_gadget_ep0_enable,
+       .disable = cdns3_gadget_ep0_disable,
+       .alloc_request = cdns3_gadget_ep_alloc_request,
+diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
+index 210c1d615082..82b6fd2bc890 100644
+--- a/drivers/usb/cdns3/gadget.c
++++ b/drivers/usb/cdns3/gadget.c
+@@ -1200,7 +1200,7 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+               td_size = DIV_ROUND_UP(request->length,
+                                      priv_ep->endpoint.maxpacket);
+               if (priv_dev->gadget.speed == USB_SPEED_SUPER)
+-                      trb->length = TRB_TDL_SS_SIZE(td_size);
++                      trb->length = cpu_to_le32(TRB_TDL_SS_SIZE(td_size));
+               else
+                       control |= TRB_TDL_HS_SIZE(td_size);
+       }
+@@ -1247,10 +1247,10 @@ static int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep,
+                       priv_req->trb->control = cpu_to_le32(control);
+               if (sg_supported) {
+-                      trb->control |= TRB_ISP;
++                      trb->control |= cpu_to_le32(TRB_ISP);
+                       /* Don't set chain bit for last TRB */
+                       if (sg_iter < num_trb - 1)
+-                              trb->control |= TRB_CHAIN;
++                              trb->control |= cpu_to_le32(TRB_CHAIN);
+                       s = sg_next(s);
+               }
+-- 
+2.43.0
+