commit: e9b6c85e7fce52eee5421adcdab412041f3d8535 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Thu Aug 12 11:51:11 2021 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Thu Aug 12 11:51:11 2021 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e9b6c85e
Linux patch 4.19.203 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 1202_linux-4.19.203.patch | 1744 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1748 insertions(+) diff --git a/0000_README b/0000_README index d188882..d01fd15 100644 --- a/0000_README +++ b/0000_README @@ -847,6 +847,10 @@ Patch: 1201_linux-4.19.202.patch From: https://www.kernel.org Desc: Linux 4.19.202 +Patch: 1202_linux-4.19.203.patch +From: https://www.kernel.org +Desc: Linux 4.19.203 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1202_linux-4.19.203.patch b/1202_linux-4.19.203.patch new file mode 100644 index 0000000..9e3c569 --- /dev/null +++ b/1202_linux-4.19.203.patch @@ -0,0 +1,1744 @@ +diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histogram.rst +index 5ac724baea7d9..c14dab13a47e8 100644 +--- a/Documentation/trace/histogram.rst ++++ b/Documentation/trace/histogram.rst +@@ -191,7 +191,7 @@ Documentation written by Tom Zanussi + with the event, in nanoseconds. May be + modified by .usecs to have timestamps + interpreted as microseconds. +- cpu int the cpu on which the event occurred. ++ common_cpu int the cpu on which the event occurred. + ====================== ==== ======================================= + + Extended error information +diff --git a/Makefile b/Makefile +index b0f3a4d5a85d3..6d2670300d470 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + VERSION = 4 + PATCHLEVEL = 19 +-SUBLEVEL = 202 ++SUBLEVEL = 203 + EXTRAVERSION = + NAME = "People's Front" + +diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c +index d0dccae53ba9f..8a89b9adb4fe4 100644 +--- a/arch/alpha/kernel/smp.c ++++ b/arch/alpha/kernel/smp.c +@@ -585,7 +585,7 @@ void + smp_send_stop(void) + { + cpumask_t to_whom; +- cpumask_copy(&to_whom, cpu_possible_mask); ++ cpumask_copy(&to_whom, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &to_whom); + #ifdef DEBUG_IPI_MSG + if (hard_smp_processor_id() != boot_cpu_id) +diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi +index 038d8c90f6dfe..621396884c318 100644 +--- a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi ++++ b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi +@@ -43,6 +43,7 @@ + assigned-clock-rates = <0>, <198000000>; + cap-power-off-card; + keep-power-in-suspend; ++ max-frequency = <25000000>; + mmc-pwrseq = <&wifi_pwrseq>; + no-1-8-v; + non-removable; +diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi +index 61a06f6add3ca..d1cb9ba080b25 100644 +--- a/arch/arm/boot/dts/omap5-board-common.dtsi ++++ b/arch/arm/boot/dts/omap5-board-common.dtsi +@@ -33,14 +33,6 @@ + regulator-max-microvolt = <5000000>; + }; + +- vdds_1v8_main: fixedregulator-vdds_1v8_main { +- compatible = "regulator-fixed"; +- regulator-name = "vdds_1v8_main"; +- vin-supply = <&smps7_reg>; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; +- }; +- + vmmcsd_fixed: fixedregulator-mmcsd { + compatible = "regulator-fixed"; + regulator-name = "vmmcsd_fixed"; +@@ -490,6 +482,7 @@ + regulator-boot-on; + }; + ++ vdds_1v8_main: + smps7_reg: smps7 { + /* VDDS_1v8_OMAP over VDDS_1v8_MAIN */ + regulator-name = "smps7"; +diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c +index 04b3bf71de94b..ae0a61c61a6e1 100644 +--- a/arch/arm/mach-imx/mmdc.c ++++ b/arch/arm/mach-imx/mmdc.c +@@ -11,6 +11,7 @@ + * http://www.gnu.org/copyleft/gpl.html + */ + ++#include <linux/clk.h> + #include <linux/hrtimer.h> + #include <linux/init.h> + #include <linux/interrupt.h> +@@ -472,6 +473,7 @@ static int imx_mmdc_remove(struct platform_device *pdev) + + cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); + perf_pmu_unregister(&pmu_mmdc->pmu); ++ iounmap(pmu_mmdc->mmdc_base); + kfree(pmu_mmdc); + return 0; + } +@@ -546,7 +548,20 @@ static int imx_mmdc_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; + void __iomem *mmdc_base, *reg; ++ struct clk *mmdc_ipg_clk; + u32 val; ++ int err; ++ ++ /* the ipg clock is optional */ ++ mmdc_ipg_clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(mmdc_ipg_clk)) ++ mmdc_ipg_clk = NULL; ++ ++ err = clk_prepare_enable(mmdc_ipg_clk); ++ if (err) { ++ dev_err(&pdev->dev, "Unable to enable mmdc ipg clock.\n"); ++ return err; ++ } + + mmdc_base = of_iomap(np, 0); + WARN_ON(!mmdc_base); +@@ -564,7 +579,11 @@ static int imx_mmdc_probe(struct platform_device *pdev) + val &= ~(1 << BP_MMDC_MAPSR_PSD); + writel_relaxed(val, reg); + +- return imx_mmdc_perf_init(pdev, mmdc_base); ++ err = imx_mmdc_perf_init(pdev, mmdc_base); ++ if (err) ++ iounmap(mmdc_base); ++ ++ return err; + } + + int imx_mmdc_get_ddr_type(void) +diff --git a/arch/mips/Makefile b/arch/mips/Makefile +index 63e2ad43bd6ad..8f4e169cde114 100644 +--- a/arch/mips/Makefile ++++ b/arch/mips/Makefile +@@ -325,7 +325,7 @@ KBUILD_LDFLAGS += -m $(ld-emul) + + ifdef CONFIG_MIPS + CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ +- egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ ++ egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ + sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') + endif + +diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c +index 11e9527c6e441..62ffac500eb52 100644 +--- a/arch/mips/mti-malta/malta-platform.c ++++ b/arch/mips/mti-malta/malta-platform.c +@@ -47,7 +47,8 @@ static struct plat_serial8250_port uart8250_data[] = { + .mapbase = 0x1f000900, /* The CBUS UART */ + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, + .uartclk = 3686400, /* Twice the usual clk! */ +- .iotype = UPIO_MEM32, ++ .iotype = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) ? ++ UPIO_MEM32BE : UPIO_MEM32, + .flags = CBUS_UART_FLAGS, + .regshift = 3, + }, +diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h +index 05659c7b43d4c..d2e87dbc55c58 100644 +--- a/arch/x86/events/perf_event.h ++++ b/arch/x86/events/perf_event.h +@@ -799,9 +799,10 @@ void x86_pmu_stop(struct perf_event *event, int flags); + + static inline void x86_pmu_disable_event(struct perf_event *event) + { ++ u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask); + struct hw_perf_event *hwc = &event->hw; + +- wrmsrl(hwc->config_base, hwc->config); ++ wrmsrl(hwc->config_base, hwc->config & ~disable_mask); + } + + void x86_pmu_enable_event(struct perf_event *event); +diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c +index 5faa49a95ac97..762baba4ecd51 100644 +--- a/arch/x86/kvm/mmu.c ++++ b/arch/x86/kvm/mmu.c +@@ -2042,7 +2042,7 @@ static int is_empty_shadow_page(u64 *spt) + * aggregate version in order to make the slab shrinker + * faster + */ +-static inline void kvm_mod_used_mmu_pages(struct kvm *kvm, unsigned long nr) ++static inline void kvm_mod_used_mmu_pages(struct kvm *kvm, long nr) + { + kvm->arch.n_used_mmu_pages += nr; + percpu_counter_add(&kvm_total_used_mmu_pages, nr); +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 9cfc669b4a243..f913127e942a1 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -3366,8 +3366,17 @@ static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu) + + static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu) + { +- return kvm_arch_interrupt_allowed(vcpu) && +- kvm_cpu_accept_dm_intr(vcpu); ++ /* ++ * Do not cause an interrupt window exit if an exception ++ * is pending or an event needs reinjection; userspace ++ * might want to inject the interrupt manually using KVM_SET_REGS ++ * or KVM_SET_SREGS. For that to work, we must be at an ++ * instruction boundary and with no events half-injected. ++ */ ++ return (kvm_arch_interrupt_allowed(vcpu) && ++ kvm_cpu_accept_dm_intr(vcpu) && ++ !kvm_event_needs_reinjection(vcpu) && ++ !vcpu->arch.exception.pending); + } + + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, +diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c +index 0529e94a20f7f..019cf002eceec 100644 +--- a/block/blk-iolatency.c ++++ b/block/blk-iolatency.c +@@ -800,7 +800,11 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, + + enable = iolatency_set_min_lat_nsec(blkg, lat_val); + if (enable) { +- WARN_ON_ONCE(!blk_get_queue(blkg->q)); ++ if (!blk_get_queue(blkg->q)) { ++ ret = -ENODEV; ++ goto out; ++ } ++ + blkg_get(blkg); + } + +diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c +index 4c8ce483805d8..a3bd6280882c3 100644 +--- a/drivers/acpi/acpica/nsrepair2.c ++++ b/drivers/acpi/acpica/nsrepair2.c +@@ -375,13 +375,6 @@ acpi_ns_repair_CID(struct acpi_evaluate_info *info, + + (*element_ptr)->common.reference_count = + original_ref_count; +- +- /* +- * The original_element holds a reference from the package object +- * that represents _HID. Since a new element was created by _HID, +- * remove the reference from the _CID package. +- */ +- acpi_ut_remove_reference(original_element); + } + + element_ptr++; +diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c +index 7484ffdabd543..ec62d26c32a9d 100644 +--- a/drivers/ata/libata-sff.c ++++ b/drivers/ata/libata-sff.c +@@ -657,6 +657,20 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf, + } + EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); + ++static void ata_pio_xfer(struct ata_queued_cmd *qc, struct page *page, ++ unsigned int offset, size_t xfer_size) ++{ ++ bool do_write = (qc->tf.flags & ATA_TFLAG_WRITE); ++ unsigned char *buf; ++ ++ buf = kmap_atomic(page); ++ qc->ap->ops->sff_data_xfer(qc, buf + offset, xfer_size, do_write); ++ kunmap_atomic(buf); ++ ++ if (!do_write && !PageSlab(page)) ++ flush_dcache_page(page); ++} ++ + /** + * ata_pio_sector - Transfer a sector of data. + * @qc: Command on going +@@ -668,11 +682,9 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); + */ + static void ata_pio_sector(struct ata_queued_cmd *qc) + { +- int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); + struct ata_port *ap = qc->ap; + struct page *page; + unsigned int offset; +- unsigned char *buf; + + if (!qc->cursg) { + qc->curbytes = qc->nbytes; +@@ -690,13 +702,20 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) + + DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); + +- /* do the actual data transfer */ +- buf = kmap_atomic(page); +- ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); +- kunmap_atomic(buf); ++ /* ++ * Split the transfer when it splits a page boundary. Note that the ++ * split still has to be dword aligned like all ATA data transfers. ++ */ ++ WARN_ON_ONCE(offset % 4); ++ if (offset + qc->sect_size > PAGE_SIZE) { ++ unsigned int split_len = PAGE_SIZE - offset; + +- if (!do_write && !PageSlab(page)) +- flush_dcache_page(page); ++ ata_pio_xfer(qc, page, offset, split_len); ++ ata_pio_xfer(qc, nth_page(page, 1), 0, ++ qc->sect_size - split_len); ++ } else { ++ ata_pio_xfer(qc, page, offset, qc->sect_size); ++ } + + qc->curbytes += qc->sect_size; + qc->cursg_ofs += qc->sect_size; +diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c +index 3b7b748c4d4f2..821e27bda4ca2 100644 +--- a/drivers/base/firmware_loader/fallback.c ++++ b/drivers/base/firmware_loader/fallback.c +@@ -86,12 +86,11 @@ static void __fw_load_abort(struct fw_priv *fw_priv) + { + /* + * There is a small window in which user can write to 'loading' +- * between loading done and disappearance of 'loading' ++ * between loading done/aborted and disappearance of 'loading' + */ +- if (fw_sysfs_done(fw_priv)) ++ if (fw_state_is_aborted(fw_priv) || fw_sysfs_done(fw_priv)) + return; + +- list_del_init(&fw_priv->pending_list); + fw_state_aborted(fw_priv); + } + +@@ -297,7 +296,6 @@ static ssize_t firmware_loading_store(struct device *dev, + * Same logic as fw_load_abort, only the DONE bit + * is ignored and we set ABORT only on failure. + */ +- list_del_init(&fw_priv->pending_list); + if (rc) { + fw_state_aborted(fw_priv); + written = rc; +@@ -559,6 +557,11 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, + } + + mutex_lock(&fw_lock); ++ if (fw_state_is_aborted(fw_priv)) { ++ mutex_unlock(&fw_lock); ++ retval = -EINTR; ++ goto out; ++ } + list_add(&fw_priv->pending_list, &pending_fw_head); + mutex_unlock(&fw_lock); + +@@ -581,11 +584,10 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, + if (fw_state_is_aborted(fw_priv)) { + if (retval == -ERESTARTSYS) + retval = -EINTR; +- else +- retval = -EAGAIN; + } else if (fw_priv->is_paged_buf && !fw_priv->data) + retval = -ENOMEM; + ++out: + device_del(f_dev); + err_put_dev: + put_device(f_dev); +diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h +index 4c1395f8e7ed2..e2000b4ad09b3 100644 +--- a/drivers/base/firmware_loader/firmware.h ++++ b/drivers/base/firmware_loader/firmware.h +@@ -106,8 +106,16 @@ static inline void __fw_state_set(struct fw_priv *fw_priv, + + WRITE_ONCE(fw_st->status, status); + +- if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) ++ if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) { ++#ifdef CONFIG_FW_LOADER_USER_HELPER ++ /* ++ * Doing this here ensures that the fw_priv is deleted from ++ * the pending list in all abort/done paths. ++ */ ++ list_del_init(&fw_priv->pending_list); ++#endif + complete_all(&fw_st->completion); ++ } + } + + static inline void fw_state_aborted(struct fw_priv *fw_priv) +diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c +index 8e9213b36e313..24410a0d6df07 100644 +--- a/drivers/base/firmware_loader/main.c ++++ b/drivers/base/firmware_loader/main.c +@@ -558,8 +558,10 @@ static void fw_abort_batch_reqs(struct firmware *fw) + return; + + fw_priv = fw->priv; ++ mutex_lock(&fw_lock); + if (!fw_state_is_aborted(fw_priv)) + fw_state_aborted(fw_priv); ++ mutex_unlock(&fw_lock); + } + + /* called from request_firmware() and request_firmware_work_func() */ +diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c +index 294850bdc195d..61de486dec416 100644 +--- a/drivers/clk/clk-stm32f4.c ++++ b/drivers/clk/clk-stm32f4.c +@@ -454,7 +454,7 @@ struct stm32f4_pll { + + struct stm32f4_pll_post_div_data { + int idx; +- u8 pll_num; ++ int pll_idx; + const char *name; + const char *parent; + u8 flag; +@@ -485,13 +485,13 @@ static const struct clk_div_table post_divr_table[] = { + + #define MAX_POST_DIV 3 + static const struct stm32f4_pll_post_div_data post_div_data[MAX_POST_DIV] = { +- { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q", ++ { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q", + CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL}, + +- { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q", ++ { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q", + CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL }, + +- { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, ++ { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, + STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table }, + }; + +@@ -1499,7 +1499,7 @@ static void __init stm32f4_rcc_init(struct device_node *np) + post_div->width, + post_div->flag_div, + post_div->div_table, +- clks[post_div->pll_num], ++ clks[post_div->pll_idx], + &stm32f4_clk_lock); + + if (post_div->idx != NO_IDX) +diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c +index 93d250db0b6f0..50015a2ea5ce0 100644 +--- a/drivers/media/common/videobuf2/videobuf2-core.c ++++ b/drivers/media/common/videobuf2/videobuf2-core.c +@@ -1391,6 +1391,7 @@ static int vb2_start_streaming(struct vb2_queue *q) + int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) + { + struct vb2_buffer *vb; ++ enum vb2_buffer_state orig_state; + int ret; + + if (q->error) { +@@ -1420,6 +1421,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) + * Add to the queued buffers list, a buffer will stay on it until + * dequeued in dqbuf. + */ ++ orig_state = vb->state; + list_add_tail(&vb->queued_entry, &q->queued_list); + q->queued_count++; + q->waiting_for_buffers = false; +@@ -1450,8 +1452,17 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) + if (q->streaming && !q->start_streaming_called && + q->queued_count >= q->min_buffers_needed) { + ret = vb2_start_streaming(q); +- if (ret) ++ if (ret) { ++ /* ++ * Since vb2_core_qbuf will return with an error, ++ * we should return it to state DEQUEUED since ++ * the error indicates that the buffer wasn't queued. ++ */ ++ list_del(&vb->queued_entry); ++ q->queued_count--; ++ vb->state = orig_state; + return ret; ++ } + } + + dprintk(2, "qbuf of buffer %d succeeded\n", vb->index); +diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +index a970224a94bdd..857ef9edbc123 100644 +--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c ++++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +@@ -50,7 +50,16 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req) + } else { + /* read */ + requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); +- pipe = usb_rcvctrlpipe(d->udev, 0); ++ ++ /* ++ * Zero-length transfers must use usb_sndctrlpipe() and ++ * rtl28xxu_identify_state() uses a zero-length i2c read ++ * command to determine the chip type. ++ */ ++ if (req->size) ++ pipe = usb_rcvctrlpipe(d->udev, 0); ++ else ++ pipe = usb_sndctrlpipe(d->udev, 0); + } + + ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value, +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +index cf01e73d1bcc8..2610acf9ac36c 100644 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +@@ -2668,7 +2668,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) + } + + /* Allocated memory for FW statistics */ +- if (bnx2x_alloc_fw_stats_mem(bp)) ++ rc = bnx2x_alloc_fw_stats_mem(bp); ++ if (rc) + LOAD_ERROR_EXIT(bp, load_error0); + + /* request pf to initialize status blocks */ +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 6b9eada1feb21..3fc823e9cdc9d 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -3733,13 +3733,13 @@ fec_drv_remove(struct platform_device *pdev) + if (of_phy_is_fixed_link(np)) + of_phy_deregister_fixed_link(np); + of_node_put(fep->phy_node); +- free_netdev(ndev); + + clk_disable_unprepare(fep->clk_ahb); + clk_disable_unprepare(fep->clk_ipg); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + ++ free_netdev(ndev); + return 0; + } + +diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c +index b9a1a9f999ea6..039d5dd98dfe9 100644 +--- a/drivers/net/ethernet/natsemi/natsemi.c ++++ b/drivers/net/ethernet/natsemi/natsemi.c +@@ -819,7 +819,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) + printk(version); + #endif + +- i = pci_enable_device(pdev); ++ i = pcim_enable_device(pdev); + if (i) return i; + + /* natsemi has a non-standard PM control register +@@ -852,7 +852,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) + ioaddr = ioremap(iostart, iosize); + if (!ioaddr) { + i = -ENOMEM; +- goto err_ioremap; ++ goto err_pci_request_regions; + } + + /* Work around the dropped serial bit. */ +@@ -974,9 +974,6 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) + err_register_netdev: + iounmap(ioaddr); + +- err_ioremap: +- pci_release_regions(pdev); +- + err_pci_request_regions: + free_netdev(dev); + return i; +@@ -3242,7 +3239,6 @@ static void natsemi_remove1(struct pci_dev *pdev) + + NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); + unregister_netdev (dev); +- pci_release_regions (pdev); + iounmap(ioaddr); + free_netdev (dev); + } +diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c +index 5ae3fa82909f8..0766288e2f38a 100644 +--- a/drivers/net/ethernet/neterion/vxge/vxge-main.c ++++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c +@@ -3529,13 +3529,13 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) + + kfree(vdev->vpaths); + +- /* we are safe to free it now */ +- free_netdev(dev); +- + vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", + buf); + vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, + __func__, __LINE__); ++ ++ /* we are safe to free it now */ ++ free_netdev(dev); + } + + /* +diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +index 9043d2cadd5de..2e75d0af4a585 100644 +--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c ++++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +@@ -292,6 +292,8 @@ nfp_net_get_link_ksettings(struct net_device *netdev, + + /* Init to unknowns */ + ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); ++ ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); ++ ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); + cmd->base.port = PORT_OTHER; + cmd->base.speed = SPEED_UNKNOWN; + cmd->base.duplex = DUPLEX_UNKNOWN; +diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c +index 2d71646640ac5..f98e2f417c2ea 100644 +--- a/drivers/net/ethernet/qlogic/qla3xxx.c ++++ b/drivers/net/ethernet/qlogic/qla3xxx.c +@@ -155,7 +155,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) + "driver lock acquired\n"); + return 1; + } +- ssleep(1); ++ mdelay(1000); + } while (++i < 10); + + netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); +@@ -3292,7 +3292,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) + if ((value & ISP_CONTROL_SR) == 0) + break; + +- ssleep(1); ++ mdelay(1000); + } while ((--max_wait_time)); + + /* +@@ -3328,7 +3328,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) + ispControlStatus); + if ((value & ISP_CONTROL_FSR) == 0) + break; +- ssleep(1); ++ mdelay(1000); + } while ((--max_wait_time)); + } + if (max_wait_time == 0) +diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c +index b7a0df95d4b0f..9f1777e56d7db 100644 +--- a/drivers/net/usb/pegasus.c ++++ b/drivers/net/usb/pegasus.c +@@ -750,12 +750,16 @@ static inline void disable_net_traffic(pegasus_t *pegasus) + set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp); + } + +-static inline void get_interrupt_interval(pegasus_t *pegasus) ++static inline int get_interrupt_interval(pegasus_t *pegasus) + { + u16 data; + u8 interval; ++ int ret; ++ ++ ret = read_eprom_word(pegasus, 4, &data); ++ if (ret < 0) ++ return ret; + +- read_eprom_word(pegasus, 4, &data); + interval = data >> 8; + if (pegasus->usb->speed != USB_SPEED_HIGH) { + if (interval < 0x80) { +@@ -770,6 +774,8 @@ static inline void get_interrupt_interval(pegasus_t *pegasus) + } + } + pegasus->intr_interval = interval; ++ ++ return 0; + } + + static void set_carrier(struct net_device *net) +@@ -1188,7 +1194,9 @@ static int pegasus_probe(struct usb_interface *intf, + | NETIF_MSG_PROBE | NETIF_MSG_LINK); + + pegasus->features = usb_dev_id[dev_index].private; +- get_interrupt_interval(pegasus); ++ res = get_interrupt_interval(pegasus); ++ if (res) ++ goto out2; + if (reset_mac(pegasus)) { + dev_err(&intf->dev, "can't reset MAC\n"); + res = -EIO; +diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c +index d08e1de26030e..54b37a30df18b 100644 +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -22,6 +22,7 @@ + #include <linux/usb/cdc.h> + #include <linux/usb/usbnet.h> + #include <linux/usb/cdc-wdm.h> ++#include <linux/u64_stats_sync.h> + + /* This driver supports wwan (3G/LTE/?) devices using a vendor + * specific management protocol called Qualcomm MSM Interface (QMI) - +@@ -74,6 +75,7 @@ struct qmimux_hdr { + struct qmimux_priv { + struct net_device *real_dev; + u8 mux_id; ++ struct pcpu_sw_netstats __percpu *stats64; + }; + + static int qmimux_open(struct net_device *dev) +@@ -100,19 +102,65 @@ static netdev_tx_t qmimux_start_xmit(struct sk_buff *skb, struct net_device *dev + struct qmimux_priv *priv = netdev_priv(dev); + unsigned int len = skb->len; + struct qmimux_hdr *hdr; ++ netdev_tx_t ret; + + hdr = skb_push(skb, sizeof(struct qmimux_hdr)); + hdr->pad = 0; + hdr->mux_id = priv->mux_id; + hdr->pkt_len = cpu_to_be16(len); + skb->dev = priv->real_dev; +- return dev_queue_xmit(skb); ++ ret = dev_queue_xmit(skb); ++ ++ if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { ++ struct pcpu_sw_netstats *stats64 = this_cpu_ptr(priv->stats64); ++ ++ u64_stats_update_begin(&stats64->syncp); ++ stats64->tx_packets++; ++ stats64->tx_bytes += len; ++ u64_stats_update_end(&stats64->syncp); ++ } else { ++ dev->stats.tx_dropped++; ++ } ++ ++ return ret; ++} ++ ++static void qmimux_get_stats64(struct net_device *net, ++ struct rtnl_link_stats64 *stats) ++{ ++ struct qmimux_priv *priv = netdev_priv(net); ++ unsigned int start; ++ int cpu; ++ ++ netdev_stats_to_stats64(stats, &net->stats); ++ ++ for_each_possible_cpu(cpu) { ++ struct pcpu_sw_netstats *stats64; ++ u64 rx_packets, rx_bytes; ++ u64 tx_packets, tx_bytes; ++ ++ stats64 = per_cpu_ptr(priv->stats64, cpu); ++ ++ do { ++ start = u64_stats_fetch_begin_irq(&stats64->syncp); ++ rx_packets = stats64->rx_packets; ++ rx_bytes = stats64->rx_bytes; ++ tx_packets = stats64->tx_packets; ++ tx_bytes = stats64->tx_bytes; ++ } while (u64_stats_fetch_retry_irq(&stats64->syncp, start)); ++ ++ stats->rx_packets += rx_packets; ++ stats->rx_bytes += rx_bytes; ++ stats->tx_packets += tx_packets; ++ stats->tx_bytes += tx_bytes; ++ } + } + + static const struct net_device_ops qmimux_netdev_ops = { +- .ndo_open = qmimux_open, +- .ndo_stop = qmimux_stop, +- .ndo_start_xmit = qmimux_start_xmit, ++ .ndo_open = qmimux_open, ++ .ndo_stop = qmimux_stop, ++ .ndo_start_xmit = qmimux_start_xmit, ++ .ndo_get_stats64 = qmimux_get_stats64, + }; + + static void qmimux_setup(struct net_device *dev) +@@ -197,8 +245,19 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + } + + skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, pkt_len); +- if (netif_rx(skbn) != NET_RX_SUCCESS) ++ if (netif_rx(skbn) != NET_RX_SUCCESS) { ++ net->stats.rx_errors++; + return 0; ++ } else { ++ struct pcpu_sw_netstats *stats64; ++ struct qmimux_priv *priv = netdev_priv(net); ++ ++ stats64 = this_cpu_ptr(priv->stats64); ++ u64_stats_update_begin(&stats64->syncp); ++ stats64->rx_packets++; ++ stats64->rx_bytes += pkt_len; ++ u64_stats_update_end(&stats64->syncp); ++ } + + skip: + offset += len + qmimux_hdr_sz; +@@ -222,6 +281,12 @@ static int qmimux_register_device(struct net_device *real_dev, u8 mux_id) + priv->mux_id = mux_id; + priv->real_dev = real_dev; + ++ priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); ++ if (!priv->stats64) { ++ err = -ENOBUFS; ++ goto out_free_newdev; ++ } ++ + err = register_netdevice(new_dev); + if (err < 0) + goto out_free_newdev; +@@ -252,6 +317,7 @@ static void qmimux_unregister_device(struct net_device *dev, + struct qmimux_priv *priv = netdev_priv(dev); + struct net_device *real_dev = priv->real_dev; + ++ free_percpu(priv->stats64); + netdev_upper_dev_unlink(real_dev, dev); + unregister_netdevice_queue(dev, head); + +diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c +index aae7e6df99cd3..ba13e3c3d6b87 100644 +--- a/drivers/pcmcia/i82092.c ++++ b/drivers/pcmcia/i82092.c +@@ -105,6 +105,7 @@ static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *i + for (i = 0;i<socket_count;i++) { + sockets[i].card_state = 1; /* 1 = present but empty */ + sockets[i].io_base = pci_resource_start(dev, 0); ++ sockets[i].dev = dev; + sockets[i].socket.features |= SS_CAP_PCCARD; + sockets[i].socket.map_size = 0x1000; + sockets[i].socket.irq_mask = 0; +diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c +index acf0c244141f4..84dd776d36c33 100644 +--- a/drivers/scsi/sr.c ++++ b/drivers/scsi/sr.c +@@ -217,7 +217,7 @@ static unsigned int sr_get_events(struct scsi_device *sdev) + else if (med->media_event_code == 2) + return DISK_EVENT_MEDIA_CHANGE; + else if (med->media_event_code == 3) +- return DISK_EVENT_EJECT_REQUEST; ++ return DISK_EVENT_MEDIA_CHANGE; + return 0; + } + +diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c +index 7fe4488ace579..419756ebf2c05 100644 +--- a/drivers/spi/spi-meson-spicc.c ++++ b/drivers/spi/spi-meson-spicc.c +@@ -599,6 +599,8 @@ static int meson_spicc_remove(struct platform_device *pdev) + + clk_disable_unprepare(spicc->core); + ++ spi_master_put(spicc->master); ++ + return 0; + } + +diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c +index d6b93e1f78d8a..8aac87598e620 100644 +--- a/drivers/staging/rtl8723bs/hal/sdio_ops.c ++++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c +@@ -1077,6 +1077,8 @@ void sd_int_dpc(struct adapter *adapter) + } else { + rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); + } ++ } else { ++ kfree(c2h_evt); + } + } else { + /* Error handling for malloc fail */ +diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c +index 7cb7efe62b011..4f4a7e2b122bf 100644 +--- a/drivers/tee/optee/call.c ++++ b/drivers/tee/optee/call.c +@@ -413,11 +413,13 @@ void optee_enable_shm_cache(struct optee *optee) + } + + /** +- * optee_disable_shm_cache() - Disables caching of some shared memory allocation +- * in OP-TEE ++ * __optee_disable_shm_cache() - Disables caching of some shared memory ++ * allocation in OP-TEE + * @optee: main service struct ++ * @is_mapped: true if the cached shared memory addresses were mapped by this ++ * kernel, are safe to dereference, and should be freed + */ +-void optee_disable_shm_cache(struct optee *optee) ++static void __optee_disable_shm_cache(struct optee *optee, bool is_mapped) + { + struct optee_call_waiter w; + +@@ -436,6 +438,13 @@ void optee_disable_shm_cache(struct optee *optee) + if (res.result.status == OPTEE_SMC_RETURN_OK) { + struct tee_shm *shm; + ++ /* ++ * Shared memory references that were not mapped by ++ * this kernel must be ignored to prevent a crash. ++ */ ++ if (!is_mapped) ++ continue; ++ + shm = reg_pair_to_ptr(res.result.shm_upper32, + res.result.shm_lower32); + tee_shm_free(shm); +@@ -446,6 +455,27 @@ void optee_disable_shm_cache(struct optee *optee) + optee_cq_wait_final(&optee->call_queue, &w); + } + ++/** ++ * optee_disable_shm_cache() - Disables caching of mapped shared memory ++ * allocations in OP-TEE ++ * @optee: main service struct ++ */ ++void optee_disable_shm_cache(struct optee *optee) ++{ ++ return __optee_disable_shm_cache(optee, true); ++} ++ ++/** ++ * optee_disable_unmapped_shm_cache() - Disables caching of shared memory ++ * allocations in OP-TEE which are not ++ * currently mapped ++ * @optee: main service struct ++ */ ++void optee_disable_unmapped_shm_cache(struct optee *optee) ++{ ++ return __optee_disable_shm_cache(optee, false); ++} ++ + #define PAGELIST_ENTRIES_PER_PAGE \ + ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) + +diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c +index 1d71fcb13dba6..473981e3ad70b 100644 +--- a/drivers/tee/optee/core.c ++++ b/drivers/tee/optee/core.c +@@ -619,6 +619,15 @@ static struct optee *optee_probe(struct device_node *np) + optee->memremaped_shm = memremaped_shm; + optee->pool = pool; + ++ /* ++ * Ensure that there are no pre-existing shm objects before enabling ++ * the shm cache so that there's no chance of receiving an invalid ++ * address during shutdown. This could occur, for example, if we're ++ * kexec booting from an older kernel that did not properly cleanup the ++ * shm cache. ++ */ ++ optee_disable_unmapped_shm_cache(optee); ++ + optee_enable_shm_cache(optee); + + pr_info("initialized driver\n"); +diff --git a/drivers/tee/optee/optee_private.h b/drivers/tee/optee/optee_private.h +index 35e79386c556b..489039acb16ca 100644 +--- a/drivers/tee/optee/optee_private.h ++++ b/drivers/tee/optee/optee_private.h +@@ -160,6 +160,7 @@ int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session); + + void optee_enable_shm_cache(struct optee *optee); + void optee_disable_shm_cache(struct optee *optee); ++void optee_disable_unmapped_shm_cache(struct optee *optee); + + int optee_shm_register(struct tee_context *ctx, struct tee_shm *shm, + struct page **pages, size_t num_pages, +diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c +index 56693dfe0f5b7..68f71298c11b5 100644 +--- a/drivers/tty/serial/8250/8250_port.c ++++ b/drivers/tty/serial/8250/8250_port.c +@@ -313,7 +313,11 @@ static const struct serial8250_config uart_config[] = { + /* Uart divisor latch read */ + static int default_serial_dl_read(struct uart_8250_port *up) + { +- return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; ++ /* Assign these in pieces to truncate any bits above 7. */ ++ unsigned char dll = serial_in(up, UART_DLL); ++ unsigned char dlm = serial_in(up, UART_DLM); ++ ++ return dll | dlm << 8; + } + + /* Uart divisor latch write */ +@@ -1301,9 +1305,11 @@ static void autoconfig(struct uart_8250_port *up) + serial_out(up, UART_LCR, 0); + + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); +- scratch = serial_in(up, UART_IIR) >> 6; + +- switch (scratch) { ++ /* Assign this as it is to truncate any bits above 7. */ ++ scratch = serial_in(up, UART_IIR); ++ ++ switch (scratch >> 6) { + case 0: + autoconfig_8250(up); + break; +diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c +index e6a7c86b70f25..5c98f561272dd 100644 +--- a/drivers/usb/class/usbtmc.c ++++ b/drivers/usb/class/usbtmc.c +@@ -1537,17 +1537,10 @@ static void usbtmc_interrupt(struct urb *urb) + dev_err(dev, "overflow with length %d, actual length is %d\n", + data->iin_wMaxPacketSize, urb->actual_length); + /* fall through */ +- case -ECONNRESET: +- case -ENOENT: +- case -ESHUTDOWN: +- case -EILSEQ: +- case -ETIME: +- case -EPIPE: ++ default: + /* urb terminated, clean up */ + dev_dbg(dev, "urb terminated, status: %d\n", status); + return; +- default: +- dev_err(dev, "unknown status received: %d\n", status); + } + exit: + rv = usb_submit_urb(urb, GFP_ATOMIC); +diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c +index 3740cf95560e9..0697fde51d00f 100644 +--- a/drivers/usb/common/usb-otg-fsm.c ++++ b/drivers/usb/common/usb-otg-fsm.c +@@ -193,7 +193,11 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm) + if (!fsm->host_req_flag) + return; + +- INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); ++ if (!fsm->hnp_work_inited) { ++ INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); ++ fsm->hnp_work_inited = true; ++ } ++ + schedule_delayed_work(&fsm->hnp_polling_work, + msecs_to_jiffies(T_HOST_REQ_POLL)); + } +diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c +index fa8a8e04008ae..1d10d29c115bc 100644 +--- a/drivers/usb/gadget/function/f_hid.c ++++ b/drivers/usb/gadget/function/f_hid.c +@@ -41,6 +41,7 @@ struct f_hidg { + unsigned char bInterfaceSubClass; + unsigned char bInterfaceProtocol; + unsigned char protocol; ++ unsigned char idle; + unsigned short report_desc_length; + char *report_desc; + unsigned short report_length; +@@ -344,6 +345,11 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer, + + spin_lock_irqsave(&hidg->write_spinlock, flags); + ++ if (!hidg->req) { ++ spin_unlock_irqrestore(&hidg->write_spinlock, flags); ++ return -ESHUTDOWN; ++ } ++ + #define WRITE_COND (!hidg->write_pending) + try_again: + /* write queue */ +@@ -364,8 +370,14 @@ try_again: + count = min_t(unsigned, count, hidg->report_length); + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); +- status = copy_from_user(req->buf, buffer, count); + ++ if (!req) { ++ ERROR(hidg->func.config->cdev, "hidg->req is NULL\n"); ++ status = -ESHUTDOWN; ++ goto release_write_pending; ++ } ++ ++ status = copy_from_user(req->buf, buffer, count); + if (status != 0) { + ERROR(hidg->func.config->cdev, + "copy_from_user error\n"); +@@ -393,14 +405,17 @@ try_again: + + spin_unlock_irqrestore(&hidg->write_spinlock, flags); + ++ if (!hidg->in_ep->enabled) { ++ ERROR(hidg->func.config->cdev, "in_ep is disabled\n"); ++ status = -ESHUTDOWN; ++ goto release_write_pending; ++ } ++ + status = usb_ep_queue(hidg->in_ep, req, GFP_ATOMIC); +- if (status < 0) { +- ERROR(hidg->func.config->cdev, +- "usb_ep_queue error on int endpoint %zd\n", status); ++ if (status < 0) + goto release_write_pending; +- } else { ++ else + status = count; +- } + + return status; + release_write_pending: +@@ -529,6 +544,14 @@ static int hidg_setup(struct usb_function *f, + goto respond; + break; + ++ case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 ++ | HID_REQ_GET_IDLE): ++ VDBG(cdev, "get_idle\n"); ++ length = min_t(unsigned int, length, 1); ++ ((u8 *) req->buf)[0] = hidg->idle; ++ goto respond; ++ break; ++ + case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 + | HID_REQ_SET_REPORT): + VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength); +@@ -552,6 +575,14 @@ static int hidg_setup(struct usb_function *f, + goto stall; + break; + ++ case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 ++ | HID_REQ_SET_IDLE): ++ VDBG(cdev, "set_idle\n"); ++ length = 0; ++ hidg->idle = value >> 8; ++ goto respond; ++ break; ++ + case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8 + | USB_REQ_GET_DESCRIPTOR): + switch (value >> 8) { +@@ -779,6 +810,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) + hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; + hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; + hidg->protocol = HID_REPORT_PROTOCOL; ++ hidg->idle = 1; + hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); + hidg_ss_in_comp_desc.wBytesPerInterval = + cpu_to_le16(hidg->report_length); +diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c +index c87cb25e70ec5..e6dce35ca1aa9 100644 +--- a/drivers/usb/serial/ch341.c ++++ b/drivers/usb/serial/ch341.c +@@ -625,6 +625,7 @@ static struct usb_serial_driver ch341_device = { + .owner = THIS_MODULE, + .name = "ch341-uart", + }, ++ .bulk_in_size = 512, + .id_table = id_table, + .num_ports = 1, + .open = ch341_open, +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 8242bf6863035..784d281eb8479 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -209,6 +209,7 @@ static const struct usb_device_id id_table_combined[] = { + { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) }, + { USB_DEVICE(FTDI_VID, FTDI_VARDAAN_PID) }, ++ { USB_DEVICE(FTDI_VID, FTDI_AUTO_M3_OP_COM_V2_PID) }, + { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) }, + { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) }, + { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) }, +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index add602bebd820..755858ca20bac 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -159,6 +159,9 @@ + /* Vardaan Enterprises Serial Interface VEUSB422R3 */ + #define FTDI_VARDAAN_PID 0xF070 + ++/* Auto-M3 Ltd. - OP-COM USB V2 - OBD interface Adapter */ ++#define FTDI_AUTO_M3_OP_COM_V2_PID 0x4f50 ++ + /* + * Xsens Technologies BV products (http://www.xsens.com). + */ +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 9370c6fa7bc80..e6103a27e4403 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1203,6 +1203,8 @@ static const struct usb_device_id option_ids[] = { + .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1055, 0xff), /* Telit FN980 (PCIe) */ + .driver_info = NCTRL(0) | RSVD(1) }, ++ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */ ++ .driver_info = NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), + .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index 358f6378882f4..797fe41d071f0 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -2317,7 +2317,7 @@ again: + goto journal_error; + err = ext4_handle_dirty_dx_node(handle, dir, + frame->bh); +- if (err) ++ if (restart || err) + goto journal_error; + } else { + struct dx_root *dxroot; +diff --git a/fs/pipe.c b/fs/pipe.c +index 2a297bce381f5..1489257a6c95f 100644 +--- a/fs/pipe.c ++++ b/fs/pipe.c +@@ -29,6 +29,21 @@ + + #include "internal.h" + ++/* ++ * New pipe buffers will be restricted to this size while the user is exceeding ++ * their pipe buffer quota. The general pipe use case needs at least two ++ * buffers: one for data yet to be read, and one for new data. If this is less ++ * than two, then a write to a non-empty pipe may block even if the pipe is not ++ * full. This can occur with GNU make jobserver or similar uses of pipes as ++ * semaphores: multiple processes may be waiting to write tokens back to the ++ * pipe before reading tokens: https://lore.kernel.org/lkml/1628086770.5rn8p04n6j.none@localhost/. ++ * ++ * Users can reduce their pipe buffers with F_SETPIPE_SZ below this at their ++ * own risk, namely: pipe writes to non-full pipes may block until the pipe is ++ * emptied. ++ */ ++#define PIPE_MIN_DEF_BUFFERS 2 ++ + /* + * The max size that a non-root user is allowed to grow the pipe. Can + * be set by root in /proc/sys/fs/pipe-max-size +@@ -654,8 +669,8 @@ struct pipe_inode_info *alloc_pipe_info(void) + user_bufs = account_pipe_buffers(user, 0, pipe_bufs); + + if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) { +- user_bufs = account_pipe_buffers(user, pipe_bufs, 1); +- pipe_bufs = 1; ++ user_bufs = account_pipe_buffers(user, pipe_bufs, PIPE_MIN_DEF_BUFFERS); ++ pipe_bufs = PIPE_MIN_DEF_BUFFERS; + } + + if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user()) +diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c +index 5229038852ca1..4ebad6781b0e3 100644 +--- a/fs/reiserfs/stree.c ++++ b/fs/reiserfs/stree.c +@@ -387,6 +387,24 @@ void pathrelse(struct treepath *search_path) + search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET; + } + ++static int has_valid_deh_location(struct buffer_head *bh, struct item_head *ih) ++{ ++ struct reiserfs_de_head *deh; ++ int i; ++ ++ deh = B_I_DEH(bh, ih); ++ for (i = 0; i < ih_entry_count(ih); i++) { ++ if (deh_location(&deh[i]) > ih_item_len(ih)) { ++ reiserfs_warning(NULL, "reiserfs-5094", ++ "directory entry location seems wrong %h", ++ &deh[i]); ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ + static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) + { + struct block_head *blkh; +@@ -454,11 +472,14 @@ static int is_leaf(char *buf, int blocksize, struct buffer_head *bh) + "(second one): %h", ih); + return 0; + } +- if (is_direntry_le_ih(ih) && (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE))) { +- reiserfs_warning(NULL, "reiserfs-5093", +- "item entry count seems wrong %h", +- ih); +- return 0; ++ if (is_direntry_le_ih(ih)) { ++ if (ih_item_len(ih) < (ih_entry_count(ih) * IH_SIZE)) { ++ reiserfs_warning(NULL, "reiserfs-5093", ++ "item entry count seems wrong %h", ++ ih); ++ return 0; ++ } ++ return has_valid_deh_location(bh, ih); + } + prev_location = ih_location(ih); + } +diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c +index ec5716dd58c23..831a542c22c66 100644 +--- a/fs/reiserfs/super.c ++++ b/fs/reiserfs/super.c +@@ -2085,6 +2085,14 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) + unlock_new_inode(root_inode); + } + ++ if (!S_ISDIR(root_inode->i_mode) || !inode_get_bytes(root_inode) || ++ !root_inode->i_size) { ++ SWARN(silent, s, "", "corrupt root inode, run fsck"); ++ iput(root_inode); ++ errval = -EUCLEAN; ++ goto error; ++ } ++ + s->s_root = d_make_root(root_inode); + if (!s->s_root) + goto error; +diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h +index e78eb577d0fa1..8ef7d148c1493 100644 +--- a/include/linux/usb/otg-fsm.h ++++ b/include/linux/usb/otg-fsm.h +@@ -196,6 +196,7 @@ struct otg_fsm { + struct mutex lock; + u8 *host_req_flag; + struct delayed_work hnp_polling_work; ++ bool hnp_work_inited; + bool state_changed; + }; + +diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h +index 6a61faf0cc79a..75d892dc77969 100644 +--- a/include/net/bluetooth/hci_core.h ++++ b/include/net/bluetooth/hci_core.h +@@ -1042,6 +1042,7 @@ struct hci_dev *hci_alloc_dev(void); + void hci_free_dev(struct hci_dev *hdev); + int hci_register_dev(struct hci_dev *hdev); + void hci_unregister_dev(struct hci_dev *hdev); ++void hci_cleanup_dev(struct hci_dev *hdev); + int hci_suspend_dev(struct hci_dev *hdev); + int hci_resume_dev(struct hci_dev *hdev); + int hci_reset_dev(struct hci_dev *hdev); +diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h +index a8f5410ae0d4b..f237573a26513 100644 +--- a/include/net/ip6_route.h ++++ b/include/net/ip6_route.h +@@ -243,7 +243,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, + + static inline unsigned int ip6_skb_dst_mtu(struct sk_buff *skb) + { +- int mtu; ++ unsigned int mtu; + + struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ? + inet6_sk(skb->sk) : NULL; +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 895026ccfea27..8168403427a67 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4727,6 +4727,10 @@ static const char readme_msg[] = + "\t [:pause][:continue][:clear]\n" + "\t [:name=histname1]\n" + "\t [if <filter>]\n\n" ++ "\t Note, special fields can be used as well:\n" ++ "\t common_timestamp - to record current timestamp\n" ++ "\t common_cpu - to record the CPU the event happened on\n" ++ "\n" + "\t When a matching event is hit, an entry is added to a hash\n" + "\t table using the key(s) and value(s) named, and the value of a\n" + "\t sum called 'hitcount' is incremented. Keys and values\n" +diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c +index 28e4ff45cb4c5..6d2a69652c391 100644 +--- a/kernel/trace/trace_events_hist.c ++++ b/kernel/trace/trace_events_hist.c +@@ -1773,7 +1773,7 @@ static const char *hist_field_name(struct hist_field *field, + field->flags & HIST_FIELD_FL_ALIAS) + field_name = hist_field_name(field->operands[0], ++level); + else if (field->flags & HIST_FIELD_FL_CPU) +- field_name = "cpu"; ++ field_name = "common_cpu"; + else if (field->flags & HIST_FIELD_FL_EXPR || + field->flags & HIST_FIELD_FL_VAR_REF) { + if (field->system) { +@@ -2627,14 +2627,23 @@ parse_field(struct hist_trigger_data *hist_data, struct trace_event_file *file, + hist_data->enable_timestamps = true; + if (*flags & HIST_FIELD_FL_TIMESTAMP_USECS) + hist_data->attrs->ts_in_usecs = true; +- } else if (strcmp(field_name, "cpu") == 0) ++ } else if (strcmp(field_name, "common_cpu") == 0) + *flags |= HIST_FIELD_FL_CPU; + else { + field = trace_find_event_field(file->event_call, field_name); + if (!field || !field->size) { +- hist_err("Couldn't find field: ", field_name); +- field = ERR_PTR(-EINVAL); +- goto out; ++ /* ++ * For backward compatibility, if field_name ++ * was "cpu", then we treat this the same as ++ * common_cpu. ++ */ ++ if (strcmp(field_name, "cpu") == 0) { ++ *flags |= HIST_FIELD_FL_CPU; ++ } else { ++ hist_err("Couldn't find field: ", field_name); ++ field = ERR_PTR(-EINVAL); ++ goto out; ++ } + } + } + out: +@@ -2911,6 +2920,10 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, + + expr->operands[0] = operand1; + expr->operands[1] = operand2; ++ ++ /* The operand sizes should be the same, so just pick one */ ++ expr->size = operand1->size; ++ + expr->operator = field_op; + expr->name = expr_str(expr, 0); + expr->type = kstrdup(operand1->type, GFP_KERNEL); +@@ -5048,7 +5061,7 @@ static void hist_field_print(struct seq_file *m, struct hist_field *hist_field) + seq_printf(m, "%s=", hist_field->var.name); + + if (hist_field->flags & HIST_FIELD_FL_CPU) +- seq_puts(m, "cpu"); ++ seq_puts(m, "common_cpu"); + else if (field_name) { + if (hist_field->flags & HIST_FIELD_FL_VAR_REF || + hist_field->flags & HIST_FIELD_FL_ALIAS) +diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c +index 219cdbb476fb7..7a85f215da45c 100644 +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -3261,14 +3261,10 @@ EXPORT_SYMBOL(hci_register_dev); + /* Unregister HCI device */ + void hci_unregister_dev(struct hci_dev *hdev) + { +- int id; +- + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + + hci_dev_set_flag(hdev, HCI_UNREGISTER); + +- id = hdev->id; +- + write_lock(&hci_dev_list_lock); + list_del(&hdev->list); + write_unlock(&hci_dev_list_lock); +@@ -3297,7 +3293,14 @@ void hci_unregister_dev(struct hci_dev *hdev) + } + + device_del(&hdev->dev); ++ /* Actual cleanup is deferred until hci_cleanup_dev(). */ ++ hci_dev_put(hdev); ++} ++EXPORT_SYMBOL(hci_unregister_dev); + ++/* Cleanup HCI device */ ++void hci_cleanup_dev(struct hci_dev *hdev) ++{ + debugfs_remove_recursive(hdev->debugfs); + kfree_const(hdev->hw_info); + kfree_const(hdev->fw_info); +@@ -3320,11 +3323,8 @@ void hci_unregister_dev(struct hci_dev *hdev) + hci_discovery_filter_clear(hdev); + hci_dev_unlock(hdev); + +- hci_dev_put(hdev); +- +- ida_simple_remove(&hci_index_ida, id); ++ ida_simple_remove(&hci_index_ida, hdev->id); + } +-EXPORT_SYMBOL(hci_unregister_dev); + + /* Suspend HCI device */ + int hci_suspend_dev(struct hci_dev *hdev) +diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c +index 06156de24c50b..3ba0c6df73ce9 100644 +--- a/net/bluetooth/hci_sock.c ++++ b/net/bluetooth/hci_sock.c +@@ -59,6 +59,17 @@ struct hci_pinfo { + char comm[TASK_COMM_LEN]; + }; + ++static struct hci_dev *hci_hdev_from_sock(struct sock *sk) ++{ ++ struct hci_dev *hdev = hci_pi(sk)->hdev; ++ ++ if (!hdev) ++ return ERR_PTR(-EBADFD); ++ if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) ++ return ERR_PTR(-EPIPE); ++ return hdev; ++} ++ + void hci_sock_set_flag(struct sock *sk, int nr) + { + set_bit(nr, &hci_pi(sk)->flags); +@@ -752,19 +763,13 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) + if (event == HCI_DEV_UNREG) { + struct sock *sk; + +- /* Detach sockets from device */ ++ /* Wake up sockets using this dead device */ + read_lock(&hci_sk_list.lock); + sk_for_each(sk, &hci_sk_list.head) { +- lock_sock(sk); + if (hci_pi(sk)->hdev == hdev) { +- hci_pi(sk)->hdev = NULL; + sk->sk_err = EPIPE; +- sk->sk_state = BT_OPEN; + sk->sk_state_change(sk); +- +- hci_dev_put(hdev); + } +- release_sock(sk); + } + read_unlock(&hci_sk_list.lock); + } +@@ -923,10 +928,10 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) + static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, + unsigned long arg) + { +- struct hci_dev *hdev = hci_pi(sk)->hdev; ++ struct hci_dev *hdev = hci_hdev_from_sock(sk); + +- if (!hdev) +- return -EBADFD; ++ if (IS_ERR(hdev)) ++ return PTR_ERR(hdev); + + if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) + return -EBUSY; +@@ -1080,6 +1085,18 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, + + lock_sock(sk); + ++ /* Allow detaching from dead device and attaching to alive device, if ++ * the caller wants to re-bind (instead of close) this socket in ++ * response to hci_sock_dev_event(HCI_DEV_UNREG) notification. ++ */ ++ hdev = hci_pi(sk)->hdev; ++ if (hdev && hci_dev_test_flag(hdev, HCI_UNREGISTER)) { ++ hci_pi(sk)->hdev = NULL; ++ sk->sk_state = BT_OPEN; ++ hci_dev_put(hdev); ++ } ++ hdev = NULL; ++ + if (sk->sk_state == BT_BOUND) { + err = -EALREADY; + goto done; +@@ -1356,9 +1373,9 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, + + lock_sock(sk); + +- hdev = hci_pi(sk)->hdev; +- if (!hdev) { +- err = -EBADFD; ++ hdev = hci_hdev_from_sock(sk); ++ if (IS_ERR(hdev)) { ++ err = PTR_ERR(hdev); + goto done; + } + +@@ -1718,9 +1735,9 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, + goto done; + } + +- hdev = hci_pi(sk)->hdev; +- if (!hdev) { +- err = -EBADFD; ++ hdev = hci_hdev_from_sock(sk); ++ if (IS_ERR(hdev)) { ++ err = PTR_ERR(hdev); + goto done; + } + +diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c +index 9874844a95a98..b69d88b88d2e4 100644 +--- a/net/bluetooth/hci_sysfs.c ++++ b/net/bluetooth/hci_sysfs.c +@@ -83,6 +83,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn) + static void bt_host_release(struct device *dev) + { + struct hci_dev *hdev = to_hci_dev(dev); ++ ++ if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) ++ hci_cleanup_dev(hdev); + kfree(hdev); + module_put(THIS_MODULE); + } +diff --git a/net/sctp/auth.c b/net/sctp/auth.c +index b2ca66c4a21d2..9e0c98df20daf 100644 +--- a/net/sctp/auth.c ++++ b/net/sctp/auth.c +@@ -880,14 +880,18 @@ int sctp_auth_set_key(struct sctp_endpoint *ep, + memcpy(key->data, &auth_key->sca_key[0], auth_key->sca_keylength); + cur_key->key = key; + +- if (replace) { +- list_del_init(&shkey->key_list); +- sctp_auth_shkey_release(shkey); +- if (asoc && asoc->active_key_id == auth_key->sca_keynumber) +- sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL); ++ if (!replace) { ++ list_add(&cur_key->key_list, sh_keys); ++ return 0; + } ++ ++ list_del_init(&shkey->key_list); ++ sctp_auth_shkey_release(shkey); + list_add(&cur_key->key_list, sh_keys); + ++ if (asoc && asoc->active_key_id == auth_key->sca_keynumber) ++ sctp_auth_asoc_init_active_key(asoc, GFP_KERNEL); ++ + return 0; + } + +diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py +index 9b6dd4f36335b..5706b42be3d27 100755 +--- a/scripts/tracing/draw_functrace.py ++++ b/scripts/tracing/draw_functrace.py +@@ -17,7 +17,7 @@ Usage: + $ cat /sys/kernel/debug/tracing/trace_pipe > ~/raw_trace_func + Wait some times but not too much, the script is a bit slow. + Break the pipe (Ctrl + Z) +- $ scripts/draw_functrace.py < raw_trace_func > draw_functrace ++ $ scripts/tracing/draw_functrace.py < ~/raw_trace_func > draw_functrace + Then you have your drawn trace in draw_functrace + """ + +@@ -103,10 +103,10 @@ def parseLine(line): + line = line.strip() + if line.startswith("#"): + raise CommentLineException +- m = re.match("[^]]+?\\] +([0-9.]+): (\\w+) <-(\\w+)", line) ++ m = re.match("[^]]+?\\] +([a-z.]+) +([0-9.]+): (\\w+) <-(\\w+)", line) + if m is None: + raise BrokenLineException +- return (m.group(1), m.group(2), m.group(3)) ++ return (m.group(2), m.group(3), m.group(4)) + + + def main(): +diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c +index 16289aefb443a..efecb8b8e7b16 100644 +--- a/sound/core/seq/seq_ports.c ++++ b/sound/core/seq/seq_ports.c +@@ -532,10 +532,11 @@ static int check_and_subscribe_port(struct snd_seq_client *client, + return err; + } + +-static void delete_and_unsubscribe_port(struct snd_seq_client *client, +- struct snd_seq_client_port *port, +- struct snd_seq_subscribers *subs, +- bool is_src, bool ack) ++/* called with grp->list_mutex held */ ++static void __delete_and_unsubscribe_port(struct snd_seq_client *client, ++ struct snd_seq_client_port *port, ++ struct snd_seq_subscribers *subs, ++ bool is_src, bool ack) + { + struct snd_seq_port_subs_info *grp; + struct list_head *list; +@@ -543,7 +544,6 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client, + + grp = is_src ? &port->c_src : &port->c_dest; + list = is_src ? &subs->src_list : &subs->dest_list; +- down_write(&grp->list_mutex); + write_lock_irq(&grp->list_lock); + empty = list_empty(list); + if (!empty) +@@ -553,6 +553,18 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client, + + if (!empty) + unsubscribe_port(client, port, grp, &subs->info, ack); ++} ++ ++static void delete_and_unsubscribe_port(struct snd_seq_client *client, ++ struct snd_seq_client_port *port, ++ struct snd_seq_subscribers *subs, ++ bool is_src, bool ack) ++{ ++ struct snd_seq_port_subs_info *grp; ++ ++ grp = is_src ? &port->c_src : &port->c_dest; ++ down_write(&grp->list_mutex); ++ __delete_and_unsubscribe_port(client, port, subs, is_src, ack); + up_write(&grp->list_mutex); + } + +@@ -608,27 +620,30 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector, + struct snd_seq_client_port *dest_port, + struct snd_seq_port_subscribe *info) + { +- struct snd_seq_port_subs_info *src = &src_port->c_src; ++ struct snd_seq_port_subs_info *dest = &dest_port->c_dest; + struct snd_seq_subscribers *subs; + int err = -ENOENT; + +- down_write(&src->list_mutex); ++ /* always start from deleting the dest port for avoiding concurrent ++ * deletions ++ */ ++ down_write(&dest->list_mutex); + /* look for the connection */ +- list_for_each_entry(subs, &src->list_head, src_list) { ++ list_for_each_entry(subs, &dest->list_head, dest_list) { + if (match_subs_info(info, &subs->info)) { +- atomic_dec(&subs->ref_count); /* mark as not ready */ ++ __delete_and_unsubscribe_port(dest_client, dest_port, ++ subs, false, ++ connector->number != dest_client->number); + err = 0; + break; + } + } +- up_write(&src->list_mutex); ++ up_write(&dest->list_mutex); + if (err < 0) + return err; + + delete_and_unsubscribe_port(src_client, src_port, subs, true, + connector->number != src_client->number); +- delete_and_unsubscribe_port(dest_client, dest_port, subs, false, +- connector->number != dest_client->number); + kfree(subs); + return 0; + } +diff --git a/sound/usb/clock.c b/sound/usb/clock.c +index 863ac42076e55..d1455fb2c6fca 100644 +--- a/sound/usb/clock.c ++++ b/sound/usb/clock.c +@@ -296,6 +296,12 @@ static int __uac_clock_find_source(struct snd_usb_audio *chip, + selector->baCSourceID[ret - 1], + visited, validate); + if (ret > 0) { ++ /* ++ * For Samsung USBC Headset (AKG), setting clock selector again ++ * will result in incorrect default clock setting problems ++ */ ++ if (chip->usb_id == USB_ID(0x04e8, 0xa051)) ++ return ret; + err = uac_clock_selector_set_val(chip, entity_id, cur); + if (err < 0) + return err; +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 87d3ea9796384..4114594e57a30 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1555,6 +1555,7 @@ static const struct registration_quirk registration_quirks[] = { + REG_QUIRK_ENTRY(0x0951, 0x16ea, 2), /* Kingston HyperX Cloud Flight S */ + REG_QUIRK_ENTRY(0x0ecb, 0x1f46, 2), /* JBL Quantum 600 */ + REG_QUIRK_ENTRY(0x0ecb, 0x2039, 2), /* JBL Quantum 400 */ ++ REG_QUIRK_ENTRY(0x0ecb, 0x203c, 2), /* JBL Quantum 600 */ + REG_QUIRK_ENTRY(0x0ecb, 0x203e, 2), /* JBL Quantum 800 */ + { 0 } /* terminator */ + };
