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);
