Merge tag 'iommu-fixes-v5.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2020 20:41:33 +0000 (13:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 29 May 2020 20:41:33 +0000 (13:41 -0700)
Pull iommu fixes from Joerg Roedel:

 - Two build fixes for issues introduced during the merge window

 - A fix for a reference count leak in an error path of
   iommu_group_alloc()

* tag 'iommu-fixes-v5.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu: Fix reference count leak in iommu_group_alloc.
  x86: Hide the archdata.iommu field behind generic IOMMU_API
  ia64: Hide the archdata.iommu field behind generic IOMMU_API

61 files changed:
arch/arm/boot/compressed/vmlinux.lds.S
arch/arm/include/asm/assembler.h
arch/arm/include/asm/uaccess-asm.h [new file with mode: 0644]
arch/arm/kernel/atags_proc.c
arch/arm/kernel/entry-armv.S
arch/arm/kernel/entry-header.S
arch/arm/kernel/ptrace.c
arch/csky/abiv1/inc/abi/entry.h
arch/csky/abiv2/inc/abi/entry.h
arch/csky/include/asm/thread_info.h
arch/csky/kernel/entry.S
block/blk-core.c
drivers/clk/qcom/Kconfig
drivers/clk/qcom/gcc-sm8150.c
drivers/gpu/drm/amd/amdkfd/kfd_priv.h
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/ingenic/ingenic-drm.c
drivers/infiniband/core/rdma_core.c
drivers/infiniband/hw/mlx5/mr.c
drivers/infiniband/hw/qib/qib_sysfs.c
drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_ib.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/input/evdev.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/applespi.c
drivers/input/keyboard/cros_ec_keyb.c
drivers/input/keyboard/dlink-dir685-touchkeys.c
drivers/input/misc/axp20x-pek.c
drivers/input/mouse/synaptics.c
drivers/input/rmi4/rmi_driver.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/touchscreen/elants_i2c.c
drivers/input/touchscreen/mms114.c
drivers/input/touchscreen/usbtouchscreen.c
drivers/mmc/core/block.c
drivers/mmc/host/sdhci.c
drivers/nvme/host/pci.c
fs/binfmt_elf.c
fs/notify/fanotify/fanotify.c
fs/xattr.c
include/asm-generic/topology.h
include/linux/device_cgroup.h
include/linux/fanotify.h
include/linux/input/lm8333.h
include/linux/mm.h
include/rdma/uverbs_std_types.h
kernel/cgroup/rstat.c
mm/khugepaged.c
mm/z3fold.c
security/Makefile
security/commoncap.c
security/device_cgroup.c
sound/core/hwdep.c
sound/pci/hda/patch_realtek.c
sound/usb/mixer.c
sound/usb/mixer_maps.c
sound/usb/quirks-table.h

index b247f39..f82b596 100644 (file)
@@ -42,7 +42,7 @@ SECTIONS
   }
   .table : ALIGN(4) {
     _table_start = .;
-    LONG(ZIMAGE_MAGIC(2))
+    LONG(ZIMAGE_MAGIC(4))
     LONG(ZIMAGE_MAGIC(0x5a534c4b))
     LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start))
     LONG(ZIMAGE_MAGIC(_kernel_bss_size))
index 9992912..3546d29 100644 (file)
 #endif
 
 #include <asm/ptrace.h>
-#include <asm/domain.h>
 #include <asm/opcodes-virt.h>
 #include <asm/asm-offsets.h>
 #include <asm/page.h>
 #include <asm/thread_info.h>
+#include <asm/uaccess-asm.h>
 
 #define IOMEM(x)       (x)
 
