diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml index db61f0731a203..2e35aeaa8781d 100644 --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml @@ -57,7 +57,7 @@ patternProperties: rate sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle + $ref: /schemas/types.yaml#/definitions/phandle-array description: phandle of the CPU DAI patternProperties: @@ -71,7 +71,7 @@ patternProperties: properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle + $ref: /schemas/types.yaml#/definitions/phandle-array description: phandle of the codec DAI required: diff --git a/Documentation/virt/kvm/mmu.rst b/Documentation/virt/kvm/mmu.rst index 5bfe28b0728e8..20d85daed395e 100644 --- a/Documentation/virt/kvm/mmu.rst +++ b/Documentation/virt/kvm/mmu.rst @@ -171,8 +171,8 @@ Shadow pages contain the following information: shadow pages) so role.quadrant takes values in the range 0..3. Each quadrant maps 1GB virtual address space. role.access: - Inherited guest access permissions in the form uwx. Note execute - permission is positive, not negative. + Inherited guest access permissions from the parent ptes in the form uwx. + Note execute permission is positive, not negative. role.invalid: The page is invalid and should not be used. It is a root page that is currently pinned (by a cpu hardware register pointing to it); once it is diff --git a/Makefile b/Makefile index ebc02c56db03c..82ca490ce5f48 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 12 -SUBLEVEL = 10 +SUBLEVEL = 11 EXTRAVERSION = NAME = Frozen Wasteland @@ -912,6 +912,11 @@ CC_FLAGS_LTO += -fvisibility=hidden # Limit inlining across translation units to reduce binary size KBUILD_LDFLAGS += -mllvm -import-instr-limit=5 + +# Check for frame size exceeding threshold during prolog/epilog insertion. +ifneq ($(CONFIG_FRAME_WARN),0) +KBUILD_LDFLAGS += -plugin-opt=-warn-stack-size=$(CONFIG_FRAME_WARN) +endif endif ifdef CONFIG_LTO diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h index 0d67ed682e077..bc4ffa7ca04c7 100644 --- a/arch/arm/include/asm/cpuidle.h +++ b/arch/arm/include/asm/cpuidle.h @@ -7,9 +7,11 @@ #ifdef CONFIG_CPU_IDLE extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); +#define __cpuidle_method_section __used __section("__cpuidle_method_of_table") #else static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { return -ENODEV; } +#define __cpuidle_method_section __maybe_unused /* drop silently */ #endif /* Common ARM WFI state */ @@ -42,8 +44,7 @@ struct of_cpuidle_method { #define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \ static const struct of_cpuidle_method __cpuidle_method_of_table_##name \ - __used __section("__cpuidle_method_of_table") \ - = { .method = _method, .ops = _ops } + __cpuidle_method_section = { .method = _method, .ops = _ops } extern int arm_cpuidle_suspend(int index); diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index de03838b343b8..a9b72eacfc0b3 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c @@ -37,7 +37,7 @@ */ notrace void arch_local_irq_disable(void) { - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -53,7 +53,7 @@ notrace void arch_local_irq_disable(void) : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_disable); @@ -61,7 +61,7 @@ notrace unsigned long arch_local_irq_save(void) { unsigned long flags; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -78,7 +78,7 @@ notrace unsigned long arch_local_irq_save(void) : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); return flags; } @@ -88,7 +88,7 @@ notrace void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -106,7 +106,7 @@ notrace void arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_restore); diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index 1b4aafc1f6a27..9716a0484ecf0 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -122,7 +122,15 @@ }; /include/ "pq3-i2c-0.dtsi" + i2c@3000 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-i2c-1.dtsi" + i2c@3100 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-duart-0.dtsi" /include/ "pq3-espi-0.dtsi" spi0: spi@7000 { diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index 872e4485dc3f0..ddc018d42252f 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi @@ -371,7 +371,23 @@ }; /include/ "qoriq-i2c-0.dtsi" + i2c@118000 { + fsl,i2c-erratum-a004447; + }; + + i2c@118100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-i2c-1.dtsi" + i2c@119000 { + fsl,i2c-erratum-a004447; + }; + + i2c@119100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-duart-0.dtsi" /include/ "qoriq-duart-1.dtsi" /include/ "qoriq-gpio-0.dtsi" diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 1f2e5bfb9bb03..2855a1a3d6121 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -192,8 +192,9 @@ endif KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE) ifdef CONFIG_LTO_CLANG -KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \ - -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) +ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) +KBUILD_LDFLAGS += -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) +endif endif ifdef CONFIG_X86_NEED_RELOCS diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 9b89376318388..9e1f64bc988b0 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -1406,6 +1406,8 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool die_id = i; else die_id = topology_phys_to_logical_pkg(i); + if (die_id < 0) + die_id = -ENODEV; map->pbus_to_dieid[bus] = die_id; break; } @@ -1452,14 +1454,14 @@ static int snbep_pci2phy_map_init(int devid, int nodeid_loc, int idmap_loc, bool i = -1; if (reverse) { for (bus = 255; bus >= 0; bus--) { - if (map->pbus_to_dieid[bus] >= 0) + if (map->pbus_to_dieid[bus] != -1) i = map->pbus_to_dieid[bus]; else map->pbus_to_dieid[bus] = i; } } else { for (bus = 0; bus <= 255; bus++) { - if (map->pbus_to_dieid[bus] >= 0) + if (map->pbus_to_dieid[bus] != -1) i = map->pbus_to_dieid[bus]; else map->pbus_to_dieid[bus] = i; @@ -5103,9 +5105,10 @@ static struct intel_uncore_type icx_uncore_m2m = { .perf_ctr = SNR_M2M_PCI_PMON_CTR0, .event_ctl = SNR_M2M_PCI_PMON_CTL0, .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .event_mask_ext = SNR_M2M_PCI_PMON_UMASK_EXT, .box_ctl = SNR_M2M_PCI_PMON_BOX_CTL, .ops = &snr_m2m_uncore_pci_ops, - .format_group = &skx_uncore_format_group, + .format_group = &snr_m2m_uncore_format_group, }; static struct attribute *icx_upi_uncore_formats_attr[] = { diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index 3ef5868ac588a..7aecb2fc31863 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c @@ -63,7 +63,7 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) case 15: return msr - MSR_P4_BPU_PERFCTR0; } - fallthrough; + break; case X86_VENDOR_ZHAOXIN: case X86_VENDOR_CENTAUR: return msr - MSR_ARCH_PERFMON_PERFCTR0; @@ -96,7 +96,7 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) case 15: return msr - MSR_P4_BSU_ESCR0; } - fallthrough; + break; case X86_VENDOR_ZHAOXIN: case X86_VENDOR_CENTAUR: return msr - MSR_ARCH_PERFMON_EVENTSEL0; diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 55d7b473ac447..a2becf9c2553e 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -90,8 +90,8 @@ struct guest_walker { gpa_t pte_gpa[PT_MAX_FULL_LEVELS]; pt_element_t __user *ptep_user[PT_MAX_FULL_LEVELS]; bool pte_writable[PT_MAX_FULL_LEVELS]; - unsigned pt_access; - unsigned pte_access; + unsigned int pt_access[PT_MAX_FULL_LEVELS]; + unsigned int pte_access; gfn_t gfn; struct x86_exception fault; }; @@ -418,13 +418,15 @@ retry_walk: } walker->ptes[walker->level - 1] = pte; + + /* Convert to ACC_*_MASK flags for struct guest_walker. */ + walker->pt_access[walker->level - 1] = FNAME(gpte_access)(pt_access ^ walk_nx_mask); } while (!is_last_gpte(mmu, walker->level, pte)); pte_pkey = FNAME(gpte_pkeys)(vcpu, pte); accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0; /* Convert to ACC_*_MASK flags for struct guest_walker. */ - walker->pt_access = FNAME(gpte_access)(pt_access ^ walk_nx_mask); walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask); errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access); if (unlikely(errcode)) @@ -463,7 +465,8 @@ retry_walk: } pgprintk("%s: pte %llx pte_access %x pt_access %x\n", - __func__, (u64)pte, walker->pte_access, walker->pt_access); + __func__, (u64)pte, walker->pte_access, + walker->pt_access[walker->level - 1]); return 1; error: @@ -642,7 +645,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, bool huge_page_disallowed = exec && nx_huge_page_workaround_enabled; struct kvm_mmu_page *sp = NULL; struct kvm_shadow_walk_iterator it; - unsigned direct_access, access = gw->pt_access; + unsigned int direct_access, access; int top_level, level, req_level, ret; gfn_t base_gfn = gw->gfn; @@ -674,6 +677,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, sp = NULL; if (!is_shadow_present_pte(*it.sptep)) { table_gfn = gw->table_gfn[it.level - 2]; + access = gw->pt_access[it.level - 2]; sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1, false, access); } diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index a61c015870e33..4f839148948bc 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -1550,16 +1550,16 @@ TRACE_EVENT(kvm_nested_vmenter_failed, TP_ARGS(msg, err), TP_STRUCT__entry( - __field(const char *, msg) + __string(msg, msg) __field(u32, err) ), TP_fast_assign( - __entry->msg = msg; + __assign_str(msg, msg); __entry->err = err; ), - TP_printk("%s%s", __entry->msg, !__entry->err ? "" : + TP_printk("%s%s", __get_str(msg), !__entry->err ? "" : __print_symbolic(__entry->err, VMX_VMENTER_INSTRUCTION_ERRORS)) ); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 822c23c3752c5..cf37205784297 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2982,6 +2982,19 @@ static void kvm_vcpu_flush_tlb_all(struct kvm_vcpu *vcpu) static void kvm_vcpu_flush_tlb_guest(struct kvm_vcpu *vcpu) { ++vcpu->stat.tlb_flush; + + if (!tdp_enabled) { + /* + * A TLB flush on behalf of the guest is equivalent to + * INVPCID(all), toggling CR4.PGE, etc., which requires + * a forced sync of the shadow page tables. Unload the + * entire MMU here and the subsequent load will sync the + * shadow page tables, and also flush the TLB. + */ + kvm_mmu_unload(vcpu); + return; + } + static_call(kvm_x86_tlb_flush_guest)(vcpu); } diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 6cd7f7025df47..d8a91521144e0 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c @@ -233,7 +233,8 @@ async_xor_offs(struct page *dest, unsigned int offset, if (submit->flags & ASYNC_TX_XOR_DROP_DST) { src_cnt--; src_list++; - src_offs++; + if (src_offs) + src_offs++; } /* wait for any prerequisite operations */ diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index be7da23fad76f..a4bd673934c0a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -330,32 +330,21 @@ static void acpi_bus_osc_negotiate_platform_control(void) if (ACPI_FAILURE(acpi_run_osc(handle, &context))) return; - capbuf_ret = context.ret.pointer; - if (context.ret.length <= OSC_SUPPORT_DWORD) { - kfree(context.ret.pointer); - return; - } + kfree(context.ret.pointer); - /* - * Now run _OSC again with query flag clear and with the caps - * supported by both the OS and the platform. - */ + /* Now run _OSC again with query flag clear */ capbuf[OSC_QUERY_DWORD] = 0; - capbuf[OSC_SUPPORT_DWORD] = capbuf_ret[OSC_SUPPORT_DWORD]; - kfree(context.ret.pointer); if (ACPI_FAILURE(acpi_run_osc(handle, &context))) return; capbuf_ret = context.ret.pointer; - if (context.ret.length > OSC_SUPPORT_DWORD) { - osc_sb_apei_support_acked = - capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT; - osc_pc_lpi_support_confirmed = - capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT; - osc_sb_native_usb4_support_confirmed = - capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT; - } + osc_sb_apei_support_acked = + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT; + osc_pc_lpi_support_confirmed = + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT; + osc_sb_native_usb4_support_confirmed = + capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_NATIVE_USB4_SUPPORT; kfree(context.ret.pointer); } diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 09fd13757b658..4d2118c8dd6c0 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -1009,10 +1009,8 @@ static void acpi_sleep_hibernate_setup(void) return; acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs); - if (facs) { + if (facs) s4_hardware_signature = facs->hardware_signature; - acpi_put_table((struct acpi_table_header *)facs); - } } #else /* !CONFIG_HIBERNATION */ static inline void acpi_sleep_hibernate_setup(void) {} diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c index ef549c695b55c..3e50a9fc4d822 100644 --- a/drivers/bus/mhi/pci_generic.c +++ b/drivers/bus/mhi/pci_generic.c @@ -505,7 +505,7 @@ static void mhi_pci_remove(struct pci_dev *pdev) struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev); struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl; - del_timer(&mhi_pdev->health_check_timer); + del_timer_sync(&mhi_pdev->health_check_timer); cancel_work_sync(&mhi_pdev->recovery_work); if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { diff --git a/drivers/gpio/gpio-wcd934x.c b/drivers/gpio/gpio-wcd934x.c index 1cbce59908558..97e6caedf1f33 100644 --- a/drivers/gpio/gpio-wcd934x.c +++ b/drivers/gpio/gpio-wcd934x.c @@ -7,7 +7,7 @@ #include #include -#define WCD_PIN_MASK(p) BIT(p - 1) +#define WCD_PIN_MASK(p) BIT(p) #define WCD_REG_DIR_CTL_OFFSET 0x42 #define WCD_REG_VAL_CTL_OFFSET 0x43 #define WCD934X_NPINS 5 diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index f2d46b7ac6f9f..232abbba36868 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -314,9 +314,10 @@ int drm_master_open(struct drm_file *file_priv) void drm_master_release(struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; - struct drm_master *master = file_priv->master; + struct drm_master *master; mutex_lock(&dev->master_mutex); + master = file_priv->master; if (file_priv->magic) idr_remove(&file_priv->master->magic_map, file_priv->magic); diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index d273d1a8603a9..495a4767a4430 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -118,17 +118,18 @@ int drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_unique *u = data; - struct drm_master *master = file_priv->master; + struct drm_master *master; - mutex_lock(&master->dev->master_mutex); + mutex_lock(&dev->master_mutex); + master = file_priv->master; if (u->unique_len >= master->unique_len) { if (copy_to_user(u->unique, master->unique, master->unique_len)) { - mutex_unlock(&master->dev->master_mutex); + mutex_unlock(&dev->master_mutex); return -EFAULT; } } u->unique_len = master->unique_len; - mutex_unlock(&master->dev->master_mutex); + mutex_unlock(&dev->master_mutex); return 0; } diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index b3fd3501c4127..5275b2723293b 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -577,7 +577,7 @@ static void mcde_dsi_setup_video_mode(struct mcde_dsi *d, * porches and sync. */ /* (ps/s) / (pixels/s) = ps/pixels */ - pclk = DIV_ROUND_UP_ULL(1000000000000, mode->clock); + pclk = DIV_ROUND_UP_ULL(1000000000000, (mode->clock * 1000)); dev_dbg(d->dev, "picoseconds between two pixels: %llu\n", pclk); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index b4d8e1b01ee4f..f6c1b62b901e2 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -157,7 +157,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) * GPU registers so we need to add 0x1a800 to the register value on A630 * to get the right value from PM4. */ - get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800, + get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, rbmemptr_stats(ring, index, alwayson_start)); /* Invalidate CCU depth and color */ @@ -187,7 +187,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO, rbmemptr_stats(ring, index, cpcycles_end)); - get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800, + get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, rbmemptr_stats(ring, index, alwayson_end)); /* Write the fence to the scratch register */ @@ -206,8 +206,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_RING(ring, submit->seqno); trace_msm_gpu_submit_flush(submit, - gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L, - REG_A6XX_GMU_ALWAYS_ON_COUNTER_H)); + gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, + REG_A6XX_CP_ALWAYS_ON_COUNTER_HI)); a6xx_flush(gpu, ring); } @@ -462,6 +462,113 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0); } +/* For a615, a616, a618, A619, a630, a640 and a680 */ +static const u32 a6xx_protect[] = { + A6XX_PROTECT_RDONLY(0x00000, 0x04ff), + A6XX_PROTECT_RDONLY(0x00501, 0x0005), + A6XX_PROTECT_RDONLY(0x0050b, 0x02f4), + A6XX_PROTECT_NORDWR(0x0050e, 0x0000), + A6XX_PROTECT_NORDWR(0x00510, 0x0000), + A6XX_PROTECT_NORDWR(0x00534, 0x0000), + A6XX_PROTECT_NORDWR(0x00800, 0x0082), + A6XX_PROTECT_NORDWR(0x008a0, 0x0008), + A6XX_PROTECT_NORDWR(0x008ab, 0x0024), + A6XX_PROTECT_RDONLY(0x008de, 0x00ae), + A6XX_PROTECT_NORDWR(0x00900, 0x004d), + A6XX_PROTECT_NORDWR(0x0098d, 0x0272), + A6XX_PROTECT_NORDWR(0x00e00, 0x0001), + A6XX_PROTECT_NORDWR(0x00e03, 0x000c), + A6XX_PROTECT_NORDWR(0x03c00, 0x00c3), + A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff), + A6XX_PROTECT_NORDWR(0x08630, 0x01cf), + A6XX_PROTECT_NORDWR(0x08e00, 0x0000), + A6XX_PROTECT_NORDWR(0x08e08, 0x0000), + A6XX_PROTECT_NORDWR(0x08e50, 0x001f), + A6XX_PROTECT_NORDWR(0x09624, 0x01db), + A6XX_PROTECT_NORDWR(0x09e70, 0x0001), + A6XX_PROTECT_NORDWR(0x09e78, 0x0187), + A6XX_PROTECT_NORDWR(0x0a630, 0x01cf), + A6XX_PROTECT_NORDWR(0x0ae02, 0x0000), + A6XX_PROTECT_NORDWR(0x0ae50, 0x032f), + A6XX_PROTECT_NORDWR(0x0b604, 0x0000), + A6XX_PROTECT_NORDWR(0x0be02, 0x0001), + A6XX_PROTECT_NORDWR(0x0be20, 0x17df), + A6XX_PROTECT_NORDWR(0x0f000, 0x0bff), + A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff), + A6XX_PROTECT_NORDWR(0x11c00, 0x0000), /* note: infinite range */ +}; + +/* These are for a620 and a650 */ +static const u32 a650_protect[] = { + A6XX_PROTECT_RDONLY(0x00000, 0x04ff), + A6XX_PROTECT_RDONLY(0x00501, 0x0005), + A6XX_PROTECT_RDONLY(0x0050b, 0x02f4), + A6XX_PROTECT_NORDWR(0x0050e, 0x0000), + A6XX_PROTECT_NORDWR(0x00510, 0x0000), + A6XX_PROTECT_NORDWR(0x00534, 0x0000), + A6XX_PROTECT_NORDWR(0x00800, 0x0082), + A6XX_PROTECT_NORDWR(0x008a0, 0x0008), + A6XX_PROTECT_NORDWR(0x008ab, 0x0024), + A6XX_PROTECT_RDONLY(0x008de, 0x00ae), + A6XX_PROTECT_NORDWR(0x00900, 0x004d), + A6XX_PROTECT_NORDWR(0x0098d, 0x0272), + A6XX_PROTECT_NORDWR(0x00e00, 0x0001), + A6XX_PROTECT_NORDWR(0x00e03, 0x000c), + A6XX_PROTECT_NORDWR(0x03c00, 0x00c3), + A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff), + A6XX_PROTECT_NORDWR(0x08630, 0x01cf), + A6XX_PROTECT_NORDWR(0x08e00, 0x0000), + A6XX_PROTECT_NORDWR(0x08e08, 0x0000), + A6XX_PROTECT_NORDWR(0x08e50, 0x001f), + A6XX_PROTECT_NORDWR(0x08e80, 0x027f), + A6XX_PROTECT_NORDWR(0x09624, 0x01db), + A6XX_PROTECT_NORDWR(0x09e60, 0x0011), + A6XX_PROTECT_NORDWR(0x09e78, 0x0187), + A6XX_PROTECT_NORDWR(0x0a630, 0x01cf), + A6XX_PROTECT_NORDWR(0x0ae02, 0x0000), + A6XX_PROTECT_NORDWR(0x0ae50, 0x032f), + A6XX_PROTECT_NORDWR(0x0b604, 0x0000), + A6XX_PROTECT_NORDWR(0x0b608, 0x0007), + A6XX_PROTECT_NORDWR(0x0be02, 0x0001), + A6XX_PROTECT_NORDWR(0x0be20, 0x17df), + A6XX_PROTECT_NORDWR(0x0f000, 0x0bff), + A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff), + A6XX_PROTECT_NORDWR(0x18400, 0x1fff), + A6XX_PROTECT_NORDWR(0x1a800, 0x1fff), + A6XX_PROTECT_NORDWR(0x1f400, 0x0443), + A6XX_PROTECT_RDONLY(0x1f844, 0x007b), + A6XX_PROTECT_NORDWR(0x1f887, 0x001b), + A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */ +}; + +static void a6xx_set_cp_protect(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + const u32 *regs = a6xx_protect; + unsigned i, count = ARRAY_SIZE(a6xx_protect), count_max = 32; + + BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32); + BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48); + + if (adreno_is_a650(adreno_gpu)) { + regs = a650_protect; + count = ARRAY_SIZE(a650_protect); + count_max = 48; + } + + /* + * Enable access protection to privileged registers, fault on an access + * protect violation and select the last span to protect from the start + * address all the way to the end of the register address space + */ + gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, BIT(0) | BIT(1) | BIT(3)); + + for (i = 0; i < count - 1; i++) + gpu_write(gpu, REG_A6XX_CP_PROTECT(i), regs[i]); + /* last CP_PROTECT to have "infinite" length on the last entry */ + gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]); +} + static void a6xx_set_ubwc_config(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -489,7 +596,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, - uavflagprd_inv >> 4 | lower_bit << 1); + uavflagprd_inv << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21); } @@ -776,41 +883,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) } /* Protect registers from the CP */ - gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, 0x00000003); - - gpu_write(gpu, REG_A6XX_CP_PROTECT(0), - A6XX_PROTECT_RDONLY(0x600, 0x51)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(1), A6XX_PROTECT_RW(0xae50, 0x2)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(2), A6XX_PROTECT_RW(0x9624, 0x13)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(3), A6XX_PROTECT_RW(0x8630, 0x8)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(4), A6XX_PROTECT_RW(0x9e70, 0x1)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(5), A6XX_PROTECT_RW(0x9e78, 0x187)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(6), A6XX_PROTECT_RW(0xf000, 0x810)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(7), - A6XX_PROTECT_RDONLY(0xfc00, 0x3)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(8), A6XX_PROTECT_RW(0x50e, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(9), A6XX_PROTECT_RDONLY(0x50f, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(10), A6XX_PROTECT_RW(0x510, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(11), - A6XX_PROTECT_RDONLY(0x0, 0x4f9)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(12), - A6XX_PROTECT_RDONLY(0x501, 0xa)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(13), - A6XX_PROTECT_RDONLY(0x511, 0x44)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(14), A6XX_PROTECT_RW(0xe00, 0xe)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(15), A6XX_PROTECT_RW(0x8e00, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(16), A6XX_PROTECT_RW(0x8e50, 0xf)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(17), A6XX_PROTECT_RW(0xbe02, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(18), - A6XX_PROTECT_RW(0xbe20, 0x11f3)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(19), A6XX_PROTECT_RW(0x800, 0x82)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(20), A6XX_PROTECT_RW(0x8a0, 0x8)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(21), A6XX_PROTECT_RW(0x8ab, 0x19)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(22), A6XX_PROTECT_RW(0x900, 0x4d)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(23), A6XX_PROTECT_RW(0x98d, 0x76)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(24), - A6XX_PROTECT_RDONLY(0x980, 0x4)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0)); + a6xx_set_cp_protect(gpu); /* Enable expanded apriv for targets that support it */ if (gpu->hw_apriv) { @@ -1211,7 +1284,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) if (ret) return ret; - if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami) + if (a6xx_gpu->shadow_bo) for (i = 0; i < gpu->nr_rings; i++) a6xx_gpu->shadow[i] = 0; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index ce0610c5256f7..bb544dfe57379 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -44,7 +44,7 @@ struct a6xx_gpu { * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len * registers starting at _reg. */ -#define A6XX_PROTECT_RW(_reg, _len) \ +#define A6XX_PROTECT_NORDWR(_reg, _len) \ ((1 << 31) | \ (((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF)) diff --git a/drivers/hwmon/corsair-psu.c b/drivers/hwmon/corsair-psu.c index 99494056f4bd9..7c462726382d5 100644 --- a/drivers/hwmon/corsair-psu.c +++ b/drivers/hwmon/corsair-psu.c @@ -570,6 +570,16 @@ static int corsairpsu_raw_event(struct hid_device *hdev, struct hid_report *repo return 0; } +#ifdef CONFIG_PM +static int corsairpsu_resume(struct hid_device *hdev) +{ + struct corsairpsu_data *priv = hid_get_drvdata(hdev); + + /* some PSUs turn off the microcontroller during standby, so a reinit is required */ + return corsairpsu_init(priv); +} +#endif + static const struct hid_device_id corsairpsu_idtable[] = { { HID_USB_DEVICE(0x1b1c, 0x1c03) }, /* Corsair HX550i */ { HID_USB_DEVICE(0x1b1c, 0x1c04) }, /* Corsair HX650i */ @@ -592,6 +602,10 @@ static struct hid_driver corsairpsu_driver = { .probe = corsairpsu_probe, .remove = corsairpsu_remove, .raw_event = corsairpsu_raw_event, +#ifdef CONFIG_PM + .resume = corsairpsu_resume, + .reset_resume = corsairpsu_resume, +#endif }; module_hid_driver(corsairpsu_driver); diff --git a/drivers/hwmon/tps23861.c b/drivers/hwmon/tps23861.c index c2484f15298b0..8bd6435c13e82 100644 --- a/drivers/hwmon/tps23861.c +++ b/drivers/hwmon/tps23861.c @@ -99,11 +99,14 @@ #define POWER_ENABLE 0x19 #define TPS23861_NUM_PORTS 4 +#define TPS23861_GENERAL_MASK_1 0x17 +#define TPS23861_CURRENT_SHUNT_MASK BIT(0) + #define TEMPERATURE_LSB 652 /* 0.652 degrees Celsius */ #define VOLTAGE_LSB 3662 /* 3.662 mV */ #define SHUNT_RESISTOR_DEFAULT 255000 /* 255 mOhm */ -#define CURRENT_LSB_255 62260 /* 62.260 uA */ -#define CURRENT_LSB_250 61039 /* 61.039 uA */ +#define CURRENT_LSB_250 62260 /* 62.260 uA */ +#define CURRENT_LSB_255 61039 /* 61.039 uA */ #define RESISTANCE_LSB 110966 /* 11.0966 Ohm*/ #define RESISTANCE_LSB_LOW 157216 /* 15.7216 Ohm*/ @@ -117,6 +120,7 @@ struct tps23861_data { static struct regmap_config tps23861_regmap_config = { .reg_bits = 8, .val_bits = 8, + .max_register = 0x6f, }; static int tps23861_read_temp(struct tps23861_data *data, long *val) @@ -560,6 +564,15 @@ static int tps23861_probe(struct i2c_client *client) else data->shunt_resistor = SHUNT_RESISTOR_DEFAULT; + if (data->shunt_resistor == SHUNT_RESISTOR_DEFAULT) + regmap_clear_bits(data->regmap, + TPS23861_GENERAL_MASK_1, + TPS23861_CURRENT_SHUNT_MASK); + else + regmap_set_bits(data->regmap, + TPS23861_GENERAL_MASK_1, + TPS23861_CURRENT_SHUNT_MASK); + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, &tps23861_chip_info, NULL); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index d94f05c8b8b79..af349661fd769 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #define CCR_MTX 0x10 #define CCR_TXAK 0x08 #define CCR_RSTA 0x04 +#define CCR_RSVD 0x02 #define CSR_MCF 0x80 #define CSR_MAAS 0x40 @@ -70,6 +72,7 @@ struct mpc_i2c { u8 fdr, dfsrr; #endif struct clk *clk_per; + bool has_errata_A004447; }; struct mpc_i2c_divider { @@ -176,6 +179,75 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) return 0; } +static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask) +{ + void __iomem *addr = i2c->base + MPC_I2C_SR; + u8 val; + + return readb_poll_timeout(addr, val, val & mask, 0, 100); +} + +/* + * Workaround for Erratum A004447. From the P2040CE Rev Q + * + * 1. Set up the frequency divider and sampling rate. + * 2. I2CCR - a0h + * 3. Poll for I2CSR[MBB] to get set. + * 4. If I2CSR[MAL] is set (an indication that SDA is stuck low), then go to + * step 5. If MAL is not set, then go to step 13. + * 5. I2CCR - 00h + * 6. I2CCR - 22h + * 7. I2CCR - a2h + * 8. Poll for I2CSR[MBB] to get set. + * 9. Issue read to I2CDR. + * 10. Poll for I2CSR[MIF] to be set. + * 11. I2CCR - 82h + * 12. Workaround complete. Skip the next steps. + * 13. Issue read to I2CDR. + * 14. Poll for I2CSR[MIF] to be set. + * 15. I2CCR - 80h + */ +static void mpc_i2c_fixup_A004447(struct mpc_i2c *i2c) +{ + int ret; + u32 val; + + writeccr(i2c, CCR_MEN | CCR_MSTA); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + + val = readb(i2c->base + MPC_I2C_SR); + + if (val & CSR_MAL) { + writeccr(i2c, 0x00); + writeccr(i2c, CCR_MSTA | CCR_RSVD); + writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSVD); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN | CCR_RSVD); + } else { + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN); + } +} + #if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x) static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, @@ -586,7 +658,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -622,7 +694,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -637,6 +709,18 @@ static u32 mpc_functionality(struct i2c_adapter *adap) | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL; } +static int fsl_i2c_bus_recovery(struct i2c_adapter *adap) +{ + struct mpc_i2c *i2c = i2c_get_adapdata(adap); + + if (i2c->has_errata_A004447) + mpc_i2c_fixup_A004447(i2c); + else + mpc_i2c_fixup(i2c); + + return 0; +} + static const struct i2c_algorithm mpc_algo = { .master_xfer = mpc_xfer, .functionality = mpc_functionality, @@ -648,6 +732,10 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; +static struct i2c_bus_recovery_info fsl_i2c_recovery_info = { + .recover_bus = fsl_i2c_bus_recovery, +}; + static const struct of_device_id mpc_i2c_of_match[]; static int fsl_i2c_probe(struct platform_device *op) { @@ -732,6 +820,8 @@ static int fsl_i2c_probe(struct platform_device *op) dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); platform_set_drvdata(op, i2c); + if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) + i2c->has_errata_A004447 = true; i2c->adap = mpc_ops; of_address_to_resource(op->dev.of_node, 0, &res); @@ -740,6 +830,7 @@ static int fsl_i2c_probe(struct platform_device *op) i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &op->dev; i2c->adap.dev.of_node = of_node_get(op->dev.of_node); + i2c->adap.bus_recovery_info = &fsl_i2c_recovery_info; result = i2c_add_adapter(&i2c->adap); if (result < 0) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index f5b8be3bedde9..ab55f8b3190eb 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -3247,6 +3247,11 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs) goto err_free_attr; } + if (!rdma_is_port_valid(uobj->context->device, cmd.flow_attr.port)) { + err = -EINVAL; + goto err_uobj; + } + qp = uobj_get_obj_read(qp, UVERBS_OBJECT_QP, cmd.qp_handle, attrs); if (!qp) { err = -EINVAL; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index f26a0d9208429..3b3a894f95623 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -580,12 +580,9 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->cq_caps.max_cq_moderation_count = MLX4_MAX_CQ_COUNT; props->cq_caps.max_cq_moderation_period = MLX4_MAX_CQ_PERIOD; - if (!mlx4_is_slave(dev->dev)) - err = mlx4_get_internal_clock_params(dev->dev, &clock_params); - if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) { resp.response_length += sizeof(resp.hca_core_clock_offset); - if (!err && !mlx4_is_slave(dev->dev)) { + if (!mlx4_get_internal_clock_params(dev->dev, &clock_params)) { resp.comp_mask |= MLX4_IB_QUERY_DEV_RESP_MASK_CORE_CLOCK_OFFSET; resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE; } @@ -1699,9 +1696,6 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, struct mlx4_dev *dev = (to_mdev(qp->device))->dev; int is_bonded = mlx4_is_bonded(dev); - if (!rdma_is_port_valid(qp->device, flow_attr->port)) - return ERR_PTR(-EINVAL); - if (flow_attr->flags & ~IB_FLOW_ATTR_FLAGS_DONT_TRAP) return ERR_PTR(-EOPNOTSUPP); diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index eb92cefffd777..9ce01f7296739 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -849,15 +849,14 @@ static void destroy_cq_user(struct mlx5_ib_cq *cq, struct ib_udata *udata) ib_umem_release(cq->buf.umem); } -static void init_cq_frag_buf(struct mlx5_ib_cq *cq, - struct mlx5_ib_cq_buf *buf) +static void init_cq_frag_buf(struct mlx5_ib_cq_buf *buf) { int i; void *cqe; struct mlx5_cqe64 *cqe64; for (i = 0; i < buf->nent; i++) { - cqe = get_cqe(cq, i); + cqe = mlx5_frag_buf_get_wqe(&buf->fbc, i); cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64; cqe64->op_own = MLX5_CQE_INVALID << 4; } @@ -883,7 +882,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, if (err) goto err_db; - init_cq_frag_buf(cq, &cq->buf); + init_cq_frag_buf(&cq->buf); *inlen = MLX5_ST_SZ_BYTES(create_cq_in) + MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * @@ -1184,7 +1183,7 @@ static int resize_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, if (err) goto ex; - init_cq_frag_buf(cq, cq->resize_buf); + init_cq_frag_buf(cq->resize_buf); return 0; diff --git a/drivers/infiniband/hw/mlx5/doorbell.c b/drivers/infiniband/hw/mlx5/doorbell.c index 61475b5715312..7af4df7a68237 100644 --- a/drivers/infiniband/hw/mlx5/doorbell.c +++ b/drivers/infiniband/hw/mlx5/doorbell.c @@ -41,6 +41,7 @@ struct mlx5_ib_user_db_page { struct ib_umem *umem; unsigned long user_virt; int refcnt; + struct mm_struct *mm; }; int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, @@ -53,7 +54,8 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, mutex_lock(&context->db_page_mutex); list_for_each_entry(page, &context->db_page_list, list) - if (page->user_virt == (virt & PAGE_MASK)) + if ((current->mm == page->mm) && + (page->user_virt == (virt & PAGE_MASK))) goto found; page = kmalloc(sizeof(*page), GFP_KERNEL); @@ -71,6 +73,8 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, kfree(page); goto out; } + mmgrab(current->mm); + page->mm = current->mm; list_add(&page->list, &context->db_page_list); @@ -91,6 +95,7 @@ void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db) if (!--db->u.user_page->refcnt) { list_del(&db->u.user_page->list); + mmdrop(db->u.user_page->mm); ib_umem_release(db->u.user_page->umem); kfree(db->u.user_page); } diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c index f0af3f1ae0398..d719d1225b959 100644 --- a/drivers/infiniband/hw/mlx5/fs.c +++ b/drivers/infiniband/hw/mlx5/fs.c @@ -1194,9 +1194,8 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, goto free_ucmd; } - if (flow_attr->port > dev->num_ports || - (flow_attr->flags & - ~(IB_FLOW_ATTR_FLAGS_DONT_TRAP | IB_FLOW_ATTR_FLAGS_EGRESS))) { + if (flow_attr->flags & + ~(IB_FLOW_ATTR_FLAGS_DONT_TRAP | IB_FLOW_ATTR_FLAGS_EGRESS)) { err = -EINVAL; goto free_ucmd; } @@ -2134,6 +2133,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)( if (err) goto end; + if (obj->ns_type == MLX5_FLOW_NAMESPACE_FDB && + mlx5_eswitch_mode(dev->mdev) != MLX5_ESWITCH_OFFLOADS) { + err = -EINVAL; + goto end; + } + uobj->object = obj; obj->mdev = dev->mdev; atomic_set(&obj->usecnt, 0); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c index d5a90a66b45cf..5b05cf3837da1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c @@ -163,6 +163,7 @@ static size_t ipoib_get_size(const struct net_device *dev) static struct rtnl_link_ops ipoib_link_ops __read_mostly = { .kind = "ipoib", + .netns_refund = true, .maxtype = IFLA_IPOIB_MAX, .policy = ipoib_policy, .priv_size = sizeof(struct ipoib_dev_priv), diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index ee925b58bbcea..2a1ddd47a0968 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -1100,7 +1100,6 @@ nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent) card->typ = NETJET_S_TJ300; card->base = pci_resource_start(pdev, 0); - card->irq = pdev->irq; pci_set_drvdata(pdev, card); err = setup_instance(card); if (err) diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 848dd4db16592..75311b8378858 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -364,7 +364,6 @@ struct cached_dev { /* The rest of this all shows up in sysfs */ unsigned int sequential_cutoff; - unsigned int readahead; unsigned int io_disable:1; unsigned int verify:1; diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index 29c231758293e..6d1de889baeb1 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c @@ -880,9 +880,9 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s, struct bio *bio, unsigned int sectors) { int ret = MAP_CONTINUE; - unsigned int reada = 0; struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); struct bio *miss, *cache_bio; + unsigned int size_limit; s->cache_missed = 1; @@ -892,14 +892,10 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s, goto out_submit; } - if (!(bio->bi_opf & REQ_RAHEAD) && - !(bio->bi_opf & (REQ_META|REQ_PRIO)) && - s->iop.c->gc_stats.in_use < CUTOFF_CACHE_READA) - reada = min_t(sector_t, dc->readahead >> 9, - get_capacity(bio->bi_bdev->bd_disk) - - bio_end_sector(bio)); - - s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada); + /* Limitation for valid replace key size and cache_bio bvecs number */ + size_limit = min_t(unsigned int, BIO_MAX_VECS * PAGE_SECTORS, + (1 << KEY_SIZE_BITS) - 1); + s->insert_bio_sectors = min3(size_limit, sectors, bio_sectors(bio)); s->iop.replace_key = KEY(s->iop.inode, bio->bi_iter.bi_sector + s->insert_bio_sectors, @@ -911,7 +907,8 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s, s->iop.replace = true; - miss = bio_next_split(bio, sectors, GFP_NOIO, &s->d->bio_split); + miss = bio_next_split(bio, s->insert_bio_sectors, GFP_NOIO, + &s->d->bio_split); /* btree_search_recurse()'s btree iterator is no good anymore */ ret = miss == bio ? MAP_DONE : -EINTR; @@ -933,9 +930,6 @@ static int cached_dev_cache_miss(struct btree *b, struct search *s, if (bch_bio_alloc_pages(cache_bio, __GFP_NOWARN|GFP_NOIO)) goto out_put; - if (reada) - bch_mark_cache_readahead(s->iop.c, s->d); - s->cache_miss = miss; s->iop.bio = cache_bio; bio_get(cache_bio); diff --git a/drivers/md/bcache/stats.c b/drivers/md/bcache/stats.c index 503aafe188dce..4c7ee5fedb9dc 100644 --- a/drivers/md/bcache/stats.c +++ b/drivers/md/bcache/stats.c @@ -46,7 +46,6 @@ read_attribute(cache_misses); read_attribute(cache_bypass_hits); read_attribute(cache_bypass_misses); read_attribute(cache_hit_ratio); -read_attribute(cache_readaheads); read_attribute(cache_miss_collisions); read_attribute(bypassed); @@ -64,7 +63,6 @@ SHOW(bch_stats) DIV_SAFE(var(cache_hits) * 100, var(cache_hits) + var(cache_misses))); - var_print(cache_readaheads); var_print(cache_miss_collisions); sysfs_hprint(bypassed, var(sectors_bypassed) << 9); #undef var @@ -86,7 +84,6 @@ static struct attribute *bch_stats_files[] = { &sysfs_cache_bypass_hits, &sysfs_cache_bypass_misses, &sysfs_cache_hit_ratio, - &sysfs_cache_readaheads, &sysfs_cache_miss_collisions, &sysfs_bypassed, NULL @@ -113,7 +110,6 @@ void bch_cache_accounting_clear(struct cache_accounting *acc) acc->total.cache_misses = 0; acc->total.cache_bypass_hits = 0; acc->total.cache_bypass_misses = 0; - acc->total.cache_readaheads = 0; acc->total.cache_miss_collisions = 0; acc->total.sectors_bypassed = 0; } @@ -145,7 +141,6 @@ static void scale_stats(struct cache_stats *stats, unsigned long rescale_at) scale_stat(&stats->cache_misses); scale_stat(&stats->cache_bypass_hits); scale_stat(&stats->cache_bypass_misses); - scale_stat(&stats->cache_readaheads); scale_stat(&stats->cache_miss_collisions); scale_stat(&stats->sectors_bypassed); } @@ -168,7 +163,6 @@ static void scale_accounting(struct timer_list *t) move_stat(cache_misses); move_stat(cache_bypass_hits); move_stat(cache_bypass_misses); - move_stat(cache_readaheads); move_stat(cache_miss_collisions); move_stat(sectors_bypassed); @@ -209,14 +203,6 @@ void bch_mark_cache_accounting(struct cache_set *c, struct bcache_device *d, mark_cache_stats(&c->accounting.collector, hit, bypass); } -void bch_mark_cache_readahead(struct cache_set *c, struct bcache_device *d) -{ - struct cached_dev *dc = container_of(d, struct cached_dev, disk); - - atomic_inc(&dc->accounting.collector.cache_readaheads); - atomic_inc(&c->accounting.collector.cache_readaheads); -} - void bch_mark_cache_miss_collision(struct cache_set *c, struct bcache_device *d) { struct cached_dev *dc = container_of(d, struct cached_dev, disk); diff --git a/drivers/md/bcache/stats.h b/drivers/md/bcache/stats.h index abfaabf7e7fcf..ca4f435f7216a 100644 --- a/drivers/md/bcache/stats.h +++ b/drivers/md/bcache/stats.h @@ -7,7 +7,6 @@ struct cache_stat_collector { atomic_t cache_misses; atomic_t cache_bypass_hits; atomic_t cache_bypass_misses; - atomic_t cache_readaheads; atomic_t cache_miss_collisions; atomic_t sectors_bypassed; }; diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index cc89f3156d1aa..05ac1d6fbbf35 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -137,7 +137,6 @@ rw_attribute(io_disable); rw_attribute(discard); rw_attribute(running); rw_attribute(label); -rw_attribute(readahead); rw_attribute(errors); rw_attribute(io_error_limit); rw_attribute(io_error_halflife); @@ -260,7 +259,6 @@ SHOW(__bch_cached_dev) var_printf(partial_stripes_expensive, "%u"); var_hprint(sequential_cutoff); - var_hprint(readahead); sysfs_print(running, atomic_read(&dc->running)); sysfs_print(state, states[BDEV_STATE(&dc->sb)]); @@ -365,7 +363,6 @@ STORE(__cached_dev) sysfs_strtoul_clamp(sequential_cutoff, dc->sequential_cutoff, 0, UINT_MAX); - d_strtoi_h(readahead); if (attr == &sysfs_clear_stats) bch_cache_accounting_clear(&dc->accounting); @@ -538,7 +535,6 @@ static struct attribute *bch_cached_dev_files[] = { &sysfs_running, &sysfs_state, &sysfs_label, - &sysfs_readahead, #ifdef CONFIG_BCACHE_DEBUG &sysfs_verify, &sysfs_bypass_torture_test, diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c index 29385dc470d5d..db61a1f43ae91 100644 --- a/drivers/md/dm-verity-verify-sig.c +++ b/drivers/md/dm-verity-verify-sig.c @@ -15,7 +15,7 @@ #define DM_VERITY_VERIFY_ERR(s) DM_VERITY_ROOT_HASH_VERIFICATION " " s static bool require_signatures; -module_param(require_signatures, bool, false); +module_param(require_signatures, bool, 0444); MODULE_PARM_DESC(require_signatures, "Verify the roothash of dm-verity hash tree"); diff --git a/drivers/misc/cardreader/rtl8411.c b/drivers/misc/cardreader/rtl8411.c index a07674ed05965..4c5621b17a6fb 100644 --- a/drivers/misc/cardreader/rtl8411.c +++ b/drivers/misc/cardreader/rtl8411.c @@ -468,6 +468,7 @@ static void rtl8411_init_common_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_CFG; pcr->tx_initial_phase = SET_CLOCK_PHASE(23, 7, 14); pcr->rx_initial_phase = SET_CLOCK_PHASE(4, 3, 10); pcr->ic_version = rtl8411_get_ic_version(pcr); diff --git a/drivers/misc/cardreader/rts5209.c b/drivers/misc/cardreader/rts5209.c index 39a6a7ecc32e9..29f5414072bf1 100644 --- a/drivers/misc/cardreader/rts5209.c +++ b/drivers/misc/cardreader/rts5209.c @@ -255,6 +255,7 @@ void rts5209_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_CFG; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 16); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); diff --git a/drivers/misc/cardreader/rts5227.c b/drivers/misc/cardreader/rts5227.c index 8200af22b529e..4bcfbc9afbac1 100644 --- a/drivers/misc/cardreader/rts5227.c +++ b/drivers/misc/cardreader/rts5227.c @@ -358,6 +358,7 @@ void rts5227_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_CFG; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15); pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7); @@ -483,6 +484,7 @@ void rts522a_init_params(struct rtsx_pcr *pcr) rts5227_init_params(pcr); pcr->ops = &rts522a_pcr_ops; + pcr->aspm_mode = ASPM_MODE_REG; pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 20, 11); pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; diff --git a/drivers/misc/cardreader/rts5228.c b/drivers/misc/cardreader/rts5228.c index 781a86def59a9..ffc128278613b 100644 --- a/drivers/misc/cardreader/rts5228.c +++ b/drivers/misc/cardreader/rts5228.c @@ -718,6 +718,7 @@ void rts5228_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_REG; pcr->tx_initial_phase = SET_CLOCK_PHASE(28, 27, 11); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); diff --git a/drivers/misc/cardreader/rts5229.c b/drivers/misc/cardreader/rts5229.c index 89e6f124ca5ca..c748eaf1ec1f9 100644 --- a/drivers/misc/cardreader/rts5229.c +++ b/drivers/misc/cardreader/rts5229.c @@ -246,6 +246,7 @@ void rts5229_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = DRIVER_TYPE_D; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_CFG; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15); pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 6, 6); diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c index b2676e7f50271..53f3a1f45c4a7 100644 --- a/drivers/misc/cardreader/rts5249.c +++ b/drivers/misc/cardreader/rts5249.c @@ -566,6 +566,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_CFG; pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); @@ -729,6 +730,7 @@ static const struct pcr_ops rts524a_pcr_ops = { void rts524a_init_params(struct rtsx_pcr *pcr) { rts5249_init_params(pcr); + pcr->aspm_mode = ASPM_MODE_REG; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; pcr->option.ltr_l1off_snooze_sspwrgate = @@ -845,6 +847,7 @@ static const struct pcr_ops rts525a_pcr_ops = { void rts525a_init_params(struct rtsx_pcr *pcr) { rts5249_init_params(pcr); + pcr->aspm_mode = ASPM_MODE_REG; pcr->tx_initial_phase = SET_CLOCK_PHASE(25, 29, 11); pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; pcr->option.ltr_l1off_snooze_sspwrgate = diff --git a/drivers/misc/cardreader/rts5260.c b/drivers/misc/cardreader/rts5260.c index 080a7d67a8e1a..9b42b20a3e5ae 100644 --- a/drivers/misc/cardreader/rts5260.c +++ b/drivers/misc/cardreader/rts5260.c @@ -628,6 +628,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_REG; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); diff --git a/drivers/misc/cardreader/rts5261.c b/drivers/misc/cardreader/rts5261.c index 6c64dade8e1af..1fd4e0e507302 100644 --- a/drivers/misc/cardreader/rts5261.c +++ b/drivers/misc/cardreader/rts5261.c @@ -783,6 +783,7 @@ void rts5261_init_params(struct rtsx_pcr *pcr) pcr->sd30_drive_sel_1v8 = 0x00; pcr->sd30_drive_sel_3v3 = 0x00; pcr->aspm_en = ASPM_L1_EN; + pcr->aspm_mode = ASPM_MODE_REG; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 11); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index 273311184669a..baf83594a01d3 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -85,12 +85,18 @@ static void rtsx_comm_set_aspm(struct rtsx_pcr *pcr, bool enable) if (pcr->aspm_enabled == enable) return; - if (pcr->aspm_en & 0x02) - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, FORCE_ASPM_CTL0 | - FORCE_ASPM_CTL1, enable ? 0 : FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1); - else - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, FORCE_ASPM_CTL0 | - FORCE_ASPM_CTL1, FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1); + if (pcr->aspm_mode == ASPM_MODE_CFG) { + pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC, + enable ? pcr->aspm_en : 0); + } else if (pcr->aspm_mode == ASPM_MODE_REG) { + if (pcr->aspm_en & 0x02) + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, FORCE_ASPM_CTL0 | + FORCE_ASPM_CTL1, enable ? 0 : FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1); + else + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, FORCE_ASPM_CTL0 | + FORCE_ASPM_CTL1, FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1); + } if (!enable && (pcr->aspm_en & 0x02)) mdelay(10); @@ -1394,7 +1400,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) return err; } - rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); + if (pcr->aspm_mode == ASPM_MODE_REG) + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); /* No CD interrupt if probing driver with card inserted. * So we need to initialize pcr->card_exist here. @@ -1410,6 +1417,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) { int err; + u16 cfg_val; + u8 val; spin_lock_init(&pcr->lock); mutex_init(&pcr->pcr_mutex); @@ -1477,6 +1486,21 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) if (!pcr->slots) return -ENOMEM; + if (pcr->aspm_mode == ASPM_MODE_CFG) { + pcie_capability_read_word(pcr->pci, PCI_EXP_LNKCTL, &cfg_val); + if (cfg_val & PCI_EXP_LNKCTL_ASPM_L1) + pcr->aspm_enabled = true; + else + pcr->aspm_enabled = false; + + } else if (pcr->aspm_mode == ASPM_MODE_REG) { + rtsx_pci_read_register(pcr, ASPM_FORCE_CTL, &val); + if (val & FORCE_ASPM_CTL0 && val & FORCE_ASPM_CTL1) + pcr->aspm_enabled = false; + else + pcr->aspm_enabled = true; + } + if (pcr->ops->fetch_vendor_settings) pcr->ops->fetch_vendor_settings(pcr); @@ -1506,7 +1530,6 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, struct pcr_handle *handle; u32 base, len; int ret, i, bar = 0; - u8 val; dev_dbg(&(pcidev->dev), ": Realtek PCI-E Card Reader found at %s [%04x:%04x] (rev %x)\n", @@ -1572,11 +1595,6 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, pcr->host_cmds_addr = pcr->rtsx_resv_buf_addr; pcr->host_sg_tbl_ptr = pcr->rtsx_resv_buf + HOST_CMDS_BUF_LEN; pcr->host_sg_tbl_addr = pcr->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; - rtsx_pci_read_register(pcr, ASPM_FORCE_CTL, &val); - if (val & FORCE_ASPM_CTL0 && val & FORCE_ASPM_CTL1) - pcr->aspm_enabled = false; - else - pcr->aspm_enabled = true; pcr->card_inserted = 0; pcr->card_removed = 0; INIT_DELAYED_WORK(&pcr->carddet_work, rtsx_pci_card_detect); diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 158c21e5a942f..7a4a6efb8369c 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -679,14 +679,19 @@ static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode) /* Issue CMD19 twice for each tap */ for (i = 0; i < 2 * priv->tap_num; i++) { + int cmd_error; + /* Set sampling clock position */ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num); - if (mmc_send_tuning(mmc, opcode, NULL) == 0) + if (mmc_send_tuning(mmc, opcode, &cmd_error) == 0) set_bit(i, priv->taps); if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_SMPCMP) == 0) set_bit(i, priv->smpcmp); + + if (cmd_error) + mmc_abort_tuning(mmc, opcode); } ret = renesas_sdhi_select_tuning(host); @@ -926,7 +931,7 @@ static const struct soc_device_attribute sdhi_quirks_match[] = { { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 }, { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, - { .soc_id = "r8a7796", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps1357 }, + { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 }, { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 }, { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 }, { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 }, diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index ba8e70a8e3125..6b12ce822e51a 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -327,6 +327,8 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) break; } + dev->base_addr = ioaddr; + /* Reserve any actual interrupt. */ if (dev->irq) { retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); @@ -334,8 +336,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) goto err_out; } - dev->base_addr = ioaddr; - lp = netdev_priv(dev); spin_lock_init(&lp->lock); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 74cbbb22470b5..fa4bf727a48db 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1526,6 +1526,7 @@ static struct slave *bond_alloc_slave(struct bonding *bond, slave->bond = bond; slave->dev = slave_dev; + INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); if (bond_kobj_init(slave)) return NULL; @@ -1538,7 +1539,6 @@ static struct slave *bond_alloc_slave(struct bonding *bond, return NULL; } } - INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); return slave; } diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 55e5d479acce3..854e25f43fa70 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1530,6 +1530,7 @@ static const struct ksz_chip_data ksz9477_switch_chips[] = { .num_statics = 16, .cpu_ports = 0x7F, /* can be configured as cpu port */ .port_cnt = 7, /* total physical port count */ + .phy_errata_9477 = true, }, }; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 9c2f51f230351..9108b497b3c99 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -1224,8 +1224,10 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, goto failed; /* SR-IOV capability was enabled but there are no VFs*/ - if (iov->total == 0) + if (iov->total == 0) { + err = -EINVAL; goto failed; + } iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param); diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 0f6a6cb7e98d7..51b19172d63be 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2837,6 +2837,9 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) struct gem_stats *hwstat = &bp->hw_stats.gem; struct net_device_stats *nstat = &bp->dev->stats; + if (!netif_running(bp->dev)) + return nstat; + gem_update_stats(bp); nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index f6cfec81ccc3b..dc4ac1a2b6b67 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -823,6 +823,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8 #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac +#define QUERY_DEV_CAP_MAP_CLOCK_TO_USER 0xc1 #define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc #define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0 #define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2 @@ -841,6 +842,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) if (mlx4_is_mfunc(dev)) disable_unsupported_roce_caps(outbox); + MLX4_GET(field, outbox, QUERY_DEV_CAP_MAP_CLOCK_TO_USER); + dev_cap->map_clock_to_user = field & 0x80; MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET); dev_cap->reserved_qps = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET); diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 8f020f26ebf5f..cf64e54eecb05 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -131,6 +131,7 @@ struct mlx4_dev_cap { u32 health_buffer_addrs; struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1]; bool wol_port[MLX4_MAX_PORTS + 1]; + bool map_clock_to_user; }; struct mlx4_func_cap { diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index c326b434734e1..00c84656b2e7e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -498,6 +498,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) } } + dev->caps.map_clock_to_user = dev_cap->map_clock_to_user; dev->caps.uar_page_size = PAGE_SIZE; dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; @@ -1948,6 +1949,11 @@ int mlx4_get_internal_clock_params(struct mlx4_dev *dev, if (mlx4_is_slave(dev)) return -EOPNOTSUPP; + if (!dev->caps.map_clock_to_user) { + mlx4_dbg(dev, "Map clock to user is not supported.\n"); + return -EOPNOTSUPP; + } + if (!params) return -EINVAL; diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 214e347097a7a..2376b2729633f 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -114,7 +114,7 @@ static int ql_sem_spinlock(struct ql3_adapter *qdev, value = readl(&port_regs->CommonRegs.semaphoreReg); if ((value & (sem_mask >> 16)) == sem_bits) return 0; - ssleep(1); + mdelay(1000); } while (--seconds); return -1; } diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index d1e908846f5dd..22fbb0ae77fba 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -90,6 +90,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx) efx->pci_dev->irq); goto fail1; } + efx->irqs_hooked = true; return 0; } diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 8235185540798..d3c916821b113 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -607,7 +607,8 @@ void mdiobus_unregister(struct mii_bus *bus) struct mdio_device *mdiodev; int i; - BUG_ON(bus->state != MDIOBUS_REGISTERED); + if (WARN_ON_ONCE(bus->state != MDIOBUS_REGISTERED)) + return; bus->state = MDIOBUS_UNREGISTERED; for (i = 0; i < PHY_MAX_ADDR; i++) { diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig index a44d49d63968a..494675aeaaad7 100644 --- a/drivers/nvme/host/Kconfig +++ b/drivers/nvme/host/Kconfig @@ -71,7 +71,8 @@ config NVME_FC config NVME_TCP tristate "NVM Express over Fabrics TCP host driver" depends on INET - depends on BLK_DEV_NVME + depends on BLOCK + select NVME_CORE select NVME_FABRICS select CRYPTO select CRYPTO_CRC32C diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 604ab0e5a2adb..fb02ca2e3096f 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c @@ -336,6 +336,11 @@ static void nvmf_log_connect_error(struct nvme_ctrl *ctrl, cmd->connect.recfmt); break; + case NVME_SC_HOST_PATH_ERROR: + dev_err(ctrl->device, + "Connect command failed: host path error\n"); + break; + default: dev_err(ctrl->device, "Connect command failed, error wo/DNR bit: %d\n", diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 7d16cb4cd8acf..83921dab8368d 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -388,10 +388,10 @@ static void nvmet_keep_alive_timer(struct work_struct *work) { struct nvmet_ctrl *ctrl = container_of(to_delayed_work(work), struct nvmet_ctrl, ka_work); - bool cmd_seen = ctrl->cmd_seen; + bool reset_tbkas = ctrl->reset_tbkas; - ctrl->cmd_seen = false; - if (cmd_seen) { + ctrl->reset_tbkas = false; + if (reset_tbkas) { pr_debug("ctrl %d reschedule traffic based keep-alive timer\n", ctrl->cntlid); schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); @@ -804,6 +804,13 @@ void nvmet_sq_destroy(struct nvmet_sq *sq) percpu_ref_exit(&sq->ref); if (ctrl) { + /* + * The teardown flow may take some time, and the host may not + * send us keep-alive during this period, hence reset the + * traffic based keep-alive timer so we don't trigger a + * controller teardown as a result of a keep-alive expiration. + */ + ctrl->reset_tbkas = true; nvmet_ctrl_put(ctrl); sq->ctrl = NULL; /* allows reusing the queue later */ } @@ -953,7 +960,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq, } if (sq->ctrl) - sq->ctrl->cmd_seen = true; + sq->ctrl->reset_tbkas = true; return true; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 5aad34b106dc2..43a668dc8bc4d 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -166,7 +166,7 @@ struct nvmet_ctrl { struct nvmet_subsys *subsys; struct nvmet_sq **sqs; - bool cmd_seen; + bool reset_tbkas; struct mutex lock; u64 cap; diff --git a/drivers/phy/broadcom/phy-brcm-usb-init.h b/drivers/phy/broadcom/phy-brcm-usb-init.h index 899b9eb43fad6..a39f30fa2e991 100644 --- a/drivers/phy/broadcom/phy-brcm-usb-init.h +++ b/drivers/phy/broadcom/phy-brcm-usb-init.h @@ -78,7 +78,7 @@ static inline u32 brcm_usb_readl(void __iomem *addr) * Other architectures (e.g., ARM) either do not support big endian, or * else leave I/O in little endian mode. */ - if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN)) + if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) return __raw_readl(addr); else return readl_relaxed(addr); @@ -87,7 +87,7 @@ static inline u32 brcm_usb_readl(void __iomem *addr) static inline void brcm_usb_writel(u32 val, void __iomem *addr) { /* See brcmnand_readl() comments */ - if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN)) + if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) __raw_writel(val, addr); else writel_relaxed(val, addr); diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index 19f32ae877b94..acca76729c090 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -612,6 +612,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) sp->nsubnodes = node; if (sp->num_lanes > SIERRA_MAX_LANES) { + ret = -EINVAL; dev_err(dev, "Invalid lane configuration\n"); goto put_child2; } diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index e28e25f98708c..dceac77148721 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -894,6 +894,7 @@ static int wiz_probe(struct platform_device *pdev) if (wiz->typec_dir_delay < WIZ_TYPEC_DIR_DEBOUNCE_MIN || wiz->typec_dir_delay > WIZ_TYPEC_DIR_DEBOUNCE_MAX) { + ret = -EINVAL; dev_err(dev, "Invalid typec-dir-debounce property\n"); goto err_addr_to_resource; } diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 6853a896c4766..740ecf6011a9b 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -223,7 +223,7 @@ config PINCTRL_SC7280 config PINCTRL_SC8180X tristate "Qualcomm Technologies Inc SC8180x pin controller driver" depends on GPIOLIB && OF - select PINCTRL_MSM + depends on PINCTRL_MSM help This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm Technologies Inc TLMM block found on the Qualcomm diff --git a/drivers/pinctrl/qcom/pinctrl-sdx55.c b/drivers/pinctrl/qcom/pinctrl-sdx55.c index 5aaf57b40407f..0bb4931cec59e 100644 --- a/drivers/pinctrl/qcom/pinctrl-sdx55.c +++ b/drivers/pinctrl/qcom/pinctrl-sdx55.c @@ -410,15 +410,15 @@ static const char * const gpio_groups[] = { "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", - "gpio50", "gpio51", "gpio52", "gpio52", "gpio53", "gpio53", "gpio54", - "gpio55", "gpio56", "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", - "gpio62", "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", - "gpio69", "gpio70", "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", - "gpio76", "gpio77", "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", - "gpio83", "gpio84", "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", - "gpio90", "gpio91", "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", - "gpio97", "gpio98", "gpio99", "gpio100", "gpio101", "gpio102", - "gpio103", "gpio104", "gpio105", "gpio106", "gpio107", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91", + "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98", + "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104", + "gpio105", "gpio106", "gpio107", }; static const char * const qdss_stm_groups[] = { diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c index 89761d3e1a476..d68d51fb24ffd 100644 --- a/drivers/platform/surface/aggregator/controller.c +++ b/drivers/platform/surface/aggregator/controller.c @@ -1907,7 +1907,7 @@ static int ssam_ssh_event_disable(struct ssam_controller *ctrl, { int status; - status = __ssam_ssh_event_request(ctrl, reg, reg.cid_enable, id, flags); + status = __ssam_ssh_event_request(ctrl, reg, reg.cid_disable, id, flags); if (status < 0 && status != -EINVAL) { ssam_err(ctrl, diff --git a/drivers/regulator/atc260x-regulator.c b/drivers/regulator/atc260x-regulator.c index d8b429955d33f..05147d2c38428 100644 --- a/drivers/regulator/atc260x-regulator.c +++ b/drivers/regulator/atc260x-regulator.c @@ -28,16 +28,16 @@ static const struct linear_range atc2609a_dcdc_voltage_ranges[] = { static const struct linear_range atc2609a_ldo_voltage_ranges0[] = { REGULATOR_LINEAR_RANGE(700000, 0, 15, 100000), - REGULATOR_LINEAR_RANGE(2100000, 16, 28, 100000), + REGULATOR_LINEAR_RANGE(2100000, 0, 12, 100000), }; static const struct linear_range atc2609a_ldo_voltage_ranges1[] = { REGULATOR_LINEAR_RANGE(850000, 0, 15, 100000), - REGULATOR_LINEAR_RANGE(2100000, 16, 27, 100000), + REGULATOR_LINEAR_RANGE(2100000, 0, 11, 100000), }; static const unsigned int atc260x_ldo_voltage_range_sel[] = { - 0x0, 0x1, + 0x0, 0x20, }; static int atc260x_dcdc_set_voltage_time_sel(struct regulator_dev *rdev, @@ -411,7 +411,7 @@ enum atc2609a_reg_ids { .owner = THIS_MODULE, \ } -#define atc2609a_reg_desc_ldo_range_pick(num, n_range) { \ +#define atc2609a_reg_desc_ldo_range_pick(num, n_range, n_volt) { \ .name = "LDO"#num, \ .supply_name = "ldo"#num, \ .of_match = of_match_ptr("ldo"#num), \ @@ -421,6 +421,7 @@ enum atc2609a_reg_ids { .type = REGULATOR_VOLTAGE, \ .linear_ranges = atc2609a_ldo_voltage_ranges##n_range, \ .n_linear_ranges = ARRAY_SIZE(atc2609a_ldo_voltage_ranges##n_range), \ + .n_voltages = n_volt, \ .vsel_reg = ATC2609A_PMU_LDO##num##_CTL0, \ .vsel_mask = GENMASK(4, 1), \ .vsel_range_reg = ATC2609A_PMU_LDO##num##_CTL0, \ @@ -458,12 +459,12 @@ static const struct regulator_desc atc2609a_reg[] = { atc2609a_reg_desc_ldo_bypass(0), atc2609a_reg_desc_ldo_bypass(1), atc2609a_reg_desc_ldo_bypass(2), - atc2609a_reg_desc_ldo_range_pick(3, 0), - atc2609a_reg_desc_ldo_range_pick(4, 0), + atc2609a_reg_desc_ldo_range_pick(3, 0, 29), + atc2609a_reg_desc_ldo_range_pick(4, 0, 29), atc2609a_reg_desc_ldo(5), - atc2609a_reg_desc_ldo_range_pick(6, 1), - atc2609a_reg_desc_ldo_range_pick(7, 0), - atc2609a_reg_desc_ldo_range_pick(8, 0), + atc2609a_reg_desc_ldo_range_pick(6, 1, 28), + atc2609a_reg_desc_ldo_range_pick(7, 0, 29), + atc2609a_reg_desc_ldo_range_pick(8, 0, 29), atc2609a_reg_desc_ldo_fixed(9), }; diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index 8ff47ea522d69..5b6f4d3d1a146 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -364,7 +364,7 @@ BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range, NULL); BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table, - regulator_map_voltage_ascend, bd718xx_set_voltage_sel_restricted, + regulator_map_voltage_ascend, bd71837_set_voltage_sel_restricted, regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, NULL); /* diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 16114aea099a2..898acb8ae405e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1422,6 +1422,12 @@ static int set_machine_constraints(struct regulator_dev *rdev) * and we have control then make sure it is enabled. */ if (rdev->constraints->always_on || rdev->constraints->boot_on) { + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ + if (rdev->supply_name && !rdev->supply) + return -EPROBE_DEFER; + if (rdev->supply) { ret = regulator_enable(rdev->supply); if (ret < 0) { diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index 08cbf688e14d3..e669250902580 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -280,7 +280,7 @@ static unsigned int da9121_map_mode(unsigned int mode) case DA9121_BUCK_MODE_FORCE_PFM: return REGULATOR_MODE_STANDBY; default: - return -EINVAL; + return REGULATOR_MODE_INVALID; } } @@ -317,7 +317,7 @@ static unsigned int da9121_buck_get_mode(struct regulator_dev *rdev) { struct da9121 *chip = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); - unsigned int val; + unsigned int val, mode; int ret = 0; ret = regmap_read(chip->regmap, da9121_mode_field[id].reg, &val); @@ -326,7 +326,11 @@ static unsigned int da9121_buck_get_mode(struct regulator_dev *rdev) return -EINVAL; } - return da9121_map_mode(val & da9121_mode_field[id].msk); + mode = da9121_map_mode(val & da9121_mode_field[id].msk); + if (mode == REGULATOR_MODE_INVALID) + return -EINVAL; + + return mode; } static const struct regulator_ops da9121_buck_ops = { diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c index e83eb4fb1876a..1684faf82ed25 100644 --- a/drivers/regulator/fan53880.c +++ b/drivers/regulator/fan53880.c @@ -51,6 +51,7 @@ static const struct regulator_ops fan53880_ops = { REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \ }, \ .n_linear_ranges = 2, \ + .n_voltages = 0x74, \ .vsel_reg = FAN53880_LDO ## _num ## VOUT, \ .vsel_mask = 0x7f, \ .enable_reg = FAN53880_ENABLE, \ @@ -76,6 +77,7 @@ static const struct regulator_desc fan53880_regulators[] = { REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500), }, .n_linear_ranges = 2, + .n_voltages = 0xf8, .vsel_reg = FAN53880_BUCKVOUT, .vsel_mask = 0x7f, .enable_reg = FAN53880_ENABLE, @@ -95,6 +97,7 @@ static const struct regulator_desc fan53880_regulators[] = { REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000), }, .n_linear_ranges = 2, + .n_voltages = 0x71, .vsel_reg = FAN53880_BOOSTVOUT, .vsel_mask = 0x7f, .enable_reg = FAN53880_ENABLE_BOOST, diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 02ad83153e19a..34e255c235d4c 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c @@ -88,10 +88,15 @@ static int reg_domain_disable(struct regulator_dev *rdev) { struct fixed_voltage_data *priv = rdev_get_drvdata(rdev); struct device *dev = rdev->dev.parent; + int ret; + + ret = dev_pm_genpd_set_performance_state(dev, 0); + if (ret) + return ret; priv->enable_counter--; - return dev_pm_genpd_set_performance_state(dev, 0); + return 0; } static int reg_is_enabled(struct regulator_dev *rdev) diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index 8d9731e4052bf..5c439c850d090 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -814,6 +814,13 @@ static int max77620_regulator_probe(struct platform_device *pdev) config.dev = dev; config.driver_data = pmic; + /* + * Set of_node_reuse flag to prevent driver core from attempting to + * claim any pinmux resources already claimed by the parent device. + * Otherwise PMIC driver will fail to re-probe. + */ + device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); + for (id = 0; id < MAX77620_NUM_REGS; id++) { struct regulator_dev *rdev; struct regulator_desc *rdesc; diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c index 852fb2596ffda..5adc552dffd58 100644 --- a/drivers/regulator/rtmv20-regulator.c +++ b/drivers/regulator/rtmv20-regulator.c @@ -103,9 +103,47 @@ static int rtmv20_lsw_disable(struct regulator_dev *rdev) return 0; } +static int rtmv20_lsw_set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + int sel; + + if (min_uA > RTMV20_LSW_MAXUA || max_uA < RTMV20_LSW_MINUA) + return -EINVAL; + + if (max_uA > RTMV20_LSW_MAXUA) + max_uA = RTMV20_LSW_MAXUA; + + sel = (max_uA - RTMV20_LSW_MINUA) / RTMV20_LSW_STEPUA; + + /* Ensure the selected setting is still in range */ + if ((sel * RTMV20_LSW_STEPUA + RTMV20_LSW_MINUA) < min_uA) + return -EINVAL; + + sel <<= ffs(rdev->desc->csel_mask) - 1; + + return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg, + rdev->desc->csel_mask, sel); +} + +static int rtmv20_lsw_get_current_limit(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val); + if (ret) + return ret; + + val &= rdev->desc->csel_mask; + val >>= ffs(rdev->desc->csel_mask) - 1; + + return val * RTMV20_LSW_STEPUA + RTMV20_LSW_MINUA; +} + static const struct regulator_ops rtmv20_regulator_ops = { - .set_current_limit = regulator_set_current_limit_regmap, - .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = rtmv20_lsw_set_current_limit, + .get_current_limit = rtmv20_lsw_get_current_limit, .enable = rtmv20_lsw_enable, .disable = rtmv20_lsw_disable, .is_enabled = regulator_is_enabled_regmap, diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c index 0e8b3caa81461..66ffc2d54e979 100644 --- a/drivers/regulator/scmi-regulator.c +++ b/drivers/regulator/scmi-regulator.c @@ -176,7 +176,7 @@ scmi_config_linear_regulator_mappings(struct scmi_regulator *sreg, sreg->desc.uV_step = vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_STEP]; sreg->desc.linear_min_sel = 0; - sreg->desc.n_voltages = delta_uV / sreg->desc.uV_step; + sreg->desc.n_voltages = (delta_uV / sreg->desc.uV_step) + 1; sreg->desc.ops = &scmi_reg_linear_ops; } diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 8c625b530035f..9b61e9b131ade 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -86,6 +86,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) struct vfio_ccw_private *private; struct irb *irb; bool is_final; + bool cp_is_finished = false; private = container_of(work, struct vfio_ccw_private, io_work); irb = &private->irb; @@ -94,14 +95,21 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)); if (scsw_is_solicited(&irb->scsw)) { cp_update_scsw(&private->cp, &irb->scsw); - if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) + if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) { cp_free(&private->cp); + cp_is_finished = true; + } } mutex_lock(&private->io_mutex); memcpy(private->io_region->irb_area, irb, sizeof(*irb)); mutex_unlock(&private->io_mutex); - if (private->mdev && is_final) + /* + * Reset to IDLE only if processing of a channel program + * has finished. Do not overwrite a possible processing + * state if the final interrupt was for HSCH or CSCH. + */ + if (private->mdev && cp_is_finished) private->state = VFIO_CCW_STATE_IDLE; if (private->io_trigger) diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index 23e61aa638e4e..e435a9cd92dac 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c @@ -318,6 +318,7 @@ static void fsm_io_request(struct vfio_ccw_private *private, } err_out: + private->state = VFIO_CCW_STATE_IDLE; trace_vfio_ccw_fsm_io_request(scsw->cmd.fctl, schid, io_region->ret_code, errstr); } diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 767ac41686fe2..5971641964c6f 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -276,8 +276,6 @@ static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private, } vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ); - if (region->ret_code != 0) - private->state = VFIO_CCW_STATE_IDLE; ret = (region->ret_code != 0) ? region->ret_code : count; out_unlock: diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 1a0dc18d69155..ed300a279a387 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1220,6 +1220,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) was a result from the ABTS request rather than the CLEANUP request */ set_bit(BNX2FC_FLAG_IO_CLEANUP, &io_req->req_flags); + rc = FAILED; goto done; } diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 4580e081e4894..b21246b1ba99c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -4799,14 +4799,14 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba) { int i; - free_irq(pci_irq_vector(pdev, 1), hisi_hba); - free_irq(pci_irq_vector(pdev, 2), hisi_hba); - free_irq(pci_irq_vector(pdev, 11), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; int nr = hisi_sas_intr_conv ? 16 : 16 + i; - free_irq(pci_irq_vector(pdev, nr), cq); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); } pci_free_irq_vectors(pdev); } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 2f162603876f9..b93dd8ef4ac82 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -254,12 +254,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, device_enable_async_suspend(&shost->shost_dev); + get_device(&shost->shost_gendev); error = device_add(&shost->shost_dev); if (error) goto out_del_gendev; - get_device(&shost->shost_gendev); - if (shost->transportt->host_size) { shost->shost_data = kzalloc(shost->transportt->host_size, GFP_KERNEL); @@ -278,33 +277,36 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, if (!shost->work_q) { error = -EINVAL; - goto out_free_shost_data; + goto out_del_dev; } } error = scsi_sysfs_add_host(shost); if (error) - goto out_destroy_host; + goto out_del_dev; scsi_proc_host_add(shost); scsi_autopm_put_host(shost); return error; - out_destroy_host: - if (shost->work_q) - destroy_workqueue(shost->work_q); - out_free_shost_data: - kfree(shost->shost_data); + /* + * Any host allocation in this function will be freed in + * scsi_host_dev_release(). + */ out_del_dev: device_del(&shost->shost_dev); out_del_gendev: + /* + * Host state is SHOST_RUNNING so we have to explicitly release + * ->shost_dev. + */ + put_device(&shost->shost_dev); device_del(&shost->shost_gendev); out_disable_runtime_pm: device_disable_async_suspend(&shost->shost_gendev); pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); - scsi_mq_destroy_tags(shost); fail: return error; } @@ -345,7 +347,7 @@ static void scsi_host_dev_release(struct device *dev) ida_simple_remove(&host_index_ida, shost->host_no); - if (parent) + if (shost->shost_state != SHOST_CREATED) put_device(parent); kfree(shost); } @@ -392,8 +394,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) mutex_init(&shost->scan_mutex); index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); - if (index < 0) - goto fail_kfree; + if (index < 0) { + kfree(shost); + return NULL; + } shost->host_no = index; shost->dma_channel = 0xff; @@ -486,7 +490,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost_printk(KERN_WARNING, shost, "error handler thread failed to spawn, error = %ld\n", PTR_ERR(shost->ehandler)); - goto fail_index_remove; + goto fail; } shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d", @@ -495,17 +499,18 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) if (!shost->tmf_work_q) { shost_printk(KERN_WARNING, shost, "failed to create tmf workq\n"); - goto fail_kthread; + goto fail; } scsi_proc_hostdir_add(shost->hostt); return shost; + fail: + /* + * Host state is still SHOST_CREATED and that is enough to release + * ->shost_gendev. scsi_host_dev_release() will free + * dev_name(&shost->shost_dev). + */ + put_device(&shost->shost_gendev); - fail_kthread: - kthread_stop(shost->ehandler); - fail_index_remove: - ida_simple_remove(&host_index_ida, shost->host_no); - fail_kfree: - kfree(shost); return NULL; } EXPORT_SYMBOL(scsi_host_alloc); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 480e7d2dcf3e6..745d6d98c02e2 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1558,10 +1558,12 @@ void qlt_stop_phase2(struct qla_tgt *tgt) return; } + mutex_lock(&tgt->ha->optrom_mutex); mutex_lock(&vha->vha_tgt.tgt_mutex); tgt->tgt_stop = 0; tgt->tgt_stopped = 1; mutex_unlock(&vha->vha_tgt.tgt_mutex); + mutex_unlock(&tgt->ha->optrom_mutex); ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n", tgt); diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 8a79605d96521..b9969fce6b4d1 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -585,7 +585,13 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter, case BTSTAT_SUCCESS: case BTSTAT_LINKED_COMMAND_COMPLETED: case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG: - /* If everything went fine, let's move on.. */ + /* + * Commands like INQUIRY may transfer less data than + * requested by the initiator via bufflen. Set residual + * count to make upper layer aware of the actual amount + * of data returned. + */ + scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen); cmd->result = (DID_OK << 16); break; diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 8965fe61c8b44..fe40626e45aa8 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -68,7 +68,7 @@ #define BCM2835_SPI_FIFO_SIZE 64 #define BCM2835_SPI_FIFO_SIZE_3_4 48 #define BCM2835_SPI_DMA_MIN_LENGTH 96 -#define BCM2835_SPI_NUM_CS 4 /* raise as necessary */ +#define BCM2835_SPI_NUM_CS 24 /* raise as necessary */ #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | SPI_NO_CS | SPI_3WIRE) @@ -1195,6 +1195,12 @@ static int bcm2835_spi_setup(struct spi_device *spi) struct gpio_chip *chip; u32 cs; + if (spi->chip_select >= BCM2835_SPI_NUM_CS) { + dev_err(&spi->dev, "only %d chip-selects supported\n", + BCM2835_SPI_NUM_CS - 1); + return -EINVAL; + } + /* * Precalculate SPI slave's CS register value for ->prepare_message(): * The driver always uses software-controlled GPIO chip select, hence @@ -1288,7 +1294,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ctlr->use_gpio_descriptors = true; ctlr->mode_bits = BCM2835_SPI_MODE_BITS; ctlr->bits_per_word_mask = SPI_BPW_MASK(8); - ctlr->num_chipselect = BCM2835_SPI_NUM_CS; + ctlr->num_chipselect = 3; ctlr->setup = bcm2835_spi_setup; ctlr->transfer_one = bcm2835_spi_transfer_one; ctlr->handle_err = bcm2835_spi_handle_err; diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 1a7352abd8786..3d8948a17095b 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -181,6 +181,8 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; + bool initial_setup = false; + int retval; bitbang = spi_master_get_devdata(spi->master); @@ -189,22 +191,30 @@ int spi_bitbang_setup(struct spi_device *spi) if (!cs) return -ENOMEM; spi->controller_state = cs; + initial_setup = true; } /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; - if (!cs->txrx_word) - return -EINVAL; + if (!cs->txrx_word) { + retval = -EINVAL; + goto err_free; + } if (bitbang->setup_transfer) { - int retval = bitbang->setup_transfer(spi, NULL); + retval = bitbang->setup_transfer(spi, NULL); if (retval < 0) - return retval; + goto err_free; } dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); return 0; + +err_free: + if (initial_setup) + kfree(cs); + return retval; } EXPORT_SYMBOL_GPL(spi_bitbang_setup); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index d0e5aa18b7bad..bdf94cc7be1af 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -440,6 +440,7 @@ static int fsl_spi_setup(struct spi_device *spi) { struct mpc8xxx_spi *mpc8xxx_spi; struct fsl_spi_reg __iomem *reg_base; + bool initial_setup = false; int retval; u32 hw_mode; struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); @@ -452,6 +453,7 @@ static int fsl_spi_setup(struct spi_device *spi) if (!cs) return -ENOMEM; spi_set_ctldata(spi, cs); + initial_setup = true; } mpc8xxx_spi = spi_master_get_devdata(spi->master); @@ -475,6 +477,8 @@ static int fsl_spi_setup(struct spi_device *spi) retval = fsl_spi_setup_transfer(spi, NULL); if (retval < 0) { cs->hw_mode = hw_mode; /* Restore settings */ + if (initial_setup) + kfree(cs); return retval; } diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 71402f71ddd85..df28c6664aba6 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -424,15 +424,22 @@ done: static int uwire_setup(struct spi_device *spi) { struct uwire_state *ust = spi->controller_state; + bool initial_setup = false; + int status; if (ust == NULL) { ust = kzalloc(sizeof(*ust), GFP_KERNEL); if (ust == NULL) return -ENOMEM; spi->controller_state = ust; + initial_setup = true; } - return uwire_setup_transfer(spi, NULL); + status = uwire_setup_transfer(spi, NULL); + if (status && initial_setup) + kfree(ust); + + return status; } static void uwire_cleanup(struct spi_device *spi) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index d4c9510af3931..3596bbe4b7760 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1032,8 +1032,22 @@ static void omap2_mcspi_release_dma(struct spi_master *master) } } +static void omap2_mcspi_cleanup(struct spi_device *spi) +{ + struct omap2_mcspi_cs *cs; + + if (spi->controller_state) { + /* Unlink controller state from context save list */ + cs = spi->controller_state; + list_del(&cs->node); + + kfree(cs); + } +} + static int omap2_mcspi_setup(struct spi_device *spi) { + bool initial_setup = false; int ret; struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); struct omap2_mcspi_regs *ctx = &mcspi->ctx; @@ -1051,35 +1065,28 @@ static int omap2_mcspi_setup(struct spi_device *spi) spi->controller_state = cs; /* Link this to context save list */ list_add_tail(&cs->node, &ctx->cs); + initial_setup = true; } ret = pm_runtime_get_sync(mcspi->dev); if (ret < 0) { pm_runtime_put_noidle(mcspi->dev); + if (initial_setup) + omap2_mcspi_cleanup(spi); return ret; } ret = omap2_mcspi_setup_transfer(spi, NULL); + if (ret && initial_setup) + omap2_mcspi_cleanup(spi); + pm_runtime_mark_last_busy(mcspi->dev); pm_runtime_put_autosuspend(mcspi->dev); return ret; } -static void omap2_mcspi_cleanup(struct spi_device *spi) -{ - struct omap2_mcspi_cs *cs; - - if (spi->controller_state) { - /* Unlink controller state from context save list */ - cs = spi->controller_state; - list_del(&cs->node); - - kfree(cs); - } -} - static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data) { struct omap2_mcspi *mcspi = data; diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 0cc767283674b..825cc5b2ab2fb 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1254,6 +1254,8 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip, chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; err = gpiod_direction_output(gpiod, !chip->gpio_cs_inverted); + if (err) + gpiod_put(chip->gpiod_cs); } return err; @@ -1267,6 +1269,7 @@ static int setup(struct spi_device *spi) struct driver_data *drv_data = spi_controller_get_devdata(spi->controller); uint tx_thres, tx_hi_thres, rx_thres; + int err; switch (drv_data->ssp_type) { case QUARK_X1000_SSP: @@ -1413,7 +1416,11 @@ static int setup(struct spi_device *spi) if (drv_data->ssp_type == CE4100_SSP) return 0; - return setup_cs(spi, chip, chip_info); + err = setup_cs(spi, chip, chip_info); + if (err) + kfree(chip); + + return err; } static void cleanup(struct spi_device *spi) diff --git a/drivers/spi/spi-sprd.c b/drivers/spi/spi-sprd.c index b41a75749b498..28e70db9bbba8 100644 --- a/drivers/spi/spi-sprd.c +++ b/drivers/spi/spi-sprd.c @@ -1068,6 +1068,7 @@ static const struct of_device_id sprd_spi_of_match[] = { { .compatible = "sprd,sc9860-spi", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, sprd_spi_of_match); static struct platform_driver sprd_spi_driver = { .driver = { diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c index 5d8a5ee62fa23..2765289028fae 100644 --- a/drivers/spi/spi-zynq-qspi.c +++ b/drivers/spi/spi-zynq-qspi.c @@ -528,18 +528,17 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->master); int err = 0, i; u8 *tmpbuf; - u8 opcode = op->cmd.opcode; dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n", - opcode, op->cmd.buswidth, op->addr.buswidth, + op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, op->dummy.buswidth, op->data.buswidth); zynq_qspi_chipselect(mem->spi, true); zynq_qspi_config_op(xqspi, mem->spi); - if (op->cmd.nbytes) { + if (op->cmd.opcode) { reinit_completion(&xqspi->data_completion); - xqspi->txbuf = &opcode; + xqspi->txbuf = (u8 *)&op->cmd.opcode; xqspi->rxbuf = NULL; xqspi->tx_bytes = op->cmd.nbytes; xqspi->rx_bytes = op->cmd.nbytes; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6ae7418f648ca..e067c54e87dd7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -47,10 +47,6 @@ static void spidev_release(struct device *dev) { struct spi_device *spi = to_spi_device(dev); - /* spi controllers may cleanup for released devices */ - if (spi->controller->cleanup) - spi->controller->cleanup(spi); - spi_controller_put(spi->controller); kfree(spi->driver_override); kfree(spi); @@ -558,6 +554,12 @@ static int spi_dev_check(struct device *dev, void *data) return 0; } +static void spi_cleanup(struct spi_device *spi) +{ + if (spi->controller->cleanup) + spi->controller->cleanup(spi); +} + /** * spi_add_device - Add spi_device allocated with spi_alloc_device * @spi: spi_device to register @@ -622,11 +624,13 @@ int spi_add_device(struct spi_device *spi) /* Device may be bound to an active driver when this returns */ status = device_add(&spi->dev); - if (status < 0) + if (status < 0) { dev_err(dev, "can't add %s, status %d\n", dev_name(&spi->dev), status); - else + spi_cleanup(spi); + } else { dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); + } done: mutex_unlock(&spi_add_lock); @@ -719,7 +723,9 @@ void spi_unregister_device(struct spi_device *spi) } if (ACPI_COMPANION(&spi->dev)) acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); - device_unregister(&spi->dev); + device_del(&spi->dev); + spi_cleanup(spi); + put_device(&spi->dev); } EXPORT_SYMBOL_GPL(spi_unregister_device); diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index ff164a8c8679a..cbec65e5a4645 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -2359,7 +2359,7 @@ void rtw_cfg80211_indicate_sta_assoc(struct adapter *padapter, u8 *pmgmt_frame, DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); { - struct station_info sinfo; + struct station_info sinfo = {}; u8 ie_offset; if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ) ie_offset = _ASOCREQ_IE_OFFSET_; diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 582bfeceedb47..e72ec9c787f98 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -2006,7 +2006,7 @@ static void cdns3_configure_dmult(struct cdns3_device *priv_dev, else mask = BIT(priv_ep->num); - if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) { + if (priv_ep->type != USB_ENDPOINT_XFER_ISOC && !priv_ep->dir) { cdns3_set_register_bit(®s->tdl_from_trb, mask); cdns3_set_register_bit(®s->tdl_beh, mask); cdns3_set_register_bit(®s->tdl_beh2, mask); @@ -2045,15 +2045,13 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable) case USB_ENDPOINT_XFER_INT: ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_INT); - if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) || - priv_dev->dev_ver > DEV_VER_V2) + if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir) ep_cfg |= EP_CFG_TDL_CHK; break; case USB_ENDPOINT_XFER_BULK: ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_BULK); - if ((priv_dev->dev_ver == DEV_VER_V2 && !priv_ep->dir) || - priv_dev->dev_ver > DEV_VER_V2) + if (priv_dev->dev_ver >= DEV_VER_V2 && !priv_ep->dir) ep_cfg |= EP_CFG_TDL_CHK; break; default: @@ -3255,8 +3253,10 @@ static int __cdns3_gadget_init(struct cdns *cdns) pm_runtime_get_sync(cdns->dev); ret = cdns3_gadget_start(cdns); - if (ret) + if (ret) { + pm_runtime_put_sync(cdns->dev); return ret; + } /* * Because interrupt line can be shared with other components in diff --git a/drivers/usb/cdns3/cdnsp-ring.c b/drivers/usb/cdns3/cdnsp-ring.c index 5f0513c96c04e..68972746e3636 100644 --- a/drivers/usb/cdns3/cdnsp-ring.c +++ b/drivers/usb/cdns3/cdnsp-ring.c @@ -1517,13 +1517,14 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data) { struct cdnsp_device *pdev = (struct cdnsp_device *)data; union cdnsp_trb *event_ring_deq; + unsigned long flags; int counter = 0; - spin_lock(&pdev->lock); + spin_lock_irqsave(&pdev->lock, flags); if (pdev->cdnsp_state & (CDNSP_STATE_HALTED | CDNSP_STATE_DYING)) { cdnsp_died(pdev); - spin_unlock(&pdev->lock); + spin_unlock_irqrestore(&pdev->lock, flags); return IRQ_HANDLED; } @@ -1539,7 +1540,7 @@ irqreturn_t cdnsp_thread_irq_handler(int irq, void *data) cdnsp_update_erst_dequeue(pdev, event_ring_deq, 1); - spin_unlock(&pdev->lock); + spin_unlock_irqrestore(&pdev->lock, flags); return IRQ_HANDLED; } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c16d900cdaee3..393f216b91615 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -2061,6 +2061,7 @@ static int udc_start(struct ci_hdrc *ci) ci->gadget.name = ci->platdata->name; ci->gadget.otg_caps = otg_caps; ci->gadget.sg_supported = 1; + ci->gadget.irq = ci->irq; if (ci->platdata->flags & CI_HDRC_REQUIRES_ALIGNED_DMA) ci->gadget.quirk_avoids_skb_reserve = 1; diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index bdf1f98dfad8c..ffe301d6ea359 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -651,7 +651,7 @@ static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv, return PTR_ERR(priv->usb_glue_regmap); /* Create a regmap for each USB2 PHY control register set */ - for (i = 0; i < priv->usb2_ports; i++) { + for (i = 0; i < priv->drvdata->num_phys; i++) { struct regmap_config u2p_regmap_config = { .reg_bits = 8, .val_bits = 32, @@ -659,6 +659,9 @@ static int dwc3_meson_g12a_setup_regmaps(struct dwc3_meson_g12a *priv, .max_register = U2P_R1, }; + if (!strstr(priv->drvdata->phy_names[i], "usb2")) + continue; + u2p_regmap_config.name = devm_kasprintf(priv->dev, GFP_KERNEL, "u2p-%d", i); if (!u2p_regmap_config.name) @@ -772,13 +775,13 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) ret = priv->drvdata->usb_init(priv); if (ret) - goto err_disable_clks; + goto err_disable_regulator; /* Init PHYs */ for (i = 0 ; i < PHY_COUNT ; ++i) { ret = phy_init(priv->phys[i]); if (ret) - goto err_disable_clks; + goto err_disable_regulator; } /* Set PHY Power */ @@ -816,6 +819,10 @@ err_phys_exit: for (i = 0 ; i < PHY_COUNT ; ++i) phy_exit(priv->phys[i]); +err_disable_regulator: + if (priv->vbus) + regulator_disable(priv->vbus); + err_disable_clks: clk_bulk_disable_unprepare(priv->drvdata->num_clks, priv->drvdata->clks); diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 8b668ef46f7f1..3cd2942643725 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -292,6 +292,9 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) epnum |= 1; dep = dwc->eps[epnum]; + if (dep == NULL) + return NULL; + if (dep->flags & DWC3_EP_ENABLED) return dep; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a721d0e4d9994..1f9454e0d447b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2240,13 +2240,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) } /* - * Synchronize any pending event handling before executing the controller - * halt routine. + * Synchronize and disable any further event handling while controller + * is being enabled/disabled. */ - if (!is_on) { - dwc3_gadget_disable_irq(dwc); - synchronize_irq(dwc->irq_gadget); - } + disable_irq(dwc->irq_gadget); spin_lock_irqsave(&dwc->lock, flags); @@ -2284,6 +2281,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) ret = dwc3_gadget_run_stop(dwc, is_on, false); spin_unlock_irqrestore(&dwc->lock, flags); + enable_irq(dwc->irq_gadget); + pm_runtime_put(dwc->dev); return ret; @@ -4012,6 +4011,7 @@ err5: dwc3_gadget_free_endpoints(dwc); err4: usb_put_gadget(dwc->gadget); + dwc->gadget = NULL; err3: dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce, dwc->bounce_addr); @@ -4031,6 +4031,9 @@ err0: void dwc3_gadget_exit(struct dwc3 *dwc) { + if (!dwc->gadget) + return; + usb_del_gadget(dwc->gadget); dwc3_gadget_free_endpoints(dwc); usb_put_gadget(dwc->gadget); diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 8bb25773b61e9..05507606b2b42 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -164,6 +164,14 @@ int usb_assign_descriptors(struct usb_function *f, { struct usb_gadget *g = f->config->cdev->gadget; + /* super-speed-plus descriptor falls back to super-speed one, + * if such a descriptor was provided, thus avoiding a NULL + * pointer dereference if a 5gbps capable gadget is used with + * a 10gbps capable config (device port + cable + host port) + */ + if (!ssp) + ssp = ss; + if (fs) { f->fs_descriptors = usb_copy_descriptors(fs); if (!f->fs_descriptors) diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 7f5cf488b2b1e..ffe2486fce71c 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -791,7 +791,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) fs_ecm_notify_desc.bEndpointAddress; status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function, - ecm_ss_function, NULL); + ecm_ss_function, ecm_ss_function); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index cfcc4e81fb776..2cd9942707b46 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -302,7 +302,7 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress; status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function, - eem_ss_function, NULL); + eem_ss_function, eem_ss_function); if (status) goto fail; @@ -495,7 +495,7 @@ static int eem_unwrap(struct gether *port, skb2 = skb_clone(skb, GFP_ATOMIC); if (unlikely(!skb2)) { DBG(cdev, "unable to unframe EEM packet\n"); - continue; + goto next; } skb_trim(skb2, len - ETH_FCS_LEN); @@ -505,7 +505,7 @@ static int eem_unwrap(struct gether *port, GFP_ATOMIC); if (unlikely(!skb3)) { dev_kfree_skb_any(skb2); - continue; + goto next; } dev_kfree_skb_any(skb2); skb_queue_tail(list, skb3); diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 10a5d9f0f2b90..f29abc7867d59 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -3567,6 +3567,9 @@ static void ffs_func_unbind(struct usb_configuration *c, ffs->func = NULL; } + /* Drain any pending AIO completions */ + drain_workqueue(ffs->io_completion_wq); + if (!--opts->refcnt) functionfs_unbind(ffs); diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 1125f4715830d..e556993081170 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -802,7 +802,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) hidg_fs_out_ep_desc.bEndpointAddress; status = usb_assign_descriptors(f, hidg_fs_descriptors, - hidg_hs_descriptors, hidg_ss_descriptors, NULL); + hidg_hs_descriptors, hidg_ss_descriptors, + hidg_ss_descriptors); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index b56ad7c3838b8..ae41f556eb752 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -207,7 +207,7 @@ autoconf_fail: ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs, - ss_loopback_descs, NULL); + ss_loopback_descs, ss_loopback_descs); if (ret) return ret; diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 019bea8e09cce..855127249f242 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -583,7 +583,7 @@ static void ncm_do_notify(struct f_ncm *ncm) data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget)); data[1] = data[0]; - DBG(cdev, "notify speed %d\n", ncm_bitrate(cdev->gadget)); + DBG(cdev, "notify speed %u\n", ncm_bitrate(cdev->gadget)); ncm->notify_state = NCM_NOTIFY_CONNECT; break; } @@ -1101,11 +1101,11 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, ncm->ndp_dgram_count = 1; /* Note: we skip opts->next_ndp_index */ - } - /* Delay the timer. */ - hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS, - HRTIMER_MODE_REL_SOFT); + /* Start the timer. */ + hrtimer_start(&ncm->task_timer, TX_TIMEOUT_NSECS, + HRTIMER_MODE_REL_SOFT); + } /* Add the datagram position entries */ ntb_ndp = skb_put_zero(ncm->skb_tx_ndp, dgram_idx_len); diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 61ce8e68f7a30..61bbf27b52037 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1101,7 +1101,8 @@ autoconf_fail: ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_printer_function, - hs_printer_function, ss_printer_function, NULL); + hs_printer_function, ss_printer_function, + ss_printer_function); if (ret) return ret; diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 0739b05a0ef7b..ee95e8f5f9d48 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -789,7 +789,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress; status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function, - eth_ss_function, NULL); + eth_ss_function, eth_ss_function); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index e627138463504..1ed8ff0ac2d31 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -233,7 +233,7 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function, - gser_ss_function, NULL); + gser_ss_function, gser_ss_function); if (status) goto fail; dev_dbg(&cdev->gadget->dev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 5a201ba7b155b..1abf08e5164af 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -431,7 +431,8 @@ no_iso: ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_source_sink_descs, - hs_source_sink_descs, ss_source_sink_descs, NULL); + hs_source_sink_descs, ss_source_sink_descs, + ss_source_sink_descs); if (ret) return ret; diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index 4d945254905d9..51c1cae162d9b 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -358,7 +358,7 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) fs_subset_out_desc.bEndpointAddress; status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function, - ss_eth_function, NULL); + ss_eth_function, ss_eth_function); if (status) goto fail; diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 410fa89eae8f6..5a2e9ce2bc352 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -2061,7 +2061,8 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; ret = usb_assign_descriptors(f, uasp_fs_function_desc, - uasp_hs_function_desc, uasp_ss_function_desc, NULL); + uasp_hs_function_desc, uasp_ss_function_desc, + uasp_ss_function_desc); if (ret) goto ep_fail; diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 7bc18cf8042cc..18c2bbddf080b 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -59,6 +59,7 @@ #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e +#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb @@ -182,6 +183,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) (pdev->device == PCI_DEVICE_ID_AMD_PROMONTORYA_1))) xhci->quirks |= XHCI_U2_DISABLE_WAKE; + if (pdev->vendor == PCI_VENDOR_ID_AMD && + pdev->device == PCI_DEVICE_ID_AMD_RENOIR_XHCI) + xhci->quirks |= XHCI_BROKEN_D3COLD; + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { xhci->quirks |= XHCI_LPM_SUPPORT; xhci->quirks |= XHCI_INTEL_HOST; @@ -539,7 +544,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) * Systems with the TI redriver that loses port status change events * need to have the registers polled during D3, so avoid D3cold. */ - if (xhci->quirks & XHCI_COMP_MODE_QUIRK) + if (xhci->quirks & (XHCI_COMP_MODE_QUIRK | XHCI_BROKEN_D3COLD)) pci_d3cold_disable(pdev); if (xhci->quirks & XHCI_PME_STUCK_QUIRK) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index ca822ad3b65b0..4e171099d2cbd 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1892,6 +1892,7 @@ struct xhci_hcd { #define XHCI_DISABLE_SPARSE BIT_ULL(38) #define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39) #define XHCI_NO_SOFT_RETRY BIT_ULL(40) +#define XHCI_BROKEN_D3COLD BIT_ULL(41) unsigned int num_active_eps; unsigned int limit_active_eps; diff --git a/drivers/usb/misc/brcmstb-usb-pinmap.c b/drivers/usb/misc/brcmstb-usb-pinmap.c index b3cfe8666ea7d..336653091e3b3 100644 --- a/drivers/usb/misc/brcmstb-usb-pinmap.c +++ b/drivers/usb/misc/brcmstb-usb-pinmap.c @@ -263,6 +263,8 @@ static int __init brcmstb_usb_pinmap_probe(struct platform_device *pdev) return -EINVAL; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -EINVAL; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata) + diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 8f09a387b7738..4c8f0112481f3 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2009,9 +2009,8 @@ static void musb_pm_runtime_check_session(struct musb *musb) schedule_delayed_work(&musb->irq_work, msecs_to_jiffies(1000)); musb->quirk_retries--; - break; } - fallthrough; + break; case MUSB_QUIRK_B_INVALID_VBUS_91: if (musb->quirk_retries && !musb->flush_irq_work) { musb_dbg(musb, diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index a373cd63b3a44..f6e1ce0a47edb 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -252,9 +252,11 @@ struct cp210x_serial_private { u8 gpio_input; #endif u8 partnum; + u32 fw_version; speed_t min_speed; speed_t max_speed; bool use_actual_rate; + bool no_flow_control; }; enum cp210x_event_state { @@ -398,6 +400,7 @@ struct cp210x_special_chars { /* CP210X_VENDOR_SPECIFIC values */ #define CP210X_READ_2NCONFIG 0x000E +#define CP210X_GET_FW_VER_2N 0x0010 #define CP210X_READ_LATCH 0x00C2 #define CP210X_GET_PARTNUM 0x370B #define CP210X_GET_PORTCONFIG 0x370C @@ -537,6 +540,12 @@ struct cp210x_single_port_config { #define CP210X_2NCONFIG_GPIO_RSTLATCH_IDX 587 #define CP210X_2NCONFIG_GPIO_CONTROL_IDX 600 +/* CP2102N QFN20 port configuration values */ +#define CP2102N_QFN20_GPIO2_TXLED_MODE BIT(2) +#define CP2102N_QFN20_GPIO3_RXLED_MODE BIT(3) +#define CP2102N_QFN20_GPIO1_RS485_MODE BIT(4) +#define CP2102N_QFN20_GPIO0_CLK_MODE BIT(6) + /* CP210X_VENDOR_SPECIFIC, CP210X_WRITE_LATCH call writes these 0x2 bytes. */ struct cp210x_gpio_write { u8 mask; @@ -1122,6 +1131,7 @@ static bool cp210x_termios_change(const struct ktermios *a, const struct ktermio static void cp210x_set_flow_control(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { + struct cp210x_serial_private *priv = usb_get_serial_data(port->serial); struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); struct cp210x_special_chars chars; struct cp210x_flow_ctl flow_ctl; @@ -1129,6 +1139,15 @@ static void cp210x_set_flow_control(struct tty_struct *tty, u32 ctl_hs; int ret; + /* + * Some CP2102N interpret ulXonLimit as ulFlowReplace (erratum + * CP2102N_E104). Report back that flow control is not supported. + */ + if (priv->no_flow_control) { + tty->termios.c_cflag &= ~CRTSCTS; + tty->termios.c_iflag &= ~(IXON | IXOFF); + } + if (old_termios && C_CRTSCTS(tty) == (old_termios->c_cflag & CRTSCTS) && I_IXON(tty) == (old_termios->c_iflag & IXON) && @@ -1185,19 +1204,20 @@ static void cp210x_set_flow_control(struct tty_struct *tty, port_priv->crtscts = false; } - if (I_IXOFF(tty)) + if (I_IXOFF(tty)) { flow_repl |= CP210X_SERIAL_AUTO_RECEIVE; - else + + flow_ctl.ulXonLimit = cpu_to_le32(128); + flow_ctl.ulXoffLimit = cpu_to_le32(128); + } else { flow_repl &= ~CP210X_SERIAL_AUTO_RECEIVE; + } if (I_IXON(tty)) flow_repl |= CP210X_SERIAL_AUTO_TRANSMIT; else flow_repl &= ~CP210X_SERIAL_AUTO_TRANSMIT; - flow_ctl.ulXonLimit = cpu_to_le32(128); - flow_ctl.ulXoffLimit = cpu_to_le32(128); - dev_dbg(&port->dev, "%s - ctrl = 0x%02x, flow = 0x%02x\n", __func__, ctl_hs, flow_repl); @@ -1726,7 +1746,19 @@ static int cp2102n_gpioconf_init(struct usb_serial *serial) priv->gpio_pushpull = (gpio_pushpull >> 3) & 0x0f; /* 0 indicates GPIO mode, 1 is alternate function */ - priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f; + if (priv->partnum == CP210X_PARTNUM_CP2102N_QFN20) { + /* QFN20 is special... */ + if (gpio_ctrl & CP2102N_QFN20_GPIO0_CLK_MODE) /* GPIO 0 */ + priv->gpio_altfunc |= BIT(0); + if (gpio_ctrl & CP2102N_QFN20_GPIO1_RS485_MODE) /* GPIO 1 */ + priv->gpio_altfunc |= BIT(1); + if (gpio_ctrl & CP2102N_QFN20_GPIO2_TXLED_MODE) /* GPIO 2 */ + priv->gpio_altfunc |= BIT(2); + if (gpio_ctrl & CP2102N_QFN20_GPIO3_RXLED_MODE) /* GPIO 3 */ + priv->gpio_altfunc |= BIT(3); + } else { + priv->gpio_altfunc = (gpio_ctrl >> 2) & 0x0f; + } if (priv->partnum == CP210X_PARTNUM_CP2102N_QFN28) { /* @@ -1901,6 +1933,45 @@ static void cp210x_init_max_speed(struct usb_serial *serial) priv->use_actual_rate = use_actual_rate; } +static int cp210x_get_fw_version(struct usb_serial *serial, u16 value) +{ + struct cp210x_serial_private *priv = usb_get_serial_data(serial); + u8 ver[3]; + int ret; + + ret = cp210x_read_vendor_block(serial, REQTYPE_DEVICE_TO_HOST, value, + ver, sizeof(ver)); + if (ret) + return ret; + + dev_dbg(&serial->interface->dev, "%s - %d.%d.%d\n", __func__, + ver[0], ver[1], ver[2]); + + priv->fw_version = ver[0] << 16 | ver[1] << 8 | ver[2]; + + return 0; +} + +static void cp210x_determine_quirks(struct usb_serial *serial) +{ + struct cp210x_serial_private *priv = usb_get_serial_data(serial); + int ret; + + switch (priv->partnum) { + case CP210X_PARTNUM_CP2102N_QFN28: + case CP210X_PARTNUM_CP2102N_QFN24: + case CP210X_PARTNUM_CP2102N_QFN20: + ret = cp210x_get_fw_version(serial, CP210X_GET_FW_VER_2N); + if (ret) + break; + if (priv->fw_version <= 0x10004) + priv->no_flow_control = true; + break; + default: + break; + } +} + static int cp210x_attach(struct usb_serial *serial) { int result; @@ -1921,6 +1992,7 @@ static int cp210x_attach(struct usb_serial *serial) usb_set_serial_data(serial, priv); + cp210x_determine_quirks(serial); cp210x_init_max_speed(serial); result = cp210x_gpio_init(serial); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5a725ffb76756..41e81ab7f64a9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -611,6 +611,7 @@ static const struct usb_device_id id_table_combined[] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONLX_PLUS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NT_ORION_IO_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_NT_ORIONMX_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SYNAPSE_SS200_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX_PID) }, { USB_DEVICE(FTDI_VID, FTDI_CUSTOMWARE_MINIPLEX2_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index d854e04a4286e..add602bebd820 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -581,6 +581,7 @@ #define FTDI_NT_ORIONLXM_PID 0x7c90 /* OrionLXm Substation Automation Platform */ #define FTDI_NT_ORIONLX_PLUS_PID 0x7c91 /* OrionLX+ Substation Automation Platform */ #define FTDI_NT_ORION_IO_PID 0x7c92 /* Orion I/O */ +#define FTDI_NT_ORIONMX_PID 0x7c93 /* OrionMX */ /* * Synapse Wireless product ids (FTDI_VID) diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 83c62f920c501..c2ece584724e9 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -26,6 +26,7 @@ #define ZYXEL_VENDOR_ID 0x0586 #define ZYXEL_OMNINET_ID 0x1000 +#define ZYXEL_OMNI_56K_PLUS_ID 0x1500 /* This one seems to be a re-branded ZyXEL device */ #define BT_IGNITIONPRO_ID 0x2000 @@ -40,6 +41,7 @@ static void omninet_port_remove(struct usb_serial_port *port); static const struct usb_device_id id_table[] = { { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, + { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNI_56K_PLUS_ID) }, { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 599dcb2e374d0..527029ab23016 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -416,7 +416,7 @@ static void qt2_close(struct usb_serial_port *port) /* flush the port transmit buffer */ i = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), + usb_sndctrlpipe(serial->dev, 0), QT2_FLUSH_DEVICE, 0x40, 1, port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); @@ -426,7 +426,7 @@ static void qt2_close(struct usb_serial_port *port) /* flush the port receive buffer */ i = usb_control_msg(serial->dev, - usb_rcvctrlpipe(serial->dev, 0), + usb_sndctrlpipe(serial->dev, 0), QT2_FLUSH_DEVICE, 0x40, 0, port_priv->device_port, NULL, 0, QT2_USB_TIMEOUT); @@ -654,7 +654,7 @@ static int qt2_attach(struct usb_serial *serial) int status; /* power on unit */ - status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), + status = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0xc2, 0x40, 0x8000, 0, NULL, 0, QT2_USB_TIMEOUT); if (status < 0) { diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 42acdc8b684fe..b9035c3407b56 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -239,7 +239,7 @@ find_mux: dev = class_find_device(&typec_mux_class, NULL, fwnode, mux_fwnode_match); - return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER); + return dev ? to_typec_mux(dev) : ERR_PTR(-EPROBE_DEFER); } /** diff --git a/drivers/usb/typec/mux/intel_pmc_mux.c b/drivers/usb/typec/mux/intel_pmc_mux.c index 46a25b8db72e5..31b1b3b555c77 100644 --- a/drivers/usb/typec/mux/intel_pmc_mux.c +++ b/drivers/usb/typec/mux/intel_pmc_mux.c @@ -586,6 +586,11 @@ static int pmc_usb_probe_iom(struct pmc_usb *pmc) return -ENOMEM; } + if (IS_ERR(pmc->iom_base)) { + put_device(&adev->dev); + return PTR_ERR(pmc->iom_base); + } + pmc->iom_adev = adev; return 0; @@ -636,8 +641,10 @@ static int pmc_usb_probe(struct platform_device *pdev) break; ret = pmc_usb_register_port(pmc, i, fwnode); - if (ret) + if (ret) { + fwnode_handle_put(fwnode); goto err_remove_ports; + } } platform_set_drvdata(pdev, pmc); diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index b3e3dff464917..6133c0679c273 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -1531,19 +1531,25 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, if (PD_VDO_VID(p[0]) != USB_SID_PD) break; - if (PD_VDO_SVDM_VER(p[0]) < svdm_version) + if (PD_VDO_SVDM_VER(p[0]) < svdm_version) { typec_partner_set_svdm_version(port->partner, PD_VDO_SVDM_VER(p[0])); + svdm_version = PD_VDO_SVDM_VER(p[0]); + } - tcpm_ams_start(port, DISCOVER_IDENTITY); - /* 6.4.4.3.1: Only respond as UFP (device) */ - if (port->data_role == TYPEC_DEVICE && + port->ams = DISCOVER_IDENTITY; + /* + * PD2.0 Spec 6.10.3: respond with NAK as DFP (data host) + * PD3.1 Spec 6.4.4.2.5.1: respond with NAK if "invalid field" or + * "wrong configuation" or "Unrecognized" + */ + if ((port->data_role == TYPEC_DEVICE || svdm_version >= SVDM_VER_2_0) && port->nr_snk_vdo) { /* * Product Type DFP and Connector Type are not defined in SVDM * version 1.0 and shall be set to zero. */ - if (typec_get_negotiated_svdm_version(typec) < SVDM_VER_2_0) + if (svdm_version < SVDM_VER_2_0) response[1] = port->snk_vdo[0] & ~IDH_DFP_MASK & ~IDH_CONN_MASK; else @@ -1554,19 +1560,18 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, } break; case CMD_DISCOVER_SVID: - tcpm_ams_start(port, DISCOVER_SVIDS); + port->ams = DISCOVER_SVIDS; break; case CMD_DISCOVER_MODES: - tcpm_ams_start(port, DISCOVER_MODES); + port->ams = DISCOVER_MODES; break; case CMD_ENTER_MODE: - tcpm_ams_start(port, DFP_TO_UFP_ENTER_MODE); + port->ams = DFP_TO_UFP_ENTER_MODE; break; case CMD_EXIT_MODE: - tcpm_ams_start(port, DFP_TO_UFP_EXIT_MODE); + port->ams = DFP_TO_UFP_EXIT_MODE; break; case CMD_ATTENTION: - tcpm_ams_start(port, ATTENTION); /* Attention command does not have response */ *adev_action = ADEV_ATTENTION; return 0; @@ -1917,6 +1922,9 @@ static void vdm_run_state_machine(struct tcpm_port *port) tcpm_log(port, "VDM Tx error, retry"); port->vdm_retries++; port->vdm_state = VDM_STATE_READY; + if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMDT(vdo_hdr) == CMDT_INIT) + tcpm_ams_finish(port); + } else { tcpm_ams_finish(port); } break; @@ -2163,20 +2171,25 @@ static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload, if (!type) { tcpm_log(port, "Alert message received with no type"); + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); return; } /* Just handling non-battery alerts for now */ if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) { - switch (port->state) { - case SRC_READY: - case SNK_READY: + if (port->pwr_role == TYPEC_SOURCE) { + port->upcoming_state = GET_STATUS_SEND; + tcpm_ams_start(port, GETTING_SOURCE_SINK_STATUS); + } else { + /* + * Do not check SinkTxOk here in case the Source doesn't set its Rp to + * SinkTxOk in time. + */ + port->ams = GETTING_SOURCE_SINK_STATUS; tcpm_set_state(port, GET_STATUS_SEND, 0); - break; - default: - tcpm_queue_message(port, PD_MSG_CTRL_WAIT); - break; } + } else { + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); } } @@ -2420,7 +2433,12 @@ static void tcpm_pd_data_request(struct tcpm_port *port, tcpm_pd_handle_state(port, BIST_RX, BIST, 0); break; case PD_DATA_ALERT: - tcpm_handle_alert(port, msg->payload, cnt); + if (port->state != SRC_READY && port->state != SNK_READY) + tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ? + SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET, + NONE_AMS, 0); + else + tcpm_handle_alert(port, msg->payload, cnt); break; case PD_DATA_BATT_STATUS: case PD_DATA_GET_COUNTRY_INFO: @@ -2744,24 +2762,16 @@ static void tcpm_pd_ext_msg_request(struct tcpm_port *port, switch (type) { case PD_EXT_STATUS: - /* - * If PPS related events raised then get PPS status to clear - * (see USB PD 3.0 Spec, 6.5.2.4) - */ - if (msg->ext_msg.data[USB_PD_EXT_SDB_EVENT_FLAGS] & - USB_PD_EXT_SDB_PPS_EVENTS) - tcpm_pd_handle_state(port, GET_PPS_STATUS_SEND, - GETTING_SOURCE_SINK_STATUS, 0); - - else - tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0); - break; case PD_EXT_PPS_STATUS: - /* - * For now the PPS status message is used to clear events - * and nothing more. - */ - tcpm_pd_handle_state(port, ready_state(port), NONE_AMS, 0); + if (port->ams == GETTING_SOURCE_SINK_STATUS) { + tcpm_ams_finish(port); + tcpm_set_state(port, ready_state(port), 0); + } else { + /* unexpected Status or PPS_Status Message */ + tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ? + SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET, + NONE_AMS, 0); + } break; case PD_EXT_SOURCE_CAP_EXT: case PD_EXT_GET_BATT_CAP: @@ -6226,6 +6236,10 @@ void tcpm_unregister_port(struct tcpm_port *port) { int i; + hrtimer_cancel(&port->enable_frs_timer); + hrtimer_cancel(&port->vdm_state_machine_timer); + hrtimer_cancel(&port->state_machine_timer); + tcpm_reset_port(port); for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++) typec_unregister_altmode(port->port_altmode[i]); diff --git a/drivers/usb/typec/tcpm/wcove.c b/drivers/usb/typec/tcpm/wcove.c index 79ae63950050c..5d125339687a3 100644 --- a/drivers/usb/typec/tcpm/wcove.c +++ b/drivers/usb/typec/tcpm/wcove.c @@ -378,7 +378,7 @@ static int wcove_pd_transmit(struct tcpc_dev *tcpc, const u8 *data = (void *)msg; int i; - for (i = 0; i < pd_header_cnt(msg->header) * 4 + 2; i++) { + for (i = 0; i < pd_header_cnt_le(msg->header) * 4 + 2; i++) { ret = regmap_write(wcove->regmap, USBC_TX_DATA + i, data[i]); if (ret) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 7104ddb9696d6..0c4a0f1ac0446 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -1253,6 +1253,7 @@ err_unregister: } err_reset: + memset(&ucsi->cap, 0, sizeof(ucsi->cap)); ucsi_reset_ppm(ucsi); err: return ret; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 289f1f09481d7..da6bf9a70fc68 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2558,6 +2558,24 @@ static int validate_super(struct btrfs_fs_info *fs_info, ret = -EINVAL; } + if (memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid, + BTRFS_FSID_SIZE)) { + btrfs_err(fs_info, + "superblock fsid doesn't match fsid of fs_devices: %pU != %pU", + fs_info->super_copy->fsid, fs_info->fs_devices->fsid); + ret = -EINVAL; + } + + if (btrfs_fs_incompat(fs_info, METADATA_UUID) && + memcmp(fs_info->fs_devices->metadata_uuid, + fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) { + btrfs_err(fs_info, +"superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU", + fs_info->super_copy->metadata_uuid, + fs_info->fs_devices->metadata_uuid); + ret = -EINVAL; + } + if (memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid, BTRFS_FSID_SIZE) != 0) { btrfs_err(fs_info, @@ -3185,14 +3203,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device disk_super = fs_info->super_copy; - ASSERT(!memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid, - BTRFS_FSID_SIZE)); - - if (btrfs_fs_incompat(fs_info, METADATA_UUID)) { - ASSERT(!memcmp(fs_info->fs_devices->metadata_uuid, - fs_info->super_copy->metadata_uuid, - BTRFS_FSID_SIZE)); - } features = btrfs_super_flags(disk_super); if (features & BTRFS_SUPER_FLAG_CHANGING_FSID_V2) { diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index abee4b62741da..f21d98c738785 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1094,7 +1094,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, int del_nr = 0; int del_slot = 0; int recow; - int ret; + int ret = 0; u64 ino = btrfs_ino(inode); path = btrfs_alloc_path(); @@ -1315,7 +1315,7 @@ again: } out: btrfs_free_path(path); - return 0; + return ret; } /* diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index faae6ebd8a279..276b5511ff809 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3302,6 +3302,22 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, * begins and releases it only after writing its superblock. */ mutex_lock(&fs_info->tree_log_mutex); + + /* + * The previous transaction writeout phase could have failed, and thus + * marked the fs in an error state. We must not commit here, as we + * could have updated our generation in the super_for_commit and + * writing the super here would result in transid mismatches. If there + * is an error here just bail. + */ + if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { + ret = -EIO; + btrfs_set_log_full_commit(trans); + btrfs_abort_transaction(trans, ret); + mutex_unlock(&fs_info->tree_log_mutex); + goto out_wake_log_root; + } + btrfs_set_super_log_root(fs_info->super_for_commit, log_root_start); btrfs_set_super_log_root_level(fs_info->super_for_commit, log_root_level); ret = write_all_supers(fs_info, 1); diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index 304ce64c70a44..cfff29718b840 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -150,6 +150,18 @@ static inline u32 sb_zone_number(int shift, int mirror) return (u32)zone; } +static inline sector_t zone_start_sector(u32 zone_number, + struct block_device *bdev) +{ + return (sector_t)zone_number << ilog2(bdev_zone_sectors(bdev)); +} + +static inline u64 zone_start_physical(u32 zone_number, + struct btrfs_zoned_device_info *zone_info) +{ + return (u64)zone_number << zone_info->zone_size_shift; +} + /* * Emulate blkdev_report_zones() for a non-zoned device. It slices up the block * device into static sized chunks and fake a conventional zone on each of @@ -405,8 +417,8 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device) if (sb_zone + 1 >= zone_info->nr_zones) continue; - sector = sb_zone << (zone_info->zone_size_shift - SECTOR_SHIFT); - ret = btrfs_get_dev_zones(device, sector << SECTOR_SHIFT, + ret = btrfs_get_dev_zones(device, + zone_start_physical(sb_zone, zone_info), &zone_info->sb_zones[sb_pos], &nr_zones); if (ret) @@ -721,7 +733,7 @@ int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw, if (sb_zone + 1 >= nr_zones) return -ENOENT; - ret = blkdev_report_zones(bdev, sb_zone << zone_sectors_shift, + ret = blkdev_report_zones(bdev, zone_start_sector(sb_zone, bdev), BTRFS_NR_SB_LOG_ZONES, copy_zone_info_cb, zones); if (ret < 0) @@ -826,7 +838,7 @@ int btrfs_reset_sb_log_zones(struct block_device *bdev, int mirror) return -ENOENT; return blkdev_zone_mgmt(bdev, REQ_OP_ZONE_RESET, - sb_zone << zone_sectors_shift, + zone_start_sector(sb_zone, bdev), zone_sectors * BTRFS_NR_SB_LOG_ZONES, GFP_NOFS); } @@ -878,7 +890,8 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start, if (!(end <= sb_zone || sb_zone + BTRFS_NR_SB_LOG_ZONES <= begin)) { have_sb = true; - pos = ((u64)sb_zone + BTRFS_NR_SB_LOG_ZONES) << shift; + pos = zone_start_physical( + sb_zone + BTRFS_NR_SB_LOG_ZONES, zinfo); break; } diff --git a/fs/coredump.c b/fs/coredump.c index 1c0fdc1aa70b4..f559dc5b326ae 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -519,7 +519,7 @@ static bool dump_interrupted(void) * but then we need to teach dump_write() to restart and clear * TIF_SIGPENDING. */ - return signal_pending(current); + return fatal_signal_pending(current) || freezing(current); } static void wait_for_dump_helpers(struct file *file) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index ff5c4d0d6d131..686b211342a87 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -406,7 +406,7 @@ struct nfs_client *nfs_get_client(const struct nfs_client_initdata *cl_init) if (cl_init->hostname == NULL) { WARN_ON(1); - return NULL; + return ERR_PTR(-EINVAL); } /* see if the client already exists */ diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 065cb04222a1b..543d916f79abb 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -205,6 +205,7 @@ struct nfs4_exception { struct inode *inode; nfs4_stateid *stateid; long timeout; + unsigned char task_is_privileged : 1; unsigned char delay : 1, recovering : 1, retry : 1; diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 889a9f4c0310d..42719384e25fe 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -435,8 +435,8 @@ struct nfs_client *nfs4_init_client(struct nfs_client *clp, */ nfs_mark_client_ready(clp, -EPERM); } - nfs_put_client(clp); clear_bit(NFS_CS_TSM_POSSIBLE, &clp->cl_flags); + nfs_put_client(clp); return old; error: diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0b809cc6ad1df..64153ef18dd08 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -590,6 +590,8 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_ goto out_retry; } if (exception->recovering) { + if (exception->task_is_privileged) + return -EDEADLOCK; ret = nfs4_wait_clnt_recover(clp); if (test_bit(NFS_MIG_FAILED, &server->mig_status)) return -EIO; @@ -615,6 +617,8 @@ nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server, goto out_retry; } if (exception->recovering) { + if (exception->task_is_privileged) + return -EDEADLOCK; rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); @@ -5940,6 +5944,14 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen do { err = __nfs4_proc_set_acl(inode, buf, buflen); trace_nfs4_set_acl(inode, err); + if (err == -NFS4ERR_BADOWNER || err == -NFS4ERR_BADNAME) { + /* + * no need to retry since the kernel + * isn't involved in encoding the ACEs. + */ + err = -EINVAL; + break; + } err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); } while (exception.retry); @@ -6381,6 +6393,7 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) struct nfs4_exception exception = { .inode = data->inode, .stateid = &data->stateid, + .task_is_privileged = data->args.seq_args.sa_privileged, }; if (!nfs4_sequence_done(task, &data->res.seq_res)) @@ -6504,7 +6517,6 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, data = kzalloc(sizeof(*data), GFP_NOFS); if (data == NULL) return -ENOMEM; - nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, 0); nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP, @@ -6535,6 +6547,12 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, } } + if (!data->inode) + nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, + 1); + else + nfs4_init_sequence(&data->args.seq_args, &data->res.seq_res, 1, + 0); task_setup_data.callback_data = data; msg.rpc_argp = &data->args; msg.rpc_resp = &data->res; @@ -9620,15 +9638,20 @@ int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync) &task_setup_data.rpc_client, &msg); dprintk("--> %s\n", __func__); + lrp->inode = nfs_igrab_and_active(lrp->args.inode); if (!sync) { - lrp->inode = nfs_igrab_and_active(lrp->args.inode); if (!lrp->inode) { nfs4_layoutreturn_release(lrp); return -EAGAIN; } task_setup_data.flags |= RPC_TASK_ASYNC; } - nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1, 0); + if (!lrp->inode) + nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1, + 1); + else + nfs4_init_sequence(&lrp->args.seq_args, &lrp->res.seq_res, 1, + 0); task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) return PTR_ERR(task); diff --git a/fs/proc/base.c b/fs/proc/base.c index 58bbf334265b7..9cbd915025ad7 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2674,6 +2674,13 @@ out: } #ifdef CONFIG_SECURITY +static int proc_pid_attr_open(struct inode *inode, struct file *file) +{ + file->private_data = NULL; + __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS); + return 0; +} + static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -2704,7 +2711,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, int rv; /* A task may only write when it was the opener. */ - if (file->f_cred != current_real_cred()) + if (file->private_data != current->mm) return -EPERM; rcu_read_lock(); @@ -2754,9 +2761,11 @@ out: } static const struct file_operations proc_pid_attr_operations = { + .open = proc_pid_attr_open, .read = proc_pid_attr_read, .write = proc_pid_attr_write, .llseek = generic_file_llseek, + .release = mem_release, }; #define LSM_DIR_OPS(LSM) \ diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 0331d5d49551a..3c751cdd8594c 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -943,6 +943,7 @@ #ifdef CONFIG_AMD_MEM_ENCRYPT #define PERCPU_DECRYPTED_SECTION \ . = ALIGN(PAGE_SIZE); \ + *(.data..decrypted) \ *(.data..percpu..decrypted) \ . = ALIGN(PAGE_SIZE); #else diff --git a/include/dt-bindings/usb/pd.h b/include/dt-bindings/usb/pd.h index fef3ef65967fa..cb70b4ceeddef 100644 --- a/include/dt-bindings/usb/pd.h +++ b/include/dt-bindings/usb/pd.h @@ -163,10 +163,10 @@ #define UFP_VDO_VER1_2 2 /* Device Capability */ -#define DEV_USB2_CAPABLE BIT(0) -#define DEV_USB2_BILLBOARD BIT(1) -#define DEV_USB3_CAPABLE BIT(2) -#define DEV_USB4_CAPABLE BIT(3) +#define DEV_USB2_CAPABLE (1 << 0) +#define DEV_USB2_BILLBOARD (1 << 1) +#define DEV_USB3_CAPABLE (1 << 2) +#define DEV_USB4_CAPABLE (1 << 3) /* Connector Type */ #define UFP_RECEPTACLE 2 @@ -191,9 +191,9 @@ /* Alternate Modes */ #define UFP_ALTMODE_NOT_SUPP 0 -#define UFP_ALTMODE_TBT3 BIT(0) -#define UFP_ALTMODE_RECFG BIT(1) -#define UFP_ALTMODE_NO_RECFG BIT(2) +#define UFP_ALTMODE_TBT3 (1 << 0) +#define UFP_ALTMODE_RECFG (1 << 1) +#define UFP_ALTMODE_NO_RECFG (1 << 2) /* USB Highest Speed */ #define UFP_USB2_ONLY 0 @@ -217,9 +217,9 @@ * <4:0> :: Port number */ #define DFP_VDO_VER1_1 1 -#define HOST_USB2_CAPABLE BIT(0) -#define HOST_USB3_CAPABLE BIT(1) -#define HOST_USB4_CAPABLE BIT(2) +#define HOST_USB2_CAPABLE (1 << 0) +#define HOST_USB3_CAPABLE (1 << 1) +#define HOST_USB4_CAPABLE (1 << 2) #define DFP_RECEPTACLE 2 #define DFP_CAPTIVE 3 diff --git a/include/linux/entry-kvm.h b/include/linux/entry-kvm.h index 8b2b1d68b9545..136b8d97d8c01 100644 --- a/include/linux/entry-kvm.h +++ b/include/linux/entry-kvm.h @@ -3,6 +3,7 @@ #define __LINUX_ENTRYKVM_H #include +#include /* Transfer to guest mode work */ #ifdef CONFIG_KVM_XFER_TO_GUEST_WORK @@ -57,7 +58,7 @@ int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu); static inline void xfer_to_guest_mode_prepare(void) { lockdep_assert_irqs_disabled(); - rcu_nocb_flush_deferred_wakeup(); + tick_nohz_user_enter_prepare(); } /** diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 99dccea4293c6..6e884bf58c0a9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1118,7 +1118,15 @@ __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn) static inline unsigned long __gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn) { - return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE; + /* + * The index was checked originally in search_memslots. To avoid + * that a malicious guest builds a Spectre gadget out of e.g. page + * table walks, do not let the processor speculate loads outside + * the guest's registered memslots. + */ + unsigned long offset = gfn - slot->base_gfn; + offset = array_index_nospec(offset, slot->npages); + return slot->userspace_addr + offset * PAGE_SIZE; } static inline int memslot_id(struct kvm *kvm, gfn_t gfn) diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h index 017a4c01cb315..61f0974c33d72 100644 --- a/include/linux/mfd/rohm-bd71828.h +++ b/include/linux/mfd/rohm-bd71828.h @@ -26,11 +26,11 @@ enum { BD71828_REGULATOR_AMOUNT, }; -#define BD71828_BUCK1267_VOLTS 0xEF -#define BD71828_BUCK3_VOLTS 0x10 -#define BD71828_BUCK4_VOLTS 0x20 -#define BD71828_BUCK5_VOLTS 0x10 -#define BD71828_LDO_VOLTS 0x32 +#define BD71828_BUCK1267_VOLTS 0x100 +#define BD71828_BUCK3_VOLTS 0x20 +#define BD71828_BUCK4_VOLTS 0x40 +#define BD71828_BUCK5_VOLTS 0x20 +#define BD71828_LDO_VOLTS 0x40 /* LDO6 is fixed 1.8V voltage */ #define BD71828_LDO_6_VOLTAGE 1800000 diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 236a7d04f891e..30bb59fe970cb 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -630,6 +630,7 @@ struct mlx4_caps { bool wol_port[MLX4_MAX_PORTS + 1]; struct mlx4_rate_limit_caps rl_caps; u32 health_buffer_addrs; + bool map_clock_to_user; }; struct mlx4_buf_list { diff --git a/include/linux/rtsx_pci.h b/include/linux/rtsx_pci.h index 6f155f99aa160..4ab7bfc675f11 100644 --- a/include/linux/rtsx_pci.h +++ b/include/linux/rtsx_pci.h @@ -1109,6 +1109,7 @@ struct pcr_ops { }; enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN}; +enum ASPM_MODE {ASPM_MODE_CFG, ASPM_MODE_REG}; #define ASPM_L1_1_EN BIT(0) #define ASPM_L1_2_EN BIT(1) @@ -1234,6 +1235,7 @@ struct rtsx_pcr { u8 card_drive_sel; #define ASPM_L1_EN 0x02 u8 aspm_en; + enum ASPM_MODE aspm_mode; bool aspm_enabled; #define PCR_MS_PMOS (1 << 0) diff --git a/include/linux/sched.h b/include/linux/sched.h index ef00bb22164cd..edc01bcefbfd8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -350,11 +350,19 @@ struct load_weight { * Only for tasks we track a moving average of the past instantaneous * estimated utilization. This allows to absorb sporadic drops in utilization * of an otherwise almost periodic task. + * + * The UTIL_AVG_UNCHANGED flag is used to synchronize util_est with util_avg + * updates. When a task is dequeued, its util_est should not be updated if its + * util_avg has not been updated in the meantime. + * This information is mapped into the MSB bit of util_est.enqueued at dequeue + * time. Since max value of util_est.enqueued for a task is 1024 (PELT util_avg + * for a task) it is safe to use MSB. */ struct util_est { unsigned int enqueued; unsigned int ewma; #define UTIL_EST_WEIGHT_SHIFT 2 +#define UTIL_AVG_UNCHANGED 0x80000000 } __attribute__((__aligned__(sizeof(u64)))); /* diff --git a/include/linux/tick.h b/include/linux/tick.h index 7340613c7eff7..1a0ff88fa107b 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -11,6 +11,7 @@ #include #include #include +#include #ifdef CONFIG_GENERIC_CLOCKEVENTS extern void __init tick_init(void); @@ -300,4 +301,10 @@ static inline void tick_nohz_task_switch(void) __tick_nohz_task_switch(); } +static inline void tick_nohz_user_enter_prepare(void) +{ + if (tick_nohz_full_cpu(smp_processor_id())) + rcu_nocb_flush_deferred_wakeup(); +} + #endif diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index bf00259493e07..96b7ff66f074b 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -460,7 +460,7 @@ static inline unsigned int rdo_max_power(u32 rdo) #define PD_T_RECEIVER_RESPONSE 15 /* 15ms max */ #define PD_T_SOURCE_ACTIVITY 45 #define PD_T_SINK_ACTIVITY 135 -#define PD_T_SINK_WAIT_CAP 240 +#define PD_T_SINK_WAIT_CAP 310 /* 310 - 620 ms */ #define PD_T_PS_TRANSITION 500 #define PD_T_SRC_TRANSITION 35 #define PD_T_DRP_SNK 40 diff --git a/include/linux/usb/pd_ext_sdb.h b/include/linux/usb/pd_ext_sdb.h index 0eb83ce195970..b517ebc8f0ff2 100644 --- a/include/linux/usb/pd_ext_sdb.h +++ b/include/linux/usb/pd_ext_sdb.h @@ -24,8 +24,4 @@ enum usb_pd_ext_sdb_fields { #define USB_PD_EXT_SDB_EVENT_OVP BIT(3) #define USB_PD_EXT_SDB_EVENT_CF_CV_MODE BIT(4) -#define USB_PD_EXT_SDB_PPS_EVENTS (USB_PD_EXT_SDB_EVENT_OCP | \ - USB_PD_EXT_SDB_EVENT_OTP | \ - USB_PD_EXT_SDB_EVENT_OVP) - #endif /* __LINUX_USB_PD_EXT_SDB_H */ diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index b1a76fe046cba..6bd003568fa5c 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5126,6 +5126,12 @@ int btf_distill_func_proto(struct bpf_verifier_log *log, m->ret_size = ret; for (i = 0; i < nargs; i++) { + if (i == nargs - 1 && args[i].type == 0) { + bpf_log(log, + "The function %s with variable args is unsupported.\n", + tname); + return -EINVAL; + } ret = __get_type_size(btf, args[i].type, &t); if (ret < 0) { bpf_log(log, @@ -5133,6 +5139,12 @@ int btf_distill_func_proto(struct bpf_verifier_log *log, tname, i, btf_kind_str[BTF_INFO_KIND(t->info)]); return -EINVAL; } + if (ret == 0) { + bpf_log(log, + "The function %s has malformed void argument.\n", + tname); + return -EINVAL; + } m->arg_size[i] = ret; } m->nr_args = nargs; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index b186d852fe3df..9e600767803b5 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12556,6 +12556,17 @@ int bpf_check_attach_target(struct bpf_verifier_log *log, return 0; } +BTF_SET_START(btf_id_deny) +BTF_ID_UNUSED +#ifdef CONFIG_SMP +BTF_ID(func, migrate_disable) +BTF_ID(func, migrate_enable) +#endif +#if !defined CONFIG_PREEMPT_RCU && !defined CONFIG_TINY_RCU +BTF_ID(func, rcu_read_unlock_strict) +#endif +BTF_SET_END(btf_id_deny) + static int check_attach_btf_id(struct bpf_verifier_env *env) { struct bpf_prog *prog = env->prog; @@ -12615,6 +12626,9 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) ret = bpf_lsm_verify_prog(&env->log, prog); if (ret < 0) return ret; + } else if (prog->type == BPF_PROG_TYPE_TRACING && + btf_id_set_contains(&btf_id_deny, btf_id)) { + return -EINVAL; } key = bpf_trampoline_compute_key(tgt_prog, prog->aux->attach_btf, btf_id); diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index a5751784ad740..f6dddb3a8f4a2 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -820,6 +820,10 @@ static int cgroup1_rename(struct kernfs_node *kn, struct kernfs_node *new_parent struct cgroup *cgrp = kn->priv; int ret; + /* do not accept '\n' to prevent making /proc//cgroup unparsable */ + if (strchr(new_name_str, '\n')) + return -EINVAL; + if (kernfs_type(kn) != KERNFS_DIR) return -ENOTDIR; if (kn->parent != new_parent) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 9153b20e5cc65..2529d1f883305 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -5626,8 +5626,6 @@ int __init cgroup_init_early(void) return 0; } -static u16 cgroup_disable_mask __initdata; - /** * cgroup_init - cgroup initialization * @@ -5686,12 +5684,8 @@ int __init cgroup_init(void) * disabled flag and cftype registration needs kmalloc, * both of which aren't available during early_init. */ - if (cgroup_disable_mask & (1 << ssid)) { - static_branch_disable(cgroup_subsys_enabled_key[ssid]); - printk(KERN_INFO "Disabling %s control group subsystem\n", - ss->name); + if (!cgroup_ssid_enabled(ssid)) continue; - } if (cgroup1_ssid_disabled(ssid)) printk(KERN_INFO "Disabling %s control group subsystem in v1 mounts\n", @@ -6206,7 +6200,10 @@ static int __init cgroup_disable(char *str) if (strcmp(token, ss->name) && strcmp(token, ss->legacy_name)) continue; - cgroup_disable_mask |= 1 << i; + + static_branch_disable(cgroup_subsys_enabled_key[i]); + pr_info("Disabling %s control group subsystem\n", + ss->name); } } return 1; diff --git a/kernel/entry/common.c b/kernel/entry/common.c index 2003d69bd6d54..e9d21e939ec00 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "common.h" @@ -186,7 +187,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs, local_irq_disable_exit_to_user(); /* Check if any of the above work has queued a deferred wakeup */ - rcu_nocb_flush_deferred_wakeup(); + tick_nohz_user_enter_prepare(); ti_work = READ_ONCE(current_thread_info()->flags); } @@ -202,7 +203,7 @@ static void exit_to_user_mode_prepare(struct pt_regs *regs) lockdep_assert_irqs_disabled(); /* Flush pending rcuog wakeup before the last need_resched() check */ - rcu_nocb_flush_deferred_wakeup(); + tick_nohz_user_enter_prepare(); if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK)) ti_work = exit_to_user_mode_loop(regs, ti_work); diff --git a/kernel/events/core.c b/kernel/events/core.c index c24ea952e7ae4..67237fc439236 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4542,7 +4542,9 @@ find_get_context(struct pmu *pmu, struct task_struct *task, cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); ctx = &cpuctx->ctx; get_ctx(ctx); + raw_spin_lock_irqsave(&ctx->lock, flags); ++ctx->pin_count; + raw_spin_unlock_irqrestore(&ctx->lock, flags); return ctx; } diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 9c8b3ed2199a8..9e0a915e6eb83 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -888,6 +888,7 @@ __initcall(init_sched_debug_procfs); #define __PS(S, F) SEQ_printf(m, "%-45s:%21Ld\n", S, (long long)(F)) #define __P(F) __PS(#F, F) #define P(F) __PS(#F, p->F) +#define PM(F, M) __PS(#F, p->F & (M)) #define __PSN(S, F) SEQ_printf(m, "%-45s:%14Ld.%06ld\n", S, SPLIT_NS((long long)(F))) #define __PN(F) __PSN(#F, F) #define PN(F) __PSN(#F, p->F) @@ -1014,7 +1015,7 @@ void proc_sched_show_task(struct task_struct *p, struct pid_namespace *ns, P(se.avg.util_avg); P(se.avg.last_update_time); P(se.avg.util_est.ewma); - P(se.avg.util_est.enqueued); + PM(se.avg.util_est.enqueued, ~UTIL_AVG_UNCHANGED); #endif #ifdef CONFIG_UCLAMP_TASK __PS("uclamp.min", p->uclamp_req[UCLAMP_MIN].value); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index a073a839cd065..487312a5ceabb 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3494,10 +3494,9 @@ update_tg_cfs_runnable(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cf static inline void update_tg_cfs_load(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq *gcfs_rq) { - long delta_avg, running_sum, runnable_sum = gcfs_rq->prop_runnable_sum; + long delta, running_sum, runnable_sum = gcfs_rq->prop_runnable_sum; unsigned long load_avg; u64 load_sum = 0; - s64 delta_sum; u32 divider; if (!runnable_sum) @@ -3544,13 +3543,13 @@ update_tg_cfs_load(struct cfs_rq *cfs_rq, struct sched_entity *se, struct cfs_rq load_sum = (s64)se_weight(se) * runnable_sum; load_avg = div_s64(load_sum, divider); - delta_sum = load_sum - (s64)se_weight(se) * se->avg.load_sum; - delta_avg = load_avg - se->avg.load_avg; + delta = load_avg - se->avg.load_avg; se->avg.load_sum = runnable_sum; se->avg.load_avg = load_avg; - add_positive(&cfs_rq->avg.load_avg, delta_avg); - add_positive(&cfs_rq->avg.load_sum, delta_sum); + + add_positive(&cfs_rq->avg.load_avg, delta); + cfs_rq->avg.load_sum = cfs_rq->avg.load_avg * divider; } static inline void add_tg_cfs_propagate(struct cfs_rq *cfs_rq, long runnable_sum) @@ -3897,7 +3896,7 @@ static inline unsigned long _task_util_est(struct task_struct *p) { struct util_est ue = READ_ONCE(p->se.avg.util_est); - return (max(ue.ewma, ue.enqueued) | UTIL_AVG_UNCHANGED); + return max(ue.ewma, (ue.enqueued & ~UTIL_AVG_UNCHANGED)); } static inline unsigned long task_util_est(struct task_struct *p) @@ -3997,7 +3996,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq, * Reset EWMA on utilization increases, the moving average is used only * to smooth utilization decreases. */ - ue.enqueued = (task_util(p) | UTIL_AVG_UNCHANGED); + ue.enqueued = task_util(p); if (sched_feat(UTIL_EST_FASTUP)) { if (ue.ewma < ue.enqueued) { ue.ewma = ue.enqueued; @@ -4046,6 +4045,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq, ue.ewma += last_ewma_diff; ue.ewma >>= UTIL_EST_WEIGHT_SHIFT; done: + ue.enqueued |= UTIL_AVG_UNCHANGED; WRITE_ONCE(p->se.avg.util_est, ue); trace_sched_util_est_se_tp(&p->se); @@ -8006,7 +8006,7 @@ static bool __update_blocked_fair(struct rq *rq, bool *done) /* Propagate pending load changes to the parent, if any: */ se = cfs_rq->tg->se[cpu]; if (se && !skip_blocked_update(se)) - update_load_avg(cfs_rq_of(se), se, 0); + update_load_avg(cfs_rq_of(se), se, UPDATE_TG); /* * There can be a lot of idle CPU cgroups. Don't let fully diff --git a/kernel/sched/pelt.h b/kernel/sched/pelt.h index 795e43e02afc6..0b9aeebb9c325 100644 --- a/kernel/sched/pelt.h +++ b/kernel/sched/pelt.h @@ -42,15 +42,6 @@ static inline u32 get_pelt_divider(struct sched_avg *avg) return LOAD_AVG_MAX - 1024 + avg->period_contrib; } -/* - * When a task is dequeued, its estimated utilization should not be update if - * its util_avg has not been updated at least once. - * This flag is used to synchronize util_avg updates with util_est updates. - * We map this information into the LSB bit of the utilization saved at - * dequeue time (i.e. util_est.dequeued). - */ -#define UTIL_AVG_UNCHANGED 0x1 - static inline void cfs_se_util_change(struct sched_avg *avg) { unsigned int enqueued; @@ -58,7 +49,7 @@ static inline void cfs_se_util_change(struct sched_avg *avg) if (!sched_feat(UTIL_EST)) return; - /* Avoid store if the flag has been already set */ + /* Avoid store if the flag has been already reset */ enqueued = avg->util_est.enqueued; if (!(enqueued & UTIL_AVG_UNCHANGED)) return; diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index e10a4af887373..538c9b7ffaf14 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -230,6 +230,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs) #ifdef CONFIG_NO_HZ_FULL cpumask_var_t tick_nohz_full_mask; +EXPORT_SYMBOL_GPL(tick_nohz_full_mask); bool tick_nohz_full_running; EXPORT_SYMBOL_GPL(tick_nohz_full_running); static atomic_t tick_dep_mask; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 826b88b727a62..433a84d442eeb 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1967,12 +1967,18 @@ static int ftrace_hash_ipmodify_update(struct ftrace_ops *ops, static void print_ip_ins(const char *fmt, const unsigned char *p) { + char ins[MCOUNT_INSN_SIZE]; int i; + if (copy_from_kernel_nofault(ins, p, MCOUNT_INSN_SIZE)) { + printk(KERN_CONT "%s[FAULT] %px\n", fmt, p); + return; + } + printk(KERN_CONT "%s", fmt); for (i = 0; i < MCOUNT_INSN_SIZE; i++) - printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); + printk(KERN_CONT "%s%02x", i ? ":" : "", ins[i]); } enum ftrace_bug_type ftrace_bug_type; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 67c01dc5cdeb7..f2d4ee80feb34 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -2735,7 +2735,7 @@ trace_event_buffer_lock_reserve(struct trace_buffer **current_rb, (entry = this_cpu_read(trace_buffered_event))) { /* Try to use the per cpu buffer first */ val = this_cpu_inc_return(trace_buffered_event_cnt); - if ((len < (PAGE_SIZE - sizeof(*entry))) && val == 1) { + if ((len < (PAGE_SIZE - sizeof(*entry) - sizeof(entry->array[0]))) && val == 1) { trace_event_setup(entry, type, trace_ctx); entry->array[0] = len; return entry; diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 79f2319543ced..994eafd25d648 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "workqueue_internal.h" @@ -5772,6 +5773,7 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) { unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ; bool lockup_detected = false; + unsigned long now = jiffies; struct worker_pool *pool; int pi; @@ -5786,6 +5788,12 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) if (list_empty(&pool->worklist)) continue; + /* + * If a virtual machine is stopped by the host it can look to + * the watchdog like a stall. + */ + kvm_check_and_clear_guest_paused(); + /* get the latest of pool and touched timestamps */ if (pool->cpu >= 0) touched = READ_ONCE(per_cpu(wq_watchdog_touched_cpu, pool->cpu)); @@ -5799,12 +5807,12 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) ts = touched; /* did we stall? */ - if (time_after(jiffies, ts + thresh)) { + if (time_after(now, ts + thresh)) { lockup_detected = true; pr_emerg("BUG: workqueue lockup - pool"); pr_cont_pool_info(pool); pr_cont(" stuck for %us!\n", - jiffies_to_msecs(jiffies - pool_ts) / 1000); + jiffies_to_msecs(now - pool_ts) / 1000); } } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 3a62f97acf39d..6133e412b948c 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -461,11 +461,13 @@ void netlink_table_ungrab(void) static inline void netlink_lock_table(void) { + unsigned long flags; + /* read_lock() synchronizes us to netlink_table_grab */ - read_lock(&nl_table_lock); + read_lock_irqsave(&nl_table_lock, flags); atomic_inc(&nl_table_users); - read_unlock(&nl_table_lock); + read_unlock_irqrestore(&nl_table_lock, flags); } static inline void diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 9c7eb8455ba8e..5f1d438a0a23f 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -329,7 +329,7 @@ static int rawsock_create(struct net *net, struct socket *sock, return -ESOCKTNOSUPPORT; if (sock->type == SOCK_RAW) { - if (!capable(CAP_NET_RAW)) + if (!ns_capable(net->user_ns, CAP_NET_RAW)) return -EPERM; sock->ops = &rawsock_raw_ops; } else { diff --git a/net/rds/connection.c b/net/rds/connection.c index f2fcab182095c..a3bc4b54d4910 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -240,12 +240,23 @@ static struct rds_connection *__rds_conn_create(struct net *net, if (loop_trans) { rds_trans_put(loop_trans); conn->c_loopback = 1; - if (is_outgoing && trans->t_prefer_loopback) { - /* "outgoing" connection - and the transport - * says it wants the connection handled by the - * loopback transport. This is what TCP does. - */ - trans = &rds_loop_transport; + if (trans->t_prefer_loopback) { + if (likely(is_outgoing)) { + /* "outgoing" connection to local address. + * Protocol says it wants the connection + * handled by the loopback transport. + * This is what TCP does. + */ + trans = &rds_loop_transport; + } else { + /* No transport currently in use + * should end up here, but if it + * does, reset/destroy the connection. + */ + kmem_cache_free(rds_conn_slab, conn); + conn = ERR_PTR(-EOPNOTSUPP); + goto out; + } } } diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 43db0eca911fa..abf19c0e3ba0b 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -313,8 +313,8 @@ out: } #endif -static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr, - __u32 scope_id) +int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr, + __u32 scope_id) { struct net_device *dev = NULL; #if IS_ENABLED(CONFIG_IPV6) diff --git a/net/rds/tcp.h b/net/rds/tcp.h index bad9cf49d5657..dc8d745d68575 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -59,7 +59,8 @@ u32 rds_tcp_snd_una(struct rds_tcp_connection *tc); u64 rds_tcp_map_seq(struct rds_tcp_connection *tc, u32 seq); extern struct rds_transport rds_tcp_transport; void rds_tcp_accept_work(struct sock *sk); - +int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr, + __u32 scope_id); /* tcp_connect.c */ int rds_tcp_conn_path_connect(struct rds_conn_path *cp); void rds_tcp_conn_path_shutdown(struct rds_conn_path *conn); diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 101cf14215a0b..09cadd556d1e1 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -167,6 +167,12 @@ int rds_tcp_accept_one(struct socket *sock) } #endif + if (!rds_tcp_laddr_check(sock_net(sock->sk), peer_addr, dev_if)) { + /* local address connection is only allowed via loopback */ + ret = -EOPNOTSUPP; + goto out; + } + conn = rds_conn_create(sock_net(sock->sk), my_addr, peer_addr, &rds_tcp_transport, 0, GFP_KERNEL, dev_if); diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index 1645e4142e302..9863be6fd43e1 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -297,8 +297,16 @@ int snd_seq_timer_open(struct snd_seq_queue *q) return err; } spin_lock_irq(&tmr->lock); - tmr->timeri = t; + if (tmr->timeri) + err = -EBUSY; + else + tmr->timeri = t; spin_unlock_irq(&tmr->lock); + if (err < 0) { + snd_timer_close(t); + snd_timer_instance_free(t); + return err; + } return 0; } diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index e0faa6601966c..5805c5de39fbf 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -804,7 +804,7 @@ static void generate_pkt_descs(struct amdtp_stream *s, struct pkt_desc *descs, static inline void cancel_stream(struct amdtp_stream *s) { s->packet_index = -1; - if (current_work() == &s->period_work) + if (in_interrupt()) amdtp_stream_pcm_abort(s); WRITE_ONCE(s->pcm_buffer_pointer, SNDRV_PCM_POS_XRUN); } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cc13a68197f3c..e46e43dac6bfd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6560,6 +6560,7 @@ enum { ALC285_FIXUP_HP_SPECTRE_X360, ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, ALC623_FIXUP_LENOVO_THINKSTATION_P340, + ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, }; static const struct hda_fixup alc269_fixups[] = { @@ -8132,6 +8133,15 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC283_FIXUP_HEADSET_MIC, }, + [ALC255_FIXUP_ACER_HEADPHONE_AND_MIC] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x21, 0x03211030 }, /* Change the Headphone location to Left */ + { } + }, + .chained = true, + .chain_id = ALC255_FIXUP_XIAOMI_HEADSET_MIC + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -8168,6 +8178,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x132a, "Acer TravelMate B114-21", ALC233_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1330, "Acer TravelMate X514-51T", ALC255_FIXUP_ACER_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), SND_PCI_QUIRK(0x1028, 0x05bd, "Dell Latitude E6440", ALC292_FIXUP_DELL_E7X), @@ -8296,6 +8307,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8519, "HP Spectre x360 15-df0xxx", ALC285_FIXUP_HP_SPECTRE_X360), SND_PCI_QUIRK(0x103c, 0x869d, "HP", ALC236_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO), + SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8729, "HP", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8730, "HP ProBook 445 G7", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), @@ -8314,10 +8327,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x884c, "HP EliteBook 840 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x886d, "HP ZBook Fury 17.3 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8870, "HP ZBook Fury 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8873, "HP ZBook Studio 15.6 Inch G8 Mobile Workstation PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), + SND_PCI_QUIRK(0x103c, 0x888d, "HP ZBook Power 15.6 inch G8 Mobile Workstation PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8896, "HP EliteBook 855 G8 Notebook PC", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), @@ -8722,6 +8737,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC285_FIXUP_HP_SPECTRE_X360, .name = "alc285-hp-spectre-x360"}, {.id = ALC287_FIXUP_IDEAPAD_BASS_SPK_AMP, .name = "alc287-ideapad-bass-spk-amp"}, {.id = ALC623_FIXUP_LENOVO_THINKSTATION_P340, .name = "alc623-lenovo-thinkstation-p340"}, + {.id = ALC255_FIXUP_ACER_HEADPHONE_AND_MIC, .name = "alc255-acer-headphone-and-mic"}, {} }; #define ALC225_STANDARD_PINS \ diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index 417cda24030cd..2447a1e6e913f 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -237,10 +237,6 @@ static int acp3x_dma_open(struct snd_soc_component *component, return ret; } - if (!adata->play_stream && !adata->capture_stream && - !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) - rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); - i2s_data->acp3x_base = adata->acp3x_base; runtime->private_data = i2s_data; return ret; @@ -367,12 +363,6 @@ static int acp3x_dma_close(struct snd_soc_component *component, } } - /* Disable ACP irq, when the current stream is being closed and - * another stream is also not active. - */ - if (!adata->play_stream && !adata->capture_stream && - !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream) - rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); return 0; } diff --git a/sound/soc/amd/raven/acp3x.h b/sound/soc/amd/raven/acp3x.h index 03fe93913e12e..c3f0c8b7545db 100644 --- a/sound/soc/amd/raven/acp3x.h +++ b/sound/soc/amd/raven/acp3x.h @@ -77,6 +77,7 @@ #define ACP_POWER_OFF_IN_PROGRESS 0x03 #define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38 +#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF struct acp3x_platform_info { u16 play_i2s_instance; diff --git a/sound/soc/amd/raven/pci-acp3x.c b/sound/soc/amd/raven/pci-acp3x.c index d3536fd6a1240..a013a607b3d47 100644 --- a/sound/soc/amd/raven/pci-acp3x.c +++ b/sound/soc/amd/raven/pci-acp3x.c @@ -76,6 +76,19 @@ static int acp3x_reset(void __iomem *acp3x_base) return -ETIMEDOUT; } +static void acp3x_enable_interrupts(void __iomem *acp_base) +{ + rv_writel(0x01, acp_base + mmACP_EXTERNAL_INTR_ENB); +} + +static void acp3x_disable_interrupts(void __iomem *acp_base) +{ + rv_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base + + mmACP_EXTERNAL_INTR_STAT); + rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_CNTL); + rv_writel(0x00, acp_base + mmACP_EXTERNAL_INTR_ENB); +} + static int acp3x_init(struct acp3x_dev_data *adata) { void __iomem *acp3x_base = adata->acp3x_base; @@ -93,6 +106,7 @@ static int acp3x_init(struct acp3x_dev_data *adata) pr_err("ACP3x reset failed\n"); return ret; } + acp3x_enable_interrupts(acp3x_base); return 0; } @@ -100,6 +114,7 @@ static int acp3x_deinit(void __iomem *acp3x_base) { int ret; + acp3x_disable_interrupts(acp3x_base); /* Reset */ ret = acp3x_reset(acp3x_base); if (ret) { diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 7878da89d8e09..b7b9c891e2f04 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -3581,6 +3581,7 @@ static const struct of_device_id rx_macro_dt_match[] = { { .compatible = "qcom,sm8250-lpass-rx-macro" }, { } }; +MODULE_DEVICE_TABLE(of, rx_macro_dt_match); static struct platform_driver rx_macro_driver = { .driver = { diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index e8c6c738bbaa0..5341ca02951c6 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -1846,6 +1846,7 @@ static const struct of_device_id tx_macro_dt_match[] = { { .compatible = "qcom,sm8250-lpass-tx-macro" }, { } }; +MODULE_DEVICE_TABLE(of, tx_macro_dt_match); static struct platform_driver tx_macro_driver = { .driver = { .name = "tx_macro", diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 4be24e7f51c89..f8e49e45ce33f 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -41,6 +41,7 @@ struct max98088_priv { enum max98088_type devtype; struct max98088_pdata *pdata; struct clk *mclk; + unsigned char mclk_prescaler; unsigned int sysclk; struct max98088_cdata dai[2]; int eq_textcnt; @@ -998,13 +999,16 @@ static int max98088_dai1_hw_params(struct snd_pcm_substream *substream, /* Configure NI when operating as master */ if (snd_soc_component_read(component, M98088_REG_14_DAI1_FORMAT) & M98088_DAI_MAS) { + unsigned long pclk; + if (max98088->sysclk == 0) { dev_err(component->dev, "Invalid system clock frequency\n"); return -EINVAL; } ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) * (unsigned long long int)rate; - do_div(ni, (unsigned long long int)max98088->sysclk); + pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler); + ni = DIV_ROUND_CLOSEST_ULL(ni, pclk); snd_soc_component_write(component, M98088_REG_12_DAI1_CLKCFG_HI, (ni >> 8) & 0x7F); snd_soc_component_write(component, M98088_REG_13_DAI1_CLKCFG_LO, @@ -1065,13 +1069,16 @@ static int max98088_dai2_hw_params(struct snd_pcm_substream *substream, /* Configure NI when operating as master */ if (snd_soc_component_read(component, M98088_REG_1C_DAI2_FORMAT) & M98088_DAI_MAS) { + unsigned long pclk; + if (max98088->sysclk == 0) { dev_err(component->dev, "Invalid system clock frequency\n"); return -EINVAL; } ni = 65536ULL * (rate < 50000 ? 96ULL : 48ULL) * (unsigned long long int)rate; - do_div(ni, (unsigned long long int)max98088->sysclk); + pclk = DIV_ROUND_CLOSEST(max98088->sysclk, max98088->mclk_prescaler); + ni = DIV_ROUND_CLOSEST_ULL(ni, pclk); snd_soc_component_write(component, M98088_REG_1A_DAI2_CLKCFG_HI, (ni >> 8) & 0x7F); snd_soc_component_write(component, M98088_REG_1B_DAI2_CLKCFG_LO, @@ -1113,8 +1120,10 @@ static int max98088_dai_set_sysclk(struct snd_soc_dai *dai, */ if ((freq >= 10000000) && (freq < 20000000)) { snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x10); + max98088->mclk_prescaler = 1; } else if ((freq >= 20000000) && (freq < 30000000)) { snd_soc_component_write(component, M98088_REG_10_SYS_CLK, 0x20); + max98088->mclk_prescaler = 2; } else { dev_err(component->dev, "Invalid master clock frequency\n"); return -EINVAL; diff --git a/sound/soc/codecs/sti-sas.c b/sound/soc/codecs/sti-sas.c index ec9933b054ad3..423daac9d5a9f 100644 --- a/sound/soc/codecs/sti-sas.c +++ b/sound/soc/codecs/sti-sas.c @@ -411,6 +411,7 @@ static const struct of_device_id sti_sas_dev_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, sti_sas_dev_match); static int sti_sas_driver_probe(struct platform_device *pdev) { diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 22912cab5e638..cc24e89a7f8d7 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -574,6 +574,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { /* Glavey TM800A550L */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are too generic, also match on BIOS version */ + DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), + }, + .driver_data = (void *)(BYTCR_INPUT_DEFAULTS | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), @@ -652,6 +663,20 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_MONO_SPEAKER | BYT_RT5640_MCLK_EN), }, + { /* Lenovo Miix 3-830 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 3-830"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_MONO_SPEAKER | + BYT_RT5640_DIFF_MIC | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { /* Linx Linx7 tablet */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"), diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 0cffc9527e289..6680c12716d44 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2223,6 +2223,8 @@ static char *fmt_single_name(struct device *dev, int *id) return NULL; name = devm_kstrdup(dev, devname, GFP_KERNEL); + if (!name) + return NULL; /* are we a "%s.%d" name (platform and SPI components) */ found = strstr(name, dev->driver->name); diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index fd265803f7bc7..c83fb62559616 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -256,6 +256,7 @@ suspend: /* reset FW state */ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED; + sdev->enabled_cores_mask = 0; return ret; } diff --git a/tools/bootconfig/include/linux/bootconfig.h b/tools/bootconfig/include/linux/bootconfig.h index 078cbd2ba651d..de7f30f99af38 100644 --- a/tools/bootconfig/include/linux/bootconfig.h +++ b/tools/bootconfig/include/linux/bootconfig.h @@ -4,4 +4,8 @@ #include "../../../../include/linux/bootconfig.h" +#ifndef fallthrough +# define fallthrough +#endif + #endif diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c index 7362bef1a3683..6cd6080cac04c 100644 --- a/tools/bootconfig/main.c +++ b/tools/bootconfig/main.c @@ -399,6 +399,7 @@ static int apply_xbc(const char *path, const char *xbc_path) } /* TODO: Ensure the @path is initramfs/initrd image */ if (fstat(fd, &stat) < 0) { + ret = -errno; pr_err("Failed to get the size of %s\n", path); goto out; } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index e9d4e6f4bdf3e..b7cfdbf207b70 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1710,6 +1710,7 @@ int perf_session__peek_event(struct perf_session *session, off_t file_offset, if (event->header.size < hdr_sz || event->header.size > buf_sz) return -1; + buf += hdr_sz; rest = event->header.size - hdr_sz; if (readn(fd, buf, rest) != (ssize_t)rest) diff --git a/tools/testing/selftests/bpf/verifier/stack_ptr.c b/tools/testing/selftests/bpf/verifier/stack_ptr.c index 07eaa04412ae4..8ab94d65f3d54 100644 --- a/tools/testing/selftests/bpf/verifier/stack_ptr.c +++ b/tools/testing/selftests/bpf/verifier/stack_ptr.c @@ -295,8 +295,6 @@ BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), BPF_EXIT_INSN(), }, - .result_unpriv = REJECT, - .errstr_unpriv = "invalid write to stack R1 off=0 size=1", .result = ACCEPT, .retval = 42, }, diff --git a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c index e5913fd3b9030..7ae2859d495c5 100644 --- a/tools/testing/selftests/bpf/verifier/value_ptr_arith.c +++ b/tools/testing/selftests/bpf/verifier/value_ptr_arith.c @@ -300,8 +300,6 @@ }, .fixup_map_array_48b = { 3 }, .result = ACCEPT, - .result_unpriv = REJECT, - .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", .retval = 1, }, { @@ -371,8 +369,6 @@ }, .fixup_map_array_48b = { 3 }, .result = ACCEPT, - .result_unpriv = REJECT, - .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", .retval = 1, }, { @@ -472,8 +468,6 @@ }, .fixup_map_array_48b = { 3 }, .result = ACCEPT, - .result_unpriv = REJECT, - .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", .retval = 1, }, { @@ -766,8 +760,6 @@ }, .fixup_map_array_48b = { 3 }, .result = ACCEPT, - .result_unpriv = REJECT, - .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", .retval = 1, }, {