commit:     190af96490abc9ac3659f6e8a74e7ae51df04e0a
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat May 25 15:18:56 2024 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat May 25 15:18:56 2024 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=190af964

Linux patch 6.9.2

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README            |    4 +
 1001_linux-6.9.2.patch | 1480 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1484 insertions(+)

diff --git a/0000_README b/0000_README
index 55885e7a..111716b6 100644
--- a/0000_README
+++ b/0000_README
@@ -47,6 +47,10 @@ Patch:  1000_linux-6.9.1.patch
 From:   https://www.kernel.org
 Desc:   Linux 6.9.1
 
+Patch:  1001_linux-6.9.2.patch
+From:   https://www.kernel.org
+Desc:   Linux 6.9.2
+
 Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
 From:   
http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default.

diff --git a/1001_linux-6.9.2.patch b/1001_linux-6.9.2.patch
new file mode 100644
index 00000000..0b2b2476
--- /dev/null
+++ b/1001_linux-6.9.2.patch
@@ -0,0 +1,1480 @@
+diff --git a/Documentation/ABI/stable/sysfs-block 
b/Documentation/ABI/stable/sysfs-block
+index 1fe9a553c37b7..f0025d1c3d5ac 100644
+--- a/Documentation/ABI/stable/sysfs-block
++++ b/Documentation/ABI/stable/sysfs-block
+@@ -101,6 +101,16 @@ Description:
+               devices that support receiving integrity metadata.
+ 
+ 
++What:         /sys/block/<disk>/partscan
++Date:         May 2024
++Contact:      Christoph Hellwig <[email protected]>
++Description:
++              The /sys/block/<disk>/partscan files reports if partition
++              scanning is enabled for the disk.  It returns "1" if partition
++              scanning is enabled, or "0" if not.  The value type is a 32-bit
++              unsigned integer, but only "0" and "1" are valid values.
++
++
+ What:         /sys/block/<disk>/<partition>/alignment_offset
+ Date:         April 2009
+ Contact:      Martin K. Petersen <[email protected]>
+diff --git a/Documentation/admin-guide/hw-vuln/core-scheduling.rst 
b/Documentation/admin-guide/hw-vuln/core-scheduling.rst
+index cf1eeefdfc32f..a92e10ec402e7 100644
+--- a/Documentation/admin-guide/hw-vuln/core-scheduling.rst
++++ b/Documentation/admin-guide/hw-vuln/core-scheduling.rst
+@@ -67,8 +67,8 @@ arg4:
+     will be performed for all tasks in the task group of ``pid``.
+ 
+ arg5:
+-    userspace pointer to an unsigned long for storing the cookie returned by
+-    ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.
++    userspace pointer to an unsigned long long for storing the cookie returned
++    by ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.
+ 
+ In order for a process to push a cookie to, or pull a cookie from a process, 
it
+ is required to have the ptrace access mode: `PTRACE_MODE_READ_REALCREDS` to 
the
+diff --git a/Documentation/admin-guide/mm/damon/usage.rst 
b/Documentation/admin-guide/mm/damon/usage.rst
+index 6fce035fdbf5c..7daf1a95f9cb4 100644
+--- a/Documentation/admin-guide/mm/damon/usage.rst
++++ b/Documentation/admin-guide/mm/damon/usage.rst
+@@ -153,7 +153,7 @@ Users can write below commands for the kdamond to the 
``state`` file.
+ - ``clear_schemes_tried_regions``: Clear the DAMON-based operating scheme
+   action tried regions directory for each DAMON-based operation scheme of the
+   kdamond.
+-- ``update_schemes_effective_bytes``: Update the contents of
++- ``update_schemes_effective_quotas``: Update the contents of
+   ``effective_bytes`` files for each DAMON-based operation scheme of the
+   kdamond.  For more details, refer to :ref:`quotas directory <sysfs_quotas>`.
+ 
+@@ -342,7 +342,7 @@ Based on the user-specified :ref:`goal 
<sysfs_schemes_quota_goals>`, the
+ effective size quota is further adjusted.  Reading ``effective_bytes`` returns
+ the current effective size quota.  The file is not updated in real time, so
+ users should ask DAMON sysfs interface to update the content of the file for
+-the stats by writing a special keyword, ``update_schemes_effective_bytes`` to
++the stats by writing a special keyword, ``update_schemes_effective_quotas`` to
+ the relevant ``kdamonds/<N>/state`` file.
+ 
+ Under ``weights`` directory, three files (``sz_permil``,
+@@ -434,7 +434,7 @@ pages of all memory cgroups except 
``/having_care_already``.::
+     # # further filter out all cgroups except one at '/having_care_already'
+     echo memcg > 1/type
+     echo /having_care_already > 1/memcg_path
+-    echo N > 1/matching
++    echo Y > 1/matching
+ 
+ Note that ``anon`` and ``memcg`` filters are currently supported only when
+ ``paddr`` :ref:`implementation <sysfs_context>` is being used.
+diff --git a/Documentation/sphinx/kernel_include.py 
b/Documentation/sphinx/kernel_include.py
+index abe7680883771..6387624423363 100755
+--- a/Documentation/sphinx/kernel_include.py
++++ b/Documentation/sphinx/kernel_include.py
+@@ -97,7 +97,6 @@ class KernelInclude(Include):
+         # HINT: this is the only line I had to change / commented out:
+         #path = utils.relative_path(None, path)
+ 
+-        path = nodes.reprunicode(path)
+         encoding = self.options.get(
+             'encoding', self.state.document.settings.input_encoding)
+         e_handler=self.state.document.settings.input_encoding_error_handler
+diff --git a/Makefile b/Makefile
+index a7045435151e6..8302496ee7a57 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 6
+ PATCHLEVEL = 9
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Hurr durr I'ma ninja sloth
+ 
+diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
+index 44958ebaf626e..b77bbb67e77b0 100644
+--- a/arch/x86/include/asm/percpu.h
++++ b/arch/x86/include/asm/percpu.h
+@@ -70,7 +70,7 @@
+       unsigned long tcp_ptr__;                                \
+       tcp_ptr__ = __raw_cpu_read(, this_cpu_off);             \
+                                                               \
+-      tcp_ptr__ += (unsigned long)(ptr);                      \
++      tcp_ptr__ += (__force unsigned long)(ptr);              \
+       (typeof(*(ptr)) __kernel __force *)tcp_ptr__;           \
+ })
+ #else /* CONFIG_USE_X86_SEG_SUPPORT */
+@@ -102,8 +102,8 @@
+ #endif /* CONFIG_SMP */
+ 
+ #define __my_cpu_type(var)    typeof(var) __percpu_seg_override
+-#define __my_cpu_ptr(ptr)     (__my_cpu_type(*ptr) *)(uintptr_t)(ptr)
+-#define __my_cpu_var(var)     (*__my_cpu_ptr(&var))
++#define __my_cpu_ptr(ptr)     (__my_cpu_type(*ptr)*)(__force uintptr_t)(ptr)
++#define __my_cpu_var(var)     (*__my_cpu_ptr(&(var)))
+ #define __percpu_arg(x)               __percpu_prefix "%" #x
+ #define __force_percpu_arg(x) __force_percpu_prefix "%" #x
+ 
+diff --git a/block/genhd.c b/block/genhd.c
+index bb29a68e1d676..52a4521df067b 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -345,9 +345,7 @@ int disk_scan_partitions(struct gendisk *disk, blk_mode_t 
mode)
+       struct file *file;
+       int ret = 0;
+ 
+-      if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN))
+-              return -EINVAL;
+-      if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
++      if (!disk_has_partscan(disk))
+               return -EINVAL;
+       if (disk->open_partitions)
+               return -EBUSY;
+@@ -503,8 +501,7 @@ int __must_check device_add_disk(struct device *parent, 
struct gendisk *disk,
+                       goto out_unregister_bdi;
+ 
+               /* Make sure the first partition scan will be proceed */
+-              if (get_capacity(disk) && !(disk->flags & GENHD_FL_NO_PART) &&
+-                  !test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
++              if (get_capacity(disk) && disk_has_partscan(disk))
+                       set_bit(GD_NEED_PART_SCAN, &disk->state);
+ 
+               bdev_add(disk->part0, ddev->devt);
+@@ -1047,6 +1044,12 @@ static ssize_t diskseq_show(struct device *dev,
+       return sprintf(buf, "%llu\n", disk->diskseq);
+ }
+ 
++static ssize_t partscan_show(struct device *dev,
++              struct device_attribute *attr, char *buf)
++{
++      return sprintf(buf, "%u\n", disk_has_partscan(dev_to_disk(dev)));
++}
++
+ static DEVICE_ATTR(range, 0444, disk_range_show, NULL);
+ static DEVICE_ATTR(ext_range, 0444, disk_ext_range_show, NULL);
+ static DEVICE_ATTR(removable, 0444, disk_removable_show, NULL);
+@@ -1060,6 +1063,7 @@ static DEVICE_ATTR(stat, 0444, part_stat_show, NULL);
+ static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL);
+ static DEVICE_ATTR(badblocks, 0644, disk_badblocks_show, 
disk_badblocks_store);
+ static DEVICE_ATTR(diskseq, 0444, diskseq_show, NULL);
++static DEVICE_ATTR(partscan, 0444, partscan_show, NULL);
+ 
+ #ifdef CONFIG_FAIL_MAKE_REQUEST
+ ssize_t part_fail_show(struct device *dev,
+@@ -1106,6 +1110,7 @@ static struct attribute *disk_attrs[] = {
+       &dev_attr_events_async.attr,
+       &dev_attr_events_poll_msecs.attr,
+       &dev_attr_diskseq.attr,
++      &dev_attr_partscan.attr,
+ #ifdef CONFIG_FAIL_MAKE_REQUEST
+       &dev_attr_fail.attr,
+ #endif
+diff --git a/block/partitions/core.c b/block/partitions/core.c
+index b11e88c82c8cf..37b5f92d07fec 100644
+--- a/block/partitions/core.c
++++ b/block/partitions/core.c
+@@ -573,10 +573,7 @@ static int blk_add_partitions(struct gendisk *disk)
+       struct parsed_partitions *state;
+       int ret = -EAGAIN, p;
+ 
+-      if (disk->flags & GENHD_FL_NO_PART)
+-              return 0;
+-
+-      if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
++      if (!disk_has_partscan(disk))
+               return 0;
+ 
+       state = check_partition(disk);
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c
+index dd6923d37931f..b21a7b246a0dc 100644
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -5367,7 +5367,7 @@ static long binder_ioctl(struct file *filp, unsigned int 
cmd, unsigned long arg)
+                       goto err;
+               break;
+       case BINDER_SET_MAX_THREADS: {
+-              int max_threads;
++              u32 max_threads;
+ 
+               if (copy_from_user(&max_threads, ubuf,
+                                  sizeof(max_threads))) {
+diff --git a/drivers/android/binder_internal.h 
b/drivers/android/binder_internal.h
+index 7270d4d222070..5b7c80b99ae86 100644
+--- a/drivers/android/binder_internal.h
++++ b/drivers/android/binder_internal.h
+@@ -421,7 +421,7 @@ struct binder_proc {
+       struct list_head todo;
+       struct binder_stats stats;
+       struct list_head delivered_death;
+-      int max_threads;
++      u32 max_threads;
+       int requested_threads;
+       int requested_threads_started;
+       int tmp_ref;
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index e3946f7b736e3..01b99471d1bbe 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -3118,6 +3118,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
+                       bt_dev_err(hdev, "Failed to get fw flavor (%d)", err);
+                       return err;
+               }
++              fw_flavor = (fw_flavor & 0x00000080) >> 7;
+       }
+ 
+       mediatek = hci_get_priv(hdev);
+diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
+index 2015c9fcc3c91..28166df81cf8d 100644
+--- a/drivers/cpufreq/amd-pstate.c
++++ b/drivers/cpufreq/amd-pstate.c
+@@ -50,7 +50,8 @@
+ 
+ #define AMD_PSTATE_TRANSITION_LATENCY 20000
+ #define AMD_PSTATE_TRANSITION_DELAY   1000
+-#define AMD_PSTATE_PREFCORE_THRESHOLD 166
++#define CPPC_HIGHEST_PERF_PERFORMANCE 196
++#define CPPC_HIGHEST_PERF_DEFAULT     166
+ 
+ /*
+  * TODO: We need more time to fine tune processors with shared memory solution
+@@ -290,6 +291,21 @@ static inline int amd_pstate_enable(bool enable)
+       return static_call(amd_pstate_enable)(enable);
+ }
+ 
++static u32 amd_pstate_highest_perf_set(struct amd_cpudata *cpudata)
++{
++      struct cpuinfo_x86 *c = &cpu_data(0);
++
++      /*
++       * For AMD CPUs with Family ID 19H and Model ID range 0x70 to 0x7f,
++       * the highest performance level is set to 196.
++       * https://bugzilla.kernel.org/show_bug.cgi?id=218759
++       */
++      if (c->x86 == 0x19 && (c->x86_model >= 0x70 && c->x86_model <= 0x7f))
++              return CPPC_HIGHEST_PERF_PERFORMANCE;
++
++      return CPPC_HIGHEST_PERF_DEFAULT;
++}
++
+ static int pstate_init_perf(struct amd_cpudata *cpudata)
+ {
+       u64 cap1;
+@@ -306,7 +322,7 @@ static int pstate_init_perf(struct amd_cpudata *cpudata)
+        * the default max perf.
+        */
+       if (cpudata->hw_prefcore)
+-              highest_perf = AMD_PSTATE_PREFCORE_THRESHOLD;
++              highest_perf = amd_pstate_highest_perf_set(cpudata);
+       else
+               highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
+ 
+@@ -330,7 +346,7 @@ static int cppc_init_perf(struct amd_cpudata *cpudata)
+               return ret;
+ 
+       if (cpudata->hw_prefcore)
+-              highest_perf = AMD_PSTATE_PREFCORE_THRESHOLD;
++              highest_perf = amd_pstate_highest_perf_set(cpudata);
+       else
+               highest_perf = cppc_perf.highest_perf;
+ 
+diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c 
b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+index ac41f9c0a2834..8e7b35f764e39 100644
+--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
++++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+@@ -1055,7 +1055,12 @@ static bool setup_dsc_config(
+       if (!is_dsc_possible)
+               goto done;
+ 
+-      dsc_cfg->num_slices_v = pic_height/slice_height;
++      if (slice_height > 0) {
++              dsc_cfg->num_slices_v = pic_height / slice_height;
++      } else {
++              is_dsc_possible = false;
++              goto done;
++      }
+ 
+       if (target_bandwidth_kbps > 0) {
+               is_dsc_possible = decide_dsc_target_bpp_x16(
+diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c 
b/drivers/media/v4l2-core/v4l2-ctrls-core.c
+index c4d995f32191c..09ceb2a868764 100644
+--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
++++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
+@@ -2504,8 +2504,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler 
*hdl)
+ EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
+ 
+ /* Log the control name and value */
+-static void log_ctrl(const struct v4l2_ctrl_handler *hdl,
+-                   struct v4l2_ctrl *ctrl,
++static void log_ctrl(const struct v4l2_ctrl *ctrl,
+                    const char *prefix, const char *colon)
+ {
+       if (ctrl->flags & (V4L2_CTRL_FLAG_DISABLED | V4L2_CTRL_FLAG_WRITE_ONLY))
+@@ -2515,11 +2514,7 @@ static void log_ctrl(const struct v4l2_ctrl_handler 
*hdl,
+ 
+       pr_info("%s%s%s: ", prefix, colon, ctrl->name);
+ 
+-      if (ctrl->handler != hdl)
+-              v4l2_ctrl_lock(ctrl);
+       ctrl->type_ops->log(ctrl);
+-      if (ctrl->handler != hdl)
+-              v4l2_ctrl_unlock(ctrl);
+ 
+       if (ctrl->flags & (V4L2_CTRL_FLAG_INACTIVE |
+                          V4L2_CTRL_FLAG_GRABBED |
+@@ -2538,7 +2533,7 @@ static void log_ctrl(const struct v4l2_ctrl_handler *hdl,
+ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
+                                 const char *prefix)
+ {
+-      struct v4l2_ctrl_ref *ref;
++      struct v4l2_ctrl *ctrl;
+       const char *colon = "";
+       int len;
+ 
+@@ -2550,12 +2545,9 @@ void v4l2_ctrl_handler_log_status(struct 
v4l2_ctrl_handler *hdl,
+       if (len && prefix[len - 1] != ' ')
+               colon = ": ";
+       mutex_lock(hdl->lock);
+-      list_for_each_entry(ref, &hdl->ctrl_refs, node) {
+-              if (ref->from_other_dev ||
+-                  (ref->ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
+-                      continue;
+-              log_ctrl(hdl, ref->ctrl, prefix, colon);
+-      }
++      list_for_each_entry(ctrl, &hdl->ctrls, node)
++              if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
++                      log_ctrl(ctrl, prefix, colon);
+       mutex_unlock(hdl->lock);
+ }
+ EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
+diff --git a/drivers/net/ethernet/micrel/ks8851_common.c 
b/drivers/net/ethernet/micrel/ks8851_common.c
+index 502518cdb4618..6453c92f0fa7c 100644
+--- a/drivers/net/ethernet/micrel/ks8851_common.c
++++ b/drivers/net/ethernet/micrel/ks8851_common.c
+@@ -328,7 +328,6 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
+ {
+       struct ks8851_net *ks = _ks;
+       struct sk_buff_head rxq;
+-      unsigned handled = 0;
+       unsigned long flags;
+       unsigned int status;
+       struct sk_buff *skb;
+@@ -336,24 +335,17 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
+       ks8851_lock(ks, &flags);
+ 
+       status = ks8851_rdreg16(ks, KS_ISR);
++      ks8851_wrreg16(ks, KS_ISR, status);
+ 
+       netif_dbg(ks, intr, ks->netdev,
+                 "%s: status 0x%04x\n", __func__, status);
+ 
+-      if (status & IRQ_LCI)
+-              handled |= IRQ_LCI;
+-
+       if (status & IRQ_LDI) {
+               u16 pmecr = ks8851_rdreg16(ks, KS_PMECR);
+               pmecr &= ~PMECR_WKEVT_MASK;
+               ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
+-
+-              handled |= IRQ_LDI;
+       }
+ 
+-      if (status & IRQ_RXPSI)
+-              handled |= IRQ_RXPSI;
+-
+       if (status & IRQ_TXI) {
+               unsigned short tx_space = ks8851_rdreg16(ks, KS_TXMIR);
+ 
+@@ -365,20 +357,12 @@ static irqreturn_t ks8851_irq(int irq, void *_ks)
+               if (netif_queue_stopped(ks->netdev))
+                       netif_wake_queue(ks->netdev);
+               spin_unlock(&ks->statelock);
+-
+-              handled |= IRQ_TXI;
+       }
+ 
+-      if (status & IRQ_RXI)
+-              handled |= IRQ_RXI;
+-
+       if (status & IRQ_SPIBEI) {
+               netdev_err(ks->netdev, "%s: spi bus error\n", __func__);
+-              handled |= IRQ_SPIBEI;
+       }
+ 
+-      ks8851_wrreg16(ks, KS_ISR, handled);
+-
+       if (status & IRQ_RXI) {
+               /* the datasheet says to disable the rx interrupt during
+                * packet read-out, however we're masking the interrupt
+diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
+index df9d767cb5242..56ede5fa02617 100644
+--- a/drivers/net/usb/ax88179_178a.c
++++ b/drivers/net/usb/ax88179_178a.c
+@@ -174,6 +174,7 @@ struct ax88179_data {
+       u32 wol_supported;
+       u32 wolopts;
+       u8 disconnecting;
++      u8 initialized;
+ };
+ 
+ struct ax88179_int_data {
+@@ -1673,6 +1674,18 @@ static int ax88179_reset(struct usbnet *dev)
+       return 0;
+ }
+ 
++static int ax88179_net_reset(struct usbnet *dev)
++{
++      struct ax88179_data *ax179_data = dev->driver_priv;
++
++      if (ax179_data->initialized)
++              ax88179_reset(dev);
++      else
++              ax179_data->initialized = 1;
++
++      return 0;
++}
++
+ static int ax88179_stop(struct usbnet *dev)
+ {
+       u16 tmp16;
+@@ -1692,6 +1705,7 @@ static const struct driver_info ax88179_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1704,6 +1718,7 @@ static const struct driver_info ax88178a_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1716,7 +1731,7 @@ static const struct driver_info cypress_GX3_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset = ax88179_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1729,7 +1744,7 @@ static const struct driver_info dlink_dub1312_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset = ax88179_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1742,7 +1757,7 @@ static const struct driver_info sitecom_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset = ax88179_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1755,7 +1770,7 @@ static const struct driver_info samsung_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset = ax88179_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1768,7 +1783,7 @@ static const struct driver_info lenovo_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset = ax88179_reset,
++      .reset = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1781,7 +1796,7 @@ static const struct driver_info belkin_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset  = ax88179_reset,
++      .reset  = ax88179_net_reset,
+       .stop   = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1794,7 +1809,7 @@ static const struct driver_info toshiba_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset  = ax88179_reset,
++      .reset  = ax88179_net_reset,
+       .stop = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1807,7 +1822,7 @@ static const struct driver_info mct_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset  = ax88179_reset,
++      .reset  = ax88179_net_reset,
+       .stop   = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1820,7 +1835,7 @@ static const struct driver_info at_umc2000_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset  = ax88179_reset,
++      .reset  = ax88179_net_reset,
+       .stop   = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1833,7 +1848,7 @@ static const struct driver_info at_umc200_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset  = ax88179_reset,
++      .reset  = ax88179_net_reset,
+       .stop   = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+@@ -1846,7 +1861,7 @@ static const struct driver_info at_umc2000sp_info = {
+       .unbind = ax88179_unbind,
+       .status = ax88179_status,
+       .link_reset = ax88179_link_reset,
+-      .reset  = ax88179_reset,
++      .reset  = ax88179_net_reset,
+       .stop   = ax88179_stop,
+       .flags  = FLAG_ETHER | FLAG_FRAMING_AX,
+       .rx_fixup = ax88179_rx_fixup,
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c 
b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+index 4696d73c8971b..1b7254569a37a 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+@@ -1484,7 +1484,6 @@ static void iwl_req_fw_callback(const struct firmware 
*ucode_raw, void *context)
+       size_t trigger_tlv_sz[FW_DBG_TRIGGER_MAX];
+       u32 api_ver;
+       int i;
+-      bool load_module = false;
+       bool usniffer_images = false;
+       bool failure = true;
+ 
+@@ -1732,19 +1731,12 @@ static void iwl_req_fw_callback(const struct firmware 
*ucode_raw, void *context)
+                       goto out_unbind;
+               }
+       } else {
+-              load_module = true;
++              request_module_nowait("%s", op->name);
+       }
+       mutex_unlock(&iwlwifi_opmode_table_mtx);
+ 
+       complete(&drv->request_firmware_complete);
+ 
+-      /*
+-       * Load the module last so we don't block anything
+-       * else from proceeding if the module fails to load
+-       * or hangs loading.
+-       */
+-      if (load_module)
+-              request_module("%s", op->name);
+       failure = false;
+       goto free;
+ 
+diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
+index a35409eda0cf2..67518291a8ad6 100644
+--- a/drivers/remoteproc/mtk_scp.c
++++ b/drivers/remoteproc/mtk_scp.c
+@@ -132,7 +132,7 @@ static int scp_elf_read_ipi_buf_addr(struct mtk_scp *scp,
+ static int scp_ipi_init(struct mtk_scp *scp, const struct firmware *fw)
+ {
+       int ret;
+-      size_t offset;
++      size_t buf_sz, offset;
+ 
+       /* read the ipi buf addr from FW itself first */
+       ret = scp_elf_read_ipi_buf_addr(scp, fw, &offset);
+@@ -144,6 +144,14 @@ static int scp_ipi_init(struct mtk_scp *scp, const struct 
firmware *fw)
+       }
+       dev_info(scp->dev, "IPI buf addr %#010zx\n", offset);
+ 
++      /* Make sure IPI buffer fits in the L2TCM range assigned to this core */
++      buf_sz = sizeof(*scp->recv_buf) + sizeof(*scp->send_buf);
++
++      if (scp->sram_size < buf_sz + offset) {
++              dev_err(scp->dev, "IPI buffer does not fit in SRAM.\n");
++              return -EOVERFLOW;
++      }
++
+       scp->recv_buf = (struct mtk_share_obj __iomem *)
+                       (scp->sram_base + offset);
+       scp->send_buf = (struct mtk_share_obj __iomem *)
+diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
+index 7ce7bb1640054..58ea1e1391cee 100644
+--- a/drivers/tty/serial/kgdboc.c
++++ b/drivers/tty/serial/kgdboc.c
+@@ -19,6 +19,7 @@
+ #include <linux/console.h>
+ #include <linux/vt_kern.h>
+ #include <linux/input.h>
++#include <linux/irq_work.h>
+ #include <linux/module.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_core.h>
+@@ -48,6 +49,25 @@ static struct kgdb_io               kgdboc_earlycon_io_ops;
+ static int                      (*earlycon_orig_exit)(struct console *con);
+ #endif /* IS_BUILTIN(CONFIG_KGDB_SERIAL_CONSOLE) */
+ 
++/*
++ * When we leave the debug trap handler we need to reset the keyboard status
++ * (since the original keyboard state gets partially clobbered by kdb use of
++ * the keyboard).
++ *
++ * The path to deliver the reset is somewhat circuitous.
++ *
++ * To deliver the reset we register an input handler, reset the keyboard and
++ * then deregister the input handler. However, to get this done right, we do
++ * have to carefully manage the calling context because we can only register
++ * input handlers from task context.
++ *
++ * In particular we need to trigger the action from the debug trap handler 
with
++ * all its NMI and/or NMI-like oddities. To solve this the kgdboc trap exit 
code
++ * (the "post_exception" callback) uses irq_work_queue(), which is NMI-safe, 
to
++ * schedule a callback from a hardirq context. From there we have to defer the
++ * work again, this time using schedule_work(), to get a callback using the
++ * system workqueue, which runs in task context.
++ */
+ #ifdef CONFIG_KDB_KEYBOARD
+ static int kgdboc_reset_connect(struct input_handler *handler,
+                               struct input_dev *dev,
+@@ -99,10 +119,17 @@ static void kgdboc_restore_input_helper(struct 
work_struct *dummy)
+ 
+ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
+ 
++static void kgdboc_queue_restore_input_helper(struct irq_work *unused)
++{
++      schedule_work(&kgdboc_restore_input_work);
++}
++
++static DEFINE_IRQ_WORK(kgdboc_restore_input_irq_work, 
kgdboc_queue_restore_input_helper);
++
+ static void kgdboc_restore_input(void)
+ {
+       if (likely(system_state == SYSTEM_RUNNING))
+-              schedule_work(&kgdboc_restore_input_work);
++              irq_work_queue(&kgdboc_restore_input_irq_work);
+ }
+ 
+ static int kgdboc_register_kbd(char **cptr)
+@@ -133,6 +160,7 @@ static void kgdboc_unregister_kbd(void)
+                       i--;
+               }
+       }
++      irq_work_sync(&kgdboc_restore_input_irq_work);
+       flush_work(&kgdboc_restore_input_work);
+ }
+ #else /* ! CONFIG_KDB_KEYBOARD */
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index f94f68f1e7d2b..89fc690fdf34a 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -1699,7 +1699,6 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
+  */
+ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool 
interrupt)
+ {
+-      struct dwc3 *dwc = dep->dwc;
+       struct dwc3_gadget_ep_cmd_params params;
+       u32 cmd;
+       int ret;
+@@ -1724,8 +1723,7 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep 
*dep, bool force, bool int
+       dep->resource_index = 0;
+ 
+       if (!interrupt) {
+-              if (!DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC3, 310A))
+-                      mdelay(1);
++              mdelay(1);
+               dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
+       } else if (!ret) {
+               dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
+diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
+index 0717cfcd9f8ca..191f86da283d0 100644
+--- a/drivers/usb/typec/tipd/core.c
++++ b/drivers/usb/typec/tipd/core.c
+@@ -28,6 +28,7 @@
+ #define TPS_REG_MODE                  0x03
+ #define TPS_REG_CMD1                  0x08
+ #define TPS_REG_DATA1                 0x09
++#define TPS_REG_VERSION                       0x0F
+ #define TPS_REG_INT_EVENT1            0x14
+ #define TPS_REG_INT_EVENT2            0x15
+ #define TPS_REG_INT_MASK1             0x16
+@@ -604,11 +605,11 @@ static irqreturn_t tps25750_interrupt(int irq, void 
*data)
+       if (!tps6598x_read_status(tps, &status))
+               goto err_clear_ints;
+ 
+-      if ((event[0] | event[1]) & TPS_REG_INT_POWER_STATUS_UPDATE)
++      if (event[0] & TPS_REG_INT_POWER_STATUS_UPDATE)
+               if (!tps6598x_read_power_status(tps))
+                       goto err_clear_ints;
+ 
+-      if ((event[0] | event[1]) & TPS_REG_INT_DATA_STATUS_UPDATE)
++      if (event[0] & TPS_REG_INT_DATA_STATUS_UPDATE)
+               if (!tps6598x_read_data_status(tps))
+                       goto err_clear_ints;
+ 
+@@ -617,7 +618,7 @@ static irqreturn_t tps25750_interrupt(int irq, void *data)
+        * a plug event. Therefore, we need to check
+        * for pr/dr status change to set TypeC dr/pr accordingly.
+        */
+-      if ((event[0] | event[1]) & TPS_REG_INT_PLUG_EVENT ||
++      if (event[0] & TPS_REG_INT_PLUG_EVENT ||
+           tps6598x_has_role_changed(tps, status))
+               tps6598x_handle_plug_event(tps, status);
+ 
+@@ -636,49 +637,67 @@ static irqreturn_t tps25750_interrupt(int irq, void 
*data)
+ 
+ static irqreturn_t tps6598x_interrupt(int irq, void *data)
+ {
++      int intev_len = TPS_65981_2_6_INTEVENT_LEN;
+       struct tps6598x *tps = data;
+-      u64 event1 = 0;
+-      u64 event2 = 0;
++      u64 event1[2] = { };
++      u64 event2[2] = { };
++      u32 version;
+       u32 status;
+       int ret;
+ 
+       mutex_lock(&tps->lock);
+ 
+-      ret = tps6598x_read64(tps, TPS_REG_INT_EVENT1, &event1);
+-      ret |= tps6598x_read64(tps, TPS_REG_INT_EVENT2, &event2);
++      ret = tps6598x_read32(tps, TPS_REG_VERSION, &version);
++      if (ret)
++              dev_warn(tps->dev, "%s: failed to read version (%d)\n",
++                       __func__, ret);
++
++      if (TPS_VERSION_HW_VERSION(version) == TPS_VERSION_HW_65987_8_DH ||
++          TPS_VERSION_HW_VERSION(version) == TPS_VERSION_HW_65987_8_DK)
++              intev_len = TPS_65987_8_INTEVENT_LEN;
++
++      ret = tps6598x_block_read(tps, TPS_REG_INT_EVENT1, event1, intev_len);
++
++      ret = tps6598x_block_read(tps, TPS_REG_INT_EVENT1, event1, intev_len);
+       if (ret) {
+-              dev_err(tps->dev, "%s: failed to read events\n", __func__);
++              dev_err(tps->dev, "%s: failed to read event1\n", __func__);
+               goto err_unlock;
+       }
+-      trace_tps6598x_irq(event1, event2);
++      ret = tps6598x_block_read(tps, TPS_REG_INT_EVENT2, event2, intev_len);
++      if (ret) {
++              dev_err(tps->dev, "%s: failed to read event2\n", __func__);
++              goto err_unlock;
++      }
++      trace_tps6598x_irq(event1[0], event2[0]);
+ 
+-      if (!(event1 | event2))
++      if (!(event1[0] | event1[1] | event2[0] | event2[1]))
+               goto err_unlock;
+ 
+       if (!tps6598x_read_status(tps, &status))
+               goto err_clear_ints;
+ 
+-      if ((event1 | event2) & TPS_REG_INT_POWER_STATUS_UPDATE)
++      if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE)
+               if (!tps6598x_read_power_status(tps))
+                       goto err_clear_ints;
+ 
+-      if ((event1 | event2) & TPS_REG_INT_DATA_STATUS_UPDATE)
++      if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE)
+               if (!tps6598x_read_data_status(tps))
+                       goto err_clear_ints;
+ 
+       /* Handle plug insert or removal */
+-      if ((event1 | event2) & TPS_REG_INT_PLUG_EVENT)
++      if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT)
+               tps6598x_handle_plug_event(tps, status);
+ 
+ err_clear_ints:
+-      tps6598x_write64(tps, TPS_REG_INT_CLEAR1, event1);
+-      tps6598x_write64(tps, TPS_REG_INT_CLEAR2, event2);
++      tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event1, intev_len);
++      tps6598x_block_write(tps, TPS_REG_INT_CLEAR2, event2, intev_len);
+ 
+ err_unlock:
+       mutex_unlock(&tps->lock);
+ 
+-      if (event1 | event2)
++      if (event1[0] | event1[1] | event2[0] | event2[1])
+               return IRQ_HANDLED;
++
+       return IRQ_NONE;
+ }
+ 
+diff --git a/drivers/usb/typec/tipd/tps6598x.h 
b/drivers/usb/typec/tipd/tps6598x.h
+index 89b24519463a1..9b23e90174521 100644
+--- a/drivers/usb/typec/tipd/tps6598x.h
++++ b/drivers/usb/typec/tipd/tps6598x.h
+@@ -253,4 +253,15 @@
+ #define TPS_PTCC_DEV                          2
+ #define TPS_PTCC_APP                          3
+ 
++/* Version Register */
++#define TPS_VERSION_HW_VERSION_MASK            GENMASK(31, 24)
++#define TPS_VERSION_HW_VERSION(x)              
TPS_FIELD_GET(TPS_VERSION_HW_VERSION_MASK, (x))
++#define TPS_VERSION_HW_65981_2_6               0x00
++#define TPS_VERSION_HW_65987_8_DH              0xF7
++#define TPS_VERSION_HW_65987_8_DK              0xF9
++
++/* Int Event Register length */
++#define TPS_65981_2_6_INTEVENT_LEN             8
++#define TPS_65987_8_INTEVENT_LEN               11
++
+ #endif /* __TPS6598X_H__ */
+diff --git a/drivers/usb/typec/ucsi/displayport.c 
b/drivers/usb/typec/ucsi/displayport.c
+index d9d3c91125ca8..8be92fc1d12c9 100644
+--- a/drivers/usb/typec/ucsi/displayport.c
++++ b/drivers/usb/typec/ucsi/displayport.c
+@@ -275,8 +275,6 @@ static void ucsi_displayport_work(struct work_struct *work)
+       struct ucsi_dp *dp = container_of(work, struct ucsi_dp, work);
+       int ret;
+ 
+-      mutex_lock(&dp->con->lock);
+-
+       ret = typec_altmode_vdm(dp->alt, dp->header,
+                               dp->vdo_data, dp->vdo_size);
+       if (ret)
+@@ -285,8 +283,6 @@ static void ucsi_displayport_work(struct work_struct *work)
+       dp->vdo_data = NULL;
+       dp->vdo_size = 0;
+       dp->header = 0;
+-
+-      mutex_unlock(&dp->con->lock);
+ }
+ 
+ void ucsi_displayport_remove_partner(struct typec_altmode *alt)
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 69e7da33ca49a..00e62b81a7363 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -233,6 +233,19 @@ static inline unsigned int disk_openers(struct gendisk 
*disk)
+       return atomic_read(&disk->part0->bd_openers);
+ }
+ 
++/**
++ * disk_has_partscan - return %true if partition scanning is enabled on a disk
++ * @disk: disk to check
++ *
++ * Returns %true if partitions scanning is enabled for @disk, or %false if
++ * partition scanning is disabled either permanently or temporarily.
++ */
++static inline bool disk_has_partscan(struct gendisk *disk)
++{
++      return !(disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN)) &&
++              !test_bit(GD_SUPPRESS_PART_SCAN, &disk->state);
++}
++
+ /*
+  * The gendisk is refcounted by the part0 block_device, and the bd_device
+  * therein is also used for device model presentation in sysfs.
+diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
+index 5c12761cbc0e2..07198beb3d80b 100644
+--- a/include/net/bluetooth/hci.h
++++ b/include/net/bluetooth/hci.h
+@@ -1666,6 +1666,15 @@ struct hci_cp_le_set_event_mask {
+       __u8     mask[8];
+ } __packed;
+ 
++/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
++ * 7.8.2 LE Read Buffer Size command
++ * MAX_LE_MTU is 0xffff.
++ * 0 is also valid. It means that no dedicated LE Buffer exists.
++ * It should use the HCI_Read_Buffer_Size command and mtu is shared
++ * between BR/EDR and LE.
++ */
++#define HCI_MIN_LE_MTU 0x001b
++
+ #define HCI_OP_LE_READ_BUFFER_SIZE    0x2002
+ struct hci_rp_le_read_buffer_size {
+       __u8     status;
+diff --git a/include/net/bluetooth/hci_core.h 
b/include/net/bluetooth/hci_core.h
+index e8f581f3f3ce6..b1c8489ff93e4 100644
+--- a/include/net/bluetooth/hci_core.h
++++ b/include/net/bluetooth/hci_core.h
+@@ -706,6 +706,7 @@ struct hci_conn {
+       __u16           handle;
+       __u16           sync_handle;
+       __u16           state;
++      __u16           mtu;
+       __u8            mode;
+       __u8            type;
+       __u8            role;
+diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
+index 05346250f7195..6ab404dda7949 100644
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -909,11 +909,37 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int 
type, bdaddr_t *dst,
+ {
+       struct hci_conn *conn;
+ 
++      switch (type) {
++      case ACL_LINK:
++              if (!hdev->acl_mtu)
++                      return ERR_PTR(-ECONNREFUSED);
++              break;
++      case ISO_LINK:
++              if (hdev->iso_mtu)
++                      /* Dedicated ISO Buffer exists */
++                      break;
++              fallthrough;
++      case LE_LINK:
++              if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
++                      return ERR_PTR(-ECONNREFUSED);
++              if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
++                      return ERR_PTR(-ECONNREFUSED);
++              break;
++      case SCO_LINK:
++      case ESCO_LINK:
++              if (!hdev->sco_pkts)
++                      /* Controller does not support SCO or eSCO over HCI */
++                      return ERR_PTR(-ECONNREFUSED);
++              break;
++      default:
++              return ERR_PTR(-ECONNREFUSED);
++      }
++
+       bt_dev_dbg(hdev, "dst %pMR handle 0x%4.4x", dst, handle);
+ 
+       conn = kzalloc(sizeof(*conn), GFP_KERNEL);
+       if (!conn)
+-              return NULL;
++              return ERR_PTR(-ENOMEM);
+ 
+       bacpy(&conn->dst, dst);
+       bacpy(&conn->src, &hdev->bdaddr);
+@@ -944,10 +970,12 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int 
type, bdaddr_t *dst,
+       switch (type) {
+       case ACL_LINK:
+               conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
++              conn->mtu = hdev->acl_mtu;
+               break;
+       case LE_LINK:
+               /* conn->src should reflect the local identity address */
+               hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
++              conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
+               break;
+       case ISO_LINK:
+               /* conn->src should reflect the local identity address */
+@@ -959,6 +987,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int 
type, bdaddr_t *dst,
+               else if (conn->role == HCI_ROLE_MASTER)
+                       conn->cleanup = cis_cleanup;
+ 
++              conn->mtu = hdev->iso_mtu ? hdev->iso_mtu :
++                          hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
+               break;
+       case SCO_LINK:
+               if (lmp_esco_capable(hdev))
+@@ -966,9 +996,12 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int 
type, bdaddr_t *dst,
+                                       (hdev->esco_type & EDR_ESCO_MASK);
+               else
+                       conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
++
++              conn->mtu = hdev->sco_mtu;
+               break;
+       case ESCO_LINK:
+               conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
++              conn->mtu = hdev->sco_mtu;
+               break;
+       }
+ 
+@@ -1011,7 +1044,7 @@ struct hci_conn *hci_conn_add_unset(struct hci_dev 
*hdev, int type,
+ 
+       handle = hci_conn_hash_alloc_unset(hdev);
+       if (unlikely(handle < 0))
+-              return NULL;
++              return ERR_PTR(-ECONNREFUSED);
+ 
+       return hci_conn_add(hdev, type, dst, role, handle);
+ }
+@@ -1317,8 +1350,8 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, 
bdaddr_t *dst,
+               bacpy(&conn->dst, dst);
+       } else {
+               conn = hci_conn_add_unset(hdev, LE_LINK, dst, role);
+-              if (!conn)
+-                      return ERR_PTR(-ENOMEM);
++              if (IS_ERR(conn))
++                      return conn;
+               hci_conn_hold(conn);
+               conn->pending_sec_level = sec_level;
+       }
+@@ -1494,8 +1527,8 @@ static struct hci_conn *hci_add_bis(struct hci_dev 
*hdev, bdaddr_t *dst,
+               return ERR_PTR(-EADDRINUSE);
+ 
+       conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
+-      if (!conn)
+-              return ERR_PTR(-ENOMEM);
++      if (IS_ERR(conn))
++              return conn;
+ 
+       conn->state = BT_CONNECT;
+ 
+@@ -1538,8 +1571,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev 
*hdev, bdaddr_t *dst,
+       BT_DBG("requesting refresh of dst_addr");
+ 
+       conn = hci_conn_add_unset(hdev, LE_LINK, dst, HCI_ROLE_MASTER);
+-      if (!conn)
+-              return ERR_PTR(-ENOMEM);
++      if (IS_ERR(conn))
++              return conn;
+ 
+       if (hci_explicit_conn_params_set(hdev, dst, dst_type) < 0) {
+               hci_conn_del(conn);
+@@ -1586,8 +1619,8 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, 
bdaddr_t *dst,
+       acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+       if (!acl) {
+               acl = hci_conn_add_unset(hdev, ACL_LINK, dst, HCI_ROLE_MASTER);
+-              if (!acl)
+-                      return ERR_PTR(-ENOMEM);
++              if (IS_ERR(acl))
++                      return acl;
+       }
+ 
+       hci_conn_hold(acl);
+@@ -1655,9 +1688,9 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, 
int type, bdaddr_t *dst,
+       sco = hci_conn_hash_lookup_ba(hdev, type, dst);
+       if (!sco) {
+               sco = hci_conn_add_unset(hdev, type, dst, HCI_ROLE_MASTER);
+-              if (!sco) {
++              if (IS_ERR(sco)) {
+                       hci_conn_drop(acl);
+-                      return ERR_PTR(-ENOMEM);
++                      return sco;
+               }
+       }
+ 
+@@ -1847,8 +1880,8 @@ struct hci_conn *hci_bind_cis(struct hci_dev *hdev, 
bdaddr_t *dst,
+                                      qos->ucast.cis);
+       if (!cis) {
+               cis = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_MASTER);
+-              if (!cis)
+-                      return ERR_PTR(-ENOMEM);
++              if (IS_ERR(cis))
++                      return cis;
+               cis->cleanup = cis_cleanup;
+               cis->dst_type = dst_type;
+               cis->iso_qos.ucast.cig = BT_ISO_QOS_CIG_UNSET;
+@@ -1983,14 +2016,8 @@ static void hci_iso_qos_setup(struct hci_dev *hdev, 
struct hci_conn *conn,
+                             struct bt_iso_io_qos *qos, __u8 phy)
+ {
+       /* Only set MTU if PHY is enabled */
+-      if (!qos->sdu && qos->phy) {
+-              if (hdev->iso_mtu > 0)
+-                      qos->sdu = hdev->iso_mtu;
+-              else if (hdev->le_mtu > 0)
+-                      qos->sdu = hdev->le_mtu;
+-              else
+-                      qos->sdu = hdev->acl_mtu;
+-      }
++      if (!qos->sdu && qos->phy)
++              qos->sdu = conn->mtu;
+ 
+       /* Use the same PHY as ACL if set to any */
+       if (qos->phy == BT_ISO_PHY_ANY)
+@@ -2071,8 +2098,8 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev 
*hdev, bdaddr_t *dst,
+               return ERR_PTR(-EBUSY);
+ 
+       conn = hci_conn_add_unset(hdev, ISO_LINK, dst, HCI_ROLE_SLAVE);
+-      if (!conn)
+-              return ERR_PTR(-ENOMEM);
++      if (IS_ERR(conn))
++              return conn;
+ 
+       conn->iso_qos = *qos;
+       conn->state = BT_LISTEN;
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
+index d72d238c1656e..4de8f0dc1a523 100644
+--- a/net/bluetooth/hci_event.c
++++ b/net/bluetooth/hci_event.c
+@@ -954,6 +954,9 @@ static u8 hci_cc_read_buffer_size(struct hci_dev *hdev, 
void *data,
+       BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
+              hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
+ 
++      if (!hdev->acl_mtu || !hdev->acl_pkts)
++              return HCI_ERROR_INVALID_PARAMETERS;
++
+       return rp->status;
+ }
+ 
+@@ -1263,6 +1266,9 @@ static u8 hci_cc_le_read_buffer_size(struct hci_dev 
*hdev, void *data,
+ 
+       BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
+ 
++      if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
++              return HCI_ERROR_INVALID_PARAMETERS;
++
+       return rp->status;
+ }
+ 
+@@ -2342,8 +2348,8 @@ static void hci_cs_create_conn(struct hci_dev *hdev, 
__u8 status)
+               if (!conn) {
+                       conn = hci_conn_add_unset(hdev, ACL_LINK, &cp->bdaddr,
+                                                 HCI_ROLE_MASTER);
+-                      if (!conn)
+-                              bt_dev_err(hdev, "no memory for new 
connection");
++                      if (IS_ERR(conn))
++                              bt_dev_err(hdev, "connection err: %ld", 
PTR_ERR(conn));
+               }
+       }
+ 
+@@ -3154,8 +3160,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, 
void *data,
+                                                     BDADDR_BREDR)) {
+                       conn = hci_conn_add_unset(hdev, ev->link_type,
+                                                 &ev->bdaddr, HCI_ROLE_SLAVE);
+-                      if (!conn) {
+-                              bt_dev_err(hdev, "no memory for new conn");
++                      if (IS_ERR(conn)) {
++                              bt_dev_err(hdev, "connection err: %ld", 
PTR_ERR(conn));
+                               goto unlock;
+                       }
+               } else {
+@@ -3343,8 +3349,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, 
void *data,
+       if (!conn) {
+               conn = hci_conn_add_unset(hdev, ev->link_type, &ev->bdaddr,
+                                         HCI_ROLE_SLAVE);
+-              if (!conn) {
+-                      bt_dev_err(hdev, "no memory for new connection");
++              if (IS_ERR(conn)) {
++                      bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
+                       goto unlock;
+               }
+       }
+@@ -3821,6 +3827,9 @@ static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev 
*hdev, void *data,
+       BT_DBG("%s acl mtu %d:%d iso mtu %d:%d", hdev->name, hdev->acl_mtu,
+              hdev->acl_pkts, hdev->iso_mtu, hdev->iso_pkts);
+ 
++      if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
++              return HCI_ERROR_INVALID_PARAMETERS;
++
+       return rp->status;
+ }
+ 
+@@ -5768,8 +5777,8 @@ static void le_conn_complete_evt(struct hci_dev *hdev, 
u8 status,
+                       goto unlock;
+ 
+               conn = hci_conn_add_unset(hdev, LE_LINK, bdaddr, role);
+-              if (!conn) {
+-                      bt_dev_err(hdev, "no memory for new connection");
++              if (IS_ERR(conn)) {
++                      bt_dev_err(hdev, "connection err: %ld", PTR_ERR(conn));
+                       goto unlock;
+               }
+ 
+@@ -6898,7 +6907,7 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, 
void *data,
+       if (!cis) {
+               cis = hci_conn_add(hdev, ISO_LINK, &acl->dst, HCI_ROLE_SLAVE,
+                                  cis_handle);
+-              if (!cis) {
++              if (IS_ERR(cis)) {
+                       hci_le_reject_cis(hdev, ev->cis_handle);
+                       goto unlock;
+               }
+@@ -7007,7 +7016,7 @@ static void hci_le_big_sync_established_evt(struct 
hci_dev *hdev, void *data,
+               if (!bis) {
+                       bis = hci_conn_add(hdev, ISO_LINK, BDADDR_ANY,
+                                          HCI_ROLE_SLAVE, handle);
+-                      if (!bis)
++                      if (IS_ERR(bis))
+                               continue;
+               }
+ 
+@@ -7079,7 +7088,7 @@ static void hci_le_big_info_adv_report_evt(struct 
hci_dev *hdev, void *data,
+       pa_sync = hci_conn_add_unset(hdev, ISO_LINK, BDADDR_ANY,
+                                    HCI_ROLE_SLAVE);
+ 
+-      if (!pa_sync)
++      if (IS_ERR(pa_sync))
+               goto unlock;
+ 
+       pa_sync->sync_handle = le16_to_cpu(ev->sync_handle);
+diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
+index ef0cc80b4c0cc..6bed4aa8291de 100644
+--- a/net/bluetooth/iso.c
++++ b/net/bluetooth/iso.c
+@@ -1285,7 +1285,7 @@ static int iso_sock_sendmsg(struct socket *sock, struct 
msghdr *msg,
+               return -ENOTCONN;
+       }
+ 
+-      mtu = iso_pi(sk)->conn->hcon->hdev->iso_mtu;
++      mtu = iso_pi(sk)->conn->hcon->mtu;
+ 
+       release_sock(sk);
+ 
+diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
+index 9223b1a698e3a..3f7a82f10fe98 100644
+--- a/net/bluetooth/l2cap_core.c
++++ b/net/bluetooth/l2cap_core.c
+@@ -6241,7 +6241,7 @@ static int l2cap_finish_move(struct l2cap_chan *chan)
+       BT_DBG("chan %p", chan);
+ 
+       chan->rx_state = L2CAP_RX_STATE_RECV;
+-      chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
++      chan->conn->mtu = chan->conn->hcon->mtu;
+ 
+       return l2cap_resegment(chan);
+ }
+@@ -6308,7 +6308,7 @@ static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
+        */
+       chan->next_tx_seq = control->reqseq;
+       chan->unacked_frames = 0;
+-      chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
++      chan->conn->mtu = chan->conn->hcon->mtu;
+ 
+       err = l2cap_resegment(chan);
+ 
+@@ -6848,18 +6848,7 @@ static struct l2cap_conn *l2cap_conn_add(struct 
hci_conn *hcon)
+ 
+       BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);
+ 
+-      switch (hcon->type) {
+-      case LE_LINK:
+-              if (hcon->hdev->le_mtu) {
+-                      conn->mtu = hcon->hdev->le_mtu;
+-                      break;
+-              }
+-              fallthrough;
+-      default:
+-              conn->mtu = hcon->hdev->acl_mtu;
+-              break;
+-      }
+-
++      conn->mtu = hcon->mtu;
+       conn->feat_mask = 0;
+ 
+       conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS;
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index e0ad30862ee41..71d36582d4efa 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -126,7 +126,6 @@ static void sco_sock_clear_timer(struct sock *sk)
+ /* ---- SCO connections ---- */
+ static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
+ {
+-      struct hci_dev *hdev = hcon->hdev;
+       struct sco_conn *conn = hcon->sco_data;
+ 
+       if (conn) {
+@@ -144,9 +143,10 @@ static struct sco_conn *sco_conn_add(struct hci_conn 
*hcon)
+ 
+       hcon->sco_data = conn;
+       conn->hcon = hcon;
++      conn->mtu = hcon->mtu;
+ 
+-      if (hdev->sco_mtu > 0)
+-              conn->mtu = hdev->sco_mtu;
++      if (hcon->mtu > 0)
++              conn->mtu = hcon->mtu;
+       else
+               conn->mtu = 60;
+ 
+diff --git a/security/keys/trusted-keys/trusted_tpm2.c 
b/security/keys/trusted-keys/trusted_tpm2.c
+index bc700f85f80be..ea277c55a38db 100644
+--- a/security/keys/trusted-keys/trusted_tpm2.c
++++ b/security/keys/trusted-keys/trusted_tpm2.c
+@@ -38,6 +38,7 @@ static int tpm2_key_encode(struct trusted_key_payload 
*payload,
+       u8 *end_work = scratch + SCRATCH_SIZE;
+       u8 *priv, *pub;
+       u16 priv_len, pub_len;
++      int ret;
+ 
+       priv_len = get_unaligned_be16(src) + 2;
+       priv = src;
+@@ -57,8 +58,10 @@ static int tpm2_key_encode(struct trusted_key_payload 
*payload,
+               unsigned char bool[3], *w = bool;
+               /* tag 0 is emptyAuth */
+               w = asn1_encode_boolean(w, w + sizeof(bool), true);
+-              if (WARN(IS_ERR(w), "BUG: Boolean failed to encode"))
+-                      return PTR_ERR(w);
++              if (WARN(IS_ERR(w), "BUG: Boolean failed to encode")) {
++                      ret = PTR_ERR(w);
++                      goto err;
++              }
+               work = asn1_encode_tag(work, end_work, 0, bool, w - bool);
+       }
+ 
+@@ -69,8 +72,10 @@ static int tpm2_key_encode(struct trusted_key_payload 
*payload,
+        * trigger, so if it does there's something nefarious going on
+        */
+       if (WARN(work - scratch + pub_len + priv_len + 14 > SCRATCH_SIZE,
+-               "BUG: scratch buffer is too small"))
+-              return -EINVAL;
++               "BUG: scratch buffer is too small")) {
++              ret = -EINVAL;
++              goto err;
++      }
+ 
+       work = asn1_encode_integer(work, end_work, options->keyhandle);
+       work = asn1_encode_octet_string(work, end_work, pub, pub_len);
+@@ -79,10 +84,18 @@ static int tpm2_key_encode(struct trusted_key_payload 
*payload,
+       work1 = payload->blob;
+       work1 = asn1_encode_sequence(work1, work1 + sizeof(payload->blob),
+                                    scratch, work - scratch);
+-      if (WARN(IS_ERR(work1), "BUG: ASN.1 encoder failed"))
+-              return PTR_ERR(work1);
++      if (IS_ERR(work1)) {
++              ret = PTR_ERR(work1);
++              pr_err("BUG: ASN.1 encoder failed with %d\n", ret);
++              goto err;
++      }
+ 
++      kfree(scratch);
+       return work1 - payload->blob;
++
++err:
++      kfree(scratch);
++      return ret;
+ }
+ 
+ struct tpm2_key_context {
+diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile
+index bbf796a5f7ba8..08cfd4baecdd7 100644
+--- a/sound/soc/intel/boards/Makefile
++++ b/sound/soc/intel/boards/Makefile
+@@ -42,6 +42,7 @@ snd-soc-sof-sdw-objs += sof_sdw.o                            
\
+                       sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o   \
+                       sof_sdw_rt712_sdca.o sof_sdw_rt715.o    \
+                       sof_sdw_rt715_sdca.o sof_sdw_rt722_sdca.o       \
++                      sof_sdw_rt_dmic.o                       \
+                       sof_sdw_cs42l42.o sof_sdw_cs42l43.o     \
+                       sof_sdw_cs_amp.o                        \
+                       sof_sdw_dmic.o                          \
+diff --git a/sound/soc/intel/boards/sof_sdw.c 
b/sound/soc/intel/boards/sof_sdw.c
+index 08f330ed5c2ea..a90b43162a54b 100644
+--- a/sound/soc/intel/boards/sof_sdw.c
++++ b/sound/soc/intel/boards/sof_sdw.c
+@@ -730,7 +730,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
+                               .dai_name = "rt712-sdca-dmic-aif1",
+                               .dai_type = SOF_SDW_DAI_TYPE_MIC,
+                               .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+-                              .rtd_init = rt712_sdca_dmic_rtd_init,
++                              .rtd_init = rt_dmic_rtd_init,
+                       },
+               },
+               .dai_num = 1,
+@@ -760,7 +760,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
+                               .dai_name = "rt712-sdca-dmic-aif1",
+                               .dai_type = SOF_SDW_DAI_TYPE_MIC,
+                               .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+-                              .rtd_init = rt712_sdca_dmic_rtd_init,
++                              .rtd_init = rt_dmic_rtd_init,
+                       },
+               },
+               .dai_num = 1,
+@@ -822,7 +822,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
+                               .dai_name = "rt715-aif2",
+                               .dai_type = SOF_SDW_DAI_TYPE_MIC,
+                               .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+-                              .rtd_init = rt715_sdca_rtd_init,
++                              .rtd_init = rt_dmic_rtd_init,
+                       },
+               },
+               .dai_num = 1,
+@@ -837,7 +837,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
+                               .dai_name = "rt715-aif2",
+                               .dai_type = SOF_SDW_DAI_TYPE_MIC,
+                               .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+-                              .rtd_init = rt715_sdca_rtd_init,
++                              .rtd_init = rt_dmic_rtd_init,
+                       },
+               },
+               .dai_num = 1,
+@@ -852,7 +852,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
+                               .dai_name = "rt715-aif2",
+                               .dai_type = SOF_SDW_DAI_TYPE_MIC,
+                               .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+-                              .rtd_init = rt715_rtd_init,
++                              .rtd_init = rt_dmic_rtd_init,
+                       },
+               },
+               .dai_num = 1,
+@@ -867,7 +867,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
+                               .dai_name = "rt715-aif2",
+                               .dai_type = SOF_SDW_DAI_TYPE_MIC,
+                               .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID},
+-                              .rtd_init = rt715_rtd_init,
++                              .rtd_init = rt_dmic_rtd_init,
+                       },
+               },
+               .dai_num = 1,
+diff --git a/sound/soc/intel/boards/sof_sdw_common.h 
b/sound/soc/intel/boards/sof_sdw_common.h
+index b1d57034361c4..8a541b6bb0ac3 100644
+--- a/sound/soc/intel/boards/sof_sdw_common.h
++++ b/sound/soc/intel/boards/sof_sdw_common.h
+@@ -190,6 +190,7 @@ int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime 
*rtd);
+ int rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd);
+ int rt715_rtd_init(struct snd_soc_pcm_runtime *rtd);
+ int rt715_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd);
++int rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd);
+ int rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd);
+ int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd);
+ 
+diff --git a/sound/soc/intel/boards/sof_sdw_rt_dmic.c 
b/sound/soc/intel/boards/sof_sdw_rt_dmic.c
+new file mode 100644
+index 0000000000000..9091f5b5c6484
+--- /dev/null
++++ b/sound/soc/intel/boards/sof_sdw_rt_dmic.c
+@@ -0,0 +1,52 @@
++// SPDX-License-Identifier: GPL-2.0-only
++// Copyright (c) 2024 Intel Corporation
++
++/*
++ * sof_sdw_rt_dmic - Helpers to handle Realtek SDW DMIC from generic machine 
driver
++ */
++
++#include <linux/device.h>
++#include <linux/errno.h>
++#include <sound/soc.h>
++#include <sound/soc-acpi.h>
++#include "sof_board_helpers.h"
++#include "sof_sdw_common.h"
++
++static const char * const dmics[] = {
++      "rt715",
++      "rt712-sdca-dmic",
++};
++
++int rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd)
++{
++      struct snd_soc_card *card = rtd->card;
++      struct snd_soc_component *component;
++      struct snd_soc_dai *codec_dai;
++      char *mic_name;
++
++      codec_dai = get_codec_dai_by_name(rtd, dmics, ARRAY_SIZE(dmics));
++      if (!codec_dai)
++              return -EINVAL;
++
++      component = codec_dai->component;
++
++      /*
++       * rt715-sdca (aka rt714) is a special case that uses different name in 
card->components
++       * and component->name_prefix.
++       */
++      if (!strcmp(component->name_prefix, "rt714"))
++              mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "rt715-sdca");
++      else
++              mic_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s", 
component->name_prefix);
++
++      card->components = devm_kasprintf(card->dev, GFP_KERNEL,
++                                        "%s mic:%s", card->components,
++                                        mic_name);
++      if (!card->components)
++              return -ENOMEM;
++
++      dev_dbg(card->dev, "card->components: %s\n", card->components);
++
++      return 0;
++}
++MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);

Reply via email to