]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Fri, 26 Jan 2024 14:04:45 +0000 (09:04 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 26 Jan 2024 14:04:45 +0000 (09:04 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/dmaengine-fix-null-pointer-in-channel-unregistration.patch [new file with mode: 0644]
queue-6.1/iio-adc-ad7091r-allow-users-to-configure-device-even.patch [new file with mode: 0644]
queue-6.1/iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch [new file with mode: 0644]
queue-6.1/iio-adc-ad7091r-set-alert-bit-in-config-register.patch [new file with mode: 0644]
queue-6.1/revert-nsvm-check-for-reserved-encodings-of-tlb_cont.patch [new file with mode: 0644]
queue-6.1/scsi-ufs-core-remove-the-ufshcd_hba_exit-call-from-u.patch [new file with mode: 0644]
queue-6.1/series [new file with mode: 0644]
queue-6.1/usb-dwc3-gadget-handle-ep0-request-dequeuing-properl.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-gadget-queue-pm-runtime-idle-on-disconnect-.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-gadget-refactor-ep0-forced-stall-restart-in.patch [new file with mode: 0644]

diff --git a/queue-6.1/dmaengine-fix-null-pointer-in-channel-unregistration.patch b/queue-6.1/dmaengine-fix-null-pointer-in-channel-unregistration.patch
new file mode 100644 (file)
index 0000000..48cf40e
--- /dev/null
@@ -0,0 +1,55 @@
+From ac1887e541ccfa6626956dd4aae806ef7d5b9b9f 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 8a6e6b60d66f..892e8389232e 100644
+--- a/drivers/dma/dmaengine.c
++++ b/drivers/dma/dmaengine.c
+@@ -1103,6 +1103,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-6.1/iio-adc-ad7091r-allow-users-to-configure-device-even.patch b/queue-6.1/iio-adc-ad7091r-allow-users-to-configure-device-even.patch
new file mode 100644 (file)
index 0000000..fa3a07d
--- /dev/null
@@ -0,0 +1,295 @@
+From e68821e0b9ff21754b123bfdb2c3f641c53c9f83 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 8aaa854f816f..3d36bcd26b0c 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 47f5763023a4..12d475463945 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-6.1/iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch b/queue-6.1/iio-adc-ad7091r-enable-internal-vref-if-external-vre.patch
new file mode 100644 (file)
index 0000000..b4d19a4
--- /dev/null
@@ -0,0 +1,67 @@
+From 2234d6e63447c84ac537c618b57d411e0fb5e5fd 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 3d36bcd26b0c..76002b91c86a 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-6.1/iio-adc-ad7091r-set-alert-bit-in-config-register.patch b/queue-6.1/iio-adc-ad7091r-set-alert-bit-in-config-register.patch
new file mode 100644 (file)
index 0000000..801c2ee
--- /dev/null
@@ -0,0 +1,53 @@
+From 72434e8d945a04b7a5c07386747c6e028e5c1bbe 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 0e5d3d2e9c98..8aaa854f816f 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-6.1/revert-nsvm-check-for-reserved-encodings-of-tlb_cont.patch b/queue-6.1/revert-nsvm-check-for-reserved-encodings-of-tlb_cont.patch
new file mode 100644 (file)
index 0000000..fc88d8f
--- /dev/null
@@ -0,0 +1,65 @@
+From 1fad458de7b2324a442126e1efff828628edbb70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Oct 2023 12:41:03 -0700
+Subject: Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested
+ VMCB"
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit a484755ab2526ebdbe042397cdd6e427eb4b1a68 ]
+
+Revert KVM's made-up consistency check on SVM's TLB control.  The APM says
+that unsupported encodings are reserved, but the APM doesn't state that
+VMRUN checks for a supported encoding.  Unless something is called out
+in "Canonicalization and Consistency Checks" or listed as MBZ (Must Be
+Zero), AMD behavior is typically to let software shoot itself in the foot.
+
+This reverts commit 174a921b6975ef959dd82ee9e8844067a62e3ec1.
+
+Fixes: 174a921b6975 ("nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB")
+Reported-by: Stefan Sterz <s.sterz@proxmox.com>
+Closes: https://lkml.kernel.org/r/b9915c9c-4cf6-051a-2d91-44cc6380f455%40proxmox.com
+Cc: stable@vger.kernel.org
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Link: https://lore.kernel.org/r/20231018194104.1896415-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/svm/nested.c | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
+index bc288e6bde64..5d4d78c9a787 100644
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -239,18 +239,6 @@ static bool nested_svm_check_bitmap_pa(struct kvm_vcpu *vcpu, u64 pa, u32 size)
+           kvm_vcpu_is_legal_gpa(vcpu, addr + size - 1);
+ }
+-static bool nested_svm_check_tlb_ctl(struct kvm_vcpu *vcpu, u8 tlb_ctl)
+-{
+-      /* Nested FLUSHBYASID is not supported yet.  */
+-      switch(tlb_ctl) {
+-              case TLB_CONTROL_DO_NOTHING:
+-              case TLB_CONTROL_FLUSH_ALL_ASID:
+-                      return true;
+-              default:
+-                      return false;
+-      }
+-}
+-
+ static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu,
+                                        struct vmcb_ctrl_area_cached *control)
+ {
+@@ -270,8 +258,6 @@ static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu,
+                                          IOPM_SIZE)))
+               return false;
+-      if (CC(!nested_svm_check_tlb_ctl(vcpu, control->tlb_ctl)))
+-              return false;
+       return true;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.1/scsi-ufs-core-remove-the-ufshcd_hba_exit-call-from-u.patch b/queue-6.1/scsi-ufs-core-remove-the-ufshcd_hba_exit-call-from-u.patch
new file mode 100644 (file)
index 0000000..029a4ba
--- /dev/null
@@ -0,0 +1,48 @@
+From 48a21764dc2244fecd2817dd9a0dfdf089e4eb5c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Dec 2023 14:52:15 -0800
+Subject: scsi: ufs: core: Remove the ufshcd_hba_exit() call from
+ ufshcd_async_scan()
+
+From: Bart Van Assche <bvanassche@acm.org>
+
+[ Upstream commit ee36710912b2075c417100a8acc642c9c6496501 ]
+
+Calling ufshcd_hba_exit() from a function that is called asynchronously
+from ufshcd_init() is wrong because this triggers multiple race
+conditions. Instead of calling ufshcd_hba_exit(), log an error message.
+
+Reported-by: Daniel Mentz <danielmentz@google.com>
+Fixes: 1d337ec2f35e ("ufs: improve init sequence")
+Signed-off-by: Bart Van Assche <bvanassche@acm.org>
+Link: https://lore.kernel.org/r/20231218225229.2542156-3-bvanassche@acm.org
+Reviewed-by: Can Guo <quic_cang@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ufs/core/ufshcd.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
+index 474e94a69b18..9fd4e9ed93b8 100644
+--- a/drivers/ufs/core/ufshcd.c
++++ b/drivers/ufs/core/ufshcd.c
+@@ -8333,12 +8333,9 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
+ out:
+       pm_runtime_put_sync(hba->dev);
+-      /*
+-       * If we failed to initialize the device or the device is not
+-       * present, turn off the power/clocks etc.
+-       */
++
+       if (ret)
+-              ufshcd_hba_exit(hba);
++              dev_err(hba->dev, "%s failed: %d\n", __func__, ret);
+ }
+ static const struct attribute_group *ufshcd_driver_groups[] = {
+-- 
+2.43.0
+
diff --git a/queue-6.1/series b/queue-6.1/series
new file mode 100644 (file)
index 0000000..d84c9b7
--- /dev/null
@@ -0,0 +1,9 @@
+usb-dwc3-gadget-refactor-ep0-forced-stall-restart-in.patch
+usb-dwc3-gadget-queue-pm-runtime-idle-on-disconnect-.patch
+usb-dwc3-gadget-handle-ep0-request-dequeuing-properl.patch
+revert-nsvm-check-for-reserved-encodings-of-tlb_cont.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
+scsi-ufs-core-remove-the-ufshcd_hba_exit-call-from-u.patch
diff --git a/queue-6.1/usb-dwc3-gadget-handle-ep0-request-dequeuing-properl.patch b/queue-6.1/usb-dwc3-gadget-handle-ep0-request-dequeuing-properl.patch
new file mode 100644 (file)
index 0000000..04fdaad
--- /dev/null
@@ -0,0 +1,73 @@
+From 381d4fb6dbc06f9bb17707277be383f656a1eaa5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 12:18:14 -0800
+Subject: usb: dwc3: gadget: Handle EP0 request dequeuing properly
+
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+
+[ Upstream commit 730e12fbec53ab59dd807d981a204258a4cfb29a ]
+
+Current EP0 dequeue path will share the same as other EPs.  However, there
+are some special considerations that need to be made for EP0 transfers:
+
+  - EP0 transfers never transition into the started_list
+  - EP0 only has one active request at a time
+
+In case there is a vendor specific control message for a function over USB
+FFS, then there is no guarantee on the timeline which the DATA/STATUS stage
+is responded to.  While this occurs, any attempt to end transfers on
+non-control EPs will end up having the DWC3_EP_DELAY_STOP flag set, and
+defer issuing of the end transfer command.  If the USB FFS application
+decides to timeout the control transfer, or if USB FFS AIO path exits, the
+USB FFS driver will issue a call to usb_ep_dequeue() for the ep0 request.
+
+In case of the AIO exit path, the AIO FS blocks until all pending USB
+requests utilizing the AIO path is completed.  However, since the dequeue
+of ep0 req does not happen properly, all non-control EPs with the
+DWC3_EP_DELAY_STOP flag set will not be handled, and the AIO exit path will
+be stuck waiting for the USB FFS data endpoints to receive a completion
+callback.
+
+Fix is to utilize dwc3_ep0_reset_state() in the dequeue API to ensure EP0
+is brought back to the SETUP state, and ensures that any deferred end
+transfer commands are handled.  This also will end any active transfers
+on EP0, compared to the previous implementation which directly called
+giveback only.
+
+Fixes: fcd2def66392 ("usb: dwc3: gadget: Refactor dwc3_gadget_ep_dequeue")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://lore.kernel.org/r/20231206201814.32664-1-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 5617a75b0d74..c4703f6b2089 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -2093,7 +2093,17 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
+       list_for_each_entry(r, &dep->pending_list, list) {
+               if (r == req) {
+-                      dwc3_gadget_giveback(dep, req, -ECONNRESET);
++                      /*
++                       * Explicitly check for EP0/1 as dequeue for those
++                       * EPs need to be handled differently.  Control EP
++                       * only deals with one USB req, and giveback will
++                       * occur during dwc3_ep0_stall_and_restart().  EP0
++                       * requests are never added to started_list.
++                       */
++                      if (dep->number > 1)
++                              dwc3_gadget_giveback(dep, req, -ECONNRESET);
++                      else
++                              dwc3_ep0_reset_state(dwc);
+                       goto out;
+               }
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.1/usb-dwc3-gadget-queue-pm-runtime-idle-on-disconnect-.patch b/queue-6.1/usb-dwc3-gadget-queue-pm-runtime-idle-on-disconnect-.patch
new file mode 100644 (file)
index 0000000..eef5622
--- /dev/null
@@ -0,0 +1,62 @@
+From 3685641a97ea691f4361bc2d9f6a98cdebea549b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 13:49:46 -0800
+Subject: usb: dwc3: gadget: Queue PM runtime idle on disconnect event
+
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+
+[ Upstream commit 3c7af52c7616c3aa6dacd2336ec748d4a65df8f4 ]
+
+There is a scenario where DWC3 runtime suspend is blocked due to the
+dwc->connected flag still being true while PM usage_count is zero after
+DWC3 giveback is completed and the USB gadget session is being terminated.
+This leads to a case where nothing schedules a PM runtime idle for the
+device.
+
+The exact condition is seen with the following sequence:
+  1.  USB bus reset is issued by the host
+  2.  Shortly after, or concurrently, a USB PD DR SWAP request is received
+      (sink->source)
+  3.  USB bus reset event handler runs and issues
+      dwc3_stop_active_transfers(), and pending transfer are stopped
+  4.  DWC3 usage_count decremented to 0, and runtime idle occurs while
+      dwc->connected == true, returns -EBUSY
+  5.  DWC3 disconnect event seen, dwc->connected set to false due to DR
+      swap handling
+  6.  No runtime idle after this point
+
+Address this by issuing an asynchronous PM runtime idle call after the
+disconnect event is completed, as it modifies the dwc->connected flag,
+which is what blocks the initial runtime idle.
+
+Fixes: fc8bb91bc83e ("usb: dwc3: implement runtime PM")
+Cc:  <stable@vger.kernel.org>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Link: https://lore.kernel.org/r/20240103214946.2596-1-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 339e8c3f7c50..5617a75b0d74 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3860,6 +3860,13 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
+       usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED);
+       dwc3_ep0_reset_state(dwc);
++
++      /*
++       * Request PM idle to address condition where usage count is
++       * already decremented to zero, but waiting for the disconnect
++       * interrupt to set dwc->connected to FALSE.
++       */
++      pm_request_idle(dwc->dev);
+ }
+ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
+-- 
+2.43.0
+
diff --git a/queue-6.1/usb-dwc3-gadget-refactor-ep0-forced-stall-restart-in.patch b/queue-6.1/usb-dwc3-gadget-refactor-ep0-forced-stall-restart-in.patch
new file mode 100644 (file)
index 0000000..f73837d
--- /dev/null
@@ -0,0 +1,114 @@
+From 6c608ba4f1e98b013aefab85419369b98de2fc7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Apr 2023 14:27:59 -0700
+Subject: usb: dwc3: gadget: Refactor EP0 forced stall/restart into a separate
+ API
+
+From: Wesley Cheng <quic_wcheng@quicinc.com>
+
+[ Upstream commit 8f40fc0808137c157dd408d2632e63bfca2aecdb ]
+
+Several sequences utilize the same routine for forcing the control endpoint
+back into the SETUP phase.  This is required, because those operations need
+to ensure that EP0 is back in the default state.
+
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Link: https://lore.kernel.org/r/20230420212759.29429-3-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 3c7af52c7616 ("usb: dwc3: gadget: Queue PM runtime idle on disconnect event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/dwc3/gadget.c | 53 ++++++++++++++++-----------------------
+ 1 file changed, 21 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 137602d9076f..339e8c3f7c50 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -139,6 +139,24 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
+       return -ETIMEDOUT;
+ }
++static void dwc3_ep0_reset_state(struct dwc3 *dwc)
++{
++      unsigned int    dir;
++
++      if (dwc->ep0state != EP0_SETUP_PHASE) {
++              dir = !!dwc->ep0_expect_in;
++              if (dwc->ep0state == EP0_DATA_PHASE)
++                      dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
++              else
++                      dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
++
++              dwc->eps[0]->trb_enqueue = 0;
++              dwc->eps[1]->trb_enqueue = 0;
++
++              dwc3_ep0_stall_and_restart(dwc);
++      }
++}
++
+ /**
+  * dwc3_ep_inc_trb - increment a trb index.
+  * @index: Pointer to the TRB index to increment.
+@@ -2552,16 +2570,9 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
+               ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
+                               msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
+               if (ret == 0) {
+-                      unsigned int    dir;
+-
+                       dev_warn(dwc->dev, "wait for SETUP phase timed out\n");
+                       spin_lock_irqsave(&dwc->lock, flags);
+-                      dir = !!dwc->ep0_expect_in;
+-                      if (dwc->ep0state == EP0_DATA_PHASE)
+-                              dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
+-                      else
+-                              dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
+-                      dwc3_ep0_stall_and_restart(dwc);
++                      dwc3_ep0_reset_state(dwc);
+                       spin_unlock_irqrestore(&dwc->lock, flags);
+               }
+       }
+@@ -3848,16 +3859,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
+       dwc->setup_packet_pending = false;
+       usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED);
+-      if (dwc->ep0state != EP0_SETUP_PHASE) {
+-              unsigned int    dir;
+-
+-              dir = !!dwc->ep0_expect_in;
+-              if (dwc->ep0state == EP0_DATA_PHASE)
+-                      dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
+-              else
+-                      dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
+-              dwc3_ep0_stall_and_restart(dwc);
+-      }
++      dwc3_ep0_reset_state(dwc);
+ }
+ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
+@@ -3913,20 +3915,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
+        * phase. So ensure that EP0 is in setup phase by issuing a stall
+        * and restart if EP0 is not in setup phase.
+        */
+-      if (dwc->ep0state != EP0_SETUP_PHASE) {
+-              unsigned int    dir;
+-
+-              dir = !!dwc->ep0_expect_in;
+-              if (dwc->ep0state == EP0_DATA_PHASE)
+-                      dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
+-              else
+-                      dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
+-
+-              dwc->eps[0]->trb_enqueue = 0;
+-              dwc->eps[1]->trb_enqueue = 0;
+-
+-              dwc3_ep0_stall_and_restart(dwc);
+-      }
++      dwc3_ep0_reset_state(dwc);
+       /*
+        * In the Synopsis DesignWare Cores USB3 Databook Rev. 3.30a
+-- 
+2.43.0
+