public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:6.9 commit in: /
Date: Sat, 25 May 2024 15:19:08 +0000 (UTC)	[thread overview]
Message-ID: <1716650336.190af96490abc9ac3659f6e8a74e7ae51df04e0a.mpagano@gentoo> (raw)

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 <hch@lst.de>
++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 <martin.petersen@oracle.com>
+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	other threads:[~2024-05-25 15:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-25 15:19 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2024-07-27 22:47 [gentoo-commits] proj/linux-patches:6.9 commit in: / Mike Pagano
2024-07-27 13:46 Mike Pagano
2024-07-25 12:08 Mike Pagano
2024-07-18 12:14 Mike Pagano
2024-07-11 11:47 Mike Pagano
2024-07-05 10:48 Mike Pagano
2024-07-05 10:47 Mike Pagano
2024-07-03 23:05 Mike Pagano
2024-06-27 12:31 Mike Pagano
2024-06-21 14:06 Mike Pagano
2024-06-16 14:31 Mike Pagano
2024-06-12 10:18 Mike Pagano
2024-05-30 12:02 Mike Pagano
2024-05-30 11:57 Mike Pagano
2024-05-23 12:41 Mike Pagano
2024-05-17 11:32 Mike Pagano
2024-05-05 18:02 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1716650336.190af96490abc9ac3659f6e8a74e7ae51df04e0a.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox