Merge 5.7-rc7 into android-mainline
Linux 5.7-rc7 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I7442ac05ba366a71926d66593a118ac66374ee7c
This commit is contained in:
@@ -288,6 +288,8 @@ Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
|
||||
Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
|
||||
Takashi YOSHII <takashi.yoshii.zj@renesas.com>
|
||||
Will Deacon <will@kernel.org> <will.deacon@arm.com>
|
||||
Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
|
||||
Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de>
|
||||
Yakir Yang <kuankuan.y@gmail.com> <ykk@rock-chips.com>
|
||||
Yusuke Goda <goda.yusuke@renesas.com>
|
||||
Gustavo Padovan <gustavo@las.ic.unicamp.br>
|
||||
|
||||
@@ -110,6 +110,9 @@ Ethernet switch connected via MDIO to the host, CPU port wired to eth0:
|
||||
#size-cells = <0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port0@0 {
|
||||
reg = <0>;
|
||||
label = "lan1";
|
||||
|
||||
+16
-4
@@ -5507,10 +5507,10 @@ F: drivers/gpu/drm/vboxvideo/
|
||||
|
||||
DRM DRIVER FOR VMWARE VIRTUAL GPU
|
||||
M: "VMware Graphics" <linux-graphics-maintainer@vmware.com>
|
||||
M: Thomas Hellstrom <thellstrom@vmware.com>
|
||||
M: Roland Scheidegger <sroland@vmware.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
T: git git://people.freedesktop.org/~thomash/linux
|
||||
T: git git://people.freedesktop.org/~sroland/linux
|
||||
F: drivers/gpu/drm/vmwgfx/
|
||||
F: include/uapi/drm/vmwgfx_drm.h
|
||||
|
||||
@@ -7829,7 +7829,7 @@ T: git git://linuxtv.org/media_tree.git
|
||||
F: drivers/media/platform/sti/hva
|
||||
|
||||
HWPOISON MEMORY FAILURE HANDLING
|
||||
M: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
|
||||
M: Naoya Horiguchi <naoya.horiguchi@nec.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: mm/hwpoison-inject.c
|
||||
@@ -7941,7 +7941,7 @@ F: Documentation/i2c/busses/i2c-parport.rst
|
||||
F: drivers/i2c/busses/i2c-parport.c
|
||||
|
||||
I2C SUBSYSTEM
|
||||
M: Wolfram Sang <wsa@the-dreams.de>
|
||||
M: Wolfram Sang <wsa@kernel.org>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://i2c.wiki.kernel.org/
|
||||
@@ -9185,6 +9185,11 @@ L: kexec@lists.infradead.org
|
||||
S: Maintained
|
||||
W: http://lse.sourceforge.net/kdump/
|
||||
F: Documentation/admin-guide/kdump/
|
||||
F: fs/proc/vmcore.c
|
||||
F: include/linux/crash_core.h
|
||||
F: include/linux/crash_dump.h
|
||||
F: include/uapi/linux/vmcore.h
|
||||
F: kernel/crash_*.c
|
||||
|
||||
KEENE FM RADIO TRANSMITTER DRIVER
|
||||
M: Hans Verkuil <hverkuil@xs4all.nl>
|
||||
@@ -10662,6 +10667,13 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/mediatek/
|
||||
|
||||
MEDIATEK I2C CONTROLLER DRIVER
|
||||
M: Qii Wang <qii.wang@mediatek.com>
|
||||
L: linux-i2c@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
|
||||
F: drivers/i2c/busses/i2c-mt65xx.c
|
||||
|
||||
MEDIATEK JPEG DRIVER
|
||||
M: Rick Chang <rick.chang@mediatek.com>
|
||||
M: Bin Liu <bin.liu@mediatek.com>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 7
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -65,6 +65,7 @@ CONFIG_DRM_UDL=y
|
||||
CONFIG_DRM_ETNAVIV=y
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_HCD_PLATFORM=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
|
||||
/* clobbers r5 register */
|
||||
.macro DSP_EARLY_INIT
|
||||
#ifdef CONFIG_ISA_ARCV2
|
||||
lr r5, [ARC_AUX_DSP_BUILD]
|
||||
bmsk r5, r5, 7
|
||||
breq r5, 0, 1f
|
||||
mov r5, DSP_CTRL_DISABLED_ALL
|
||||
sr r5, [ARC_AUX_DSP_CTRL]
|
||||
1:
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/* clobbers r10, r11 registers pair */
|
||||
|
||||
@@ -233,6 +233,8 @@
|
||||
|
||||
#ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
|
||||
__RESTORE_REGFILE_HARD
|
||||
|
||||
; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE
|
||||
add sp, sp, SZ_PT_REGS - 8
|
||||
#else
|
||||
add sp, sp, PT_r0
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
# Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
#
|
||||
|
||||
# Pass UTS_MACHINE for user_regset definition
|
||||
CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
|
||||
|
||||
obj-y := arcksyms.o setup.o irq.o reset.o ptrace.o process.o devtree.o
|
||||
obj-y += signal.o traps.o sys.o troubleshoot.o stacktrace.o disasm.o
|
||||
obj-$(CONFIG_ISA_ARCOMPACT) += entry-compact.o intc-compact.o
|
||||
|
||||
@@ -253,7 +253,7 @@ static const struct user_regset arc_regsets[] = {
|
||||
};
|
||||
|
||||
static const struct user_regset_view user_arc_view = {
|
||||
.name = UTS_MACHINE,
|
||||
.name = "arc",
|
||||
.e_machine = EM_ARC_INUSE,
|
||||
.regsets = arc_regsets,
|
||||
.n = ARRAY_SIZE(arc_regsets)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/of_clk.h>
|
||||
#include <linux/of_fdt.h>
|
||||
@@ -424,12 +425,12 @@ static void arc_chk_core_config(void)
|
||||
if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr)
|
||||
panic("Linux built with incorrect DCCM Base address\n");
|
||||
|
||||
if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz)
|
||||
if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz)
|
||||
panic("Linux built with incorrect DCCM Size\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_ICCM
|
||||
if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz)
|
||||
if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz)
|
||||
panic("Linux built with incorrect ICCM Size\n");
|
||||
#endif
|
||||
|
||||
|
||||
@@ -191,10 +191,9 @@ void show_regs(struct pt_regs *regs)
|
||||
if (user_mode(regs))
|
||||
show_faulting_vma(regs->ret); /* faulting code, not data */
|
||||
|
||||
pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n",
|
||||
regs->event, current->thread.fault_address, regs->ret);
|
||||
|
||||
pr_info("STAT32: 0x%08lx", regs->status32);
|
||||
pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\nSTAT: 0x%08lx",
|
||||
regs->event, current->thread.fault_address, regs->ret,
|
||||
regs->status32);
|
||||
|
||||
#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : ""
|
||||
|
||||
@@ -210,11 +209,10 @@ void show_regs(struct pt_regs *regs)
|
||||
(regs->status32 & STATUS_U_MASK) ? "U " : "K ",
|
||||
STS_BIT(regs, DE), STS_BIT(regs, AE));
|
||||
#endif
|
||||
pr_cont(" BTA: 0x%08lx\n", regs->bta);
|
||||
pr_info("BLK: %pS\n SP: 0x%08lx FP: 0x%08lx\n",
|
||||
(void *)regs->blink, regs->sp, regs->fp);
|
||||
pr_cont(" BTA: 0x%08lx\n SP: 0x%08lx FP: 0x%08lx BLK: %pS\n",
|
||||
regs->bta, regs->sp, regs->fp, (void *)regs->blink);
|
||||
pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
|
||||
regs->lp_start, regs->lp_end, regs->lp_count);
|
||||
regs->lp_start, regs->lp_end, regs->lp_count);
|
||||
|
||||
/* print regs->r0 thru regs->r12
|
||||
* Sequential printing was generating horrible code
|
||||
|
||||
@@ -1178,11 +1178,9 @@ int arc_unwind(struct unwind_frame_info *frame)
|
||||
#endif
|
||||
|
||||
/* update frame */
|
||||
#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
|
||||
if (frame->call_frame
|
||||
&& !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
|
||||
frame->call_frame = 0;
|
||||
#endif
|
||||
cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
|
||||
startLoc = min_t(unsigned long, UNW_SP(frame), cfa);
|
||||
endLoc = max_t(unsigned long, UNW_SP(frame), cfa);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
menuconfig ARC_PLAT_EZNPS
|
||||
bool "\"EZchip\" ARC dev platform"
|
||||
depends on ISA_ARCOMPACT
|
||||
select CPU_BIG_ENDIAN
|
||||
select CLKSRC_NPS if !PHYS_ADDR_T_64BIT
|
||||
select EZNPS_GIC
|
||||
|
||||
@@ -304,7 +304,7 @@ do { \
|
||||
__p = uaccess_mask_ptr(__p); \
|
||||
__raw_get_user((x), __p, (err)); \
|
||||
} else { \
|
||||
(x) = 0; (err) = -EFAULT; \
|
||||
(x) = (__force __typeof__(x))0; (err) = -EFAULT; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -1829,10 +1829,11 @@ static void tracehook_report_syscall(struct pt_regs *regs,
|
||||
|
||||
int syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) ||
|
||||
test_thread_flag(TIF_SYSCALL_EMU)) {
|
||||
unsigned long flags = READ_ONCE(current_thread_info()->flags);
|
||||
|
||||
if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
|
||||
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
|
||||
if (!in_syscall(regs) || test_thread_flag(TIF_SYSCALL_EMU))
|
||||
if (!in_syscall(regs) || (flags & _TIF_SYSCALL_EMU))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ config PPC
|
||||
select ARCH_HAS_PTE_SPECIAL
|
||||
select ARCH_HAS_MEMBARRIER_CALLBACKS
|
||||
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
|
||||
select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION)
|
||||
select ARCH_HAS_STRICT_KERNEL_RWX if (PPC32 && !HIBERNATION)
|
||||
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
|
||||
select ARCH_HAS_UACCESS_FLUSHCACHE
|
||||
select ARCH_HAS_UACCESS_MCSAFE if PPC64
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
* updating the accessed and modified bits in the page table tree.
|
||||
*/
|
||||
|
||||
#define _PAGE_USER 0x001 /* usermode access allowed */
|
||||
#define _PAGE_RW 0x002 /* software: user write access allowed */
|
||||
#define _PAGE_PRESENT 0x004 /* software: pte contains a translation */
|
||||
#define _PAGE_PRESENT 0x001 /* software: pte contains a translation */
|
||||
#define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */
|
||||
#define _PAGE_USER 0x004 /* usermode access allowed */
|
||||
#define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */
|
||||
#define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */
|
||||
#define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */
|
||||
@@ -27,7 +27,7 @@
|
||||
#define _PAGE_DIRTY 0x080 /* C: page changed */
|
||||
#define _PAGE_ACCESSED 0x100 /* R: page referenced */
|
||||
#define _PAGE_EXEC 0x200 /* software: exec allowed */
|
||||
#define _PAGE_HASHPTE 0x400 /* hash_page has made an HPTE for this pte */
|
||||
#define _PAGE_RW 0x400 /* software: user write access allowed */
|
||||
#define _PAGE_SPECIAL 0x800 /* software: Special page */
|
||||
|
||||
#ifdef CONFIG_PTE_64BIT
|
||||
|
||||
@@ -348,7 +348,7 @@ BEGIN_MMU_FTR_SECTION
|
||||
andis. r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
|
||||
#endif
|
||||
bne handle_page_fault_tramp_2 /* if not, try to put a PTE */
|
||||
rlwinm r3, r5, 32 - 24, 30, 30 /* DSISR_STORE -> _PAGE_RW */
|
||||
rlwinm r3, r5, 32 - 15, 21, 21 /* DSISR_STORE -> _PAGE_RW */
|
||||
bl hash_page
|
||||
b handle_page_fault_tramp_1
|
||||
FTR_SECTION_ELSE
|
||||
@@ -497,6 +497,7 @@ InstructionTLBMiss:
|
||||
andc. r1,r1,r0 /* check access & ~permission */
|
||||
bne- InstructionAddressInvalid /* return if access not permitted */
|
||||
/* Convert linux-style PTE to low word of PPC-style PTE */
|
||||
rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */
|
||||
ori r1, r1, 0xe06 /* clear out reserved bits */
|
||||
andc r1, r0, r1 /* PP = user? 1 : 0 */
|
||||
BEGIN_FTR_SECTION
|
||||
@@ -564,8 +565,9 @@ DataLoadTLBMiss:
|
||||
* we would need to update the pte atomically with lwarx/stwcx.
|
||||
*/
|
||||
/* Convert linux-style PTE to low word of PPC-style PTE */
|
||||
rlwinm r1,r0,0,30,30 /* _PAGE_RW -> PP msb */
|
||||
rlwimi r0,r0,1,30,30 /* _PAGE_USER -> PP msb */
|
||||
rlwinm r1,r0,32-9,30,30 /* _PAGE_RW -> PP msb */
|
||||
rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */
|
||||
rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */
|
||||
ori r1,r1,0xe04 /* clear out reserved bits */
|
||||
andc r1,r0,r1 /* PP = user? rw? 1: 3: 0 */
|
||||
BEGIN_FTR_SECTION
|
||||
@@ -643,6 +645,7 @@ DataStoreTLBMiss:
|
||||
* we would need to update the pte atomically with lwarx/stwcx.
|
||||
*/
|
||||
/* Convert linux-style PTE to low word of PPC-style PTE */
|
||||
rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */
|
||||
li r1,0xe06 /* clear out reserved bits & PP msb */
|
||||
andc r1,r0,r1 /* PP = user? 1: 0 */
|
||||
BEGIN_FTR_SECTION
|
||||
|
||||
@@ -35,7 +35,7 @@ mmu_hash_lock:
|
||||
/*
|
||||
* Load a PTE into the hash table, if possible.
|
||||
* The address is in r4, and r3 contains an access flag:
|
||||
* _PAGE_RW (0x002) if a write.
|
||||
* _PAGE_RW (0x400) if a write.
|
||||
* r9 contains the SRR1 value, from which we use the MSR_PR bit.
|
||||
* SPRG_THREAD contains the physical address of the current task's thread.
|
||||
*
|
||||
@@ -69,7 +69,7 @@ _GLOBAL(hash_page)
|
||||
blt+ 112f /* assume user more likely */
|
||||
lis r5, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */
|
||||
addi r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
|
||||
rlwimi r3,r9,32-14,31,31 /* MSR_PR -> _PAGE_USER */
|
||||
rlwimi r3,r9,32-12,29,29 /* MSR_PR -> _PAGE_USER */
|
||||
112:
|
||||
#ifndef CONFIG_PTE_64BIT
|
||||
rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */
|
||||
@@ -94,7 +94,7 @@ _GLOBAL(hash_page)
|
||||
#else
|
||||
rlwimi r8,r4,23,20,28 /* compute pte address */
|
||||
#endif
|
||||
rlwinm r0,r3,6,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */
|
||||
rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */
|
||||
ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE
|
||||
|
||||
/*
|
||||
@@ -310,9 +310,11 @@ Hash_msk = (((1 << Hash_bits) - 1) * 64)
|
||||
|
||||
_GLOBAL(create_hpte)
|
||||
/* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */
|
||||
rlwinm r8,r5,32-9,30,30 /* _PAGE_RW -> PP msb */
|
||||
rlwinm r0,r5,32-6,30,30 /* _PAGE_DIRTY -> PP msb */
|
||||
and r8,r5,r0 /* writable if _RW & _DIRTY */
|
||||
rlwimi r5,r5,1,30,30 /* _PAGE_USER -> PP msb */
|
||||
and r8,r8,r0 /* writable if _RW & _DIRTY */
|
||||
rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */
|
||||
rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */
|
||||
ori r8,r8,0xe04 /* clear out reserved bits */
|
||||
andc r8,r5,r8 /* PP = user? (rw&dirty? 1: 3): 0 */
|
||||
BEGIN_FTR_SECTION
|
||||
@@ -564,7 +566,7 @@ _GLOBAL(flush_hash_pages)
|
||||
33: lwarx r8,0,r5 /* fetch the pte flags word */
|
||||
andi. r0,r8,_PAGE_HASHPTE
|
||||
beq 8f /* done if HASHPTE is already clear */
|
||||
rlwinm r8,r8,0,~_PAGE_HASHPTE /* clear HASHPTE bit */
|
||||
rlwinm r8,r8,0,31,29 /* clear HASHPTE bit */
|
||||
stwcx. r8,0,r5 /* update the pte */
|
||||
bne- 33b
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
unsigned long gp_in_global __asm__("gp");
|
||||
register unsigned long gp_in_global __asm__("gp");
|
||||
|
||||
extern asmlinkage void ret_from_fork(void);
|
||||
extern asmlinkage void ret_from_kernel_thread(void);
|
||||
|
||||
@@ -47,7 +47,7 @@ static void setup_zero_page(void)
|
||||
memset((void *)empty_zero_page, 0, PAGE_SIZE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_VM
|
||||
#if defined(CONFIG_MMU) && defined(CONFIG_DEBUG_VM)
|
||||
static inline void print_mlk(char *name, unsigned long b, unsigned long t)
|
||||
{
|
||||
pr_notice("%12s : 0x%08lx - 0x%08lx (%4ld kB)\n", name, b, t,
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include <linux/slab.h>
|
||||
#include <asm/pci_insn.h>
|
||||
|
||||
/* I/O size constraints */
|
||||
#define ZPCI_MAX_READ_SIZE 8
|
||||
#define ZPCI_MAX_WRITE_SIZE 128
|
||||
|
||||
/* I/O Map */
|
||||
#define ZPCI_IOMAP_SHIFT 48
|
||||
#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL
|
||||
@@ -140,7 +144,8 @@ static inline int zpci_memcpy_fromio(void *dst,
|
||||
|
||||
while (n > 0) {
|
||||
size = zpci_get_max_write_size((u64 __force) src,
|
||||
(u64) dst, n, 8);
|
||||
(u64) dst, n,
|
||||
ZPCI_MAX_READ_SIZE);
|
||||
rc = zpci_read_single(dst, src, size);
|
||||
if (rc)
|
||||
break;
|
||||
@@ -161,7 +166,8 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst,
|
||||
|
||||
while (n > 0) {
|
||||
size = zpci_get_max_write_size((u64 __force) dst,
|
||||
(u64) src, n, 128);
|
||||
(u64) src, n,
|
||||
ZPCI_MAX_WRITE_SIZE);
|
||||
if (size > 8) /* main path */
|
||||
rc = zpci_write_block(dst, src, size);
|
||||
else
|
||||
|
||||
@@ -151,7 +151,7 @@ static int kexec_file_add_initrd(struct kimage *image,
|
||||
buf.mem += crashk_res.start;
|
||||
buf.memsz = buf.bufsz;
|
||||
|
||||
data->parm->initrd_start = buf.mem;
|
||||
data->parm->initrd_start = data->memsz;
|
||||
data->parm->initrd_size = buf.memsz;
|
||||
data->memsz += buf.memsz;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val,
|
||||
break;
|
||||
case R_390_64: /* Direct 64 bit. */
|
||||
case R_390_GLOB_DAT:
|
||||
case R_390_JMP_SLOT:
|
||||
*(u64 *)loc = val;
|
||||
break;
|
||||
case R_390_PC16: /* PC relative 16 bit. */
|
||||
|
||||
@@ -159,10 +159,13 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
rste &= ~_SEGMENT_ENTRY_NOEXEC;
|
||||
|
||||
/* Set correct table type for 2G hugepages */
|
||||
if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
|
||||
rste |= _REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE;
|
||||
else
|
||||
if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) {
|
||||
if (likely(pte_present(pte)))
|
||||
rste |= _REGION3_ENTRY_LARGE;
|
||||
rste |= _REGION_ENTRY_TYPE_R3;
|
||||
} else if (likely(pte_present(pte)))
|
||||
rste |= _SEGMENT_ENTRY_LARGE;
|
||||
|
||||
clear_huge_pte_skeys(mm, rste);
|
||||
pte_val(*ptep) = rste;
|
||||
}
|
||||
|
||||
+211
-2
@@ -11,6 +11,113 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/pci_io.h>
|
||||
#include <asm/pci_debug.h>
|
||||
|
||||
static inline void zpci_err_mmio(u8 cc, u8 status, u64 offset)
|
||||
{
|
||||
struct {
|
||||
u64 offset;
|
||||
u8 cc;
|
||||
u8 status;
|
||||
} data = {offset, cc, status};
|
||||
|
||||
zpci_err_hex(&data, sizeof(data));
|
||||
}
|
||||
|
||||
static inline int __pcistb_mio_inuser(
|
||||
void __iomem *ioaddr, const void __user *src,
|
||||
u64 len, u8 *status)
|
||||
{
|
||||
int cc = -ENXIO;
|
||||
|
||||
asm volatile (
|
||||
" sacf 256\n"
|
||||
"0: .insn rsy,0xeb00000000d4,%[len],%[ioaddr],%[src]\n"
|
||||
"1: ipm %[cc]\n"
|
||||
" srl %[cc],28\n"
|
||||
"2: sacf 768\n"
|
||||
EX_TABLE(0b, 2b) EX_TABLE(1b, 2b)
|
||||
: [cc] "+d" (cc), [len] "+d" (len)
|
||||
: [ioaddr] "a" (ioaddr), [src] "Q" (*((u8 __force *)src))
|
||||
: "cc", "memory");
|
||||
*status = len >> 24 & 0xff;
|
||||
return cc;
|
||||
}
|
||||
|
||||
static inline int __pcistg_mio_inuser(
|
||||
void __iomem *ioaddr, const void __user *src,
|
||||
u64 ulen, u8 *status)
|
||||
{
|
||||
register u64 addr asm("2") = (u64 __force) ioaddr;
|
||||
register u64 len asm("3") = ulen;
|
||||
int cc = -ENXIO;
|
||||
u64 val = 0;
|
||||
u64 cnt = ulen;
|
||||
u8 tmp;
|
||||
|
||||
/*
|
||||
* copy 0 < @len <= 8 bytes from @src into the right most bytes of
|
||||
* a register, then store it to PCI at @ioaddr while in secondary
|
||||
* address space. pcistg then uses the user mappings.
|
||||
*/
|
||||
asm volatile (
|
||||
" sacf 256\n"
|
||||
"0: llgc %[tmp],0(%[src])\n"
|
||||
" sllg %[val],%[val],8\n"
|
||||
" aghi %[src],1\n"
|
||||
" ogr %[val],%[tmp]\n"
|
||||
" brctg %[cnt],0b\n"
|
||||
"1: .insn rre,0xb9d40000,%[val],%[ioaddr]\n"
|
||||
"2: ipm %[cc]\n"
|
||||
" srl %[cc],28\n"
|
||||
"3: sacf 768\n"
|
||||
EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b)
|
||||
:
|
||||
[src] "+a" (src), [cnt] "+d" (cnt),
|
||||
[val] "+d" (val), [tmp] "=d" (tmp),
|
||||
[len] "+d" (len), [cc] "+d" (cc),
|
||||
[ioaddr] "+a" (addr)
|
||||
:: "cc", "memory");
|
||||
*status = len >> 24 & 0xff;
|
||||
|
||||
/* did we read everything from user memory? */
|
||||
if (!cc && cnt != 0)
|
||||
cc = -EFAULT;
|
||||
|
||||
return cc;
|
||||
}
|
||||
|
||||
static inline int __memcpy_toio_inuser(void __iomem *dst,
|
||||
const void __user *src, size_t n)
|
||||
{
|
||||
int size, rc = 0;
|
||||
u8 status = 0;
|
||||
mm_segment_t old_fs;
|
||||
|
||||
if (!src)
|
||||
return -EINVAL;
|
||||
|
||||
old_fs = enable_sacf_uaccess();
|
||||
while (n > 0) {
|
||||
size = zpci_get_max_write_size((u64 __force) dst,
|
||||
(u64 __force) src, n,
|
||||
ZPCI_MAX_WRITE_SIZE);
|
||||
if (size > 8) /* main path */
|
||||
rc = __pcistb_mio_inuser(dst, src, size, &status);
|
||||
else
|
||||
rc = __pcistg_mio_inuser(dst, src, size, &status);
|
||||
if (rc)
|
||||
break;
|
||||
src += size;
|
||||
dst += size;
|
||||
n -= size;
|
||||
}
|
||||
disable_sacf_uaccess(old_fs);
|
||||
if (rc)
|
||||
zpci_err_mmio(rc, status, (__force u64) dst);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long get_pfn(unsigned long user_addr, unsigned long access,
|
||||
unsigned long *pfn)
|
||||
@@ -46,6 +153,20 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
|
||||
|
||||
if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Only support read access to MIO capable devices on a MIO enabled
|
||||
* system. Otherwise we would have to check for every address if it is
|
||||
* a special ZPCI_ADDR and we would have to do a get_pfn() which we
|
||||
* don't need for MIO capable devices.
|
||||
*/
|
||||
if (static_branch_likely(&have_mio)) {
|
||||
ret = __memcpy_toio_inuser((void __iomem *) mmio_addr,
|
||||
user_buffer,
|
||||
length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (length > 64) {
|
||||
buf = kmalloc(length, GFP_KERNEL);
|
||||
if (!buf)
|
||||
@@ -56,7 +177,8 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
|
||||
ret = get_pfn(mmio_addr, VM_WRITE, &pfn);
|
||||
if (ret)
|
||||
goto out;
|
||||
io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK));
|
||||
io_addr = (void __iomem *)((pfn << PAGE_SHIFT) |
|
||||
(mmio_addr & ~PAGE_MASK));
|
||||
|
||||
ret = -EFAULT;
|
||||
if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE)
|
||||
@@ -72,6 +194,78 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int __pcilg_mio_inuser(
|
||||
void __user *dst, const void __iomem *ioaddr,
|
||||
u64 ulen, u8 *status)
|
||||
{
|
||||
register u64 addr asm("2") = (u64 __force) ioaddr;
|
||||
register u64 len asm("3") = ulen;
|
||||
u64 cnt = ulen;
|
||||
int shift = ulen * 8;
|
||||
int cc = -ENXIO;
|
||||
u64 val, tmp;
|
||||
|
||||
/*
|
||||
* read 0 < @len <= 8 bytes from the PCI memory mapped at @ioaddr (in
|
||||
* user space) into a register using pcilg then store these bytes at
|
||||
* user address @dst
|
||||
*/
|
||||
asm volatile (
|
||||
" sacf 256\n"
|
||||
"0: .insn rre,0xb9d60000,%[val],%[ioaddr]\n"
|
||||
"1: ipm %[cc]\n"
|
||||
" srl %[cc],28\n"
|
||||
" ltr %[cc],%[cc]\n"
|
||||
" jne 4f\n"
|
||||
"2: ahi %[shift],-8\n"
|
||||
" srlg %[tmp],%[val],0(%[shift])\n"
|
||||
"3: stc %[tmp],0(%[dst])\n"
|
||||
" aghi %[dst],1\n"
|
||||
" brctg %[cnt],2b\n"
|
||||
"4: sacf 768\n"
|
||||
EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b)
|
||||
:
|
||||
[cc] "+d" (cc), [val] "=d" (val), [len] "+d" (len),
|
||||
[dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp),
|
||||
[shift] "+d" (shift)
|
||||
:
|
||||
[ioaddr] "a" (addr)
|
||||
: "cc", "memory");
|
||||
|
||||
/* did we write everything to the user space buffer? */
|
||||
if (!cc && cnt != 0)
|
||||
cc = -EFAULT;
|
||||
|
||||
*status = len >> 24 & 0xff;
|
||||
return cc;
|
||||
}
|
||||
|
||||
static inline int __memcpy_fromio_inuser(void __user *dst,
|
||||
const void __iomem *src,
|
||||
unsigned long n)
|
||||
{
|
||||
int size, rc = 0;
|
||||
u8 status;
|
||||
mm_segment_t old_fs;
|
||||
|
||||
old_fs = enable_sacf_uaccess();
|
||||
while (n > 0) {
|
||||
size = zpci_get_max_write_size((u64 __force) src,
|
||||
(u64 __force) dst, n,
|
||||
ZPCI_MAX_READ_SIZE);
|
||||
rc = __pcilg_mio_inuser(dst, src, size, &status);
|
||||
if (rc)
|
||||
break;
|
||||
src += size;
|
||||
dst += size;
|
||||
n -= size;
|
||||
}
|
||||
disable_sacf_uaccess(old_fs);
|
||||
if (rc)
|
||||
zpci_err_mmio(rc, status, (__force u64) dst);
|
||||
return rc;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
|
||||
void __user *, user_buffer, size_t, length)
|
||||
{
|
||||
@@ -86,12 +280,27 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
|
||||
|
||||
if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Only support write access to MIO capable devices on a MIO enabled
|
||||
* system. Otherwise we would have to check for every address if it is
|
||||
* a special ZPCI_ADDR and we would have to do a get_pfn() which we
|
||||
* don't need for MIO capable devices.
|
||||
*/
|
||||
if (static_branch_likely(&have_mio)) {
|
||||
ret = __memcpy_fromio_inuser(
|
||||
user_buffer, (const void __iomem *)mmio_addr,
|
||||
length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (length > 64) {
|
||||
buf = kmalloc(length, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
} else
|
||||
} else {
|
||||
buf = local_buf;
|
||||
}
|
||||
|
||||
ret = get_pfn(mmio_addr, VM_READ, &pfn);
|
||||
if (ret)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#ifndef __ASM_SH_SOCKIOS_H
|
||||
#define __ASM_SH_SOCKIOS_H
|
||||
|
||||
#include <linux/time_types.h>
|
||||
|
||||
/* Socket-level I/O control calls. */
|
||||
#define FIOGETOWN _IOR('f', 123, int)
|
||||
#define FIOSETOWN _IOW('f', 124, int)
|
||||
|
||||
@@ -331,9 +331,9 @@ static void __init srmmu_nocache_init(void)
|
||||
|
||||
while (vaddr < srmmu_nocache_end) {
|
||||
pgd = pgd_offset_k(vaddr);
|
||||
p4d = p4d_offset(__nocache_fix(pgd), vaddr);
|
||||
pud = pud_offset(__nocache_fix(p4d), vaddr);
|
||||
pmd = pmd_offset(__nocache_fix(pgd), vaddr);
|
||||
p4d = p4d_offset(pgd, vaddr);
|
||||
pud = pud_offset(p4d, vaddr);
|
||||
pmd = pmd_offset(__nocache_fix(pud), vaddr);
|
||||
pte = pte_offset_kernel(__nocache_fix(pmd), vaddr);
|
||||
|
||||
pteval = ((paddr >> 4) | SRMMU_ET_PTE | SRMMU_PRIV);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define TRANS_TAP_LEN strlen(TRANS_TAP)
|
||||
|
||||
#define TRANS_GRE "gre"
|
||||
#define TRANS_GRE_LEN strlen(TRANS_RAW)
|
||||
#define TRANS_GRE_LEN strlen(TRANS_GRE)
|
||||
|
||||
#define TRANS_L2TPV3 "l2tpv3"
|
||||
#define TRANS_L2TPV3_LEN strlen(TRANS_L2TPV3)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <asm-generic/xor.h>
|
||||
#include <shared/timer-internal.h>
|
||||
#include <linux/time-internal.h>
|
||||
|
||||
/* pick an arbitrary one - measuring isn't possible with inf-cpu */
|
||||
#define XOR_SELECT_TEMPLATE(x) \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <sysdep/ptrace_user.h>
|
||||
#include <sysdep/syscalls.h>
|
||||
#include <linux/time-internal.h>
|
||||
#include <asm/unistd.h>
|
||||
|
||||
void handle_syscall(struct uml_pt_regs *r)
|
||||
{
|
||||
|
||||
@@ -59,14 +59,14 @@ u8 buf[SETUP_SECT_MAX*512];
|
||||
#define PECOFF_COMPAT_RESERVE 0x0
|
||||
#endif
|
||||
|
||||
unsigned long efi32_stub_entry;
|
||||
unsigned long efi64_stub_entry;
|
||||
unsigned long efi_pe_entry;
|
||||
unsigned long efi32_pe_entry;
|
||||
unsigned long kernel_info;
|
||||
unsigned long startup_64;
|
||||
unsigned long _ehead;
|
||||
unsigned long _end;
|
||||
static unsigned long efi32_stub_entry;
|
||||
static unsigned long efi64_stub_entry;
|
||||
static unsigned long efi_pe_entry;
|
||||
static unsigned long efi32_pe_entry;
|
||||
static unsigned long kernel_info;
|
||||
static unsigned long startup_64;
|
||||
static unsigned long _ehead;
|
||||
static unsigned long _end;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
|
||||
@@ -226,10 +226,18 @@ static int hv_cpu_die(unsigned int cpu)
|
||||
|
||||
rdmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
|
||||
if (re_ctrl.target_vp == hv_vp_index[cpu]) {
|
||||
/* Reassign to some other online CPU */
|
||||
/*
|
||||
* Reassign reenlightenment notifications to some other online
|
||||
* CPU or just disable the feature if there are no online CPUs
|
||||
* left (happens on hibernation).
|
||||
*/
|
||||
new_cpu = cpumask_any_but(cpu_online_mask, cpu);
|
||||
|
||||
re_ctrl.target_vp = hv_vp_index[new_cpu];
|
||||
if (new_cpu < nr_cpu_ids)
|
||||
re_ctrl.target_vp = hv_vp_index[new_cpu];
|
||||
else
|
||||
re_ctrl.enabled = 0;
|
||||
|
||||
wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl));
|
||||
}
|
||||
|
||||
@@ -293,6 +301,13 @@ static void hv_resume(void)
|
||||
|
||||
hv_hypercall_pg = hv_hypercall_pg_saved;
|
||||
hv_hypercall_pg_saved = NULL;
|
||||
|
||||
/*
|
||||
* Reenlightenment notifications are disabled by hv_cpu_die(0),
|
||||
* reenable them here if hv_reenlightenment_cb was previously set.
|
||||
*/
|
||||
if (hv_reenlightenment_cb)
|
||||
set_hv_tscchange_cb(hv_reenlightenment_cb);
|
||||
}
|
||||
|
||||
/* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */
|
||||
|
||||
@@ -52,9 +52,9 @@ static __always_inline void
|
||||
arch_set_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
if (__builtin_constant_p(nr)) {
|
||||
asm volatile(LOCK_PREFIX "orb %1,%0"
|
||||
asm volatile(LOCK_PREFIX "orb %b1,%0"
|
||||
: CONST_MASK_ADDR(nr, addr)
|
||||
: "iq" (CONST_MASK(nr) & 0xff)
|
||||
: "iq" (CONST_MASK(nr))
|
||||
: "memory");
|
||||
} else {
|
||||
asm volatile(LOCK_PREFIX __ASM_SIZE(bts) " %1,%0"
|
||||
@@ -72,9 +72,9 @@ static __always_inline void
|
||||
arch_clear_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
if (__builtin_constant_p(nr)) {
|
||||
asm volatile(LOCK_PREFIX "andb %1,%0"
|
||||
asm volatile(LOCK_PREFIX "andb %b1,%0"
|
||||
: CONST_MASK_ADDR(nr, addr)
|
||||
: "iq" (CONST_MASK(nr) ^ 0xff));
|
||||
: "iq" (~CONST_MASK(nr)));
|
||||
} else {
|
||||
asm volatile(LOCK_PREFIX __ASM_SIZE(btr) " %1,%0"
|
||||
: : RLONG_ADDR(addr), "Ir" (nr) : "memory");
|
||||
@@ -123,9 +123,9 @@ static __always_inline void
|
||||
arch_change_bit(long nr, volatile unsigned long *addr)
|
||||
{
|
||||
if (__builtin_constant_p(nr)) {
|
||||
asm volatile(LOCK_PREFIX "xorb %1,%0"
|
||||
asm volatile(LOCK_PREFIX "xorb %b1,%0"
|
||||
: CONST_MASK_ADDR(nr, addr)
|
||||
: "iq" ((u8)CONST_MASK(nr)));
|
||||
: "iq" (CONST_MASK(nr)));
|
||||
} else {
|
||||
asm volatile(LOCK_PREFIX __ASM_SIZE(btc) " %1,%0"
|
||||
: : RLONG_ADDR(addr), "Ir" (nr) : "memory");
|
||||
|
||||
@@ -320,12 +320,19 @@ EXPORT_SYMBOL_GPL(unwind_get_return_address);
|
||||
|
||||
unsigned long *unwind_get_return_address_ptr(struct unwind_state *state)
|
||||
{
|
||||
struct task_struct *task = state->task;
|
||||
|
||||
if (unwind_done(state))
|
||||
return NULL;
|
||||
|
||||
if (state->regs)
|
||||
return &state->regs->ip;
|
||||
|
||||
if (task != current && state->sp == task->thread.sp) {
|
||||
struct inactive_task_frame *frame = (void *)task->thread.sp;
|
||||
return &frame->ret_addr;
|
||||
}
|
||||
|
||||
if (state->sp)
|
||||
return (unsigned long *)state->sp - 1;
|
||||
|
||||
|
||||
@@ -372,7 +372,7 @@ static void enter_uniprocessor(void)
|
||||
int cpu;
|
||||
int err;
|
||||
|
||||
if (downed_cpus == NULL &&
|
||||
if (!cpumask_available(downed_cpus) &&
|
||||
!alloc_cpumask_var(&downed_cpus, GFP_KERNEL)) {
|
||||
pr_notice("Failed to allocate mask\n");
|
||||
goto out;
|
||||
@@ -402,7 +402,7 @@ static void leave_uniprocessor(void)
|
||||
int cpu;
|
||||
int err;
|
||||
|
||||
if (downed_cpus == NULL || cpumask_weight(downed_cpus) == 0)
|
||||
if (!cpumask_available(downed_cpus) || cpumask_weight(downed_cpus) == 0)
|
||||
return;
|
||||
pr_notice("Re-enabling CPUs...\n");
|
||||
for_each_cpu(cpu, downed_cpus) {
|
||||
|
||||
+5
-1
@@ -2016,9 +2016,13 @@ bool acpi_ec_dispatch_gpe(void)
|
||||
* to allow the caller to process events properly after that.
|
||||
*/
|
||||
ret = acpi_dispatch_gpe(NULL, first_ec->gpe);
|
||||
if (ret == ACPI_INTERRUPT_HANDLED)
|
||||
if (ret == ACPI_INTERRUPT_HANDLED) {
|
||||
pm_pr_dbg("EC GPE dispatched\n");
|
||||
|
||||
/* Flush the event and query workqueues. */
|
||||
acpi_ec_flush_work();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
+4
-11
@@ -980,13 +980,6 @@ static int acpi_s2idle_prepare_late(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_s2idle_sync(void)
|
||||
{
|
||||
/* The EC driver uses special workqueues that need to be flushed. */
|
||||
acpi_ec_flush_work();
|
||||
acpi_os_wait_events_complete(); /* synchronize Notify handling */
|
||||
}
|
||||
|
||||
static bool acpi_s2idle_wake(void)
|
||||
{
|
||||
if (!acpi_sci_irq_valid())
|
||||
@@ -1018,7 +1011,7 @@ static bool acpi_s2idle_wake(void)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Cancel the wakeup and process all pending events in case
|
||||
* Cancel the SCI wakeup and process all pending events in case
|
||||
* there are any wakeup ones in there.
|
||||
*
|
||||
* Note that if any non-EC GPEs are active at this point, the
|
||||
@@ -1026,8 +1019,7 @@ static bool acpi_s2idle_wake(void)
|
||||
* should be missed by canceling the wakeup here.
|
||||
*/
|
||||
pm_system_cancel_wakeup();
|
||||
|
||||
acpi_s2idle_sync();
|
||||
acpi_os_wait_events_complete();
|
||||
|
||||
/*
|
||||
* The SCI is in the "suspended" state now and it cannot produce
|
||||
@@ -1060,7 +1052,8 @@ static void acpi_s2idle_restore(void)
|
||||
* of GPEs.
|
||||
*/
|
||||
acpi_os_wait_events_complete(); /* synchronize GPE processing */
|
||||
acpi_s2idle_sync();
|
||||
acpi_ec_flush_work(); /* flush the EC driver's workqueues */
|
||||
acpi_os_wait_events_complete(); /* synchronize Notify handling */
|
||||
|
||||
s2idle_wakeup = false;
|
||||
|
||||
|
||||
+37
-18
@@ -365,6 +365,7 @@ struct device_link *device_link_add(struct device *consumer,
|
||||
link->flags |= DL_FLAG_STATELESS;
|
||||
goto reorder;
|
||||
} else {
|
||||
link->flags |= DL_FLAG_STATELESS;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -433,12 +434,16 @@ struct device_link *device_link_add(struct device *consumer,
|
||||
flags & DL_FLAG_PM_RUNTIME)
|
||||
pm_runtime_resume(supplier);
|
||||
|
||||
list_add_tail_rcu(&link->s_node, &supplier->links.consumers);
|
||||
list_add_tail_rcu(&link->c_node, &consumer->links.suppliers);
|
||||
|
||||
if (flags & DL_FLAG_SYNC_STATE_ONLY) {
|
||||
dev_dbg(consumer,
|
||||
"Linked as a sync state only consumer to %s\n",
|
||||
dev_name(supplier));
|
||||
goto out;
|
||||
}
|
||||
|
||||
reorder:
|
||||
/*
|
||||
* Move the consumer and all of the devices depending on it to the end
|
||||
@@ -449,12 +454,9 @@ reorder:
|
||||
*/
|
||||
device_reorder_to_tail(consumer, NULL);
|
||||
|
||||
list_add_tail_rcu(&link->s_node, &supplier->links.consumers);
|
||||
list_add_tail_rcu(&link->c_node, &consumer->links.suppliers);
|
||||
|
||||
dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier));
|
||||
|
||||
out:
|
||||
out:
|
||||
device_pm_unlock();
|
||||
device_links_write_unlock();
|
||||
|
||||
@@ -829,6 +831,13 @@ static void __device_links_supplier_defer_sync(struct device *sup)
|
||||
list_add_tail(&sup->links.defer_sync, &deferred_sync);
|
||||
}
|
||||
|
||||
static void device_link_drop_managed(struct device_link *link)
|
||||
{
|
||||
link->flags &= ~DL_FLAG_MANAGED;
|
||||
WRITE_ONCE(link->status, DL_STATE_NONE);
|
||||
kref_put(&link->kref, __device_link_del);
|
||||
}
|
||||
|
||||
/**
|
||||
* device_links_driver_bound - Update device links after probing its driver.
|
||||
* @dev: Device to update the links for.
|
||||
@@ -842,7 +851,7 @@ static void __device_links_supplier_defer_sync(struct device *sup)
|
||||
*/
|
||||
void device_links_driver_bound(struct device *dev)
|
||||
{
|
||||
struct device_link *link;
|
||||
struct device_link *link, *ln;
|
||||
LIST_HEAD(sync_list);
|
||||
|
||||
/*
|
||||
@@ -882,18 +891,35 @@ void device_links_driver_bound(struct device *dev)
|
||||
else
|
||||
__device_links_queue_sync_state(dev, &sync_list);
|
||||
|
||||
list_for_each_entry(link, &dev->links.suppliers, c_node) {
|
||||
list_for_each_entry_safe(link, ln, &dev->links.suppliers, c_node) {
|
||||
struct device *supplier;
|
||||
|
||||
if (!(link->flags & DL_FLAG_MANAGED))
|
||||
continue;
|
||||
|
||||
WARN_ON(link->status != DL_STATE_CONSUMER_PROBE);
|
||||
WRITE_ONCE(link->status, DL_STATE_ACTIVE);
|
||||
supplier = link->supplier;
|
||||
if (link->flags & DL_FLAG_SYNC_STATE_ONLY) {
|
||||
/*
|
||||
* When DL_FLAG_SYNC_STATE_ONLY is set, it means no
|
||||
* other DL_MANAGED_LINK_FLAGS have been set. So, it's
|
||||
* save to drop the managed link completely.
|
||||
*/
|
||||
device_link_drop_managed(link);
|
||||
} else {
|
||||
WARN_ON(link->status != DL_STATE_CONSUMER_PROBE);
|
||||
WRITE_ONCE(link->status, DL_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This needs to be done even for the deleted
|
||||
* DL_FLAG_SYNC_STATE_ONLY device link in case it was the last
|
||||
* device link that was preventing the supplier from getting a
|
||||
* sync_state() call.
|
||||
*/
|
||||
if (defer_sync_state_count)
|
||||
__device_links_supplier_defer_sync(link->supplier);
|
||||
__device_links_supplier_defer_sync(supplier);
|
||||
else
|
||||
__device_links_queue_sync_state(link->supplier,
|
||||
&sync_list);
|
||||
__device_links_queue_sync_state(supplier, &sync_list);
|
||||
}
|
||||
|
||||
dev->links.status = DL_DEV_DRIVER_BOUND;
|
||||
@@ -903,13 +929,6 @@ void device_links_driver_bound(struct device *dev)
|
||||
device_links_flush_sync_list(&sync_list, dev);
|
||||
}
|
||||
|
||||
static void device_link_drop_managed(struct device_link *link)
|
||||
{
|
||||
link->flags &= ~DL_FLAG_MANAGED;
|
||||
WRITE_ONCE(link->status, DL_STATE_NONE);
|
||||
kref_put(&link->kref, __device_link_del);
|
||||
}
|
||||
|
||||
/**
|
||||
* __device_links_no_driver - Update links of a device without a driver.
|
||||
* @dev: Device without a drvier.
|
||||
|
||||
@@ -1535,6 +1535,13 @@ static void null_config_discard(struct nullb *nullb)
|
||||
{
|
||||
if (nullb->dev->discard == false)
|
||||
return;
|
||||
|
||||
if (nullb->dev->zoned) {
|
||||
nullb->dev->discard = false;
|
||||
pr_info("discard option is ignored in zoned mode\n");
|
||||
return;
|
||||
}
|
||||
|
||||
nullb->q->limits.discard_granularity = nullb->dev->blocksize;
|
||||
nullb->q->limits.discard_alignment = nullb->dev->blocksize;
|
||||
blk_queue_max_discard_sectors(nullb->q, UINT_MAX >> 9);
|
||||
|
||||
@@ -23,6 +23,10 @@ int null_init_zoned_dev(struct nullb_device *dev, struct request_queue *q)
|
||||
pr_err("zone_size must be power-of-two\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (dev->zone_size > dev->size) {
|
||||
pr_err("Zone size larger than device capacity\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT;
|
||||
dev->nr_zones = dev_size >>
|
||||
|
||||
@@ -291,6 +291,7 @@ int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl)
|
||||
}
|
||||
|
||||
/* Setup cmd context */
|
||||
ret = -ENOMEM;
|
||||
mhi_ctxt->cmd_ctxt = mhi_alloc_coherent(mhi_cntrl,
|
||||
sizeof(*mhi_ctxt->cmd_ctxt) *
|
||||
NR_OF_CMD_RINGS,
|
||||
@@ -1100,6 +1101,7 @@ static int mhi_driver_probe(struct device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if (dl_chan) {
|
||||
/*
|
||||
* If channel supports LPM notifications then status_cb should
|
||||
|
||||
+11
-3
@@ -22,6 +22,7 @@ int dev_dax_kmem_probe(struct device *dev)
|
||||
resource_size_t kmem_size;
|
||||
resource_size_t kmem_end;
|
||||
struct resource *new_res;
|
||||
const char *new_res_name;
|
||||
int numa_node;
|
||||
int rc;
|
||||
|
||||
@@ -48,11 +49,16 @@ int dev_dax_kmem_probe(struct device *dev)
|
||||
kmem_size &= ~(memory_block_size_bytes() - 1);
|
||||
kmem_end = kmem_start + kmem_size;
|
||||
|
||||
/* Region is permanently reserved. Hot-remove not yet implemented. */
|
||||
new_res = request_mem_region(kmem_start, kmem_size, dev_name(dev));
|
||||
new_res_name = kstrdup(dev_name(dev), GFP_KERNEL);
|
||||
if (!new_res_name)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Region is permanently reserved if hotremove fails. */
|
||||
new_res = request_mem_region(kmem_start, kmem_size, new_res_name);
|
||||
if (!new_res) {
|
||||
dev_warn(dev, "could not reserve region [%pa-%pa]\n",
|
||||
&kmem_start, &kmem_end);
|
||||
kfree(new_res_name);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -63,12 +69,12 @@ int dev_dax_kmem_probe(struct device *dev)
|
||||
* unknown to us that will break add_memory() below.
|
||||
*/
|
||||
new_res->flags = IORESOURCE_SYSTEM_RAM;
|
||||
new_res->name = dev_name(dev);
|
||||
|
||||
rc = add_memory(numa_node, new_res->start, resource_size(new_res));
|
||||
if (rc) {
|
||||
release_resource(new_res);
|
||||
kfree(new_res);
|
||||
kfree(new_res_name);
|
||||
return rc;
|
||||
}
|
||||
dev_dax->dax_kmem_res = new_res;
|
||||
@@ -83,6 +89,7 @@ static int dev_dax_kmem_remove(struct device *dev)
|
||||
struct resource *res = dev_dax->dax_kmem_res;
|
||||
resource_size_t kmem_start = res->start;
|
||||
resource_size_t kmem_size = resource_size(res);
|
||||
const char *res_name = res->name;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
@@ -102,6 +109,7 @@ static int dev_dax_kmem_remove(struct device *dev)
|
||||
/* Release and free dax resources */
|
||||
release_resource(res);
|
||||
kfree(res);
|
||||
kfree(res_name);
|
||||
dev_dax->dax_kmem_res = NULL;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1166,10 +1166,11 @@ static int dmatest_run_set(const char *val, const struct kernel_param *kp)
|
||||
mutex_unlock(&info->lock);
|
||||
return ret;
|
||||
} else if (dmatest_run) {
|
||||
if (is_threaded_test_pending(info))
|
||||
start_threaded_tests(info);
|
||||
else
|
||||
pr_info("Could not start test, no channels configured\n");
|
||||
if (!is_threaded_test_pending(info)) {
|
||||
pr_info("No channels configured, continue with any\n");
|
||||
add_threaded_test(info);
|
||||
}
|
||||
start_threaded_tests(info);
|
||||
} else {
|
||||
stop_threaded_test(info);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,13 @@ int idxd_unmask_msix_vector(struct idxd_device *idxd, int vec_id)
|
||||
perm.ignore = 0;
|
||||
iowrite32(perm.bits, idxd->reg_base + offset);
|
||||
|
||||
/*
|
||||
* A readback from the device ensures that any previously generated
|
||||
* completion record writes are visible to software based on PCI
|
||||
* ordering rules.
|
||||
*/
|
||||
perm.bits = ioread32(idxd->reg_base + offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+19
-7
@@ -173,6 +173,7 @@ static int irq_process_pending_llist(struct idxd_irq_entry *irq_entry,
|
||||
struct llist_node *head;
|
||||
int queued = 0;
|
||||
|
||||
*processed = 0;
|
||||
head = llist_del_all(&irq_entry->pending_llist);
|
||||
if (!head)
|
||||
return 0;
|
||||
@@ -197,6 +198,7 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry,
|
||||
struct list_head *node, *next;
|
||||
int queued = 0;
|
||||
|
||||
*processed = 0;
|
||||
if (list_empty(&irq_entry->work_list))
|
||||
return 0;
|
||||
|
||||
@@ -218,10 +220,9 @@ static int irq_process_work_list(struct idxd_irq_entry *irq_entry,
|
||||
return queued;
|
||||
}
|
||||
|
||||
irqreturn_t idxd_wq_thread(int irq, void *data)
|
||||
static int idxd_desc_process(struct idxd_irq_entry *irq_entry)
|
||||
{
|
||||
struct idxd_irq_entry *irq_entry = data;
|
||||
int rc, processed = 0, retry = 0;
|
||||
int rc, processed, total = 0;
|
||||
|
||||
/*
|
||||
* There are two lists we are processing. The pending_llist is where
|
||||
@@ -244,15 +245,26 @@ irqreturn_t idxd_wq_thread(int irq, void *data)
|
||||
*/
|
||||
do {
|
||||
rc = irq_process_work_list(irq_entry, &processed);
|
||||
if (rc != 0) {
|
||||
retry++;
|
||||
total += processed;
|
||||
if (rc != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = irq_process_pending_llist(irq_entry, &processed);
|
||||
} while (rc != 0 && retry != 10);
|
||||
total += processed;
|
||||
} while (rc != 0);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
irqreturn_t idxd_wq_thread(int irq, void *data)
|
||||
{
|
||||
struct idxd_irq_entry *irq_entry = data;
|
||||
int processed;
|
||||
|
||||
processed = idxd_desc_process(irq_entry);
|
||||
idxd_unmask_msix_vector(irq_entry->idxd, irq_entry->id);
|
||||
/* catch anything unprocessed after unmasking */
|
||||
processed += idxd_desc_process(irq_entry);
|
||||
|
||||
if (processed == 0)
|
||||
return IRQ_NONE;
|
||||
|
||||
@@ -175,13 +175,11 @@ struct owl_dma_txd {
|
||||
* @id: physical index to this channel
|
||||
* @base: virtual memory base for the dma channel
|
||||
* @vchan: the virtual channel currently being served by this physical channel
|
||||
* @lock: a lock to use when altering an instance of this struct
|
||||
*/
|
||||
struct owl_dma_pchan {
|
||||
u32 id;
|
||||
void __iomem *base;
|
||||
struct owl_dma_vchan *vchan;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -437,14 +435,14 @@ static struct owl_dma_pchan *owl_dma_get_pchan(struct owl_dma *od,
|
||||
for (i = 0; i < od->nr_pchans; i++) {
|
||||
pchan = &od->pchans[i];
|
||||
|
||||
spin_lock_irqsave(&pchan->lock, flags);
|
||||
spin_lock_irqsave(&od->lock, flags);
|
||||
if (!pchan->vchan) {
|
||||
pchan->vchan = vchan;
|
||||
spin_unlock_irqrestore(&pchan->lock, flags);
|
||||
spin_unlock_irqrestore(&od->lock, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&pchan->lock, flags);
|
||||
spin_unlock_irqrestore(&od->lock, flags);
|
||||
}
|
||||
|
||||
return pchan;
|
||||
|
||||
@@ -900,7 +900,7 @@ static int tegra_adma_probe(struct platform_device *pdev)
|
||||
ret = dma_async_device_register(&tdma->dma_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret);
|
||||
goto irq_dispose;
|
||||
goto rpm_put;
|
||||
}
|
||||
|
||||
ret = of_dma_controller_register(pdev->dev.of_node,
|
||||
|
||||
@@ -2156,7 +2156,8 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl,
|
||||
d->residue += sg_dma_len(sgent);
|
||||
}
|
||||
|
||||
cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, CPPI5_TR_CSF_EOP);
|
||||
cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags,
|
||||
CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP);
|
||||
|
||||
return d;
|
||||
}
|
||||
@@ -2733,7 +2734,8 @@ udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
|
||||
tr_req[1].dicnt3 = 1;
|
||||
}
|
||||
|
||||
cppi5_tr_csf_set(&tr_req[num_tr - 1].flags, CPPI5_TR_CSF_EOP);
|
||||
cppi5_tr_csf_set(&tr_req[num_tr - 1].flags,
|
||||
CPPI5_TR_CSF_SUPR_EVT | CPPI5_TR_CSF_EOP);
|
||||
|
||||
if (uc->config.metadata_size)
|
||||
d->vd.tx.metadata_ops = &metadata_ops;
|
||||
|
||||
@@ -434,6 +434,7 @@ static void zynqmp_dma_free_descriptor(struct zynqmp_dma_chan *chan,
|
||||
struct zynqmp_dma_desc_sw *child, *next;
|
||||
|
||||
chan->desc_free_cnt++;
|
||||
list_del(&sdesc->node);
|
||||
list_add_tail(&sdesc->node, &chan->free_list);
|
||||
list_for_each_entry_safe(child, next, &sdesc->tx_list, node) {
|
||||
chan->desc_free_cnt++;
|
||||
@@ -608,8 +609,6 @@ static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan)
|
||||
dma_async_tx_callback callback;
|
||||
void *callback_param;
|
||||
|
||||
list_del(&desc->node);
|
||||
|
||||
callback = desc->async_tx.callback;
|
||||
callback_param = desc->async_tx.callback_param;
|
||||
if (callback) {
|
||||
|
||||
@@ -407,6 +407,58 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
|
||||
}
|
||||
}
|
||||
|
||||
static const char * const fw_err_rec_type_strs[] = {
|
||||
"IPF SAL Error Record",
|
||||
"SOC Firmware Error Record Type1 (Legacy CrashLog Support)",
|
||||
"SOC Firmware Error Record Type2",
|
||||
};
|
||||
|
||||
static void cper_print_fw_err(const char *pfx,
|
||||
struct acpi_hest_generic_data *gdata,
|
||||
const struct cper_sec_fw_err_rec_ref *fw_err)
|
||||
{
|
||||
void *buf = acpi_hest_get_payload(gdata);
|
||||
u32 offset, length = gdata->error_data_length;
|
||||
|
||||
printk("%s""Firmware Error Record Type: %s\n", pfx,
|
||||
fw_err->record_type < ARRAY_SIZE(fw_err_rec_type_strs) ?
|
||||
fw_err_rec_type_strs[fw_err->record_type] : "unknown");
|
||||
printk("%s""Revision: %d\n", pfx, fw_err->revision);
|
||||
|
||||
/* Record Type based on UEFI 2.7 */
|
||||
if (fw_err->revision == 0) {
|
||||
printk("%s""Record Identifier: %08llx\n", pfx,
|
||||
fw_err->record_identifier);
|
||||
} else if (fw_err->revision == 2) {
|
||||
printk("%s""Record Identifier: %pUl\n", pfx,
|
||||
&fw_err->record_identifier_guid);
|
||||
}
|
||||
|
||||
/*
|
||||
* The FW error record may contain trailing data beyond the
|
||||
* structure defined by the specification. As the fields
|
||||
* defined (and hence the offset of any trailing data) vary
|
||||
* with the revision, set the offset to account for this
|
||||
* variation.
|
||||
*/
|
||||
if (fw_err->revision == 0) {
|
||||
/* record_identifier_guid not defined */
|
||||
offset = offsetof(struct cper_sec_fw_err_rec_ref,
|
||||
record_identifier_guid);
|
||||
} else if (fw_err->revision == 1) {
|
||||
/* record_identifier not defined */
|
||||
offset = offsetof(struct cper_sec_fw_err_rec_ref,
|
||||
record_identifier);
|
||||
} else {
|
||||
offset = sizeof(*fw_err);
|
||||
}
|
||||
|
||||
buf += offset;
|
||||
length -= offset;
|
||||
|
||||
print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, buf, length, true);
|
||||
}
|
||||
|
||||
static void cper_print_tstamp(const char *pfx,
|
||||
struct acpi_hest_generic_data_v300 *gdata)
|
||||
{
|
||||
@@ -494,6 +546,16 @@ cper_estatus_print_section(const char *pfx, struct acpi_hest_generic_data *gdata
|
||||
else
|
||||
goto err_section_too_small;
|
||||
#endif
|
||||
} else if (guid_equal(sec_type, &CPER_SEC_FW_ERR_REC_REF)) {
|
||||
struct cper_sec_fw_err_rec_ref *fw_err = acpi_hest_get_payload(gdata);
|
||||
|
||||
printk("%ssection_type: Firmware Error Record Reference\n",
|
||||
newpfx);
|
||||
/* The minimal FW Error Record contains 16 bytes */
|
||||
if (gdata->error_data_length >= SZ_16)
|
||||
cper_print_fw_err(newpfx, gdata, fw_err);
|
||||
else
|
||||
goto err_section_too_small;
|
||||
} else {
|
||||
const void *err = acpi_hest_get_payload(gdata);
|
||||
|
||||
|
||||
@@ -114,14 +114,16 @@ static void efi_earlycon_write_char(u32 *dst, unsigned char c, unsigned int h)
|
||||
const u32 color_black = 0x00000000;
|
||||
const u32 color_white = 0x00ffffff;
|
||||
const u8 *src;
|
||||
u8 s8;
|
||||
int m;
|
||||
int m, n, bytes;
|
||||
u8 x;
|
||||
|
||||
src = font->data + c * font->height;
|
||||
s8 = *(src + h);
|
||||
bytes = BITS_TO_BYTES(font->width);
|
||||
src = font->data + c * font->height * bytes + h * bytes;
|
||||
|
||||
for (m = 0; m < 8; m++) {
|
||||
if ((s8 >> (7 - m)) & 1)
|
||||
for (m = 0; m < font->width; m++) {
|
||||
n = m % 8;
|
||||
x = *(src + m / 8);
|
||||
if ((x >> (7 - n)) & 1)
|
||||
*dst = color_white;
|
||||
else
|
||||
*dst = color_black;
|
||||
|
||||
@@ -130,11 +130,8 @@ static ssize_t systab_show(struct kobject *kobj,
|
||||
if (efi.smbios != EFI_INVALID_TABLE_ADDR)
|
||||
str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios);
|
||||
|
||||
if (IS_ENABLED(CONFIG_IA64) || IS_ENABLED(CONFIG_X86)) {
|
||||
extern char *efi_systab_show_arch(char *str);
|
||||
|
||||
if (IS_ENABLED(CONFIG_IA64) || IS_ENABLED(CONFIG_X86))
|
||||
str = efi_systab_show_arch(str);
|
||||
}
|
||||
|
||||
return str - buf;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,11 @@ static struct screen_info *setup_graphics(void)
|
||||
si = alloc_screen_info();
|
||||
if (!si)
|
||||
return NULL;
|
||||
efi_setup_gop(si, &gop_proto, size);
|
||||
status = efi_setup_gop(si, &gop_proto, size);
|
||||
if (status != EFI_SUCCESS) {
|
||||
free_screen_info(si);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
@@ -92,6 +92,19 @@ extern __pure efi_system_table_t *efi_system_table(void);
|
||||
#define EFI_LOCATE_BY_REGISTER_NOTIFY 1
|
||||
#define EFI_LOCATE_BY_PROTOCOL 2
|
||||
|
||||
/*
|
||||
* An efi_boot_memmap is used by efi_get_memory_map() to return the
|
||||
* EFI memory map in a dynamically allocated buffer.
|
||||
*
|
||||
* The buffer allocated for the EFI memory map includes extra room for
|
||||
* a minimum of EFI_MMAP_NR_SLACK_SLOTS additional EFI memory descriptors.
|
||||
* This facilitates the reuse of the EFI memory map buffer when a second
|
||||
* call to ExitBootServices() is needed because of intervening changes to
|
||||
* the EFI memory map. Other related structures, e.g. x86 e820ext, need
|
||||
* to factor in this headroom requirement as well.
|
||||
*/
|
||||
#define EFI_MMAP_NR_SLACK_SLOTS 8
|
||||
|
||||
struct efi_boot_memmap {
|
||||
efi_memory_desc_t **map;
|
||||
unsigned long *map_size;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "efistub.h"
|
||||
|
||||
#define EFI_MMAP_NR_SLACK_SLOTS 8
|
||||
|
||||
static inline bool mmap_has_headroom(unsigned long buff_size,
|
||||
unsigned long map_size,
|
||||
unsigned long desc_size)
|
||||
|
||||
@@ -54,7 +54,7 @@ void efi_retrieve_tpm2_eventlog(void)
|
||||
efi_status_t status;
|
||||
efi_physical_addr_t log_location = 0, log_last_entry = 0;
|
||||
struct linux_efi_tpm_eventlog *log_tbl = NULL;
|
||||
struct efi_tcg2_final_events_table *final_events_table;
|
||||
struct efi_tcg2_final_events_table *final_events_table = NULL;
|
||||
unsigned long first_entry_addr, last_entry_addr;
|
||||
size_t log_size, last_entry_size;
|
||||
efi_bool_t truncated;
|
||||
@@ -127,7 +127,8 @@ void efi_retrieve_tpm2_eventlog(void)
|
||||
* Figure out whether any events have already been logged to the
|
||||
* final events structure, and if so how much space they take up
|
||||
*/
|
||||
final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
|
||||
if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
|
||||
final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
|
||||
if (final_events_table && final_events_table->nr_events) {
|
||||
struct tcg_pcr_event2_head *header;
|
||||
int offset;
|
||||
|
||||
@@ -606,24 +606,18 @@ static efi_status_t allocate_e820(struct boot_params *params,
|
||||
struct setup_data **e820ext,
|
||||
u32 *e820ext_size)
|
||||
{
|
||||
unsigned long map_size, desc_size, buff_size;
|
||||
struct efi_boot_memmap boot_map;
|
||||
efi_memory_desc_t *map;
|
||||
unsigned long map_size, desc_size, map_key;
|
||||
efi_status_t status;
|
||||
__u32 nr_desc;
|
||||
__u32 nr_desc, desc_version;
|
||||
|
||||
boot_map.map = ↦
|
||||
boot_map.map_size = &map_size;
|
||||
boot_map.desc_size = &desc_size;
|
||||
boot_map.desc_ver = NULL;
|
||||
boot_map.key_ptr = NULL;
|
||||
boot_map.buff_size = &buff_size;
|
||||
/* Only need the size of the mem map and size of each mem descriptor */
|
||||
map_size = 0;
|
||||
status = efi_bs_call(get_memory_map, &map_size, NULL, &map_key,
|
||||
&desc_size, &desc_version);
|
||||
if (status != EFI_BUFFER_TOO_SMALL)
|
||||
return (status != EFI_SUCCESS) ? status : EFI_UNSUPPORTED;
|
||||
|
||||
status = efi_get_memory_map(&boot_map);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
nr_desc = buff_size / desc_size;
|
||||
nr_desc = map_size / desc_size + EFI_MMAP_NR_SLACK_SLOTS;
|
||||
|
||||
if (nr_desc > ARRAY_SIZE(params->e820_table)) {
|
||||
u32 nr_e820ext = nr_desc - ARRAY_SIZE(params->e820_table);
|
||||
|
||||
@@ -62,8 +62,11 @@ int __init efi_tpm_eventlog_init(void)
|
||||
tbl_size = sizeof(*log_tbl) + log_tbl->size;
|
||||
memblock_reserve(efi.tpm_log, tbl_size);
|
||||
|
||||
if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR)
|
||||
if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR ||
|
||||
log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
|
||||
pr_warn(FW_BUG "TPM Final Events table missing or invalid\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
final_tbl = early_memremap(efi.tpm_final_log, sizeof(*final_tbl));
|
||||
|
||||
|
||||
@@ -220,6 +220,30 @@ static enum dpcd_training_patterns
|
||||
return dpcd_tr_pattern;
|
||||
}
|
||||
|
||||
static uint8_t dc_dp_initialize_scrambling_data_symbols(
|
||||
struct dc_link *link,
|
||||
enum dc_dp_training_pattern pattern)
|
||||
{
|
||||
uint8_t disable_scrabled_data_symbols = 0;
|
||||
|
||||
switch (pattern) {
|
||||
case DP_TRAINING_PATTERN_SEQUENCE_1:
|
||||
case DP_TRAINING_PATTERN_SEQUENCE_2:
|
||||
case DP_TRAINING_PATTERN_SEQUENCE_3:
|
||||
disable_scrabled_data_symbols = 1;
|
||||
break;
|
||||
case DP_TRAINING_PATTERN_SEQUENCE_4:
|
||||
disable_scrabled_data_symbols = 0;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
DC_LOG_HW_LINK_TRAINING("%s: Invalid HW Training pattern: %d\n",
|
||||
__func__, pattern);
|
||||
break;
|
||||
}
|
||||
return disable_scrabled_data_symbols;
|
||||
}
|
||||
|
||||
static inline bool is_repeater(struct dc_link *link, uint32_t offset)
|
||||
{
|
||||
return (!link->is_lttpr_mode_transparent && offset != 0);
|
||||
@@ -252,6 +276,9 @@ static void dpcd_set_lt_pattern_and_lane_settings(
|
||||
dpcd_pattern.v1_4.TRAINING_PATTERN_SET =
|
||||
dc_dp_training_pattern_to_dpcd_training_pattern(link, pattern);
|
||||
|
||||
dpcd_pattern.v1_4.SCRAMBLING_DISABLE =
|
||||
dc_dp_initialize_scrambling_data_symbols(link, pattern);
|
||||
|
||||
dpcd_lt_buffer[DP_TRAINING_PATTERN_SET - DP_TRAINING_PATTERN_SET]
|
||||
= dpcd_pattern.raw;
|
||||
|
||||
|
||||
@@ -1625,12 +1625,79 @@ void dcn10_pipe_control_lock(
|
||||
hws->funcs.verify_allow_pstate_change_high(dc);
|
||||
}
|
||||
|
||||
/**
|
||||
* delay_cursor_until_vupdate() - Delay cursor update if too close to VUPDATE.
|
||||
*
|
||||
* Software keepout workaround to prevent cursor update locking from stalling
|
||||
* out cursor updates indefinitely or from old values from being retained in
|
||||
* the case where the viewport changes in the same frame as the cursor.
|
||||
*
|
||||
* The idea is to calculate the remaining time from VPOS to VUPDATE. If it's
|
||||
* too close to VUPDATE, then stall out until VUPDATE finishes.
|
||||
*
|
||||
* TODO: Optimize cursor programming to be once per frame before VUPDATE
|
||||
* to avoid the need for this workaround.
|
||||
*/
|
||||
static void delay_cursor_until_vupdate(struct dc *dc, struct pipe_ctx *pipe_ctx)
|
||||
{
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
struct crtc_position position;
|
||||
uint32_t vupdate_start, vupdate_end;
|
||||
unsigned int lines_to_vupdate, us_to_vupdate, vpos;
|
||||
unsigned int us_per_line, us_vupdate;
|
||||
|
||||
if (!dc->hwss.calc_vupdate_position || !dc->hwss.get_position)
|
||||
return;
|
||||
|
||||
if (!pipe_ctx->stream_res.stream_enc || !pipe_ctx->stream_res.tg)
|
||||
return;
|
||||
|
||||
dc->hwss.calc_vupdate_position(dc, pipe_ctx, &vupdate_start,
|
||||
&vupdate_end);
|
||||
|
||||
dc->hwss.get_position(&pipe_ctx, 1, &position);
|
||||
vpos = position.vertical_count;
|
||||
|
||||
/* Avoid wraparound calculation issues */
|
||||
vupdate_start += stream->timing.v_total;
|
||||
vupdate_end += stream->timing.v_total;
|
||||
vpos += stream->timing.v_total;
|
||||
|
||||
if (vpos <= vupdate_start) {
|
||||
/* VPOS is in VACTIVE or back porch. */
|
||||
lines_to_vupdate = vupdate_start - vpos;
|
||||
} else if (vpos > vupdate_end) {
|
||||
/* VPOS is in the front porch. */
|
||||
return;
|
||||
} else {
|
||||
/* VPOS is in VUPDATE. */
|
||||
lines_to_vupdate = 0;
|
||||
}
|
||||
|
||||
/* Calculate time until VUPDATE in microseconds. */
|
||||
us_per_line =
|
||||
stream->timing.h_total * 10000u / stream->timing.pix_clk_100hz;
|
||||
us_to_vupdate = lines_to_vupdate * us_per_line;
|
||||
|
||||
/* 70 us is a conservative estimate of cursor update time*/
|
||||
if (us_to_vupdate > 70)
|
||||
return;
|
||||
|
||||
/* Stall out until the cursor update completes. */
|
||||
us_vupdate = (vupdate_end - vupdate_start + 1) * us_per_line;
|
||||
udelay(us_to_vupdate + us_vupdate);
|
||||
}
|
||||
|
||||
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
|
||||
{
|
||||
/* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
|
||||
if (!pipe || pipe->top_pipe)
|
||||
return;
|
||||
|
||||
/* Prevent cursor lock from stalling out cursor updates. */
|
||||
if (lock)
|
||||
delay_cursor_until_vupdate(dc, pipe);
|
||||
|
||||
dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
|
||||
pipe->stream_res.opp->inst, lock);
|
||||
}
|
||||
@@ -3236,7 +3303,7 @@ int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx)
|
||||
return vertical_line_start;
|
||||
}
|
||||
|
||||
static void dcn10_calc_vupdate_position(
|
||||
void dcn10_calc_vupdate_position(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
uint32_t *start_line,
|
||||
|
||||
@@ -34,6 +34,11 @@ struct dc;
|
||||
void dcn10_hw_sequencer_construct(struct dc *dc);
|
||||
|
||||
int dcn10_get_vupdate_offset_from_vsync(struct pipe_ctx *pipe_ctx);
|
||||
void dcn10_calc_vupdate_position(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
uint32_t *start_line,
|
||||
uint32_t *end_line);
|
||||
void dcn10_setup_vupdate_interrupt(struct dc *dc, struct pipe_ctx *pipe_ctx);
|
||||
enum dc_status dcn10_enable_stream_timing(
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
|
||||
@@ -72,6 +72,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.set_clock = dcn10_set_clock,
|
||||
.get_clock = dcn10_get_clock,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.calc_vupdate_position = dcn10_calc_vupdate_position,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn10_private_funcs = {
|
||||
|
||||
@@ -83,6 +83,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
||||
.init_vm_ctx = dcn20_init_vm_ctx,
|
||||
.set_flip_control_gsl = dcn20_set_flip_control_gsl,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.calc_vupdate_position = dcn10_calc_vupdate_position,
|
||||
};
|
||||
|
||||
static const struct hwseq_private_funcs dcn20_private_funcs = {
|
||||
|
||||
@@ -86,6 +86,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
||||
.optimize_pwr_state = dcn21_optimize_pwr_state,
|
||||
.exit_optimized_pwr_state = dcn21_exit_optimized_pwr_state,
|
||||
.get_vupdate_offset_from_vsync = dcn10_get_vupdate_offset_from_vsync,
|
||||
.calc_vupdate_position = dcn10_calc_vupdate_position,
|
||||
.set_cursor_position = dcn10_set_cursor_position,
|
||||
.set_cursor_attribute = dcn10_set_cursor_attribute,
|
||||
.set_cursor_sdr_white_level = dcn10_set_cursor_sdr_white_level,
|
||||
|
||||
@@ -63,10 +63,8 @@ CFLAGS_$(AMDDALPATH)/dc/dml/dcn21/display_rq_dlg_calc_21.o := $(dml_ccflags)
|
||||
endif
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dml1_display_rq_dlg_calc.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/display_rq_dlg_helpers.o := $(dml_ccflags)
|
||||
CFLAGS_$(AMDDALPATH)/dc/dml/dml_common_defs.o := $(dml_ccflags)
|
||||
|
||||
DML = display_mode_lib.o display_rq_dlg_helpers.o dml1_display_rq_dlg_calc.o \
|
||||
dml_common_defs.o
|
||||
|
||||
ifdef CONFIG_DRM_AMD_DC_DCN
|
||||
DML += display_mode_vba.o dcn20/display_rq_dlg_calc_20.o dcn20/display_mode_vba_20.o
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#ifndef __DML20_DISPLAY_RQ_DLG_CALC_H__
|
||||
#define __DML20_DISPLAY_RQ_DLG_CALC_H__
|
||||
|
||||
#include "../dml_common_defs.h"
|
||||
#include "../display_rq_dlg_helpers.h"
|
||||
|
||||
struct display_mode_lib;
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#ifndef __DML20V2_DISPLAY_RQ_DLG_CALC_H__
|
||||
#define __DML20V2_DISPLAY_RQ_DLG_CALC_H__
|
||||
|
||||
#include "../dml_common_defs.h"
|
||||
#include "../display_rq_dlg_helpers.h"
|
||||
|
||||
struct display_mode_lib;
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#ifndef __DML21_DISPLAY_RQ_DLG_CALC_H__
|
||||
#define __DML21_DISPLAY_RQ_DLG_CALC_H__
|
||||
|
||||
#include "../dml_common_defs.h"
|
||||
#include "dm_services.h"
|
||||
#include "../display_rq_dlg_helpers.h"
|
||||
|
||||
struct display_mode_lib;
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
#ifndef __DISPLAY_MODE_LIB_H__
|
||||
#define __DISPLAY_MODE_LIB_H__
|
||||
|
||||
|
||||
#include "dml_common_defs.h"
|
||||
#include "dm_services.h"
|
||||
#include "dc_features.h"
|
||||
#include "display_mode_structs.h"
|
||||
#include "display_mode_enums.h"
|
||||
#include "display_mode_vba.h"
|
||||
|
||||
enum dml_project {
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
#ifndef __DML2_DISPLAY_MODE_VBA_H__
|
||||
#define __DML2_DISPLAY_MODE_VBA_H__
|
||||
|
||||
#include "dml_common_defs.h"
|
||||
|
||||
struct display_mode_lib;
|
||||
|
||||
void ModeSupportAndSystemConfiguration(struct display_mode_lib *mode_lib);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#ifndef __DISPLAY_RQ_DLG_HELPERS_H__
|
||||
#define __DISPLAY_RQ_DLG_HELPERS_H__
|
||||
|
||||
#include "dml_common_defs.h"
|
||||
#include "display_mode_lib.h"
|
||||
|
||||
/* Function: Printer functions
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#ifndef __DISPLAY_RQ_DLG_CALC_H__
|
||||
#define __DISPLAY_RQ_DLG_CALC_H__
|
||||
|
||||
#include "dml_common_defs.h"
|
||||
|
||||
struct display_mode_lib;
|
||||
|
||||
#include "display_rq_dlg_helpers.h"
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dml_common_defs.h"
|
||||
#include "dcn_calc_math.h"
|
||||
|
||||
#include "dml_inline_defs.h"
|
||||
|
||||
double dml_round(double a)
|
||||
{
|
||||
double round_pt = 0.5;
|
||||
double ceil = dml_ceil(a, 1);
|
||||
double floor = dml_floor(a, 1);
|
||||
|
||||
if (a - floor >= round_pt)
|
||||
return ceil;
|
||||
else
|
||||
return floor;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __DC_COMMON_DEFS_H__
|
||||
#define __DC_COMMON_DEFS_H__
|
||||
|
||||
#include "dm_services.h"
|
||||
#include "dc_features.h"
|
||||
#include "display_mode_structs.h"
|
||||
#include "display_mode_enums.h"
|
||||
|
||||
|
||||
double dml_round(double a);
|
||||
|
||||
#endif /* __DC_COMMON_DEFS_H__ */
|
||||
@@ -26,7 +26,6 @@
|
||||
#ifndef __DML_INLINE_DEFS_H__
|
||||
#define __DML_INLINE_DEFS_H__
|
||||
|
||||
#include "dml_common_defs.h"
|
||||
#include "dcn_calc_math.h"
|
||||
#include "dml_logger.h"
|
||||
|
||||
@@ -75,6 +74,18 @@ static inline double dml_floor(double a, double granularity)
|
||||
return (double) dcn_bw_floor2(a, granularity);
|
||||
}
|
||||
|
||||
static inline double dml_round(double a)
|
||||
{
|
||||
double round_pt = 0.5;
|
||||
double ceil = dml_ceil(a, 1);
|
||||
double floor = dml_floor(a, 1);
|
||||
|
||||
if (a - floor >= round_pt)
|
||||
return ceil;
|
||||
else
|
||||
return floor;
|
||||
}
|
||||
|
||||
static inline int dml_log2(double x)
|
||||
{
|
||||
return dml_round((double)dcn_bw_log(x, 2));
|
||||
@@ -112,7 +123,7 @@ static inline double dml_log(double x, double base)
|
||||
|
||||
static inline unsigned int dml_round_to_multiple(unsigned int num,
|
||||
unsigned int multiple,
|
||||
bool up)
|
||||
unsigned char up)
|
||||
{
|
||||
unsigned int remainder;
|
||||
|
||||
|
||||
@@ -92,6 +92,11 @@ struct hw_sequencer_funcs {
|
||||
void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
|
||||
struct crtc_position *position);
|
||||
int (*get_vupdate_offset_from_vsync)(struct pipe_ctx *pipe_ctx);
|
||||
void (*calc_vupdate_position)(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
uint32_t *start_line,
|
||||
uint32_t *end_line);
|
||||
void (*enable_per_frame_crtc_position_reset)(struct dc *dc,
|
||||
int group_size, struct pipe_ctx *grouped_pipes[]);
|
||||
void (*enable_timing_synchronization)(struct dc *dc,
|
||||
|
||||
@@ -191,10 +191,11 @@ static const struct edid_quirk {
|
||||
{ "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP },
|
||||
{ "HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP },
|
||||
|
||||
/* Oculus Rift DK1, DK2, and CV1 VR Headsets */
|
||||
/* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */
|
||||
{ "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP },
|
||||
{ "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP },
|
||||
{ "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP },
|
||||
{ "OVR", 0x0012, EDID_QUIRK_NON_DESKTOP },
|
||||
|
||||
/* Windows Mixed Reality Headsets */
|
||||
{ "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP },
|
||||
|
||||
@@ -238,8 +238,10 @@ static int submit_pin_objects(struct etnaviv_gem_submit *submit)
|
||||
}
|
||||
|
||||
if ((submit->flags & ETNA_SUBMIT_SOFTPIN) &&
|
||||
submit->bos[i].va != mapping->iova)
|
||||
submit->bos[i].va != mapping->iova) {
|
||||
etnaviv_gem_mapping_unreference(mapping);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
atomic_inc(&etnaviv_obj->gpu_active);
|
||||
|
||||
|
||||
@@ -453,7 +453,7 @@ static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu,
|
||||
if (!(gpu->identity.features & meta->feature))
|
||||
continue;
|
||||
|
||||
if (meta->nr_domains < (index - offset)) {
|
||||
if (index - offset >= meta->nr_domains) {
|
||||
offset += meta->nr_domains;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -850,7 +850,7 @@ extern void vmw_bo_bo_free(struct ttm_buffer_object *bo);
|
||||
extern int vmw_bo_init(struct vmw_private *dev_priv,
|
||||
struct vmw_buffer_object *vmw_bo,
|
||||
size_t size, struct ttm_placement *placement,
|
||||
bool interuptable,
|
||||
bool interruptible,
|
||||
void (*bo_free)(struct ttm_buffer_object *bo));
|
||||
extern int vmw_user_bo_verify_access(struct ttm_buffer_object *bo,
|
||||
struct ttm_object_file *tfile);
|
||||
|
||||
@@ -515,7 +515,7 @@ bool vmw_fence_obj_signaled(struct vmw_fence_obj *fence)
|
||||
struct vmw_fence_manager *fman = fman_from_fence(fence);
|
||||
|
||||
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->base.flags))
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
vmw_fences_update(fman);
|
||||
|
||||
|
||||
@@ -1651,7 +1651,7 @@ vmw_gb_surface_reference_internal(struct drm_device *dev,
|
||||
struct vmw_surface_metadata *metadata;
|
||||
struct ttm_base_object *base;
|
||||
uint32_t backup_handle;
|
||||
int ret = -EINVAL;
|
||||
int ret;
|
||||
|
||||
ret = vmw_surface_handle_reference(dev_priv, file_priv, req->sid,
|
||||
req->handle_type, &base);
|
||||
|
||||
@@ -120,7 +120,7 @@ static int cti_plat_create_v8_etm_connection(struct device *dev,
|
||||
|
||||
/* Can optionally have an etm node - return if not */
|
||||
cs_fwnode = fwnode_find_reference(root_fwnode, CTI_DT_CSDEV_ASSOC, 0);
|
||||
if (IS_ERR_OR_NULL(cs_fwnode))
|
||||
if (IS_ERR(cs_fwnode))
|
||||
return 0;
|
||||
|
||||
/* allocate memory */
|
||||
@@ -393,7 +393,7 @@ static int cti_plat_create_connection(struct device *dev,
|
||||
/* associated device ? */
|
||||
cs_fwnode = fwnode_find_reference(fwnode,
|
||||
CTI_DT_CSDEV_ASSOC, 0);
|
||||
if (!IS_ERR_OR_NULL(cs_fwnode)) {
|
||||
if (!IS_ERR(cs_fwnode)) {
|
||||
assoc_name = cti_plat_get_csdev_or_node_name(cs_fwnode,
|
||||
&csdev);
|
||||
fwnode_handle_put(cs_fwnode);
|
||||
|
||||
@@ -542,7 +542,7 @@ int i2c_pca_add_numbered_bus(struct i2c_adapter *adap)
|
||||
EXPORT_SYMBOL(i2c_pca_add_numbered_bus);
|
||||
|
||||
MODULE_AUTHOR("Ian Campbell <icampbell@arcom.com>, "
|
||||
"Wolfram Sang <w.sang@pengutronix.de>");
|
||||
"Wolfram Sang <kernel@pengutronix.de>");
|
||||
MODULE_DESCRIPTION("I2C-Bus PCA9564/PCA9665 algorithm");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
* @isr_mask: cached copy of local ISR enables.
|
||||
* @isr_status: cached copy of local ISR status.
|
||||
* @lock: spinlock for IRQ synchronization.
|
||||
* @isr_mutex: mutex for IRQ thread.
|
||||
*/
|
||||
struct altr_i2c_dev {
|
||||
void __iomem *base;
|
||||
@@ -86,6 +87,7 @@ struct altr_i2c_dev {
|
||||
u32 isr_mask;
|
||||
u32 isr_status;
|
||||
spinlock_t lock; /* IRQ synchronization */
|
||||
struct mutex isr_mutex;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -245,10 +247,11 @@ static irqreturn_t altr_i2c_isr(int irq, void *_dev)
|
||||
struct altr_i2c_dev *idev = _dev;
|
||||
u32 status = idev->isr_status;
|
||||
|
||||
mutex_lock(&idev->isr_mutex);
|
||||
if (!idev->msg) {
|
||||
dev_warn(idev->dev, "unexpected interrupt\n");
|
||||
altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ);
|
||||
return IRQ_HANDLED;
|
||||
goto out;
|
||||
}
|
||||
read = (idev->msg->flags & I2C_M_RD) != 0;
|
||||
|
||||
@@ -301,6 +304,8 @@ static irqreturn_t altr_i2c_isr(int irq, void *_dev)
|
||||
complete(&idev->msg_complete);
|
||||
dev_dbg(idev->dev, "Message Complete\n");
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&idev->isr_mutex);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@@ -312,6 +317,7 @@ static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg)
|
||||
u32 value;
|
||||
u8 addr = i2c_8bit_addr_from_msg(msg);
|
||||
|
||||
mutex_lock(&idev->isr_mutex);
|
||||
idev->msg = msg;
|
||||
idev->msg_len = msg->len;
|
||||
idev->buf = msg->buf;
|
||||
@@ -336,6 +342,7 @@ static int altr_i2c_xfer_msg(struct altr_i2c_dev *idev, struct i2c_msg *msg)
|
||||
altr_i2c_int_enable(idev, imask, true);
|
||||
altr_i2c_fill_tx_fifo(idev);
|
||||
}
|
||||
mutex_unlock(&idev->isr_mutex);
|
||||
|
||||
time_left = wait_for_completion_timeout(&idev->msg_complete,
|
||||
ALTR_I2C_XFER_TIMEOUT);
|
||||
@@ -409,6 +416,7 @@ static int altr_i2c_probe(struct platform_device *pdev)
|
||||
idev->dev = &pdev->dev;
|
||||
init_completion(&idev->msg_complete);
|
||||
spin_lock_init(&idev->lock);
|
||||
mutex_init(&idev->isr_mutex);
|
||||
|
||||
ret = device_property_read_u32(idev->dev, "fifo-size",
|
||||
&idev->fifo_size);
|
||||
|
||||
@@ -845,6 +845,18 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
|
||||
PINCTRL_STATE_DEFAULT);
|
||||
dev->pinctrl_pins_gpio = pinctrl_lookup_state(dev->pinctrl,
|
||||
"gpio");
|
||||
if (IS_ERR(dev->pinctrl_pins_default) ||
|
||||
IS_ERR(dev->pinctrl_pins_gpio)) {
|
||||
dev_info(&pdev->dev, "pinctrl states incomplete for recovery\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* pins will be taken as GPIO, so we might as well inform pinctrl about
|
||||
* this and move the state to GPIO
|
||||
*/
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_gpio);
|
||||
|
||||
rinfo->sda_gpiod = devm_gpiod_get(&pdev->dev, "sda", GPIOD_IN);
|
||||
if (PTR_ERR(rinfo->sda_gpiod) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
@@ -855,9 +867,7 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (IS_ERR(rinfo->sda_gpiod) ||
|
||||
IS_ERR(rinfo->scl_gpiod) ||
|
||||
IS_ERR(dev->pinctrl_pins_default) ||
|
||||
IS_ERR(dev->pinctrl_pins_gpio)) {
|
||||
IS_ERR(rinfo->scl_gpiod)) {
|
||||
dev_info(&pdev->dev, "recovery information incomplete\n");
|
||||
if (!IS_ERR(rinfo->sda_gpiod)) {
|
||||
gpiod_put(rinfo->sda_gpiod);
|
||||
@@ -867,9 +877,13 @@ static int at91_init_twi_recovery_info(struct platform_device *pdev,
|
||||
gpiod_put(rinfo->scl_gpiod);
|
||||
rinfo->scl_gpiod = NULL;
|
||||
}
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* change the state of the pins back to their default state */
|
||||
pinctrl_select_state(dev->pinctrl, dev->pinctrl_pins_default);
|
||||
|
||||
dev_info(&pdev->dev, "using scl, sda for recovery\n");
|
||||
|
||||
rinfo->prepare_recovery = at91_prepare_twi_recovery;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Mux support by Rodolfo Giometti <giometti@enneenne.com> and
|
||||
* Michael Lawnick <michael.lawnick.ext@nsn.com>
|
||||
*
|
||||
* Copyright (C) 2013-2017 Wolfram Sang <wsa@the-dreams.de>
|
||||
* Copyright (C) 2013-2017 Wolfram Sang <wsa@kernel.org>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "i2c-core: " fmt
|
||||
@@ -338,8 +338,10 @@ static int i2c_device_probe(struct device *dev)
|
||||
} else if (ACPI_COMPANION(dev)) {
|
||||
irq = i2c_acpi_get_irq(client);
|
||||
}
|
||||
if (irq == -EPROBE_DEFER)
|
||||
return irq;
|
||||
if (irq == -EPROBE_DEFER) {
|
||||
status = irq;
|
||||
goto put_sync_adapter;
|
||||
}
|
||||
|
||||
if (irq < 0)
|
||||
irq = 0;
|
||||
@@ -353,15 +355,19 @@ static int i2c_device_probe(struct device *dev)
|
||||
*/
|
||||
if (!driver->id_table &&
|
||||
!i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&
|
||||
!i2c_of_match_device(dev->driver->of_match_table, client))
|
||||
return -ENODEV;
|
||||
!i2c_of_match_device(dev->driver->of_match_table, client)) {
|
||||
status = -ENODEV;
|
||||
goto put_sync_adapter;
|
||||
}
|
||||
|
||||
if (client->flags & I2C_CLIENT_WAKE) {
|
||||
int wakeirq;
|
||||
|
||||
wakeirq = of_irq_get_byname(dev->of_node, "wakeup");
|
||||
if (wakeirq == -EPROBE_DEFER)
|
||||
return wakeirq;
|
||||
if (wakeirq == -EPROBE_DEFER) {
|
||||
status = wakeirq;
|
||||
goto put_sync_adapter;
|
||||
}
|
||||
|
||||
device_init_wakeup(&client->dev, true);
|
||||
|
||||
@@ -408,6 +414,10 @@ err_detach_pm_domain:
|
||||
err_clear_wakeup_irq:
|
||||
dev_pm_clear_wake_irq(&client->dev);
|
||||
device_init_wakeup(&client->dev, false);
|
||||
put_sync_adapter:
|
||||
if (client->flags & I2C_CLIENT_HOST_NOTIFY)
|
||||
pm_runtime_put_sync(&client->adapter->dev);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2008 Jochen Friedrich <jochen@scram.de>
|
||||
* based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
|
||||
*
|
||||
* Copyright (C) 2013, 2018 Wolfram Sang <wsa@the-dreams.de>
|
||||
* Copyright (C) 2013, 2018 Wolfram Sang <wsa@kernel.org>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/i2c/i2c.h>
|
||||
|
||||
@@ -272,6 +272,7 @@ static int i2c_demux_pinctrl_probe(struct platform_device *pdev)
|
||||
err_rollback_available:
|
||||
device_remove_file(&pdev->dev, &dev_attr_available_masters);
|
||||
err_rollback:
|
||||
i2c_demux_deactivate_master(priv);
|
||||
for (j = 0; j < i; j++) {
|
||||
of_node_put(priv->chan[j].parent_np);
|
||||
of_changeset_destroy(&priv->chan[j].chgset);
|
||||
|
||||
@@ -980,7 +980,7 @@ static int sca3000_read_data(struct sca3000_state *st,
|
||||
st->tx[0] = SCA3000_READ_REG(reg_address_high);
|
||||
ret = spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer));
|
||||
if (ret) {
|
||||
dev_err(get_device(&st->us->dev), "problem reading register");
|
||||
dev_err(&st->us->dev, "problem reading register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1812,18 +1812,18 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_adc_dma_request(struct iio_dev *indio_dev)
|
||||
static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_adc *adc = iio_priv(indio_dev);
|
||||
struct dma_slave_config config;
|
||||
int ret;
|
||||
|
||||
adc->dma_chan = dma_request_chan(&indio_dev->dev, "rx");
|
||||
adc->dma_chan = dma_request_chan(dev, "rx");
|
||||
if (IS_ERR(adc->dma_chan)) {
|
||||
ret = PTR_ERR(adc->dma_chan);
|
||||
if (ret != -ENODEV) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&indio_dev->dev,
|
||||
dev_err(dev,
|
||||
"DMA channel request failed with %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
@@ -1930,7 +1930,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = stm32_adc_dma_request(indio_dev);
|
||||
ret = stm32_adc_dma_request(dev, indio_dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ enum sd_converter_type {
|
||||
|
||||
struct stm32_dfsdm_dev_data {
|
||||
int type;
|
||||
int (*init)(struct iio_dev *indio_dev);
|
||||
int (*init)(struct device *dev, struct iio_dev *indio_dev);
|
||||
unsigned int num_channels;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
};
|
||||
@@ -1365,11 +1365,12 @@ static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev)
|
||||
}
|
||||
}
|
||||
|
||||
static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev)
|
||||
static int stm32_dfsdm_dma_request(struct device *dev,
|
||||
struct iio_dev *indio_dev)
|
||||
{
|
||||
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
|
||||
|
||||
adc->dma_chan = dma_request_chan(&indio_dev->dev, "rx");
|
||||
adc->dma_chan = dma_request_chan(dev, "rx");
|
||||
if (IS_ERR(adc->dma_chan)) {
|
||||
int ret = PTR_ERR(adc->dma_chan);
|
||||
|
||||
@@ -1425,7 +1426,7 @@ static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
|
||||
&adc->dfsdm->ch_list[ch->channel]);
|
||||
}
|
||||
|
||||
static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev)
|
||||
static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_chan_spec *ch;
|
||||
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
|
||||
@@ -1452,10 +1453,10 @@ static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev)
|
||||
indio_dev->num_channels = 1;
|
||||
indio_dev->channels = ch;
|
||||
|
||||
return stm32_dfsdm_dma_request(indio_dev);
|
||||
return stm32_dfsdm_dma_request(dev, indio_dev);
|
||||
}
|
||||
|
||||
static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
|
||||
static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_chan_spec *ch;
|
||||
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
|
||||
@@ -1499,17 +1500,17 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev)
|
||||
init_completion(&adc->completion);
|
||||
|
||||
/* Optionally request DMA */
|
||||
ret = stm32_dfsdm_dma_request(indio_dev);
|
||||
ret = stm32_dfsdm_dma_request(dev, indio_dev);
|
||||
if (ret) {
|
||||
if (ret != -ENODEV) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(&indio_dev->dev,
|
||||
dev_err(dev,
|
||||
"DMA channel request failed with %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(&indio_dev->dev, "No DMA support\n");
|
||||
dev_dbg(dev, "No DMA support\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1622,7 +1623,7 @@ static int stm32_dfsdm_adc_probe(struct platform_device *pdev)
|
||||
adc->dfsdm->fl_list[adc->fl_id].sync_mode = val;
|
||||
|
||||
adc->dev_data = dev_data;
|
||||
ret = dev_data->init(iio);
|
||||
ret = dev_data->init(dev, iio);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -32,16 +32,17 @@ struct ads8344 {
|
||||
u8 rx_buf[3];
|
||||
};
|
||||
|
||||
#define ADS8344_VOLTAGE_CHANNEL(chan, si) \
|
||||
#define ADS8344_VOLTAGE_CHANNEL(chan, addr) \
|
||||
{ \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.channel = chan, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.address = addr, \
|
||||
}
|
||||
|
||||
#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si) \
|
||||
#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, addr) \
|
||||
{ \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
@@ -50,6 +51,7 @@ struct ads8344 {
|
||||
.differential = 1, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.address = addr, \
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec ads8344_channels[] = {
|
||||
@@ -105,7 +107,7 @@ static int ads8344_read_raw(struct iio_dev *iio,
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&adc->lock);
|
||||
*value = ads8344_adc_conversion(adc, channel->scan_index,
|
||||
*value = ads8344_adc_conversion(adc, channel->address,
|
||||
channel->differential);
|
||||
mutex_unlock(&adc->lock);
|
||||
if (*value < 0)
|
||||
|
||||
@@ -194,7 +194,19 @@ static const struct iio_chan_spec atlas_orp_channels[] = {
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec atlas_do_channels[] = {
|
||||
ATLAS_CONCENTRATION_CHANNEL(0, ATLAS_REG_DO_DATA),
|
||||
{
|
||||
.type = IIO_CONCENTRATION,
|
||||
.address = ATLAS_REG_DO_DATA,
|
||||
.info_mask_separate =
|
||||
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 'u',
|
||||
.realbits = 32,
|
||||
.storagebits = 32,
|
||||
.endianness = IIO_BE,
|
||||
},
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1),
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
|
||||
@@ -223,6 +223,7 @@ static int vf610_dac_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
error_iio_device_register:
|
||||
vf610_dac_exit(info);
|
||||
clk_disable_unprepare(info->clk);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -544,8 +544,10 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev,
|
||||
|
||||
ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
|
||||
odr = st_lsm6dsx_check_odr(ref_sensor, val, &odr_val);
|
||||
if (odr < 0)
|
||||
return odr;
|
||||
if (odr < 0) {
|
||||
err = odr;
|
||||
goto release;
|
||||
}
|
||||
|
||||
sensor->ext_info.slv_odr = val;
|
||||
sensor->odr = odr;
|
||||
@@ -557,6 +559,7 @@ st_lsm6dsx_shub_write_raw(struct iio_dev *iio_dev,
|
||||
break;
|
||||
}
|
||||
|
||||
release:
|
||||
iio_device_release_direct_mode(iio_dev);
|
||||
|
||||
return err;
|
||||
|
||||
@@ -127,7 +127,8 @@ static inline int get_acpihid_device_id(struct device *dev,
|
||||
return -ENODEV;
|
||||
|
||||
list_for_each_entry(p, &acpihid_map, list) {
|
||||
if (acpi_dev_hid_uid_match(adev, p->hid, p->uid)) {
|
||||
if (acpi_dev_hid_uid_match(adev, p->hid,
|
||||
p->uid[0] ? p->uid : NULL)) {
|
||||
if (entry)
|
||||
*entry = p;
|
||||
return p->devid;
|
||||
|
||||
@@ -1329,8 +1329,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
|
||||
}
|
||||
case IVHD_DEV_ACPI_HID: {
|
||||
u16 devid;
|
||||
u8 hid[ACPIHID_HID_LEN] = {0};
|
||||
u8 uid[ACPIHID_UID_LEN] = {0};
|
||||
u8 hid[ACPIHID_HID_LEN];
|
||||
u8 uid[ACPIHID_UID_LEN];
|
||||
int ret;
|
||||
|
||||
if (h->type != 0x40) {
|
||||
@@ -1347,6 +1347,7 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
|
||||
break;
|
||||
}
|
||||
|
||||
uid[0] = '\0';
|
||||
switch (e->uidf) {
|
||||
case UID_NOT_PRESENT:
|
||||
|
||||
@@ -1361,8 +1362,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
|
||||
break;
|
||||
case UID_IS_CHARACTER:
|
||||
|
||||
memcpy(uid, (u8 *)(&e->uid), ACPIHID_UID_LEN - 1);
|
||||
uid[ACPIHID_UID_LEN - 1] = '\0';
|
||||
memcpy(uid, &e->uid, e->uidl);
|
||||
uid[e->uidl] = '\0';
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
+11
-6
@@ -693,6 +693,15 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool iommu_is_attach_deferred(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
if (domain->ops->is_attach_deferred)
|
||||
return domain->ops->is_attach_deferred(domain, dev);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* iommu_group_add_device - add a device to an iommu group
|
||||
* @group: the group into which to add the device (reference should be held)
|
||||
@@ -747,7 +756,7 @@ rename:
|
||||
|
||||
mutex_lock(&group->mutex);
|
||||
list_add_tail(&device->list, &group->devices);
|
||||
if (group->domain)
|
||||
if (group->domain && !iommu_is_attach_deferred(group->domain, dev))
|
||||
ret = __iommu_attach_device(group->domain, dev);
|
||||
mutex_unlock(&group->mutex);
|
||||
if (ret)
|
||||
@@ -1653,9 +1662,6 @@ static int __iommu_attach_device(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
if ((domain->ops->is_attach_deferred != NULL) &&
|
||||
domain->ops->is_attach_deferred(domain, dev))
|
||||
return 0;
|
||||
|
||||
if (unlikely(domain->ops->attach_dev == NULL))
|
||||
return -ENODEV;
|
||||
@@ -1727,8 +1733,7 @@ EXPORT_SYMBOL_GPL(iommu_sva_unbind_gpasid);
|
||||
static void __iommu_detach_device(struct iommu_domain *domain,
|
||||
struct device *dev)
|
||||
{
|
||||
if ((domain->ops->is_attach_deferred != NULL) &&
|
||||
domain->ops->is_attach_deferred(domain, dev))
|
||||
if (iommu_is_attach_deferred(domain, dev))
|
||||
return;
|
||||
|
||||
if (unlikely(domain->ops->detach_dev == NULL))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user