@@ -446,79 +446,6 @@ THUMB(     orr     \reg , \reg , #PSR_T_BIT        )
        .size \name , . - \name
        .endm
 
-       .macro  csdb
-#ifdef CONFIG_THUMB2_KERNEL
-       .inst.w 0xf3af8014
-#else
-       .inst   0xe320f014
-#endif
-       .endm
-
-       .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
-#ifndef CONFIG_CPU_USE_DOMAINS
-       adds    \tmp, \addr, #\size - 1
-       sbcscc  \tmp, \tmp, \limit
-       bcs     \bad
-#ifdef CONFIG_CPU_SPECTRE
-       movcs   \addr, #0
-       csdb
-#endif
-#endif
-       .endm
-
-       .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
-#ifdef CONFIG_CPU_SPECTRE
-       sub     \tmp, \limit, #1
-       subs    \tmp, \tmp, \addr       @ tmp = limit - 1 - addr
-       addhs   \tmp, \tmp, #1          @ if (tmp >= 0) {
-       subshs  \tmp, \tmp, \size       @ tmp = limit - (addr + size) }
-       movlo   \addr, #0               @ if (tmp < 0) addr = NULL
-       csdb
-#endif
-       .endm
-
-       .macro  uaccess_disable, tmp, isb=1
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
-       /*
-        * Whenever we re-enter userspace, the domains should always be
-        * set appropriately.
-        */
-       mov     \tmp, #DACR_UACCESS_DISABLE
-       mcr     p15, 0, \tmp, c3, c0, 0         @ Set domain register
-       .if     \isb
-       instr_sync
-       .endif
-#endif
-       .endm
-
-       .macro  uaccess_enable, tmp, isb=1
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
-       /*
-        * Whenever we re-enter userspace, the domains should always be
-        * set appropriately.
-        */
-       mov     \tmp, #DACR_UACCESS_ENABLE
-       mcr     p15, 0, \tmp, c3, c0, 0
-       .if     \isb
-       instr_sync
-       .endif
-#endif
-       .endm
-
-       .macro  uaccess_save, tmp
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
-       mrc     p15, 0, \tmp, c3, c0, 0
-       str     \tmp, [sp, #SVC_DACR]
-#endif
-       .endm
-
-       .macro  uaccess_restore
-#ifdef CONFIG_CPU_SW_DOMAIN_PAN
-       ldr     r0, [sp, #SVC_DACR]
-       mcr     p15, 0, r0, c3, c0, 0
-#endif
-       .endm
-
        .irp    c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
        .macro  ret\c, reg
 #if __LINUX_ARM_ARCH__ < 6
diff --git a/arch/arm/include/asm/uaccess-asm.h b/arch/arm/include/asm/uaccess-asm.h
new file mode 100644 (file)
index 0000000..907571f
--- /dev/null
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ASM_UACCESS_ASM_H__
+#define __ASM_UACCESS_ASM_H__
+
+#include <asm/asm-offsets.h>
+#include <asm/domain.h>
+#include <asm/memory.h>
+#include <asm/thread_info.h>
+
+       .macro  csdb
+#ifdef CONFIG_THUMB2_KERNEL
+       .inst.w 0xf3af8014
+#else
+       .inst   0xe320f014
+#endif
+       .endm
+
+       .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
+#ifndef CONFIG_CPU_USE_DOMAINS
+       adds    \tmp, \addr, #\size - 1
+       sbcscc  \tmp, \tmp, \limit
+       bcs     \bad
+#ifdef CONFIG_CPU_SPECTRE
+       movcs   \addr, #0
+       csdb
+#endif
+#endif
+       .endm
+
+       .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req
+#ifdef CONFIG_CPU_SPECTRE
+       sub     \tmp, \limit, #1
+       subs    \tmp, \tmp, \addr       @ tmp = limit - 1 - addr
+       addhs   \tmp, \tmp, #1          @ if (tmp >= 0) {
+       subshs  \tmp, \tmp, \size       @ tmp = limit - (addr + size) }
+       movlo   \addr, #0               @ if (tmp < 0) addr = NULL
+       csdb
+#endif
+       .endm
+
+       .macro  uaccess_disable, tmp, isb=1
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+       /*
+        * Whenever we re-enter userspace, the domains should always be
+        * set appropriately.
+        */
+       mov     \tmp, #DACR_UACCESS_DISABLE
+       mcr     p15, 0, \tmp, c3, c0, 0         @ Set domain register
+       .if     \isb
+       instr_sync
+       .endif
+#endif
+       .endm
+
+       .macro  uaccess_enable, tmp, isb=1
+#ifdef CONFIG_CPU_SW_DOMAIN_PAN
+       /*
+        * Whenever we re-enter userspace, the domains should always be
+        * set appropriately.
+        */
+       mov     \tmp, #DACR_UACCESS_ENABLE
+       mcr     p15, 0, \tmp, c3, c0, 0
+       .if     \isb
+       instr_sync
+       .endif
+#endif
+       .endm
+
+#if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS)
+#define DACR(x...)     x
+#else
+#define DACR(x...)
+#endif
+
+       /*
+        * Save the address limit on entry to a privileged exception.
+        *
+        * If we are using the DACR for kernel access by the user accessors
+        * (CONFIG_CPU_USE_DOMAINS=y), always reset the DACR kernel domain
+        * back to client mode, whether or not \disable is set.
+        *
+        * If we are using SW PAN, set the DACR user domain to no access
+        * if \disable is set.
+        */
+       .macro  uaccess_entry, tsk, tmp0, tmp1, tmp2, disable
+       ldr     \tmp1, [\tsk, #TI_ADDR_LIMIT]
+       mov     \tmp2, #TASK_SIZE
+       str     \tmp2, [\tsk, #TI_ADDR_LIMIT]
+ DACR( mrc     p15, 0, \tmp0, c3, c0, 0)
+ DACR( str     \tmp0, [sp, #SVC_DACR])
+       str     \tmp1, [sp, #SVC_ADDR_LIMIT]
+       .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN)
+       /* kernel=client, user=no access */
+       mov     \tmp2, #DACR_UACCESS_DISABLE
+       mcr     p15, 0, \tmp2, c3, c0, 0
+       instr_sync
+       .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS)
+       /* kernel=client */
+       bic     \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL)
+       orr     \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT)
+       mcr     p15, 0, \tmp2, c3, c0, 0
+       instr_sync
+       .endif
+       .endm
+
+       /* Restore the user access state previously saved by uaccess_entry */
+       .macro  uaccess_exit, tsk, tmp0, tmp1
+       ldr     \tmp1, [sp, #SVC_ADDR_LIMIT]
+ DACR( ldr     \tmp0, [sp, #SVC_DACR])
+       str     \tmp1, [\tsk, #TI_ADDR_LIMIT]
+ DACR( mcr     p15, 0, \tmp0, c3, c0, 0)
+       .endm
+
+#undef DACR
+
+#endif /* __ASM_UACCESS_ASM_H__ */
index 4247ebf..3c2faf2 100644 (file)
@@ -42,7 +42,7 @@ static int __init init_atags_procfs(void)
        size_t size;
 
        if (tag->hdr.tag != ATAG_CORE) {
-               pr_info("No ATAGs?");
+               pr_info("No ATAGs?\n");
                return -EINVAL;
        }
 
index 77f5483..55a47df 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/unistd.h>
 #include <asm/tls.h>
 #include <asm/system_info.h>
+#include <asm/uaccess-asm.h>
 
 #include "entry-header.S"
 #include <asm/entry-macro-multi.S>
@@ -179,15 +180,7 @@ ENDPROC(__und_invalid)
        stmia   r7, {r2 - r6}
 
        get_thread_info tsk
-       ldr     r0, [tsk, #TI_ADDR_LIMIT]
-       mov     r1, #TASK_SIZE
-       str     r1, [tsk, #TI_ADDR_LIMIT]
-       str     r0, [sp, #SVC_ADDR_LIMIT]
-
-       uaccess_save r0
-       .if \uaccess
-       uaccess_disable r0
-       .endif
+       uaccess_entry tsk, r0, r1, r2, \uaccess
 
        .if \trace
 #ifdef CONFIG_TRACE_IRQFLAGS
index 32051ec..40db0f9 100644 (file)
@@ -6,6 +6,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/errno.h>
 #include <asm/thread_info.h>
+#include <asm/uaccess-asm.h>
 #include <asm/v7m.h>
 
 @ Bad Abort numbers
        blne    trace_hardirqs_off
 #endif
        .endif
-       ldr     r1, [sp, #SVC_ADDR_LIMIT]
-       uaccess_restore
-       str     r1, [tsk, #TI_ADDR_LIMIT]
+       uaccess_exit tsk, r0, r1
 
 #ifndef CONFIG_THUMB2_KERNEL
        @ ARM mode SVC restore
        @ on the stack remains correct).
        @
        .macro  svc_exit_via_fiq
-       ldr     r1, [sp, #SVC_ADDR_LIMIT]
-       uaccess_restore
-       str     r1, [tsk, #TI_ADDR_LIMIT]
+       uaccess_exit tsk, r0, r1
 #ifndef CONFIG_THUMB2_KERNEL
        @ ARM mode restore
        mov     r0, sp
index b606cde..4cc6a7e 100644 (file)
@@ -219,8 +219,8 @@ static struct undef_hook arm_break_hook = {
 };
 
 static struct undef_hook thumb_break_hook = {
-       .instr_mask     = 0xffff,
-       .instr_val      = 0xde01,
+       .instr_mask     = 0xffffffff,
+       .instr_val      = 0x0000de01,
        .cpsr_mask      = PSR_T_BIT,
        .cpsr_val       = PSR_T_BIT,
        .fn             = break_trap,
index 61d94ec..13c23e2 100644 (file)
@@ -80,7 +80,6 @@
 .endm
 
 .macro RESTORE_ALL
-       psrclr  ie
        ldw     lr, (sp, 4)
        ldw     a0, (sp, 8)
        mtcr    a0, epc
        movi    r6, 0
        cpwcr   r6, cpcr31
 .endm
-
-.macro ANDI_R3 rx, imm
-       lsri    \rx, 3
-       andi    \rx, (\imm >> 3)
-.endm
 #endif /* __ASM_CSKY_ENTRY_H */
index ab63c41..4fdd6c1 100644 (file)
@@ -13,6 +13,8 @@
 #define LSAVE_A1       28
 #define LSAVE_A2       32
 #define LSAVE_A3       36
+#define LSAVE_A4       40
+#define LSAVE_A5       44
 
 #define KSPTOUSP
 #define USPTOKSP
@@ -63,7 +65,6 @@
 .endm
 
 .macro RESTORE_ALL
-       psrclr  ie
        ldw     tls, (sp, 0)
        ldw     lr, (sp, 4)
        ldw     a0, (sp, 8)
        jmpi    3f /* jump to va */
 3:
 .endm
-
-.macro ANDI_R3 rx, imm
-       lsri    \rx, 3
-       andi    \rx, (\imm >> 3)
-.endm
 #endif /* __ASM_CSKY_ENTRY_H */
index 5c61e84..8980e4e 100644 (file)
@@ -81,4 +81,10 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_RESTORE_SIGMASK   (1 << TIF_RESTORE_SIGMASK)
 #define _TIF_SECCOMP           (1 << TIF_SECCOMP)
 
+#define _TIF_WORK_MASK         (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
+                                _TIF_NOTIFY_RESUME | _TIF_UPROBE)
+
+#define _TIF_SYSCALL_WORK      (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+                                _TIF_SYSCALL_TRACEPOINT)
+
 #endif /* _ASM_CSKY_THREAD_INFO_H */
index 3760397..f138003 100644 (file)
@@ -128,39 +128,41 @@ tlbop_end 1
 ENTRY(csky_systemcall)
        SAVE_ALL TRAP0_SIZE
        zero_fp
-#ifdef CONFIG_RSEQ_DEBUG
-       mov     a0, sp
-       jbsr    rseq_syscall
-#endif
        psrset  ee, ie
 
-       lrw     r11, __NR_syscalls
-       cmphs   syscallid, r11          /* Check nr of syscall */
-       bt      ret_from_exception
+       lrw     r9, __NR_syscalls
+       cmphs   syscallid, r          /* Check nr of syscall */
+       bt      1f
 
-       lrw     r13, sys_call_table
-       ixw     r13, syscallid
-       ldw     r11, (r13)
-       cmpnei  r11, 0
+       lrw     r9, sys_call_table
+       ixw     r9, syscallid
+       ldw     syscallid, (r9)
+       cmpnei  syscallid, 0
        bf      ret_from_exception
 
        mov     r9, sp
        bmaski  r10, THREAD_SHIFT
        andn    r9, r10
-       ldw     r12, (r9, TINFO_FLAGS)
-       ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
-       cmpnei  r12, 0
+       ldw     r10, (r9, TINFO_FLAGS)
+       lrw     r9, _TIF_SYSCALL_WORK
+       and     r10, r9
+       cmpnei  r10, 0
        bt      csky_syscall_trace
 #if defined(__CSKYABIV2__)
        subi    sp, 8
        stw     r5, (sp, 0x4)
        stw     r4, (sp, 0x0)
-       jsr     r11                      /* Do system call */
+       jsr     syscallid                      /* Do system call */
        addi    sp, 8
 #else
-       jsr     r11
+       jsr     syscallid
 #endif
        stw     a0, (sp, LSAVE_A0)      /* Save return value */
+1:
+#ifdef CONFIG_DEBUG_RSEQ
+       mov     a0, sp
+       jbsr    rseq_syscall
+#endif
        jmpi    ret_from_exception
 
 csky_syscall_trace:
@@ -173,18 +175,23 @@ csky_syscall_trace:
        ldw     a3, (sp, LSAVE_A3)
 #if defined(__CSKYABIV2__)
        subi    sp, 8
-       stw     r5, (sp, 0x4)
-       stw     r4, (sp, 0x0)
+       ldw     r9, (sp, LSAVE_A4)
+       stw     r9, (sp, 0x0)
+       ldw     r9, (sp, LSAVE_A5)
+       stw     r9, (sp, 0x4)
+       jsr     syscallid                     /* Do system call */
+       addi    sp, 8
 #else
        ldw     r6, (sp, LSAVE_A4)
        ldw     r7, (sp, LSAVE_A5)
-#endif
-       jsr     r11                     /* Do system call */
-#if defined(__CSKYABIV2__)
-       addi    sp, 8
+       jsr     syscallid                     /* Do system call */
 #endif
        stw     a0, (sp, LSAVE_A0)      /* Save return value */
 
+#ifdef CONFIG_DEBUG_RSEQ
+       mov     a0, sp
+       jbsr    rseq_syscall
+#endif
        mov     a0, sp                  /* right now, sp --> pt_regs */
        jbsr    syscall_trace_exit
        br      ret_from_exception
@@ -200,18 +207,20 @@ ENTRY(ret_from_fork)
        mov     r9, sp
        bmaski  r10, THREAD_SHIFT
        andn    r9, r10
-       ldw     r12, (r9, TINFO_FLAGS)
-       ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
-       cmpnei  r12, 0
+       ldw     r10, (r9, TINFO_FLAGS)
+       lrw     r9, _TIF_SYSCALL_WORK
+       and     r10, r9
+       cmpnei  r10, 0
        bf      ret_from_exception
        mov     a0, sp                  /* sp = pt_regs pointer */
        jbsr    syscall_trace_exit
 
 ret_from_exception:
-       ld      syscallid, (sp, LSAVE_PSR)
-       btsti   syscallid, 31
-       bt      1f
+       psrclr  ie
+       ld      r9, (sp, LSAVE_PSR)
+       btsti   r9, 31
 
+       bt      1f
        /*
         * Load address of current->thread_info, Then get address of task_struct
         * Get task_needreshed in task_struct
@@ -220,11 +229,24 @@ ret_from_exception:
        bmaski  r10, THREAD_SHIFT
        andn    r9, r10
 
-       ldw     r12, (r9, TINFO_FLAGS)
-       andi    r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | _TIF_UPROBE)
-       cmpnei  r12, 0
+       ldw     r10, (r9, TINFO_FLAGS)
+       lrw     r9, _TIF_WORK_MASK
+       and     r10, r9
+       cmpnei  r10, 0
        bt      exit_work
 1:
+#ifdef CONFIG_PREEMPTION
+       mov     r9, sp
+       bmaski  r10, THREAD_SHIFT
+       andn    r9, r10
+
+       ldw     r10, (r9, TINFO_PREEMPT)
+       cmpnei  r10, 0
+       bt      2f
+       jbsr    preempt_schedule_irq    /* irq en/disable is done inside */
+2:
+#endif
+
 #ifdef CONFIG_TRACE_IRQFLAGS
        ld      r10, (sp, LSAVE_PSR)
        btsti   r10, 6
@@ -235,14 +257,15 @@ ret_from_exception:
        RESTORE_ALL
 
 exit_work:
-       lrw     syscallid, ret_from_exception
-       mov     lr, syscallid
+       lrw     r9, ret_from_exception
+       mov     lr, r9
 
-       btsti   r12, TIF_NEED_RESCHED
+       btsti   r10, TIF_NEED_RESCHED
        bt      work_resched
 
+       psrset  ie
        mov     a0, sp
-       mov     a1, r12
+       mov     a1, r10
        jmpi    do_notify_resume
 
 work_resched:
@@ -291,34 +314,10 @@ ENTRY(csky_irq)
        jbsr    trace_hardirqs_off
 #endif
 
-#ifdef CONFIG_PREEMPTION
-       mov     r9, sp                  /* Get current stack  pointer */
-       bmaski  r10, THREAD_SHIFT
-       andn    r9, r10                 /* Get thread_info */
-
-       /*
-        * Get task_struct->stack.preempt_count for current,
-        * and increase 1.
-        */
-       ldw     r12, (r9, TINFO_PREEMPT)
-       addi    r12, 1
-       stw     r12, (r9, TINFO_PREEMPT)
-#endif
 
        mov     a0, sp
        jbsr    csky_do_IRQ
 
-#ifdef CONFIG_PREEMPTION
-       subi    r12, 1
-       stw     r12, (r9, TINFO_PREEMPT)
-       cmpnei  r12, 0
-       bt      2f
-       ldw     r12, (r9, TINFO_FLAGS)
-       btsti   r12, TIF_NEED_RESCHED
-       bf      2f
-       jbsr    preempt_schedule_irq    /* irq en/disable is done inside */
-#endif
-2:
        jmpi    ret_from_exception
 
 /*
index 7e4a1da..9bfaee0 100644 (file)
@@ -891,14 +891,11 @@ generic_make_request_checks(struct bio *bio)
        }
 
        /*
-        * Non-mq queues do not honor REQ_NOWAIT, so complete a bio
-        * with BLK_STS_AGAIN status in order to catch -EAGAIN and
-        * to give a chance to the caller to repeat request gracefully.
+        * For a REQ_NOWAIT based request, return -EOPNOTSUPP
+        * if queue is not a request based queue.
         */
-       if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_mq(q)) {
-               status = BLK_STS_AGAIN;
-               goto end_io;
-       }
+       if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_mq(q))
+               goto not_supported;
 
        if (should_fail_bio(bio))
                goto end_io;
index 11ec6f4..abb121f 100644 (file)
@@ -377,6 +377,7 @@ config SM_GCC_8150
 
 config SM_GCC_8250
        tristate "SM8250 Global Clock Controller"
+       select QCOM_GDSC
        help
          Support for the global clock controller on SM8250 devices.
          Say Y if you want to use peripheral devices such as UART,
index ef98fdc..732bc7c 100644 (file)
@@ -76,8 +76,7 @@ static struct clk_alpha_pll_postdiv gpll0_out_even = {
        .clkr.hw.init = &(struct clk_init_data){
                .name = "gpll0_out_even",
                .parent_data = &(const struct clk_parent_data){
-                       .fw_name = "bi_tcxo",
-                       .name = "bi_tcxo",
+                       .hw = &gpll0.clkr.hw,
                },
                .num_parents = 1,
                .ops = &clk_trion_pll_postdiv_ops,
index 4a30498..c24cad3 100644 (file)
@@ -1050,7 +1050,7 @@ void kfd_dec_compute_active(struct kfd_dev *dev);
 /* Check with device cgroup if @kfd device is accessible */
 static inline int kfd_devcgroup_check_permission(struct kfd_dev *kfd)
 {
-#if defined(CONFIG_CGROUP_DEVICE)
+#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
        struct drm_device *ddev = kfd->ddev;
 
        return devcgroup_check_permission(DEVCG_DEV_CHAR, ddev->driver->major,
index 28e651b..7fc15b8 100644 (file)
@@ -7880,13 +7880,6 @@ static int dm_update_plane_state(struct dc *dc,
                        return -EINVAL;
                }
 
-               if (new_plane_state->crtc_x <= -new_acrtc->max_cursor_width ||
-                       new_plane_state->crtc_y <= -new_acrtc->max_cursor_height) {
-                       DRM_DEBUG_ATOMIC("Bad cursor position %d, %d\n",
-                                                        new_plane_state->crtc_x, new_plane_state->crtc_y);
-                       return -EINVAL;
-               }
-
                return 0;
        }
 
index 82fc3d5..416afb9 100644 (file)
@@ -1684,6 +1684,8 @@ static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
                return;
 
        /* Stall out until the cursor update completes. */
+       if (vupdate_end < vupdate_start)
+               vupdate_end += stream->timing.v_total;
        us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
        udelay(us_to_vupdate + us_vupdate);
 }
index 1754c05..548cc25 100644 (file)
@@ -328,8 +328,8 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc,
        if (!drm_atomic_crtc_needs_modeset(state))
                return 0;
 
-       if (state->mode.hdisplay > priv->soc_info->max_height ||
-           state->mode.vdisplay > priv->soc_info->max_width)
+       if (state->mode.hdisplay > priv->soc_info->max_width ||
+           state->mode.vdisplay > priv->soc_info->max_height)
                return -EINVAL;
 
        rate = clk_round_rate(priv->pix_clk,
@@ -474,7 +474,7 @@ static int ingenic_drm_encoder_atomic_check(struct drm_encoder *encoder,
 
 static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg)
 {
-       struct ingenic_drm *priv = arg;
+       struct ingenic_drm *priv = drm_device_get_priv(arg);
        unsigned int state;
 
        regmap_read(priv->map, JZ_REG_LCD_STATE, &state);
index bf8e149..e0a5e89 100644 (file)
@@ -153,9 +153,9 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
        uobj->context = NULL;
 
        /*
-        * For DESTROY the usecnt is held write locked, the caller is expected
-        * to put it unlock and put the object when done with it. Only DESTROY
-        * can remove the IDR handle.
+        * For DESTROY the usecnt is not changed, the caller is expected to
+        * manage it via uobj_put_destroy(). Only DESTROY can remove the IDR
+        * handle.
         */
        if (reason != RDMA_REMOVE_DESTROY)
                atomic_set(&uobj->usecnt, 0);
@@ -187,7 +187,7 @@ static int uverbs_destroy_uobject(struct ib_uobject *uobj,
 /*
  * This calls uverbs_destroy_uobject() using the RDMA_REMOVE_DESTROY
  * sequence. It should only be used from command callbacks. On success the
- * caller must pair this with rdma_lookup_put_uobject(LOOKUP_WRITE). This
+ * caller must pair this with uobj_put_destroy(). This
  * version requires the caller to have already obtained an
  * LOOKUP_DESTROY uobject kref.
  */
@@ -198,6 +198,13 @@ int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs)
 
        down_read(&ufile->hw_destroy_rwsem);
 
+       /*
+        * Once the uobject is destroyed by RDMA_REMOVE_DESTROY then it is left
+        * write locked as the callers put it back with UVERBS_LOOKUP_DESTROY.
+        * This is because any other concurrent thread can still see the object
+        * in the xarray due to RCU. Leaving it locked ensures nothing else will
+        * touch it.
+        */
        ret = uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE);
        if (ret)
                goto out_unlock;
@@ -216,7 +223,7 @@ out_unlock:
 /*
  * uobj_get_destroy destroys the HW object and returns a handle to the uobj
  * with a NULL object pointer. The caller must pair this with
- * uverbs_put_destroy.
+ * uobj_put_destroy().
  */
 struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
                                      u32 id, struct uverbs_attr_bundle *attrs)
@@ -250,8 +257,7 @@ int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
        uobj = __uobj_get_destroy(obj, id, attrs);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
-
-       rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
+       uobj_put_destroy(uobj);
        return 0;
 }
 
index a401931..4468307 100644 (file)
@@ -1439,6 +1439,7 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 
        if (is_odp_mr(mr)) {
                to_ib_umem_odp(mr->umem)->private = mr;
+               init_waitqueue_head(&mr->q_deferred_work);
                atomic_set(&mr->num_deferred_work, 0);
                err = xa_err(xa_store(&dev->odp_mkeys,
                                      mlx5_base_mkey(mr->mmkey.key), &mr->mmkey,
index 568b21e..021df06 100644 (file)
@@ -760,7 +760,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num,
                qib_dev_err(dd,
                        "Skipping linkcontrol sysfs info, (err %d) port %u\n",
                        ret, port_num);
-               goto bail;
+               goto bail_link;
        }
        kobject_uevent(&ppd->pport_kobj, KOBJ_ADD);
 
@@ -770,7 +770,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num,
                qib_dev_err(dd,
                        "Skipping sl2vl sysfs info, (err %d) port %u\n",
                        ret, port_num);
-               goto bail_link;
+               goto bail_sl;
        }
        kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD);
 
@@ -780,7 +780,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num,
                qib_dev_err(dd,
                        "Skipping diag_counters sysfs info, (err %d) port %u\n",
                        ret, port_num);
-               goto bail_sl;
+               goto bail_diagc;
        }
        kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD);
 
@@ -793,7 +793,7 @@ int qib_create_port_files(struct ib_device *ibdev, u8 port_num,
                qib_dev_err(dd,
                 "Skipping Congestion Control sysfs info, (err %d) port %u\n",
                 ret, port_num);
-               goto bail_diagc;
+               goto bail_cc;
        }
 
        kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD);
@@ -854,6 +854,7 @@ void qib_verbs_unregister_sysfs(struct qib_devdata *dd)
                                &cc_table_bin_attr);
                        kobject_put(&ppd->pport_cc_kobj);
                }
+               kobject_put(&ppd->diagc_kobj);
                kobject_put(&ppd->sl2vl_kobj);
                kobject_put(&ppd->pport_kobj);
        }
index e580ae9..780fd2d 100644 (file)
@@ -829,7 +829,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev,
            !(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
                dev_err(&pdev->dev, "PCI BAR region not MMIO\n");
                ret = -ENOMEM;
-               goto err_free_device;
+               goto err_disable_pdev;
        }
 
        ret = pci_request_regions(pdev, DRV_NAME);
index e188a95..9a3379c 100644 (file)
@@ -377,8 +377,12 @@ struct ipoib_dev_priv {
        struct ipoib_rx_buf *rx_ring;
 
        struct ipoib_tx_buf *tx_ring;
+       /* cyclic ring variables for managing tx_ring, for UD only */
        unsigned int         tx_head;
        unsigned int         tx_tail;
+       /* cyclic ring variables for counting overall outstanding send WRs */
+       unsigned int         global_tx_head;
+       unsigned int         global_tx_tail;
        struct ib_sge        tx_sge[MAX_SKB_FRAGS + 1];
        struct ib_ud_wr      tx_wr;
        struct ib_wc         send_wc[MAX_SEND_CQE];
index c59e00a..9bf0fa3 100644 (file)
@@ -756,7 +756,8 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
                return;
        }
 
-       if ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size - 1) {
+       if ((priv->global_tx_head - priv->global_tx_tail) ==
+           ipoib_sendq_size - 1) {
                ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
                          tx->qp->qp_num);
                netif_stop_queue(dev);
@@ -786,7 +787,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
        } else {
                netif_trans_update(dev);
                ++tx->tx_head;
-               ++priv->tx_head;
+               ++priv->global_tx_head;
        }
 }
 
@@ -820,10 +821,11 @@ void ipoib_cm_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
        netif_tx_lock(dev);
 
        ++tx->tx_tail;
-       ++priv->tx_tail;
+       ++priv->global_tx_tail;
 
        if (unlikely(netif_queue_stopped(dev) &&
-                    (priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >> 1 &&
+                    ((priv->global_tx_head - priv->global_tx_tail) <=
+                     ipoib_sendq_size >> 1) &&
                     test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)))
                netif_wake_queue(dev);
 
@@ -1232,8 +1234,9 @@ timeout:
                dev_kfree_skb_any(tx_req->skb);
                netif_tx_lock_bh(p->dev);
                ++p->tx_tail;
-               ++priv->tx_tail;
-               if (unlikely(priv->tx_head - priv->tx_tail == ipoib_sendq_size >> 1) &&
+               ++priv->global_tx_tail;
+               if (unlikely((priv->global_tx_head - priv->global_tx_tail) <=
+                            ipoib_sendq_size >> 1) &&
                    netif_queue_stopped(p->dev) &&
                    test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
                        netif_wake_queue(p->dev);
index c332b47..da3c531 100644 (file)
@@ -407,9 +407,11 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc)
        dev_kfree_skb_any(tx_req->skb);
 
        ++priv->tx_tail;
+       ++priv->global_tx_tail;
 
        if (unlikely(netif_queue_stopped(dev) &&
-                    ((priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >> 1) &&
+                    ((priv->global_tx_head - priv->global_tx_tail) <=
+                     ipoib_sendq_size >> 1) &&
                     test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)))
                netif_wake_queue(dev);
 
@@ -634,7 +636,8 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb,
        else
                priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM;
        /* increase the tx_head after send success, but use it for queue state */
-       if (priv->tx_head - priv->tx_tail == ipoib_sendq_size - 1) {
+       if ((priv->global_tx_head - priv->global_tx_tail) ==
+           ipoib_sendq_size - 1) {
                ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n");
                netif_stop_queue(dev);
        }
@@ -662,6 +665,7 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb,
 
                rc = priv->tx_head;
                ++priv->tx_head;
+               ++priv->global_tx_head;
        }
        return rc;
 }
@@ -807,6 +811,7 @@ int ipoib_ib_dev_stop_default(struct net_device *dev)
                                ipoib_dma_unmap_tx(priv, tx_req);
                                dev_kfree_skb_any(tx_req->skb);
                                ++priv->tx_tail;
+                               ++priv->global_tx_tail;
                        }
 
                        for (i = 0; i < ipoib_recvq_size; ++i) {
index 81b8227..ceec24d 100644 (file)
@@ -1184,9 +1184,11 @@ static void ipoib_timeout(struct net_device *dev, unsigned int txqueue)
 
        ipoib_warn(priv, "transmit timeout: latency %d msecs\n",
                   jiffies_to_msecs(jiffies - dev_trans_start(dev)));
-       ipoib_warn(priv, "queue stopped %d, tx_head %u, tx_tail %u\n",
-                  netif_queue_stopped(dev),
-                  priv->tx_head, priv->tx_tail);
+       ipoib_warn(priv,
+                  "queue stopped %d, tx_head %u, tx_tail %u, global_tx_head %u, global_tx_tail %u\n",
+                  netif_queue_stopped(dev), priv->tx_head, priv->tx_tail,
+                  priv->global_tx_head, priv->global_tx_tail);
+
        /* XXX reset QP, etc. */
 }
 
@@ -1701,7 +1703,7 @@ static int ipoib_dev_init_default(struct net_device *dev)
                goto out_rx_ring_cleanup;
        }
 
-       /* priv->tx_head, tx_tail & tx_outstanding are already 0 */
+       /* priv->tx_head, tx_tail and global_tx_tail/head are already 0 */
 
        if (ipoib_transport_dev_init(dev, priv->ca)) {
                pr_warn("%s: ipoib_transport_dev_init failed\n",
index cb6e3a5..0d57e51 100644 (file)
@@ -326,20 +326,6 @@ static int evdev_fasync(int fd, struct file *file, int on)
        return fasync_helper(fd, file, on, &client->fasync);
 }
 
-static int evdev_flush(struct file *file, fl_owner_t id)
-{
-       struct evdev_client *client = file->private_data;
-       struct evdev *evdev = client->evdev;
-
-       mutex_lock(&evdev->mutex);
-
-       if (evdev->exist && !client->revoked)
-               input_flush_device(&evdev->handle, file);
-
-       mutex_unlock(&evdev->mutex);
-       return 0;
-}
-
 static void evdev_free(struct device *dev)
 {
        struct evdev *evdev = container_of(dev, struct evdev, dev);
@@ -453,6 +439,10 @@ static int evdev_release(struct inode *inode, struct file *file)
        unsigned int i;
 
        mutex_lock(&evdev->mutex);
+
+       if (evdev->exist && !client->revoked)
+               input_flush_device(&evdev->handle, file);
+
        evdev_ungrab(evdev, client);
        mutex_unlock(&evdev->mutex);
 
@@ -1310,7 +1300,6 @@ static const struct file_operations evdev_fops = {
        .compat_ioctl   = evdev_ioctl_compat,
 #endif
        .fasync         = evdev_fasync,
-       .flush          = evdev_flush,
        .llseek         = no_llseek,
 };
 
index 6b40a1c..c77cdb3 100644 (file)
@@ -458,6 +458,16 @@ static const u8 xboxone_fw2015_init[] = {
        0x05, 0x20, 0x00, 0x01, 0x00
 };
 
+/*
+ * This packet is required for Xbox One S (0x045e:0x02ea)
+ * and Xbox One Elite Series 2 (0x045e:0x0b00) pads to
+ * initialize the controller that was previously used in
+ * Bluetooth mode.
+ */
+static const u8 xboxone_s_init[] = {
+       0x05, 0x20, 0x00, 0x0f, 0x06
+};
+
 /*
  * This packet is required for the Titanfall 2 Xbox One pads
  * (0x0e6f:0x0165) to finish initialization and for Hori pads
@@ -516,6 +526,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
        XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
        XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
        XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
+       XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init),
+       XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init),
        XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1),
        XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2),
        XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
index d383985..14362eb 100644 (file)
@@ -186,7 +186,7 @@ struct touchpad_protocol {
        u8                      number_of_fingers;
        u8                      clicked2;
        u8                      unknown3[16];
-       struct tp_finger        fingers[0];
+       struct tp_finger        fingers[];
 };
 
 /**
index 2b71c5a..fc1793c 100644 (file)
@@ -347,18 +347,14 @@ static int cros_ec_keyb_info(struct cros_ec_device *ec_dev,
        params->info_type = info_type;
        params->event_type = event_type;
 
-       ret = cros_ec_cmd_xfer(ec_dev, msg);
-       if (ret < 0) {
-               dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n",
-                        (int)info_type, (int)event_type, ret);
-       } else if (msg->result == EC_RES_INVALID_VERSION) {
+       ret = cros_ec_cmd_xfer_status(ec_dev, msg);
+       if (ret == -ENOTSUPP) {
                /* With older ECs we just return 0 for everything */
                memset(result, 0, result_size);
                ret = 0;
-       } else if (msg->result != EC_RES_SUCCESS) {
-               dev_warn(ec_dev->dev, "Error getting info %d/%d: %d\n",
-                        (int)info_type, (int)event_type, msg->result);
-               ret = -EPROTO;
+       } else if (ret < 0) {
+               dev_warn(ec_dev->dev, "Transfer error %d/%d: %d\n",
+                        (int)info_type, (int)event_type, ret);
        } else if (ret != result_size) {
                dev_warn(ec_dev->dev, "Wrong size %d/%d: %d != %zu\n",
                         (int)info_type, (int)event_type,
index b0ead71..a69dcc3 100644 (file)
@@ -143,7 +143,7 @@ MODULE_DEVICE_TABLE(of, dir685_tk_of_match);
 
 static struct i2c_driver dir685_tk_i2c_driver = {
        .driver = {
-               .name   = "dlin-dir685-touchkeys",
+               .name   = "dlink-dir685-touchkeys",
                .of_match_table = of_match_ptr(dir685_tk_of_match),
        },
        .probe          = dir685_tk_probe,
index c8f87df..9c6386b 100644 (file)
@@ -205,8 +205,11 @@ ATTRIBUTE_GROUPS(axp20x);
 
 static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
 {
-       struct input_dev *idev = pwr;
-       struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
+       struct axp20x_pek *axp20x_pek = pwr;
+       struct input_dev *idev = axp20x_pek->input;
+
+       if (!idev)
+               return IRQ_HANDLED;
 
        /*
         * The power-button is connected to ground so a falling edge (dbf)
@@ -225,22 +228,9 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
 static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
                                         struct platform_device *pdev)
 {
-       struct axp20x_dev *axp20x = axp20x_pek->axp20x;
        struct input_dev *idev;
        int error;
 
-       axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
-       if (axp20x_pek->irq_dbr < 0)
-               return axp20x_pek->irq_dbr;
-       axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
-                                                 axp20x_pek->irq_dbr);
-
-       axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
-       if (axp20x_pek->irq_dbf < 0)
-               return axp20x_pek->irq_dbf;
-       axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
-                                                 axp20x_pek->irq_dbf);
-
        axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
        if (!axp20x_pek->input)
                return -ENOMEM;
@@ -255,24 +245,6 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
 
        input_set_drvdata(idev, axp20x_pek);
 
-       error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
-                                            axp20x_pek_irq, 0,
-                                            "axp20x-pek-dbr", idev);
-       if (error < 0) {
-               dev_err(&pdev->dev, "Failed to request dbr IRQ#%d: %d\n",
-                       axp20x_pek->irq_dbr, error);
-               return error;
-       }
-
-       error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
-                                         axp20x_pek_irq, 0,
-                                         "axp20x-pek-dbf", idev);
-       if (error < 0) {
-               dev_err(&pdev->dev, "Failed to request dbf IRQ#%d: %d\n",
-                       axp20x_pek->irq_dbf, error);
-               return error;
-       }
-
        error = input_register_device(idev);
        if (error) {
                dev_err(&pdev->dev, "Can't register input device: %d\n",
@@ -280,8 +252,6 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
                return error;
        }
 
-       device_init_wakeup(&pdev->dev, true);
-
        return 0;
 }
 
@@ -339,6 +309,18 @@ static int axp20x_pek_probe(struct platform_device *pdev)
 
        axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
 
+       axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
+       if (axp20x_pek->irq_dbr < 0)
+               return axp20x_pek->irq_dbr;
+       axp20x_pek->irq_dbr = regmap_irq_get_virq(
+                       axp20x_pek->axp20x->regmap_irqc, axp20x_pek->irq_dbr);
+
+       axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
+       if (axp20x_pek->irq_dbf < 0)
+               return axp20x_pek->irq_dbf;
+       axp20x_pek->irq_dbf = regmap_irq_get_virq(
+                       axp20x_pek->axp20x->regmap_irqc, axp20x_pek->irq_dbf);
+
        if (axp20x_pek_should_register_input(axp20x_pek, pdev)) {
                error = axp20x_pek_probe_input_device(axp20x_pek, pdev);
                if (error)
@@ -347,6 +329,26 @@ static int axp20x_pek_probe(struct platform_device *pdev)
 
        axp20x_pek->info = (struct axp20x_info *)match->driver_data;
 
+       error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbr,
+                                            axp20x_pek_irq, 0,
+                                            "axp20x-pek-dbr", axp20x_pek);
+       if (error < 0) {
+               dev_err(&pdev->dev, "Failed to request dbr IRQ#%d: %d\n",
+                       axp20x_pek->irq_dbr, error);
+               return error;
+       }
+
+       error = devm_request_any_context_irq(&pdev->dev, axp20x_pek->irq_dbf,
+                                         axp20x_pek_irq, 0,
+                                         "axp20x-pek-dbf", axp20x_pek);
+       if (error < 0) {
+               dev_err(&pdev->dev, "Failed to request dbf IRQ#%d: %d\n",
+                       axp20x_pek->irq_dbf, error);
+               return error;
+       }
+
+       device_init_wakeup(&pdev->dev, true);
+
        platform_set_drvdata(pdev, axp20x_pek);
 
        return 0;
index 4d20362..758dae8 100644 (file)
@@ -170,6 +170,7 @@ static const char * const smbus_pnp_ids[] = {
        "LEN005b", /* P50 */
        "LEN005e", /* T560 */
        "LEN006c", /* T470s */
+       "LEN007a", /* T470s */
        "LEN0071", /* T480 */
        "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
        "LEN0073", /* X1 Carbon G5 (Elantech) */
index 190b997..258d5fe 100644 (file)
@@ -205,7 +205,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
 
        if (count) {
                kfree(attn_data.data);
-               attn_data.data = NULL;
+               drvdata->attn_data.data = NULL;
        }
 
        if (!kfifo_is_empty(&drvdata->attn_fifo))
@@ -1210,7 +1210,8 @@ static int rmi_driver_probe(struct device *dev)
        if (data->input) {
                rmi_driver_set_input_name(rmi_dev, data->input);
                if (!rmi_dev->xport->input) {
-                       if (input_register_device(data->input)) {
+                       retval = input_register_device(data->input);
+                       if (retval) {
                                dev_err(dev, "%s: Failed to register input device.\n",
                                        __func__);
                                goto err_destroy_functions;
index 08e919d..7e048b5 100644 (file)
@@ -662,6 +662,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
                },
        },
+       {
+               /* Lenovo ThinkPad Twist S230u */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"),
+               },
+       },
        { }
 };
 
index 14c577c..2289f96 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 
+#include <linux/bits.h>
 #include <linux/module.h>
 #include <linux/input.h>
 #include <linux/interrupt.h>
@@ -73,6 +74,7 @@
 #define FW_POS_STATE           1
 #define FW_POS_TOTAL           2
 #define FW_POS_XY              3
+#define FW_POS_TOOL_TYPE       33
 #define FW_POS_CHECKSUM                34
 #define FW_POS_WIDTH           35
 #define FW_POS_PRESSURE                45
@@ -842,6 +844,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
 {
        struct input_dev *input = ts->input;
        unsigned int n_fingers;
+       unsigned int tool_type;
        u16 finger_state;
        int i;
 
@@ -852,6 +855,10 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
        dev_dbg(&ts->client->dev,
                "n_fingers: %u, state: %04x\n",  n_fingers, finger_state);
 
+       /* Note: all fingers have the same tool type */
+       tool_type = buf[FW_POS_TOOL_TYPE] & BIT(0) ?
+                       MT_TOOL_FINGER : MT_TOOL_PALM;
+
        for (i = 0; i < MAX_CONTACT_NUM && n_fingers; i++) {
                if (finger_state & 1) {
                        unsigned int x, y, p, w;
@@ -867,7 +874,7 @@ static void elants_i2c_mt_event(struct elants_data *ts, u8 *buf)
                                i, x, y, p, w);
 
                        input_mt_slot(input, i);
-                       input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
+                       input_mt_report_slot_state(input, tool_type, true);
                        input_event(input, EV_ABS, ABS_MT_POSITION_X, x);
                        input_event(input, EV_ABS, ABS_MT_POSITION_Y, y);
                        input_event(input, EV_ABS, ABS_MT_PRESSURE, p);
@@ -1307,6 +1314,8 @@ static int elants_i2c_probe(struct i2c_client *client,
        input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, ts->y_max, 0, 0);
        input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
        input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
+       input_set_abs_params(ts->input, ABS_MT_TOOL_TYPE,
+                            0, MT_TOOL_PALM, 0, 0);
        input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res);
        input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res);
        input_abs_set_res(ts->input, ABS_MT_TOUCH_MAJOR, 1);
index 69c6d55..2ef1ada 100644 (file)
@@ -91,15 +91,15 @@ static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
        if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL)
                BUG();
 
-       /* Write register: use repeated start */
+       /* Write register */
        xfer[0].addr = client->addr;
-       xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART;
+       xfer[0].flags = client->flags & I2C_M_TEN;
        xfer[0].len = 1;
        xfer[0].buf = &buf;
 
        /* Read data */
        xfer[1].addr = client->addr;
-       xfer[1].flags = I2C_M_RD;
+       xfer[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
        xfer[1].len = len;
        xfer[1].buf = val;
 
@@ -428,10 +428,8 @@ static int mms114_probe(struct i2c_client *client,
        const void *match_data;
        int error;
 
-       if (!i2c_check_functionality(client->adapter,
-                               I2C_FUNC_PROTOCOL_MANGLING)) {
-               dev_err(&client->dev,
-                       "Need i2c bus that supports protocol mangling\n");
+       if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+               dev_err(&client->dev, "Not supported I2C adapter\n");
                return -ENODEV;
        }
 
index 16d7020..397cb1d 100644 (file)
@@ -182,6 +182,7 @@ static const struct usb_device_id usbtouch_devices[] = {
 #endif
 
 #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH
+       {USB_DEVICE(0x255e, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
        {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
        {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH},
        {USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES},
index c5367e2..7896952 100644 (file)
@@ -2484,8 +2484,8 @@ static int mmc_rpmb_chrdev_release(struct inode *inode, struct file *filp)
        struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev,
                                                  struct mmc_rpmb_data, chrdev);
 
-       put_device(&rpmb->dev);
        mmc_blk_put(rpmb->md);
+       put_device(&rpmb->dev);
 
        return 0;
 }
index 3f71646..e368f2d 100644 (file)
@@ -4000,9 +4000,6 @@ int sdhci_setup_host(struct sdhci_host *host)
                       mmc_hostname(mmc), host->version);
        }
 
-       if (host->quirks & SDHCI_QUIRK_BROKEN_CQE)
-               mmc->caps2 &= ~MMC_CAP2_CQE;
-
        if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
                host->flags |= SDHCI_USE_SDMA;
        else if (!(host->caps & SDHCI_CAN_DO_SDMA))
@@ -4539,6 +4536,12 @@ int __sdhci_add_host(struct sdhci_host *host)
        struct mmc_host *mmc = host->mmc;
        int ret;
 
+       if ((mmc->caps2 & MMC_CAP2_CQE) &&
+           (host->quirks & SDHCI_QUIRK_BROKEN_CQE)) {
+               mmc->caps2 &= ~MMC_CAP2_CQE;
+               mmc->cqe_ops = NULL;
+       }
+
        host->complete_wq = alloc_workqueue("sdhci", flags, 0);
        if (!host->complete_wq)
                return -ENOMEM;
index 3726dc7..cc46e25 100644 (file)
@@ -1382,16 +1382,19 @@ static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown)
 
 /*
  * Called only on a device that has been disabled and after all other threads
- * that can check this device's completion queues have synced. This is the
- * last chance for the driver to see a natural completion before
- * nvme_cancel_request() terminates all incomplete requests.
+ * that can check this device's completion queues have synced, except
+ * nvme_poll(). This is the last chance for the driver to see a natural
+ * completion before nvme_cancel_request() terminates all incomplete requests.
  */
 static void nvme_reap_pending_cqes(struct nvme_dev *dev)
 {
        int i;
 
-       for (i = dev->ctrl.queue_count - 1; i > 0; i--)
+       for (i = dev->ctrl.queue_count - 1; i > 0; i--) {
+               spin_lock(&dev->queues[i].cq_poll_lock);
                nvme_process_cq(&dev->queues[i]);
+               spin_unlock(&dev->queues[i].cq_poll_lock);
+       }
 }
 
 static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,
index 13f25e2..25d489b 100644 (file)
@@ -1733,7 +1733,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
                    (!regset->active || regset->active(t->task, regset) > 0)) {
                        int ret;
                        size_t size = regset_size(t->task, regset);
-                       void *data = kmalloc(size, GFP_KERNEL);
+                       void *data = kzalloc(size, GFP_KERNEL);
                        if (unlikely(!data))
                                return 0;
                        ret = regset->get(t->task, regset,
index 5435a40..c18459c 100644 (file)
@@ -520,7 +520,7 @@ static int fanotify_handle_event(struct fsnotify_group *group,
        BUILD_BUG_ON(FAN_OPEN_EXEC != FS_OPEN_EXEC);
        BUILD_BUG_ON(FAN_OPEN_EXEC_PERM != FS_OPEN_EXEC_PERM);
 
-       BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 20);
+       BUILD_BUG_ON(HWEIGHT32(ALL_FANOTIFY_EVENT_BITS) != 19);
 
        mask = fanotify_group_event_mask(group, iter_info, mask, data,
                                         data_type);
index e13265e..91608d9 100644 (file)
@@ -876,6 +876,9 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
        struct simple_xattr *new_xattr = NULL;
        int err = 0;
 
+       if (removed_size)
+               *removed_size = -1;
+
        /* value == NULL means remove */
        if (value) {
                new_xattr = simple_xattr_alloc(value, size);
@@ -914,9 +917,6 @@ int simple_xattr_set(struct simple_xattrs *xattrs, const char *name,
                list_add(&new_xattr->list, &xattrs->head);
                xattr = NULL;
        }
-
-       if (removed_size)
-               *removed_size = -1;
 out:
        spin_unlock(&xattrs->lock);
        if (xattr) {
index 2388737..5aa8705 100644 (file)
@@ -48,7 +48,7 @@
   #ifdef CONFIG_NEED_MULTIPLE_NODES
     #define cpumask_of_node(node)      ((node) == 0 ? cpu_online_mask : cpu_none_mask)
   #else
-    #define cpumask_of_node(node)      ((void)node, cpu_online_mask)
+    #define cpumask_of_node(node)      ((void)(node), cpu_online_mask)
   #endif
 #endif
 #ifndef pcibus_to_node
index fa35b52..9a72214 100644 (file)
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #include <linux/fs.h>
-#include <linux/bpf-cgroup.h>
 
 #define DEVCG_ACC_MKNOD 1
 #define DEVCG_ACC_READ  2
 #define DEVCG_DEV_CHAR  2
 #define DEVCG_DEV_ALL   4  /* this represents all devices */
 
-#ifdef CONFIG_CGROUP_DEVICE
-int devcgroup_check_permission(short type, u32 major, u32 minor,
-                              short access);
-#else
-static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
-                                            short access)
-{ return 0; }
-#endif
 
 #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
+int devcgroup_check_permission(short type, u32 major, u32 minor,
+                              short access);
 static inline int devcgroup_inode_permission(struct inode *inode, int mask)
 {
        short type, access = 0;
@@ -61,6 +54,9 @@ static inline int devcgroup_inode_mknod(int mode, dev_t dev)
 }
 
 #else
+static inline int devcgroup_check_permission(short type, u32 major, u32 minor,
+                              short access)
+{ return 0; }
 static inline int devcgroup_inode_permission(struct inode *inode, int mask)
 { return 0; }
 static inline int devcgroup_inode_mknod(int mode, dev_t dev)
index 3049a6c..b79fa9b 100644 (file)
@@ -47,8 +47,7 @@
  * Directory entry modification events - reported only to directory
  * where entry is modified and not to a watching parent.
  */
-#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE | \
-                                FAN_DIR_MODIFY)
+#define FANOTIFY_DIRENT_EVENTS (FAN_MOVE | FAN_CREATE | FAN_DELETE)
 
 /* Events that can only be reported with data type FSNOTIFY_EVENT_INODE */
 #define FANOTIFY_INODE_EVENTS  (FANOTIFY_DIRENT_EVENTS | \
index 79f918c..906da5f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * public include for LM8333 keypad driver - same license as driver
- * Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de>
+ * Copyright (C) 2012 Wolfram Sang, Pengutronix <kernel@pengutronix.de>
  */
 
 #ifndef _LM8333_H
index 5a32342..f3fe737 100644 (file)
@@ -782,6 +782,11 @@ static inline void *kvcalloc(size_t n, size_t size, gfp_t flags)
 
 extern void kvfree(const void *addr);
 
+/*
+ * Mapcount of compound page as a whole, does not include mapped sub-pages.
+ *
+ * Must be called only for compound pages or any their tail sub-pages.
+ */
 static inline int compound_mapcount(struct page *page)
 {
        VM_BUG_ON_PAGE(!PageCompound(page), page);
@@ -801,10 +806,16 @@ static inline void page_mapcount_reset(struct page *page)
 
 int __page_mapcount(struct page *page);
 
+/*
+ * Mapcount of 0-order page; when compound sub-page, includes
+ * compound_mapcount().
+ *
+ * Result is undefined for pages which cannot be mapped into userspace.
+ * For example SLAB or special types of pages. See function page_has_type().
+ * They use this place in struct page differently.
+ */
 static inline int page_mapcount(struct page *page)
 {
-       VM_BUG_ON_PAGE(PageSlab(page), page);
-
        if (unlikely(PageCompound(page)))
                return __page_mapcount(page);
        return atomic_read(&page->_mapcount) + 1;
index 1b28ce1..325fdaa 100644 (file)
@@ -88,7 +88,7 @@ struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
 
 static inline void uobj_put_destroy(struct ib_uobject *uobj)
 {
-       rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
+       rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
 }
 
 static inline void uobj_put_read(struct ib_uobject *uobj)
index 6f87352..41ca996 100644 (file)
@@ -33,12 +33,9 @@ void cgroup_rstat_updated(struct cgroup *cgrp, int cpu)
                return;
 
        /*
-        * Paired with the one in cgroup_rstat_cpu_pop_updated().  Either we
-        * see NULL updated_next or they see our updated stat.
-        */
-       smp_mb();
-
-       /*
+        * Speculative already-on-list test. This may race leading to
+        * temporary inaccuracies, which is fine.
+        *
         * Because @parent's updated_children is terminated with @parent
         * instead of NULL, we can tell whether @cgrp is on the list by
         * testing the next pointer for NULL.
@@ -134,13 +131,6 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,
                *nextp = rstatc->updated_next;
                rstatc->updated_next = NULL;
 
-               /*
-                * Paired with the one in cgroup_rstat_cpu_updated().
-                * Either they see NULL updated_next or we see their
-                * updated stat.
-                */
-               smp_mb();
-
                return pos;
        }
 
index 99d77ff..cd280af 100644 (file)
@@ -1692,6 +1692,7 @@ static void collapse_file(struct mm_struct *mm,
                if (page_has_private(page) &&
                    !try_to_release_page(page, GFP_KERNEL)) {
                        result = SCAN_PAGE_HAS_PRIVATE;
+                       putback_lru_page(page);
                        goto out_unlock;
                }
 
index 8c3bb5e..460b0fe 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/spinlock.h>
 #include <linux/zpool.h>
 #include <linux/magic.h>
+#include <linux/kmemleak.h>
 
 /*
  * NCHUNKS_ORDER determines the internal allocation granularity, effectively
@@ -215,6 +216,8 @@ static inline struct z3fold_buddy_slots *alloc_slots(struct z3fold_pool *pool,
                                 (gfp & ~(__GFP_HIGHMEM | __GFP_MOVABLE)));
 
        if (slots) {
+               /* It will be freed separately in free_handle(). */
+               kmemleak_not_leak(slots);
                memset(slots->slot, 0, sizeof(slots->slot));
                slots->pool = (unsigned long)pool;
                rwlock_init(&slots->lock);
index 22e73a3..3baf435 100644 (file)
@@ -30,7 +30,7 @@ obj-$(CONFIG_SECURITY_YAMA)           += yama/
 obj-$(CONFIG_SECURITY_LOADPIN)         += loadpin/
 obj-$(CONFIG_SECURITY_SAFESETID)       += safesetid/
 obj-$(CONFIG_SECURITY_LOCKDOWN_LSM)    += lockdown/
-obj-$(CONFIG_CGROUP_DEVICE)            += device_cgroup.o
+obj-$(CONFIG_CGROUPS)                  += device_cgroup.o
 obj-$(CONFIG_BPF_LSM)                  += bpf/
 
 # Object integrity file lists
index f4ee0ae..0ca31c8 100644 (file)
@@ -812,6 +812,7 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
        int ret;
        kuid_t root_uid;
 
+       new->cap_ambient = old->cap_ambient;
        if (WARN_ON(!cap_ambient_invariant_ok(old)))
                return -EPERM;
 
index 7d0f8f7..43ab0ad 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/rcupdate.h>
 #include <linux/mutex.h>
 
+#ifdef CONFIG_CGROUP_DEVICE
+
 static DEFINE_MUTEX(devcgroup_mutex);
 
 enum devcg_behavior {
@@ -792,7 +794,7 @@ struct cgroup_subsys devices_cgrp_subsys = {
 };
 
 /**
- * __devcgroup_check_permission - checks if an inode operation is permitted
+ * devcgroup_legacy_check_permission - checks if an inode operation is permitted
  * @dev_cgroup: the dev cgroup to be tested against
  * @type: device type
  * @major: device major number
@@ -801,7 +803,7 @@ struct cgroup_subsys devices_cgrp_subsys = {
  *
  * returns 0 on success, -EPERM case the operation is not permitted
  */
-static int __devcgroup_check_permission(short type, u32 major, u32 minor,
+static int devcgroup_legacy_check_permission(short type, u32 major, u32 minor,
                                        short access)
 {
        struct dev_cgroup *dev_cgroup;
@@ -825,6 +827,10 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
        return 0;
 }
 
+#endif /* CONFIG_CGROUP_DEVICE */
+
+#if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
+
 int devcgroup_check_permission(short type, u32 major, u32 minor, short access)
 {
        int rc = BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access);
@@ -832,6 +838,13 @@ int devcgroup_check_permission(short type, u32 major, u32 minor, short access)
        if (rc)
                return -EPERM;
 
-       return __devcgroup_check_permission(type, major, minor, access);
+       #ifdef CONFIG_CGROUP_DEVICE
+       return devcgroup_legacy_check_permission(type, major, minor, access);
+
+       #else /* CONFIG_CGROUP_DEVICE */
+       return 0;
+
+       #endif /* CONFIG_CGROUP_DEVICE */
 }
 EXPORT_SYMBOL(devcgroup_check_permission);
+#endif /* defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF) */
index b412d3b..21edb8a 100644 (file)
@@ -216,12 +216,12 @@ static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
        if (info.index >= 32)
                return -EINVAL;
        /* check whether the dsp was already loaded */
-       if (hw->dsp_loaded & (1 << info.index))
+       if (hw->dsp_loaded & (1u << info.index))
                return -EBUSY;
        err = hw->ops.dsp_load(hw, &info);
        if (err < 0)
                return err;
-       hw->dsp_loaded |= (1 << info.index);
+       hw->dsp_loaded |= (1u << info.index);
        return 0;
 }
 
index 041d2a3..e62d588 100644 (file)
@@ -384,6 +384,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
        case 0x10ec0282:
        case 0x10ec0283:
        case 0x10ec0286:
+       case 0x10ec0287:
        case 0x10ec0288:
        case 0x10ec0285:
        case 0x10ec0298:
@@ -5484,18 +5485,9 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec,
                { 0x19, 0x21a11010 }, /* dock mic */
                { }
        };
-       /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
-        * the speaker output becomes too low by some reason on Thinkpads with
-        * ALC298 codec
-        */
-       static const hda_nid_t preferred_pairs[] = {
-               0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
-               0
-       };
        struct alc_spec *spec = codec->spec;
 
        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
-               spec->gen.preferred_dacs = preferred_pairs;
                spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
                snd_hda_apply_pincfgs(codec, pincfgs);
        } else if (action == HDA_FIXUP_ACT_INIT) {
@@ -5508,6 +5500,23 @@ static void alc_fixup_tpt470_dock(struct hda_codec *codec,
        }
 }
 
+static void alc_fixup_tpt470_dacs(struct hda_codec *codec,
+                                 const struct hda_fixup *fix, int action)
+{
+       /* Assure the speaker pin to be coupled with DAC NID 0x03; otherwise
+        * the speaker output becomes too low by some reason on Thinkpads with
+        * ALC298 codec
+        */
+       static const hda_nid_t preferred_pairs[] = {
+               0x14, 0x03, 0x17, 0x02, 0x21, 0x02,
+               0
+       };
+       struct alc_spec *spec = codec->spec;
+
+       if (action == HDA_FIXUP_ACT_PRE_PROBE)
+               spec->gen.preferred_dacs = preferred_pairs;
+}
+
 static void alc_shutup_dell_xps13(struct hda_codec *codec)
 {
        struct alc_spec *spec = codec->spec;
@@ -6063,6 +6072,7 @@ enum {
        ALC700_FIXUP_INTEL_REFERENCE,
        ALC274_FIXUP_DELL_BIND_DACS,
        ALC274_FIXUP_DELL_AIO_LINEOUT_VERB,
+       ALC298_FIXUP_TPT470_DOCK_FIX,
        ALC298_FIXUP_TPT470_DOCK,
        ALC255_FIXUP_DUMMY_LINEOUT_VERB,
        ALC255_FIXUP_DELL_HEADSET_MIC,
@@ -6994,12 +7004,18 @@ static const struct hda_fixup alc269_fixups[] = {
                .chained = true,
                .chain_id = ALC274_FIXUP_DELL_BIND_DACS
        },
-       [ALC298_FIXUP_TPT470_DOCK] = {
+       [ALC298_FIXUP_TPT470_DOCK_FIX] = {
                .type = HDA_FIXUP_FUNC,
                .v.func = alc_fixup_tpt470_dock,
                .chained = true,
                .chain_id = ALC293_FIXUP_LENOVO_SPK_NOISE
        },
+       [ALC298_FIXUP_TPT470_DOCK] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc_fixup_tpt470_dacs,
+               .chained = true,
+               .chain_id = ALC298_FIXUP_TPT470_DOCK_FIX
+       },
        [ALC255_FIXUP_DUMMY_LINEOUT_VERB] = {
                .type = HDA_FIXUP_PINS,
                .v.pins = (const struct hda_pintbl[]) {
@@ -7638,6 +7654,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
        {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
        {.id = ALC292_FIXUP_TPT440, .name = "tpt440"},
        {.id = ALC292_FIXUP_TPT460, .name = "tpt460"},
+       {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"},
        {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"},
        {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"},
        {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"},
@@ -8276,6 +8293,7 @@ static int patch_alc269(struct hda_codec *codec)
        case 0x10ec0215:
        case 0x10ec0245:
        case 0x10ec0285:
+       case 0x10ec0287:
        case 0x10ec0289:
                spec->codec_variant = ALC269_TYPE_ALC215;
                spec->shutup = alc225_shutup;
@@ -9554,6 +9572,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0284, "ALC284", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0285, "ALC285", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0286, "ALC286", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0287, "ALC287", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0288, "ALC288", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0289, "ALC289", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
index a88d785..15769f2 100644 (file)
@@ -1182,6 +1182,14 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
                        cval->res = 384;
                }
                break;
+       case USB_ID(0x0495, 0x3042): /* ESS Technology Asus USB DAC */
+               if ((strstr(kctl->id.name, "Playback Volume") != NULL) ||
+                       strstr(kctl->id.name, "Capture Volume") != NULL) {
+                       cval->min >>= 8;
+                       cval->max = 0;
+                       cval->res = 1;
+               }
+               break;
        }
 }
 
index bfdc6ad..9af7aa9 100644 (file)
@@ -397,6 +397,21 @@ static const struct usbmix_connector_map trx40_mobo_connector_map[] = {
        {}
 };
 
+/* Rear panel + front mic on Gigabyte TRX40 Aorus Master with ALC1220-VB */
+static const struct usbmix_name_map aorus_master_alc1220vb_map[] = {
+       { 17, NULL },                   /* OT, IEC958?, disabled */
+       { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */
+       { 16, "Line Out" },             /* OT */
+       { 22, "Line Out Playback" },    /* FU */
+       { 7, "Line" },                  /* IT */
+       { 19, "Line Capture" },         /* FU */
+       { 8, "Mic" },                   /* IT */
+       { 20, "Mic Capture" },          /* FU */
+       { 9, "Front Mic" },             /* IT */
+       { 21, "Front Mic Capture" },    /* FU */
+       {}
+};
+
 /*
  * Control map entries
  */
@@ -526,6 +541,10 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
                .id = USB_ID(0x1b1c, 0x0a42),
                .map = corsair_virtuoso_map,
        },
+       {       /* Gigabyte TRX40 Aorus Master (rear panel + front mic) */
+               .id = USB_ID(0x0414, 0xa001),
+               .map = aorus_master_alc1220vb_map,
+       },
        {       /* Gigabyte TRX40 Aorus Pro WiFi */
                .id = USB_ID(0x0414, 0xa002),
                .map = trx40_mobo_map,
index 6313c30..eb89902 100644 (file)
@@ -3566,4 +3566,29 @@ ALC1220_VB_DESKTOP(0x0db0, 0x543d), /* MSI TRX40 */
 ALC1220_VB_DESKTOP(0x26ce, 0x0a01), /* Asrock TRX40 Creator */
 #undef ALC1220_VB_DESKTOP
 
+/* Two entries for Gigabyte TRX40 Aorus Master:
+ * TRX40 Aorus Master has two USB-audio devices, one for the front headphone
+ * with ESS SABRE9218 DAC chip, while another for the rest I/O (the rear
+ * panel and the front mic) with Realtek ALC1220-VB.
+ * Here we provide two distinct names for making UCM profiles easier.
+ */
+{
+       USB_DEVICE(0x0414, 0xa000),
+       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+               .vendor_name = "Gigabyte",
+               .product_name = "Aorus Master Front Headphone",
+               .profile_name = "Gigabyte-Aorus-Master-Front-Headphone",
+               .ifnum = QUIRK_NO_INTERFACE
+       }
+},
+{
+       USB_DEVICE(0x0414, 0xa001),
+       .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+               .vendor_name = "Gigabyte",
+               .product_name = "Aorus Master Main Audio",
+               .profile_name = "Gigabyte-Aorus-Master-Main-Audio",
+               .ifnum = QUIRK_NO_INTERFACE
+       }
+},
+
 #undef USB_DEVICE_VENDOR_SPEC