Merge branch 'linux-linaro-lsk-v4.4' into linux-linaro-lsk-v4.4-android
This commit is contained in:
commit
da9a92f0cd
166 changed files with 1652 additions and 968 deletions
|
@ -1,4 +1,4 @@
|
|||
What /sys/bus/iio/devices/iio:deviceX/in_proximity_raw
|
||||
What /sys/bus/iio/devices/iio:deviceX/in_proximity_input
|
||||
Date: March 2014
|
||||
KernelVersion: 3.15
|
||||
Contact: Matt Ranostay <mranostay@gmail.com>
|
||||
|
|
|
@ -263,19 +263,23 @@ scmd->allowed.
|
|||
|
||||
3. scmd recovered
|
||||
ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
|
||||
- shost->host_failed--
|
||||
- clear scmd->eh_eflags
|
||||
- scsi_setup_cmd_retry()
|
||||
- move from local eh_work_q to local eh_done_q
|
||||
LOCKING: none
|
||||
CONCURRENCY: at most one thread per separate eh_work_q to
|
||||
keep queue manipulation lockless
|
||||
|
||||
4. EH completes
|
||||
ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper
|
||||
layer of failure.
|
||||
layer of failure. May be called concurrently but must have
|
||||
a no more than one thread per separate eh_work_q to
|
||||
manipulate the queue locklessly
|
||||
- scmd is removed from eh_done_q and scmd->eh_entry is cleared
|
||||
- if retry is necessary, scmd is requeued using
|
||||
scsi_queue_insert()
|
||||
- otherwise, scsi_finish_command() is invoked for scmd
|
||||
- zero shost->host_failed
|
||||
LOCKING: queue or finish function performs appropriate locking
|
||||
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 15
|
||||
SUBLEVEL = 16
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ config ARC_HAS_LLSC
|
|||
|
||||
config ARC_STAR_9000923308
|
||||
bool "Workaround for llock/scond livelock"
|
||||
default y
|
||||
default n
|
||||
depends on ISA_ARCV2 && SMP && ARC_HAS_LLSC
|
||||
|
||||
config ARC_HAS_SWAPE
|
||||
|
|
|
@ -332,10 +332,6 @@ static void arc_chk_core_config(void)
|
|||
pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n");
|
||||
else if (!cpu->extn.fpu_dp && fpu_enabled)
|
||||
panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n");
|
||||
|
||||
if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic &&
|
||||
!IS_ENABLED(CONFIG_ARC_STAR_9000923308))
|
||||
panic("llock/scond livelock workaround missing\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -58,8 +58,8 @@
|
|||
soc {
|
||||
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
|
||||
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
|
||||
MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
|
||||
MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
|
||||
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
|
||||
MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
|
||||
|
||||
internal-regs {
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
/ {
|
||||
model = "NextThing C.H.I.P.";
|
||||
compatible = "nextthing,chip", "allwinner,sun5i-r8";
|
||||
compatible = "nextthing,chip", "allwinner,sun5i-r8", "allwinner,sun5i-a13";
|
||||
|
||||
aliases {
|
||||
i2c0 = &i2c0;
|
||||
|
|
|
@ -193,6 +193,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
|
|||
|
||||
#define pmd_large(pmd) (pmd_val(pmd) & 2)
|
||||
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
|
||||
#define pmd_present(pmd) (pmd_val(pmd))
|
||||
|
||||
#define copy_pmd(pmdpd,pmdps) \
|
||||
do { \
|
||||
|
|
|
@ -212,6 +212,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
|
|||
: !!(pmd_val(pmd) & (val)))
|
||||
#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val)))
|
||||
|
||||
#define pmd_present(pmd) (pmd_isset((pmd), L_PMD_SECT_VALID))
|
||||
#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF))
|
||||
#define pte_special(pte) (pte_isset((pte), L_PTE_SPECIAL))
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
|
@ -257,10 +258,10 @@ PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
|
|||
#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
|
||||
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
|
||||
|
||||
/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
|
||||
/* represent a notpresent pmd by faulting entry, this is used by pmdp_invalidate */
|
||||
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||
{
|
||||
return __pmd(0);
|
||||
return __pmd(pmd_val(pmd) & ~L_PMD_SECT_VALID);
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
||||
|
|
|
@ -182,7 +182,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|||
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
|
||||
|
||||
#define pmd_none(pmd) (!pmd_val(pmd))
|
||||
#define pmd_present(pmd) (pmd_val(pmd))
|
||||
|
||||
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ static int ksz8081_phy_fixup(struct phy_device *dev)
|
|||
static void __init imx6ul_enet_phy_init(void)
|
||||
{
|
||||
if (IS_BUILTIN(CONFIG_PHYLIB))
|
||||
phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
|
||||
phy_register_fixup_for_uid(PHY_ID_KSZ8081, MICREL_PHY_ID_MASK,
|
||||
ksz8081_phy_fixup);
|
||||
}
|
||||
|
||||
|
|
|
@ -162,22 +162,16 @@ exit:
|
|||
}
|
||||
|
||||
/*
|
||||
* This ioremap hook is used on Armada 375/38x to ensure that PCIe
|
||||
* memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
|
||||
* is needed as a workaround for a deadlock issue between the PCIe
|
||||
* interface and the cache controller.
|
||||
* This ioremap hook is used on Armada 375/38x to ensure that all MMIO
|
||||
* areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
|
||||
* needed for the HW I/O coherency mechanism to work properly without
|
||||
* deadlock.
|
||||
*/
|
||||
static void __iomem *
|
||||
armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
|
||||
unsigned int mtype, void *caller)
|
||||
armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
|
||||
unsigned int mtype, void *caller)
|
||||
{
|
||||
struct resource pcie_mem;
|
||||
|
||||
mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
|
||||
|
||||
if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
|
||||
mtype = MT_UNCACHED;
|
||||
|
||||
mtype = MT_UNCACHED;
|
||||
return __arm_ioremap_caller(phys_addr, size, mtype, caller);
|
||||
}
|
||||
|
||||
|
@ -186,7 +180,7 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
|
|||
struct device_node *cache_dn;
|
||||
|
||||
coherency_cpu_base = of_iomap(np, 0);
|
||||
arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
|
||||
arch_ioremap_caller = armada_wa_ioremap_caller;
|
||||
|
||||
/*
|
||||
* We should switch the PL310 to I/O coherency mode only if
|
||||
|
|
|
@ -73,7 +73,7 @@ config DEBUG_RODATA
|
|||
If in doubt, say Y
|
||||
|
||||
config DEBUG_ALIGN_RODATA
|
||||
depends on DEBUG_RODATA && ARM64_4K_PAGES
|
||||
depends on DEBUG_RODATA
|
||||
bool "Align linker sections up to SECTION_SIZE"
|
||||
help
|
||||
If this option is enabled, sections that may potentially be marked as
|
||||
|
|
|
@ -233,4 +233,24 @@ lr .req x30 // link register
|
|||
.long \sym\()_hi32
|
||||
.endm
|
||||
|
||||
/*
|
||||
* mov_q - move an immediate constant into a 64-bit register using
|
||||
* between 2 and 4 movz/movk instructions (depending on the
|
||||
* magnitude and sign of the operand)
|
||||
*/
|
||||
.macro mov_q, reg, val
|
||||
.if (((\val) >> 31) == 0 || ((\val) >> 31) == 0x1ffffffff)
|
||||
movz \reg, :abs_g1_s:\val
|
||||
.else
|
||||
.if (((\val) >> 47) == 0 || ((\val) >> 47) == 0x1ffff)
|
||||
movz \reg, :abs_g2_s:\val
|
||||
.else
|
||||
movz \reg, :abs_g3:\val
|
||||
movk \reg, :abs_g2_nc:\val
|
||||
.endif
|
||||
movk \reg, :abs_g1_nc:\val
|
||||
.endif
|
||||
movk \reg, :abs_g0_nc:\val
|
||||
.endm
|
||||
|
||||
#endif /* __ASM_ASSEMBLER_H */
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#define COMPAT_PSR_Z_BIT 0x40000000
|
||||
#define COMPAT_PSR_N_BIT 0x80000000
|
||||
#define COMPAT_PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
|
||||
#define COMPAT_PSR_GE_MASK 0x000f0000
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
#define COMPAT_PSR_ENDSTATE COMPAT_PSR_E_BIT
|
||||
|
@ -151,35 +152,9 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
|
|||
return regs->regs[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Are the current registers suitable for user mode? (used to maintain
|
||||
* security in signal handlers)
|
||||
*/
|
||||
static inline int valid_user_regs(struct user_pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs) && (regs->pstate & PSR_I_BIT) == 0) {
|
||||
regs->pstate &= ~(PSR_F_BIT | PSR_A_BIT);
|
||||
|
||||
/* The T bit is reserved for AArch64 */
|
||||
if (!(regs->pstate & PSR_MODE32_BIT))
|
||||
regs->pstate &= ~COMPAT_PSR_T_BIT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force PSR to something logical...
|
||||
*/
|
||||
regs->pstate &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | \
|
||||
COMPAT_PSR_T_BIT | PSR_MODE32_BIT;
|
||||
|
||||
if (!(regs->pstate & PSR_MODE32_BIT)) {
|
||||
regs->pstate &= ~COMPAT_PSR_T_BIT;
|
||||
regs->pstate |= PSR_MODE_EL0t;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* We must avoid circular header include via sched.h */
|
||||
struct task_struct;
|
||||
int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task);
|
||||
|
||||
#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ ENTRY(entry)
|
|||
*/
|
||||
mov x20, x0 // DTB address
|
||||
ldr x0, [sp, #16] // relocated _text address
|
||||
movz x21, #:abs_g0:stext_offset
|
||||
ldr w21, =stext_offset
|
||||
add x21, x0, x21
|
||||
|
||||
/*
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/irqchip/arm-gic-v3.h>
|
||||
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/boot.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cache.h>
|
||||
|
@ -100,8 +101,6 @@ _head:
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
.globl __efistub_stext_offset
|
||||
.set __efistub_stext_offset, stext - _head
|
||||
.align 3
|
||||
pe_header:
|
||||
.ascii "PE"
|
||||
|
@ -121,11 +120,11 @@ optional_header:
|
|||
.short 0x20b // PE32+ format
|
||||
.byte 0x02 // MajorLinkerVersion
|
||||
.byte 0x14 // MinorLinkerVersion
|
||||
.long _end - stext // SizeOfCode
|
||||
.long _end - efi_header_end // SizeOfCode
|
||||
.long 0 // SizeOfInitializedData
|
||||
.long 0 // SizeOfUninitializedData
|
||||
.long __efistub_entry - _head // AddressOfEntryPoint
|
||||
.long __efistub_stext_offset // BaseOfCode
|
||||
.long efi_header_end - _head // BaseOfCode
|
||||
|
||||
extra_header_fields:
|
||||
.quad 0 // ImageBase
|
||||
|
@ -142,7 +141,7 @@ extra_header_fields:
|
|||
.long _end - _head // SizeOfImage
|
||||
|
||||
// Everything before the kernel image is considered part of the header
|
||||
.long __efistub_stext_offset // SizeOfHeaders
|
||||
.long efi_header_end - _head // SizeOfHeaders
|
||||
.long 0 // CheckSum
|
||||
.short 0xa // Subsystem (EFI application)
|
||||
.short 0 // DllCharacteristics
|
||||
|
@ -186,10 +185,10 @@ section_table:
|
|||
.byte 0
|
||||
.byte 0
|
||||
.byte 0 // end of 0 padding of section name
|
||||
.long _end - stext // VirtualSize
|
||||
.long __efistub_stext_offset // VirtualAddress
|
||||
.long _edata - stext // SizeOfRawData
|
||||
.long __efistub_stext_offset // PointerToRawData
|
||||
.long _end - efi_header_end // VirtualSize
|
||||
.long efi_header_end - _head // VirtualAddress
|
||||
.long _edata - efi_header_end // SizeOfRawData
|
||||
.long efi_header_end - _head // PointerToRawData
|
||||
|
||||
.long 0 // PointerToRelocations (0 for executables)
|
||||
.long 0 // PointerToLineNumbers (0 for executables)
|
||||
|
@ -198,20 +197,23 @@ section_table:
|
|||
.long 0xe0500020 // Characteristics (section flags)
|
||||
|
||||
/*
|
||||
* EFI will load stext onwards at the 4k section alignment
|
||||
* EFI will load .text onwards at the 4k section alignment
|
||||
* described in the PE/COFF header. To ensure that instruction
|
||||
* sequences using an adrp and a :lo12: immediate will function
|
||||
* correctly at this alignment, we must ensure that stext is
|
||||
* correctly at this alignment, we must ensure that .text is
|
||||
* placed at a 4k boundary in the Image to begin with.
|
||||
*/
|
||||
.align 12
|
||||
efi_header_end:
|
||||
#endif
|
||||
|
||||
__INIT
|
||||
|
||||
ENTRY(stext)
|
||||
bl preserve_boot_args
|
||||
bl el2_setup // Drop to EL1, w20=cpu_boot_mode
|
||||
mov x23, xzr // KASLR offset, defaults to 0
|
||||
adrp x24, __PHYS_OFFSET
|
||||
and x23, x24, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0
|
||||
bl set_cpu_boot_mode_flag
|
||||
bl __create_page_tables // x25=TTBR0, x26=TTBR1
|
||||
/*
|
||||
|
@ -220,13 +222,11 @@ ENTRY(stext)
|
|||
* On return, the CPU will be ready for the MMU to be turned on and
|
||||
* the TCR will have been set.
|
||||
*/
|
||||
ldr x27, 0f // address to jump to after
|
||||
bl __cpu_setup // initialise processor
|
||||
adr_l x27, __primary_switch // address to jump to after
|
||||
// MMU has been enabled
|
||||
adr_l lr, __enable_mmu // return (PIC) address
|
||||
b __cpu_setup // initialise processor
|
||||
b __enable_mmu
|
||||
ENDPROC(stext)
|
||||
.align 3
|
||||
0: .quad __mmap_switched - (_head - TEXT_OFFSET) + KIMAGE_VADDR
|
||||
|
||||
/*
|
||||
* Preserve the arguments passed by the bootloader in x0 .. x3
|
||||
|
@ -336,7 +336,7 @@ __create_page_tables:
|
|||
cmp x0, x6
|
||||
b.lo 1b
|
||||
|
||||
ldr x7, =SWAPPER_MM_MMUFLAGS
|
||||
mov x7, SWAPPER_MM_MMUFLAGS
|
||||
|
||||
/*
|
||||
* Create the identity mapping.
|
||||
|
@ -392,12 +392,13 @@ __create_page_tables:
|
|||
* Map the kernel image (starting with PHYS_OFFSET).
|
||||
*/
|
||||
mov x0, x26 // swapper_pg_dir
|
||||
ldr x5, =KIMAGE_VADDR
|
||||
mov_q x5, KIMAGE_VADDR + TEXT_OFFSET // compile time __va(_text)
|
||||
add x5, x5, x23 // add KASLR displacement
|
||||
create_pgd_entry x0, x5, x3, x6
|
||||
ldr w6, kernel_img_size
|
||||
add x6, x6, x5
|
||||
mov x3, x24 // phys offset
|
||||
adrp x6, _end // runtime __pa(_end)
|
||||
adrp x3, _text // runtime __pa(_text)
|
||||
sub x6, x6, x3 // _end - _text
|
||||
add x6, x6, x5 // runtime __va(_end)
|
||||
create_block_map x0, x7, x3, x5, x6
|
||||
|
||||
/*
|
||||
|
@ -412,16 +413,13 @@ __create_page_tables:
|
|||
|
||||
ret x28
|
||||
ENDPROC(__create_page_tables)
|
||||
|
||||
kernel_img_size:
|
||||
.long _end - (_head - TEXT_OFFSET)
|
||||
.ltorg
|
||||
|
||||
/*
|
||||
* The following fragment of code is executed with the MMU enabled.
|
||||
*/
|
||||
.set initial_sp, init_thread_union + THREAD_START_SP
|
||||
__mmap_switched:
|
||||
__primary_switched:
|
||||
mov x28, lr // preserve LR
|
||||
adr_l x8, vectors // load VBAR_EL1 with virtual
|
||||
msr vbar_el1, x8 // vector table address
|
||||
|
@ -435,44 +433,6 @@ __mmap_switched:
|
|||
bl __pi_memset
|
||||
dsb ishst // Make zero page visible to PTW
|
||||
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
|
||||
/*
|
||||
* Iterate over each entry in the relocation table, and apply the
|
||||
* relocations in place.
|
||||
*/
|
||||
adr_l x8, __dynsym_start // start of symbol table
|
||||
adr_l x9, __reloc_start // start of reloc table
|
||||
adr_l x10, __reloc_end // end of reloc table
|
||||
|
||||
0: cmp x9, x10
|
||||
b.hs 2f
|
||||
ldp x11, x12, [x9], #24
|
||||
ldr x13, [x9, #-8]
|
||||
cmp w12, #R_AARCH64_RELATIVE
|
||||
b.ne 1f
|
||||
add x13, x13, x23 // relocate
|
||||
str x13, [x11, x23]
|
||||
b 0b
|
||||
|
||||
1: cmp w12, #R_AARCH64_ABS64
|
||||
b.ne 0b
|
||||
add x12, x12, x12, lsl #1 // symtab offset: 24x top word
|
||||
add x12, x8, x12, lsr #(32 - 3) // ... shifted into bottom word
|
||||
ldrsh w14, [x12, #6] // Elf64_Sym::st_shndx
|
||||
ldr x15, [x12, #8] // Elf64_Sym::st_value
|
||||
cmp w14, #-0xf // SHN_ABS (0xfff1) ?
|
||||
add x14, x15, x23 // relocate
|
||||
csel x15, x14, x15, ne
|
||||
add x15, x13, x15
|
||||
str x15, [x11, x23]
|
||||
b 0b
|
||||
|
||||
2: adr_l x8, kimage_vaddr // make relocated kimage_vaddr
|
||||
dc cvac, x8 // value visible to secondaries
|
||||
dsb sy // with MMU off
|
||||
#endif
|
||||
|
||||
adr_l sp, initial_sp, x4
|
||||
mov x4, sp
|
||||
and x4, x4, #~(THREAD_SIZE - 1)
|
||||
|
@ -488,17 +448,19 @@ __mmap_switched:
|
|||
bl kasan_early_init
|
||||
#endif
|
||||
#ifdef CONFIG_RANDOMIZE_BASE
|
||||
cbnz x23, 0f // already running randomized?
|
||||
tst x23, ~(MIN_KIMG_ALIGN - 1) // already running randomized?
|
||||
b.ne 0f
|
||||
mov x0, x21 // pass FDT address in x0
|
||||
mov x1, x23 // pass modulo offset in x1
|
||||
bl kaslr_early_init // parse FDT for KASLR options
|
||||
cbz x0, 0f // KASLR disabled? just proceed
|
||||
mov x23, x0 // record KASLR offset
|
||||
orr x23, x23, x0 // record KASLR offset
|
||||
ret x28 // we must enable KASLR, return
|
||||
// to __enable_mmu()
|
||||
0:
|
||||
#endif
|
||||
b start_kernel
|
||||
ENDPROC(__mmap_switched)
|
||||
ENDPROC(__primary_switched)
|
||||
|
||||
/*
|
||||
* end early head section, begin head code that is also used for
|
||||
|
@ -613,7 +575,7 @@ ENDPROC(el2_setup)
|
|||
* Sets the __boot_cpu_mode flag depending on the CPU boot mode passed
|
||||
* in x20. See arch/arm64/include/asm/virt.h for more info.
|
||||
*/
|
||||
ENTRY(set_cpu_boot_mode_flag)
|
||||
set_cpu_boot_mode_flag:
|
||||
adr_l x1, __boot_cpu_mode
|
||||
cmp w20, #BOOT_CPU_MODE_EL2
|
||||
b.ne 1f
|
||||
|
@ -646,7 +608,7 @@ ENTRY(secondary_holding_pen)
|
|||
bl el2_setup // Drop to EL1, w20=cpu_boot_mode
|
||||
bl set_cpu_boot_mode_flag
|
||||
mrs x0, mpidr_el1
|
||||
ldr x1, =MPIDR_HWID_BITMASK
|
||||
mov_q x1, MPIDR_HWID_BITMASK
|
||||
and x0, x0, x1
|
||||
adr_l x3, secondary_holding_pen_release
|
||||
pen: ldr x4, [x3]
|
||||
|
@ -666,7 +628,7 @@ ENTRY(secondary_entry)
|
|||
b secondary_startup
|
||||
ENDPROC(secondary_entry)
|
||||
|
||||
ENTRY(secondary_startup)
|
||||
secondary_startup:
|
||||
/*
|
||||
* Common entry point for secondary CPUs.
|
||||
*/
|
||||
|
@ -674,14 +636,11 @@ ENTRY(secondary_startup)
|
|||
adrp x26, swapper_pg_dir
|
||||
bl __cpu_setup // initialise processor
|
||||
|
||||
ldr x8, kimage_vaddr
|
||||
ldr w9, 0f
|
||||
sub x27, x8, w9, sxtw // address to jump to after enabling the MMU
|
||||
adr_l x27, __secondary_switch // address to jump to after enabling the MMU
|
||||
b __enable_mmu
|
||||
ENDPROC(secondary_startup)
|
||||
0: .long (_text - TEXT_OFFSET) - __secondary_switched
|
||||
|
||||
ENTRY(__secondary_switched)
|
||||
__secondary_switched:
|
||||
adr_l x5, vectors
|
||||
msr vbar_el1, x5
|
||||
isb
|
||||
|
@ -743,7 +702,6 @@ __enable_mmu:
|
|||
ic iallu // flush instructions fetched
|
||||
dsb nsh // via old mapping
|
||||
isb
|
||||
add x27, x27, x23 // relocated __mmap_switched
|
||||
#endif
|
||||
br x27
|
||||
ENDPROC(__enable_mmu)
|
||||
|
@ -752,3 +710,53 @@ __no_granule_support:
|
|||
wfe
|
||||
b __no_granule_support
|
||||
ENDPROC(__no_granule_support)
|
||||
|
||||
__primary_switch:
|
||||
#ifdef CONFIG_RELOCATABLE
|
||||
/*
|
||||
* Iterate over each entry in the relocation table, and apply the
|
||||
* relocations in place.
|
||||
*/
|
||||
ldr w8, =__dynsym_offset // offset to symbol table
|
||||
ldr w9, =__rela_offset // offset to reloc table
|
||||
ldr w10, =__rela_size // size of reloc table
|
||||
|
||||
mov_q x11, KIMAGE_VADDR // default virtual offset
|
||||
add x11, x11, x23 // actual virtual offset
|
||||
add x8, x8, x11 // __va(.dynsym)
|
||||
add x9, x9, x11 // __va(.rela)
|
||||
add x10, x9, x10 // __va(.rela) + sizeof(.rela)
|
||||
|
||||
0: cmp x9, x10
|
||||
b.hs 2f
|
||||
ldp x11, x12, [x9], #24
|
||||
ldr x13, [x9, #-8]
|
||||
cmp w12, #R_AARCH64_RELATIVE
|
||||
b.ne 1f
|
||||
add x13, x13, x23 // relocate
|
||||
str x13, [x11, x23]
|
||||
b 0b
|
||||
|
||||
1: cmp w12, #R_AARCH64_ABS64
|
||||
b.ne 0b
|
||||
add x12, x12, x12, lsl #1 // symtab offset: 24x top word
|
||||
add x12, x8, x12, lsr #(32 - 3) // ... shifted into bottom word
|
||||
ldrsh w14, [x12, #6] // Elf64_Sym::st_shndx
|
||||
ldr x15, [x12, #8] // Elf64_Sym::st_value
|
||||
cmp w14, #-0xf // SHN_ABS (0xfff1) ?
|
||||
add x14, x15, x23 // relocate
|
||||
csel x15, x14, x15, ne
|
||||
add x15, x13, x15
|
||||
str x15, [x11, x23]
|
||||
b 0b
|
||||
|
||||
2:
|
||||
#endif
|
||||
ldr x8, =__primary_switched
|
||||
br x8
|
||||
ENDPROC(__primary_switch)
|
||||
|
||||
__secondary_switch:
|
||||
ldr x8, =__secondary_switched
|
||||
br x8
|
||||
ENDPROC(__secondary_switch)
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
|
||||
#ifdef CONFIG_EFI
|
||||
|
||||
__efistub_stext_offset = stext - _text;
|
||||
|
||||
/*
|
||||
* Prevent the symbol aliases below from being emitted into the kallsyms
|
||||
* table, by forcing them to be absolute symbols (which are conveniently
|
||||
|
|
|
@ -74,7 +74,7 @@ extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
|
|||
* containing function pointers) to be reinitialized, and zero-initialized
|
||||
* .bss variables will be reset to 0.
|
||||
*/
|
||||
u64 __init kaslr_early_init(u64 dt_phys)
|
||||
u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset)
|
||||
{
|
||||
void *fdt;
|
||||
u64 seed, offset, mask, module_range;
|
||||
|
@ -132,8 +132,8 @@ u64 __init kaslr_early_init(u64 dt_phys)
|
|||
* boundary (for 4KB/16KB/64KB granule kernels, respectively). If this
|
||||
* happens, increase the KASLR offset by the size of the kernel image.
|
||||
*/
|
||||
if ((((u64)_text + offset) >> SWAPPER_TABLE_SHIFT) !=
|
||||
(((u64)_end + offset) >> SWAPPER_TABLE_SHIFT))
|
||||
if ((((u64)_text + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT) !=
|
||||
(((u64)_end + offset + modulo_offset) >> SWAPPER_TABLE_SHIFT))
|
||||
offset = (offset + (u64)(_end - _text)) & mask;
|
||||
|
||||
if (IS_ENABLED(CONFIG_KASAN))
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <linux/elf.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/syscall.h>
|
||||
|
@ -500,7 +501,7 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!valid_user_regs(&newregs))
|
||||
if (!valid_user_regs(&newregs, target))
|
||||
return -EINVAL;
|
||||
|
||||
task_pt_regs(target)->user_regs = newregs;
|
||||
|
@ -770,7 +771,7 @@ static int compat_gpr_set(struct task_struct *target,
|
|||
|
||||
}
|
||||
|
||||
if (valid_user_regs(&newregs.user_regs))
|
||||
if (valid_user_regs(&newregs.user_regs, target))
|
||||
*task_pt_regs(target) = newregs;
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
@ -1272,3 +1273,79 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
|
|||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bits which are always architecturally RES0 per ARM DDI 0487A.h
|
||||
* Userspace cannot use these until they have an architectural meaning.
|
||||
* We also reserve IL for the kernel; SS is handled dynamically.
|
||||
*/
|
||||
#define SPSR_EL1_AARCH64_RES0_BITS \
|
||||
(GENMASK_ULL(63,32) | GENMASK_ULL(27, 22) | GENMASK_ULL(20, 10) | \
|
||||
GENMASK_ULL(5, 5))
|
||||
#define SPSR_EL1_AARCH32_RES0_BITS \
|
||||
(GENMASK_ULL(63,32) | GENMASK_ULL(24, 22) | GENMASK_ULL(20,20))
|
||||
|
||||
static int valid_compat_regs(struct user_pt_regs *regs)
|
||||
{
|
||||
regs->pstate &= ~SPSR_EL1_AARCH32_RES0_BITS;
|
||||
|
||||
if (!system_supports_mixed_endian_el0()) {
|
||||
if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
|
||||
regs->pstate |= COMPAT_PSR_E_BIT;
|
||||
else
|
||||
regs->pstate &= ~COMPAT_PSR_E_BIT;
|
||||
}
|
||||
|
||||
if (user_mode(regs) && (regs->pstate & PSR_MODE32_BIT) &&
|
||||
(regs->pstate & COMPAT_PSR_A_BIT) == 0 &&
|
||||
(regs->pstate & COMPAT_PSR_I_BIT) == 0 &&
|
||||
(regs->pstate & COMPAT_PSR_F_BIT) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Force PSR to a valid 32-bit EL0t, preserving the same bits as
|
||||
* arch/arm.
|
||||
*/
|
||||
regs->pstate &= COMPAT_PSR_N_BIT | COMPAT_PSR_Z_BIT |
|
||||
COMPAT_PSR_C_BIT | COMPAT_PSR_V_BIT |
|
||||
COMPAT_PSR_Q_BIT | COMPAT_PSR_IT_MASK |
|
||||
COMPAT_PSR_GE_MASK | COMPAT_PSR_E_BIT |
|
||||
COMPAT_PSR_T_BIT;
|
||||
regs->pstate |= PSR_MODE32_BIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int valid_native_regs(struct user_pt_regs *regs)
|
||||
{
|
||||
regs->pstate &= ~SPSR_EL1_AARCH64_RES0_BITS;
|
||||
|
||||
if (user_mode(regs) && !(regs->pstate & PSR_MODE32_BIT) &&
|
||||
(regs->pstate & PSR_D_BIT) == 0 &&
|
||||
(regs->pstate & PSR_A_BIT) == 0 &&
|
||||
(regs->pstate & PSR_I_BIT) == 0 &&
|
||||
(regs->pstate & PSR_F_BIT) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Force PSR to a valid 64-bit EL0t */
|
||||
regs->pstate &= PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Are the current registers suitable for user mode? (used to maintain
|
||||
* security in signal handlers)
|
||||
*/
|
||||
int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task)
|
||||
{
|
||||
if (!test_tsk_thread_flag(task, TIF_SINGLESTEP))
|
||||
regs->pstate &= ~DBG_SPSR_SS;
|
||||
|
||||
if (is_compat_thread(task_thread_info(task)))
|
||||
return valid_compat_regs(regs);
|
||||
else
|
||||
return valid_native_regs(regs);
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ static int restore_sigframe(struct pt_regs *regs,
|
|||
*/
|
||||
regs->syscallno = ~0UL;
|
||||
|
||||
err |= !valid_user_regs(®s->user_regs);
|
||||
err |= !valid_user_regs(®s->user_regs, current);
|
||||
|
||||
if (err == 0) {
|
||||
struct fpsimd_context *fpsimd_ctx =
|
||||
|
@ -307,7 +307,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
|||
/*
|
||||
* Check that the resulting registers are actually sane.
|
||||
*/
|
||||
ret |= !valid_user_regs(®s->user_regs);
|
||||
ret |= !valid_user_regs(®s->user_regs, current);
|
||||
|
||||
/*
|
||||
* Fast forward the stepping logic so we step into the signal
|
||||
|
|
|
@ -356,7 +356,7 @@ static int compat_restore_sigframe(struct pt_regs *regs,
|
|||
*/
|
||||
regs->syscallno = ~0UL;
|
||||
|
||||
err |= !valid_user_regs(®s->user_regs);
|
||||
err |= !valid_user_regs(®s->user_regs, current);
|
||||
|
||||
aux = (struct compat_aux_sigframe __user *) sf->uc.uc_regspace;
|
||||
if (err == 0)
|
||||
|
|
|
@ -63,14 +63,19 @@ PECOFF_FILE_ALIGNMENT = 0x200;
|
|||
#endif
|
||||
|
||||
#if defined(CONFIG_DEBUG_ALIGN_RODATA)
|
||||
#define ALIGN_DEBUG_RO . = ALIGN(1<<SECTION_SHIFT);
|
||||
#define ALIGN_DEBUG_RO_MIN(min) ALIGN_DEBUG_RO
|
||||
#elif defined(CONFIG_DEBUG_RODATA)
|
||||
#define ALIGN_DEBUG_RO . = ALIGN(1<<PAGE_SHIFT);
|
||||
#define ALIGN_DEBUG_RO_MIN(min) ALIGN_DEBUG_RO
|
||||
/*
|
||||
* 4 KB granule: 1 level 2 entry
|
||||
* 16 KB granule: 128 level 3 entries, with contiguous bit
|
||||
* 64 KB granule: 32 level 3 entries, with contiguous bit
|
||||
*/
|
||||
#define SEGMENT_ALIGN SZ_2M
|
||||
#else
|
||||
#define ALIGN_DEBUG_RO
|
||||
#define ALIGN_DEBUG_RO_MIN(min) . = ALIGN(min);
|
||||
/*
|
||||
* 4 KB granule: 16 level 3 entries, with contiguous bit
|
||||
* 16 KB granule: 4 level 3 entries, without contiguous bit
|
||||
* 64 KB granule: 1 level 3 entry
|
||||
*/
|
||||
#define SEGMENT_ALIGN SZ_64K
|
||||
#endif
|
||||
|
||||
SECTIONS
|
||||
|
@ -96,7 +101,6 @@ SECTIONS
|
|||
_text = .;
|
||||
HEAD_TEXT
|
||||
}
|
||||
ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
|
||||
.text : { /* Real text segment */
|
||||
_stext = .; /* Text and read-only data */
|
||||
__exception_text_start = .;
|
||||
|
@ -114,11 +118,12 @@ SECTIONS
|
|||
*(.got) /* Global offset table */
|
||||
}
|
||||
|
||||
RO_DATA(PAGE_SIZE)
|
||||
EXCEPTION_TABLE(8)
|
||||
. = ALIGN(SEGMENT_ALIGN);
|
||||
RO_DATA(PAGE_SIZE) /* everything from this point to */
|
||||
EXCEPTION_TABLE(8) /* _etext will be marked RO NX */
|
||||
NOTES
|
||||
|
||||
ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
|
||||
. = ALIGN(SEGMENT_ALIGN);
|
||||
_etext = .; /* End of text and rodata section */
|
||||
__init_begin = .;
|
||||
|
||||
|
@ -151,12 +156,9 @@ SECTIONS
|
|||
*(.altinstr_replacement)
|
||||
}
|
||||
.rela : ALIGN(8) {
|
||||
__reloc_start = .;
|
||||
*(.rela .rela*)
|
||||
__reloc_end = .;
|
||||
}
|
||||
.dynsym : ALIGN(8) {
|
||||
__dynsym_start = .;
|
||||
*(.dynsym)
|
||||
}
|
||||
.dynstr : {
|
||||
|
@ -166,7 +168,11 @@ SECTIONS
|
|||
*(.hash)
|
||||
}
|
||||
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__rela_offset = ADDR(.rela) - KIMAGE_VADDR;
|
||||
__rela_size = SIZEOF(.rela);
|
||||
__dynsym_offset = ADDR(.dynsym) - KIMAGE_VADDR;
|
||||
|
||||
. = ALIGN(SEGMENT_ALIGN);
|
||||
__init_end = .;
|
||||
|
||||
_data = .;
|
||||
|
|
|
@ -372,6 +372,7 @@ void __init mem_init(void)
|
|||
" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n"
|
||||
" .init : 0x%p" " - 0x%p" " (%6ld KB)\n"
|
||||
" .text : 0x%p" " - 0x%p" " (%6ld KB)\n"
|
||||
" .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n"
|
||||
" .data : 0x%p" " - 0x%p" " (%6ld KB)\n"
|
||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n"
|
||||
|
@ -386,7 +387,8 @@ void __init mem_init(void)
|
|||
MLM(MODULES_VADDR, MODULES_END),
|
||||
MLG(VMALLOC_START, VMALLOC_END),
|
||||
MLK_ROUNDUP(__init_begin, __init_end),
|
||||
MLK_ROUNDUP(_text, _etext),
|
||||
MLK_ROUNDUP(_text, __start_rodata),
|
||||
MLK_ROUNDUP(__start_rodata, _etext),
|
||||
MLK_ROUNDUP(_sdata, _edata),
|
||||
#ifdef CONFIG_SPARSEMEM_VMEMMAP
|
||||
MLG(VMEMMAP_START,
|
||||
|
|
|
@ -385,7 +385,7 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt,
|
|||
|
||||
static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end)
|
||||
{
|
||||
unsigned long kernel_start = __pa(_stext);
|
||||
unsigned long kernel_start = __pa(_text);
|
||||
unsigned long kernel_end = __pa(_etext);
|
||||
|
||||
/*
|
||||
|
@ -417,7 +417,7 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
|
|||
early_pgtable_alloc);
|
||||
|
||||
/*
|
||||
* Map the linear alias of the [_stext, _etext) interval as
|
||||
* Map the linear alias of the [_text, _etext) interval as
|
||||
* read-only/non-executable. This makes the contents of the
|
||||
* region accessible to subsystems such as hibernate, but
|
||||
* protects it from inadvertent modification or execution.
|
||||
|
@ -445,12 +445,18 @@ static void __init map_mem(pgd_t *pgd)
|
|||
|
||||
void mark_rodata_ro(void)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_DEBUG_RODATA))
|
||||
return;
|
||||
unsigned long section_size;
|
||||
|
||||
create_mapping_late(__pa(_stext), (unsigned long)_stext,
|
||||
(unsigned long)_etext - (unsigned long)_stext,
|
||||
PAGE_KERNEL_ROX);
|
||||
section_size = (unsigned long)__start_rodata - (unsigned long)_text;
|
||||
create_mapping_late(__pa(_text), (unsigned long)_text,
|
||||
section_size, PAGE_KERNEL_ROX);
|
||||
/*
|
||||
* mark .rodata as read only. Use _etext rather than __end_rodata to
|
||||
* cover NOTES and EXCEPTION_TABLE.
|
||||
*/
|
||||
section_size = (unsigned long)_etext - (unsigned long)__start_rodata;
|
||||
create_mapping_late(__pa(__start_rodata), (unsigned long)__start_rodata,
|
||||
section_size, PAGE_KERNEL_RO);
|
||||
}
|
||||
|
||||
void fixup_init(void)
|
||||
|
@ -463,8 +469,8 @@ void fixup_init(void)
|
|||
unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin));
|
||||
}
|
||||
|
||||
static void __init map_kernel_chunk(pgd_t *pgd, void *va_start, void *va_end,
|
||||
pgprot_t prot, struct vm_struct *vma)
|
||||
static void __init map_kernel_segment(pgd_t *pgd, void *va_start, void *va_end,
|
||||
pgprot_t prot, struct vm_struct *vma)
|
||||
{
|
||||
phys_addr_t pa_start = __pa(va_start);
|
||||
unsigned long size = va_end - va_start;
|
||||
|
@ -489,12 +495,13 @@ static void __init map_kernel_chunk(pgd_t *pgd, void *va_start, void *va_end,
|
|||
*/
|
||||
static void __init map_kernel(pgd_t *pgd)
|
||||
{
|
||||
static struct vm_struct vmlinux_text, vmlinux_init, vmlinux_data;
|
||||
static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data;
|
||||
|
||||
map_kernel_chunk(pgd, _stext, _etext, PAGE_KERNEL_EXEC, &vmlinux_text);
|
||||
map_kernel_chunk(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
|
||||
&vmlinux_init);
|
||||
map_kernel_chunk(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data);
|
||||
map_kernel_segment(pgd, _text, __start_rodata, PAGE_KERNEL_EXEC, &vmlinux_text);
|
||||
map_kernel_segment(pgd, __start_rodata, _etext, PAGE_KERNEL, &vmlinux_rodata);
|
||||
map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
|
||||
&vmlinux_init);
|
||||
map_kernel_segment(pgd, _data, _end, PAGE_KERNEL, &vmlinux_data);
|
||||
|
||||
if (!pgd_val(*pgd_offset_raw(pgd, FIXADDR_START))) {
|
||||
/*
|
||||
|
|
|
@ -372,6 +372,7 @@ struct kvm_mips_tlb {
|
|||
#define KVM_MIPS_GUEST_TLB_SIZE 64
|
||||
struct kvm_vcpu_arch {
|
||||
void *host_ebase, *guest_ebase;
|
||||
int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
unsigned long host_stack;
|
||||
unsigned long host_gp;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define MIPS_EXC_MAX 12
|
||||
/* XXXSL More to follow */
|
||||
|
||||
extern char __kvm_mips_vcpu_run_end[];
|
||||
extern char mips32_exception[], mips32_exceptionEnd[];
|
||||
extern char mips32_GuestException[], mips32_GuestExceptionEnd[];
|
||||
|
||||
|
|
|
@ -227,6 +227,7 @@ FEXPORT(__kvm_mips_load_k0k1)
|
|||
|
||||
/* Jump to guest */
|
||||
eret
|
||||
EXPORT(__kvm_mips_vcpu_run_end)
|
||||
|
||||
VECTOR(MIPSX(exception), unknown)
|
||||
/* Find out what mode we came from and jump to the proper handler. */
|
||||
|
|
|
@ -314,6 +314,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
|
|||
memcpy(gebase + offset, mips32_GuestException,
|
||||
mips32_GuestExceptionEnd - mips32_GuestException);
|
||||
|
||||
#ifdef MODULE
|
||||
offset += mips32_GuestExceptionEnd - mips32_GuestException;
|
||||
memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
|
||||
__kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
|
||||
vcpu->arch.vcpu_run = gebase + offset;
|
||||
#else
|
||||
vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
|
||||
#endif
|
||||
|
||||
/* Invalidate the icache for these ranges */
|
||||
local_flush_icache_range((unsigned long)gebase,
|
||||
(unsigned long)gebase + ALIGN(size, PAGE_SIZE));
|
||||
|
@ -403,7 +412,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|||
/* Disable hardware page table walking while in guest */
|
||||
htw_stop();
|
||||
|
||||
r = __kvm_mips_vcpu_run(run, vcpu);
|
||||
r = vcpu->arch.vcpu_run(run, vcpu);
|
||||
|
||||
/* Re-enable HTW before enabling interrupts */
|
||||
htw_start();
|
||||
|
|
|
@ -1239,6 +1239,16 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
|||
current->thread.regs = regs - 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
/*
|
||||
* Clear any transactional state, we're exec()ing. The cause is
|
||||
* not important as there will never be a recheckpoint so it's not
|
||||
* user visible.
|
||||
*/
|
||||
if (MSR_TM_SUSPENDED(mfmsr()))
|
||||
tm_reclaim_current(0);
|
||||
#endif
|
||||
|
||||
memset(regs->gpr, 0, sizeof(regs->gpr));
|
||||
regs->ctr = 0;
|
||||
regs->link = 0;
|
||||
|
|
|
@ -718,7 +718,7 @@ unsigned char ibm_architecture_vec[] = {
|
|||
* must match by the macro below. Update the definition if
|
||||
* the structure layout changes.
|
||||
*/
|
||||
#define IBM_ARCH_VEC_NRCORES_OFFSET 125
|
||||
#define IBM_ARCH_VEC_NRCORES_OFFSET 133
|
||||
W(NR_CPUS), /* number of cores supported */
|
||||
0,
|
||||
0,
|
||||
|
|
|
@ -912,7 +912,8 @@ machine_arch_initcall(pseries, find_existing_ddw_windows);
|
|||
static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
|
||||
struct ddw_query_response *query)
|
||||
{
|
||||
struct eeh_dev *edev;
|
||||
struct device_node *dn;
|
||||
struct pci_dn *pdn;
|
||||
u32 cfg_addr;
|
||||
u64 buid;
|
||||
int ret;
|
||||
|
@ -923,11 +924,10 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
|
|||
* Retrieve them from the pci device, not the node with the
|
||||
* dma-window property
|
||||
*/
|
||||
edev = pci_dev_to_eeh_dev(dev);
|
||||
cfg_addr = edev->config_addr;
|
||||
if (edev->pe_config_addr)
|
||||
cfg_addr = edev->pe_config_addr;
|
||||
buid = edev->phb->buid;
|
||||
dn = pci_device_to_OF_node(dev);
|
||||
pdn = PCI_DN(dn);
|
||||
buid = pdn->phb->buid;
|
||||
cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
|
||||
|
||||
ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
|
||||
cfg_addr, BUID_HI(buid), BUID_LO(buid));
|
||||
|
@ -941,7 +941,8 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
|
|||
struct ddw_create_response *create, int page_shift,
|
||||
int window_shift)
|
||||
{
|
||||
struct eeh_dev *edev;
|
||||
struct device_node *dn;
|
||||
struct pci_dn *pdn;
|
||||
u32 cfg_addr;
|
||||
u64 buid;
|
||||
int ret;
|
||||
|
@ -952,11 +953,10 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
|
|||
* Retrieve them from the pci device, not the node with the
|
||||
* dma-window property
|
||||
*/
|
||||
edev = pci_dev_to_eeh_dev(dev);
|
||||
cfg_addr = edev->config_addr;
|
||||
if (edev->pe_config_addr)
|
||||
cfg_addr = edev->pe_config_addr;
|
||||
buid = edev->phb->buid;
|
||||
dn = pci_device_to_OF_node(dev);
|
||||
pdn = PCI_DN(dn);
|
||||
buid = pdn->phb->buid;
|
||||
cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
|
||||
|
||||
do {
|
||||
/* extra outputs are LIOBN and dma-addr (hi, lo) */
|
||||
|
|
|
@ -22,7 +22,7 @@ static inline int test_fp_ctl(u32 fpc)
|
|||
" la %0,0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b,1b)
|
||||
: "=d" (rc), "=d" (orig_fpc)
|
||||
: "=d" (rc), "=&d" (orig_fpc)
|
||||
: "d" (fpc), "0" (-EINVAL));
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -162,6 +162,9 @@ isoimage: $(obj)/bzImage
|
|||
for i in lib lib64 share end ; do \
|
||||
if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
|
||||
cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
|
||||
if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \
|
||||
cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \
|
||||
fi ; \
|
||||
break ; \
|
||||
fi ; \
|
||||
if [ $$i = end ] ; then exit 1 ; fi ; \
|
||||
|
|
|
@ -71,8 +71,8 @@ int amd_cache_northbridges(void)
|
|||
while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
|
||||
i++;
|
||||
|
||||
if (i == 0)
|
||||
return 0;
|
||||
if (!i)
|
||||
return -ENODEV;
|
||||
|
||||
nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL);
|
||||
if (!nb)
|
||||
|
|
|
@ -3601,7 +3601,7 @@ __init int intel_pmu_init(void)
|
|||
c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
|
||||
}
|
||||
c->idxmsk64 &=
|
||||
~(~0UL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
|
||||
~(~0ULL << (INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed));
|
||||
c->weight = hweight64(c->idxmsk64);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -959,7 +959,19 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
* normal page fault.
|
||||
*/
|
||||
regs->ip = (unsigned long)cur->addr;
|
||||
/*
|
||||
* Trap flag (TF) has been set here because this fault
|
||||
* happened where the single stepping will be done.
|
||||
* So clear it by resetting the current kprobe:
|
||||
*/
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
|
||||
/*
|
||||
* If the TF flag was set before the kprobe hit,
|
||||
* don't touch it:
|
||||
*/
|
||||
regs->flags |= kcb->kprobe_old_flags;
|
||||
|
||||
if (kcb->kprobe_status == KPROBE_REENTER)
|
||||
restore_previous_kprobe(kcb);
|
||||
else
|
||||
|
|
|
@ -6579,7 +6579,13 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
|
|||
|
||||
/* Checks for #GP/#SS exceptions. */
|
||||
exn = false;
|
||||
if (is_protmode(vcpu)) {
|
||||
if (is_long_mode(vcpu)) {
|
||||
/* Long mode: #GP(0)/#SS(0) if the memory address is in a
|
||||
* non-canonical form. This is the only check on the memory
|
||||
* destination for long mode!
|
||||
*/
|
||||
exn = is_noncanonical_address(*ret);
|
||||
} else if (is_protmode(vcpu)) {
|
||||
/* Protected mode: apply checks for segment validity in the
|
||||
* following order:
|
||||
* - segment type check (#GP(0) may be thrown)
|
||||
|
@ -6596,17 +6602,10 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
|
|||
* execute-only code segment
|
||||
*/
|
||||
exn = ((s.type & 0xa) == 8);
|
||||
}
|
||||
if (exn) {
|
||||
kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
|
||||
return 1;
|
||||
}
|
||||
if (is_long_mode(vcpu)) {
|
||||
/* Long mode: #GP(0)/#SS(0) if the memory address is in a
|
||||
* non-canonical form. This is an only check for long mode.
|
||||
*/
|
||||
exn = is_noncanonical_address(*ret);
|
||||
} else if (is_protmode(vcpu)) {
|
||||
if (exn) {
|
||||
kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
|
||||
return 1;
|
||||
}
|
||||
/* Protected mode: #GP(0)/#SS(0) if the segment is unusable.
|
||||
*/
|
||||
exn = (s.unusable != 0);
|
||||
|
|
|
@ -606,7 +606,7 @@ void ata_scsi_error(struct Scsi_Host *host)
|
|||
ata_scsi_port_error_handler(host, ap);
|
||||
|
||||
/* finish or retry handled scmd's and clean up */
|
||||
WARN_ON(host->host_failed || !list_empty(&eh_work_q));
|
||||
WARN_ON(!list_empty(&eh_work_q));
|
||||
|
||||
DPRINTK("EXIT\n");
|
||||
}
|
||||
|
|
|
@ -24,10 +24,12 @@ static char *make_driver_name(struct device_driver *drv)
|
|||
|
||||
static void module_create_drivers_dir(struct module_kobject *mk)
|
||||
{
|
||||
if (!mk || mk->drivers_dir)
|
||||
return;
|
||||
static DEFINE_MUTEX(drivers_dir_mutex);
|
||||
|
||||
mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
|
||||
mutex_lock(&drivers_dir_mutex);
|
||||
if (mk && !mk->drivers_dir)
|
||||
mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
|
||||
mutex_unlock(&drivers_dir_mutex);
|
||||
}
|
||||
|
||||
void module_add_driver(struct module *mod, struct device_driver *drv)
|
||||
|
|
|
@ -3819,6 +3819,7 @@ static void handle_new_recv_msgs(ipmi_smi_t intf)
|
|||
while (!list_empty(&intf->waiting_rcv_msgs)) {
|
||||
smi_msg = list_entry(intf->waiting_rcv_msgs.next,
|
||||
struct ipmi_smi_msg, link);
|
||||
list_del(&smi_msg->link);
|
||||
if (!run_to_completion)
|
||||
spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
|
||||
flags);
|
||||
|
@ -3828,11 +3829,14 @@ static void handle_new_recv_msgs(ipmi_smi_t intf)
|
|||
if (rv > 0) {
|
||||
/*
|
||||
* To preserve message order, quit if we
|
||||
* can't handle a message.
|
||||
* can't handle a message. Add the message
|
||||
* back at the head, this is safe because this
|
||||
* tasklet is the only thing that pulls the
|
||||
* messages.
|
||||
*/
|
||||
list_add(&smi_msg->link, &intf->waiting_rcv_msgs);
|
||||
break;
|
||||
} else {
|
||||
list_del(&smi_msg->link);
|
||||
if (rv == 0)
|
||||
/* Message handled */
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
|
|
|
@ -2,6 +2,7 @@ $(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_rsapubkey-asn1.c \
|
|||
$(obj)/qat_rsapubkey-asn1.h
|
||||
$(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
|
||||
$(obj)/qat_rsaprivkey-asn1.h
|
||||
$(obj)/qat_asym_algs.o: $(obj)/qat_rsapubkey-asn1.h $(obj)/qat_rsaprivkey-asn1.h
|
||||
|
||||
clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
|
||||
clean-files += qat_rsaprivkey-asn1.c qat_rsapvivkey-asn1.h
|
||||
|
|
|
@ -218,8 +218,11 @@ static const u32 rir_offset[MAX_RIR_RANGES][MAX_RIR_WAY] = {
|
|||
{ 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc },
|
||||
};
|
||||
|
||||
#define RIR_RNK_TGT(reg) GET_BITFIELD(reg, 16, 19)
|
||||
#define RIR_OFFSET(reg) GET_BITFIELD(reg, 2, 14)
|
||||
#define RIR_RNK_TGT(type, reg) (((type) == BROADWELL) ? \
|
||||
GET_BITFIELD(reg, 20, 23) : GET_BITFIELD(reg, 16, 19))
|
||||
|
||||
#define RIR_OFFSET(type, reg) (((type) == HASWELL || (type) == BROADWELL) ? \
|
||||
GET_BITFIELD(reg, 2, 15) : GET_BITFIELD(reg, 2, 14))
|
||||
|
||||
/* Device 16, functions 2-7 */
|
||||
|
||||
|
@ -1175,14 +1178,14 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
|
|||
pci_read_config_dword(pvt->pci_tad[i],
|
||||
rir_offset[j][k],
|
||||
®);
|
||||
tmp_mb = RIR_OFFSET(reg) << 6;
|
||||
tmp_mb = RIR_OFFSET(pvt->info.type, reg) << 6;
|
||||
|
||||
gb = div_u64_rem(tmp_mb, 1024, &mb);
|
||||
edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
|
||||
i, j, k,
|
||||
gb, (mb*1000)/1024,
|
||||
((u64)tmp_mb) << 20L,
|
||||
(u32)RIR_RNK_TGT(reg),
|
||||
(u32)RIR_RNK_TGT(pvt->info.type, reg),
|
||||
reg);
|
||||
}
|
||||
}
|
||||
|
@ -1512,7 +1515,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
|
|||
pci_read_config_dword(pvt->pci_tad[ch_add + base_ch],
|
||||
rir_offset[n_rir][idx],
|
||||
®);
|
||||
*rank = RIR_RNK_TGT(reg);
|
||||
*rank = RIR_RNK_TGT(pvt->info.type, reg);
|
||||
|
||||
edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
|
||||
n_rir,
|
||||
|
|
|
@ -60,16 +60,25 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
|
|||
kernel_memsize = kernel_size + (_end - _edata);
|
||||
|
||||
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) {
|
||||
/*
|
||||
* If CONFIG_DEBUG_ALIGN_RODATA is not set, produce a
|
||||
* displacement in the interval [0, MIN_KIMG_ALIGN) that
|
||||
* is a multiple of the minimal segment alignment (SZ_64K)
|
||||
*/
|
||||
u32 mask = (MIN_KIMG_ALIGN - 1) & ~(SZ_64K - 1);
|
||||
u32 offset = !IS_ENABLED(CONFIG_DEBUG_ALIGN_RODATA) ?
|
||||
(phys_seed >> 32) & mask : TEXT_OFFSET;
|
||||
|
||||
/*
|
||||
* If KASLR is enabled, and we have some randomness available,
|
||||
* locate the kernel at a randomized offset in physical memory.
|
||||
*/
|
||||
*reserve_size = kernel_memsize + TEXT_OFFSET;
|
||||
*reserve_size = kernel_memsize + offset;
|
||||
status = efi_random_alloc(sys_table_arg, *reserve_size,
|
||||
MIN_KIMG_ALIGN, reserve_addr,
|
||||
phys_seed);
|
||||
(u32)phys_seed);
|
||||
|
||||
*image_addr = *reserve_addr + TEXT_OFFSET;
|
||||
*image_addr = *reserve_addr + offset;
|
||||
} else {
|
||||
/*
|
||||
* Else, try a straight allocation at the preferred offset.
|
||||
|
|
|
@ -28,6 +28,10 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
|
|||
if (!desc && gpio_is_valid(gpio))
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
err = gpiod_request(desc, label);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (flags & GPIOF_OPEN_DRAIN)
|
||||
set_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
||||
|
||||
|
@ -37,10 +41,6 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
|
|||
if (flags & GPIOF_ACTIVE_LOW)
|
||||
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
||||
|
||||
err = gpiod_request(desc, label);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (flags & GPIOF_DIR_IN)
|
||||
err = gpiod_direction_input(desc);
|
||||
else
|
||||
|
|
|
@ -927,14 +927,6 @@ static int __gpiod_request(struct gpio_desc *desc, const char *label)
|
|||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
}
|
||||
done:
|
||||
if (status < 0) {
|
||||
/* Clear flags that might have been set by the caller before
|
||||
* requesting the GPIO.
|
||||
*/
|
||||
clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
||||
clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
||||
clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||
return status;
|
||||
}
|
||||
|
@ -2062,28 +2054,13 @@ struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(gpiod_get_optional);
|
||||
|
||||
/**
|
||||
* gpiod_parse_flags - helper function to parse GPIO lookup flags
|
||||
* @desc: gpio to be setup
|
||||
* @lflags: gpio_lookup_flags - returned from of_find_gpio() or
|
||||
* of_get_gpio_hog()
|
||||
*
|
||||
* Set the GPIO descriptor flags based on the given GPIO lookup flags.
|
||||
*/
|
||||
static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
|
||||
{
|
||||
if (lflags & GPIO_ACTIVE_LOW)
|
||||
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
||||
if (lflags & GPIO_OPEN_DRAIN)
|
||||
set_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
||||
if (lflags & GPIO_OPEN_SOURCE)
|
||||
set_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* gpiod_configure_flags - helper function to configure a given GPIO
|
||||
* @desc: gpio whose value will be assigned
|
||||
* @con_id: function within the GPIO consumer
|
||||
* @lflags: gpio_lookup_flags - returned from of_find_gpio() or
|
||||
* of_get_gpio_hog()
|
||||
* @dflags: gpiod_flags - optional GPIO initialization flags
|
||||
*
|
||||
* Return 0 on success, -ENOENT if no GPIO has been assigned to the
|
||||
|
@ -2091,10 +2068,17 @@ static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
|
|||
* occurred while trying to acquire the GPIO.
|
||||
*/
|
||||
static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
|
||||
enum gpiod_flags dflags)
|
||||
unsigned long lflags, enum gpiod_flags dflags)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (lflags & GPIO_ACTIVE_LOW)
|
||||
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
||||
if (lflags & GPIO_OPEN_DRAIN)
|
||||
set_bit(FLAG_OPEN_DRAIN, &desc->flags);
|
||||
if (lflags & GPIO_OPEN_SOURCE)
|
||||
set_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
||||
|
||||
/* No particular flag request, return here... */
|
||||
if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
|
||||
pr_debug("no flags found for %s\n", con_id);
|
||||
|
@ -2161,13 +2145,11 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
|
|||
return desc;
|
||||
}
|
||||
|
||||
gpiod_parse_flags(desc, lookupflags);
|
||||
|
||||
status = gpiod_request(desc, con_id);
|
||||
if (status < 0)
|
||||
return ERR_PTR(status);
|
||||
|
||||
status = gpiod_configure_flags(desc, con_id, flags);
|
||||
status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
|
||||
if (status < 0) {
|
||||
dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
|
||||
gpiod_put(desc);
|
||||
|
@ -2223,6 +2205,10 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
|
|||
if (IS_ERR(desc))
|
||||
return desc;
|
||||
|
||||
ret = gpiod_request(desc, NULL);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (active_low)
|
||||
set_bit(FLAG_ACTIVE_LOW, &desc->flags);
|
||||
|
||||
|
@ -2233,10 +2219,6 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
|
|||
set_bit(FLAG_OPEN_SOURCE, &desc->flags);
|
||||
}
|
||||
|
||||
ret = gpiod_request(desc, NULL);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return desc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
|
||||
|
@ -2289,8 +2271,6 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
|
|||
chip = gpiod_to_chip(desc);
|
||||
hwnum = gpio_chip_hwgpio(desc);
|
||||
|
||||
gpiod_parse_flags(desc, lflags);
|
||||
|
||||
local_desc = gpiochip_request_own_desc(chip, hwnum, name);
|
||||
if (IS_ERR(local_desc)) {
|
||||
pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
|
||||
|
@ -2298,7 +2278,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
|
|||
return PTR_ERR(local_desc);
|
||||
}
|
||||
|
||||
status = gpiod_configure_flags(desc, name, dflags);
|
||||
status = gpiod_configure_flags(desc, name, lflags, dflags);
|
||||
if (status < 0) {
|
||||
pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
|
||||
name, chip->label, hwnum);
|
||||
|
|
|
@ -5463,7 +5463,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev,
|
|||
case 2:
|
||||
for (i = 0; i < adev->gfx.num_compute_rings; i++) {
|
||||
ring = &adev->gfx.compute_ring[i];
|
||||
if ((ring->me == me_id) & (ring->pipe == pipe_id))
|
||||
if ((ring->me == me_id) && (ring->pipe == pipe_id))
|
||||
amdgpu_fence_process(ring);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -242,13 +242,19 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
|
|||
pqm_uninit(&p->pqm);
|
||||
|
||||
/* Iterate over all process device data structure and check
|
||||
* if we should reset all wavefronts */
|
||||
list_for_each_entry(pdd, &p->per_device_data, per_device_list)
|
||||
* if we should delete debug managers and reset all wavefronts
|
||||
*/
|
||||
list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
|
||||
if ((pdd->dev->dbgmgr) &&
|
||||
(pdd->dev->dbgmgr->pasid == p->pasid))
|
||||
kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
|
||||
|
||||
if (pdd->reset_wavefronts) {
|
||||
pr_warn("amdkfd: Resetting all wave fronts\n");
|
||||
dbgdev_wave_reset_wavefronts(pdd->dev, p);
|
||||
pdd->reset_wavefronts = false;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
|
@ -404,42 +410,52 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
|
|||
|
||||
idx = srcu_read_lock(&kfd_processes_srcu);
|
||||
|
||||
/*
|
||||
* Look for the process that matches the pasid. If there is no such
|
||||
* process, we either released it in amdkfd's own notifier, or there
|
||||
* is a bug. Unfortunately, there is no way to tell...
|
||||
*/
|
||||
hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes)
|
||||
if (p->pasid == pasid)
|
||||
break;
|
||||
if (p->pasid == pasid) {
|
||||
|
||||
srcu_read_unlock(&kfd_processes_srcu, idx);
|
||||
|
||||
pr_debug("Unbinding process %d from IOMMU\n", pasid);
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
|
||||
if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
|
||||
kfd_dbgmgr_destroy(dev->dbgmgr);
|
||||
|
||||
pqm_uninit(&p->pqm);
|
||||
|
||||
pdd = kfd_get_process_device_data(dev, p);
|
||||
|
||||
if (!pdd) {
|
||||
mutex_unlock(&p->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pdd->reset_wavefronts) {
|
||||
dbgdev_wave_reset_wavefronts(pdd->dev, p);
|
||||
pdd->reset_wavefronts = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Just mark pdd as unbound, because we still need it
|
||||
* to call amd_iommu_unbind_pasid() in when the
|
||||
* process exits.
|
||||
* We don't call amd_iommu_unbind_pasid() here
|
||||
* because the IOMMU called us.
|
||||
*/
|
||||
pdd->bound = false;
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
srcu_read_unlock(&kfd_processes_srcu, idx);
|
||||
|
||||
BUG_ON(p->pasid != pasid);
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
|
||||
if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
|
||||
kfd_dbgmgr_destroy(dev->dbgmgr);
|
||||
|
||||
pqm_uninit(&p->pqm);
|
||||
|
||||
pdd = kfd_get_process_device_data(dev, p);
|
||||
|
||||
if (!pdd) {
|
||||
mutex_unlock(&p->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pdd->reset_wavefronts) {
|
||||
dbgdev_wave_reset_wavefronts(pdd->dev, p);
|
||||
pdd->reset_wavefronts = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Just mark pdd as unbound, because we still need it to call
|
||||
* amd_iommu_unbind_pasid() in when the process exits.
|
||||
* We don't call amd_iommu_unbind_pasid() here
|
||||
* because the IOMMU called us.
|
||||
*/
|
||||
pdd->bound = false;
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
}
|
||||
|
||||
struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
|
||||
|
|
|
@ -335,6 +335,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
|
|||
|
||||
atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
|
||||
factor_reg);
|
||||
} else {
|
||||
atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -367,6 +367,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
|
|||
drm_property_unreference_blob(state->mode_blob);
|
||||
state->mode_blob = NULL;
|
||||
|
||||
memset(&state->mode, 0, sizeof(state->mode));
|
||||
|
||||
if (blob) {
|
||||
if (blob->length != sizeof(struct drm_mode_modeinfo) ||
|
||||
drm_mode_convert_umode(&state->mode,
|
||||
|
@ -379,7 +381,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
|
|||
DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
|
||||
state->mode.name, state);
|
||||
} else {
|
||||
memset(&state->mode, 0, sizeof(state->mode));
|
||||
state->enable = false;
|
||||
DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
|
||||
state);
|
||||
|
|
|
@ -2682,8 +2682,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
|
|||
goto out;
|
||||
}
|
||||
|
||||
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
|
||||
|
||||
/*
|
||||
* Check whether the primary plane supports the fb pixel format.
|
||||
* Drivers not implementing the universal planes API use a
|
||||
|
|
|
@ -2874,11 +2874,9 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
|
|||
drm_dp_port_teardown_pdt(port, port->pdt);
|
||||
|
||||
if (!port->input && port->vcpi.vcpi > 0) {
|
||||
if (mgr->mst_state) {
|
||||
drm_dp_mst_reset_vcpi_slots(mgr, port);
|
||||
drm_dp_update_payload_part1(mgr);
|
||||
drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
|
||||
}
|
||||
drm_dp_mst_reset_vcpi_slots(mgr, port);
|
||||
drm_dp_update_payload_part1(mgr);
|
||||
drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
|
||||
}
|
||||
|
||||
kref_put(&port->kref, drm_dp_free_mst_port);
|
||||
|
|
|
@ -1487,6 +1487,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
|
|||
if (out->status != MODE_OK)
|
||||
goto out;
|
||||
|
||||
drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
|
|
|
@ -39,7 +39,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
|
|||
if (!mutex_is_locked(mutex))
|
||||
return false;
|
||||
|
||||
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
|
||||
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
|
||||
return mutex->owner == task;
|
||||
#else
|
||||
/* Since UP may be pre-empted, we cannot assume that we own the lock */
|
||||
|
|
|
@ -7357,6 +7357,8 @@ enum skl_disp_power_wells {
|
|||
#define TRANS_CLK_SEL_DISABLED (0x0<<29)
|
||||
#define TRANS_CLK_SEL_PORT(x) (((x)+1)<<29)
|
||||
|
||||
#define CDCLK_FREQ 0x46200
|
||||
|
||||
#define TRANSA_MSA_MISC 0x60410
|
||||
#define TRANSB_MSA_MISC 0x61410
|
||||
#define TRANSC_MSA_MISC 0x62410
|
||||
|
|
|
@ -8228,12 +8228,14 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_encoder *encoder;
|
||||
int i;
|
||||
u32 val, final;
|
||||
bool has_lvds = false;
|
||||
bool has_cpu_edp = false;
|
||||
bool has_panel = false;
|
||||
bool has_ck505 = false;
|
||||
bool can_ssc = false;
|
||||
bool using_ssc_source = false;
|
||||
|
||||
/* We need to take the global config into account */
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
|
@ -8260,8 +8262,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
can_ssc = true;
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
|
||||
has_panel, has_lvds, has_ck505);
|
||||
/* Check if any DPLLs are using the SSC source */
|
||||
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
|
||||
u32 temp = I915_READ(PCH_DPLL(i));
|
||||
|
||||
if (!(temp & DPLL_VCO_ENABLE))
|
||||
continue;
|
||||
|
||||
if ((temp & PLL_REF_INPUT_MASK) ==
|
||||
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
|
||||
using_ssc_source = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
|
||||
has_panel, has_lvds, has_ck505, using_ssc_source);
|
||||
|
||||
/* Ironlake: try to setup display ref clock before DPLL
|
||||
* enabling. This is only under driver's control after
|
||||
|
@ -8298,9 +8314,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
|
||||
} else
|
||||
final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
|
||||
} else {
|
||||
final |= DREF_SSC_SOURCE_DISABLE;
|
||||
final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
|
||||
} else if (using_ssc_source) {
|
||||
final |= DREF_SSC_SOURCE_ENABLE;
|
||||
final |= DREF_SSC1_ENABLE;
|
||||
}
|
||||
|
||||
if (final == val)
|
||||
|
@ -8346,7 +8362,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
} else {
|
||||
DRM_DEBUG_KMS("Disabling SSC entirely\n");
|
||||
DRM_DEBUG_KMS("Disabling CPU source output\n");
|
||||
|
||||
val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
|
||||
|
||||
|
@ -8357,16 +8373,20 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
|
||||
/* Turn off the SSC source */
|
||||
val &= ~DREF_SSC_SOURCE_MASK;
|
||||
val |= DREF_SSC_SOURCE_DISABLE;
|
||||
if (!using_ssc_source) {
|
||||
DRM_DEBUG_KMS("Disabling SSC source\n");
|
||||
|
||||
/* Turn off SSC1 */
|
||||
val &= ~DREF_SSC1_ENABLE;
|
||||
/* Turn off the SSC source */
|
||||
val &= ~DREF_SSC_SOURCE_MASK;
|
||||
val |= DREF_SSC_SOURCE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DREF_CONTROL, val);
|
||||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
/* Turn off SSC1 */
|
||||
val &= ~DREF_SSC1_ENABLE;
|
||||
|
||||
I915_WRITE(PCH_DREF_CONTROL, val);
|
||||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(val != final);
|
||||
|
@ -9669,6 +9689,8 @@ static void broadwell_set_cdclk(struct drm_device *dev, int cdclk)
|
|||
sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
|
||||
mutex_unlock(&dev_priv->rps.hw_lock);
|
||||
|
||||
I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
|
||||
|
||||
intel_update_cdclk(dev);
|
||||
|
||||
WARN(cdclk != dev_priv->cdclk_freq,
|
||||
|
|
|
@ -3628,8 +3628,7 @@ static bool
|
|||
intel_dp_reset_link_train(struct intel_dp *intel_dp, uint32_t *DP,
|
||||
uint8_t dp_train_pat)
|
||||
{
|
||||
if (!intel_dp->train_set_valid)
|
||||
memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
|
||||
memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
|
||||
intel_dp_set_signal_levels(intel_dp, DP);
|
||||
return intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
|
||||
}
|
||||
|
@ -3746,22 +3745,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we used previously trained voltage and pre-emphasis values
|
||||
* and we don't get clock recovery, reset link training values
|
||||
*/
|
||||
if (intel_dp->train_set_valid) {
|
||||
DRM_DEBUG_KMS("clock recovery not ok, reset");
|
||||
/* clear the flag as we are not reusing train set */
|
||||
intel_dp->train_set_valid = false;
|
||||
if (!intel_dp_reset_link_train(intel_dp, &DP,
|
||||
DP_TRAINING_PATTERN_1 |
|
||||
DP_LINK_SCRAMBLING_DISABLE)) {
|
||||
DRM_ERROR("failed to enable link training\n");
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check to see if we've tried the max voltage */
|
||||
for (i = 0; i < intel_dp->lane_count; i++)
|
||||
|
@ -3854,7 +3837,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
|
|||
/* Make sure clock is still ok */
|
||||
if (!drm_dp_clock_recovery_ok(link_status,
|
||||
intel_dp->lane_count)) {
|
||||
intel_dp->train_set_valid = false;
|
||||
intel_dp_link_training_clock_recovery(intel_dp);
|
||||
intel_dp_set_link_train(intel_dp, &DP,
|
||||
training_pattern |
|
||||
|
@ -3871,7 +3853,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
|
|||
|
||||
/* Try 5 times, then try clock recovery if that fails */
|
||||
if (tries > 5) {
|
||||
intel_dp->train_set_valid = false;
|
||||
intel_dp_link_training_clock_recovery(intel_dp);
|
||||
intel_dp_set_link_train(intel_dp, &DP,
|
||||
training_pattern |
|
||||
|
@ -3893,10 +3874,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
|
|||
|
||||
intel_dp->DP = DP;
|
||||
|
||||
if (channel_eq) {
|
||||
intel_dp->train_set_valid = true;
|
||||
if (channel_eq)
|
||||
DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
|
||||
}
|
||||
}
|
||||
|
||||
void intel_dp_stop_link_train(struct intel_dp *intel_dp)
|
||||
|
@ -5079,13 +5058,15 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
|
|||
|
||||
void intel_dp_encoder_reset(struct drm_encoder *encoder)
|
||||
{
|
||||
struct intel_dp *intel_dp;
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
if (!HAS_DDI(dev_priv))
|
||||
intel_dp->DP = I915_READ(intel_dp->output_reg);
|
||||
|
||||
if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
|
||||
return;
|
||||
|
||||
intel_dp = enc_to_intel_dp(encoder);
|
||||
|
||||
pps_lock(intel_dp);
|
||||
|
||||
/*
|
||||
|
@ -5157,9 +5138,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
|
|||
intel_display_power_get(dev_priv, power_domain);
|
||||
|
||||
if (long_hpd) {
|
||||
/* indicate that we need to restart link training */
|
||||
intel_dp->train_set_valid = false;
|
||||
|
||||
if (!intel_digital_port_connected(dev_priv, intel_dig_port))
|
||||
goto mst_fail;
|
||||
|
||||
|
|
|
@ -783,7 +783,6 @@ struct intel_dp {
|
|||
bool has_aux_irq,
|
||||
int send_bytes,
|
||||
uint32_t aux_clock_divider);
|
||||
bool train_set_valid;
|
||||
|
||||
/* Displayport compliance testing */
|
||||
unsigned long compliance_test_type;
|
||||
|
|
|
@ -194,7 +194,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
|
|||
}
|
||||
}
|
||||
|
||||
fvv = pllreffreq * testn / testm;
|
||||
fvv = pllreffreq * (n + 1) / (m + 1);
|
||||
fvv = (fvv - 800000) / 50000;
|
||||
|
||||
if (fvv > 15)
|
||||
|
@ -214,6 +214,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
|
|||
WREG_DAC(MGA1064_PIX_PLLC_M, m);
|
||||
WREG_DAC(MGA1064_PIX_PLLC_N, n);
|
||||
WREG_DAC(MGA1064_PIX_PLLC_P, p);
|
||||
|
||||
if (mdev->unique_rev_id >= 0x04) {
|
||||
WREG_DAC(0x1a, 0x09);
|
||||
msleep(20);
|
||||
WREG_DAC(0x1a, 0x01);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -557,6 +557,8 @@ nouveau_fbcon_init(struct drm_device *dev)
|
|||
if (ret)
|
||||
goto fini;
|
||||
|
||||
if (fbcon->helper.fbdev)
|
||||
fbcon->helper.fbdev->pixmap.buf_align = 4;
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
|
|
|
@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
uint32_t fg;
|
||||
uint32_t bg;
|
||||
uint32_t dsize;
|
||||
uint32_t width;
|
||||
uint32_t *data = (uint32_t *)image->data;
|
||||
int ret;
|
||||
|
||||
|
@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
width = ALIGN(image->width, 8);
|
||||
dsize = ALIGN(width * image->height, 32) >> 5;
|
||||
|
||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
|
||||
|
@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
((image->dx + image->width) & 0xffff));
|
||||
OUT_RING(chan, bg);
|
||||
OUT_RING(chan, fg);
|
||||
OUT_RING(chan, (image->height << 16) | width);
|
||||
OUT_RING(chan, (image->height << 16) | image->width);
|
||||
OUT_RING(chan, (image->height << 16) | image->width);
|
||||
OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
|
||||
|
||||
dsize = ALIGN(image->width * image->height, 32) >> 5;
|
||||
while (dsize) {
|
||||
int iter_len = dsize > 128 ? 128 : dsize;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
struct nouveau_fbdev *nfbdev = info->par;
|
||||
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
|
||||
struct nouveau_channel *chan = drm->channel;
|
||||
uint32_t width, dwords, *data = (uint32_t *)image->data;
|
||||
uint32_t dwords, *data = (uint32_t *)image->data;
|
||||
uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
|
||||
uint32_t *palette = info->pseudo_palette;
|
||||
int ret;
|
||||
|
@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
width = ALIGN(image->width, 32);
|
||||
dwords = (width * image->height) >> 5;
|
||||
|
||||
BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
|
||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
|
@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
OUT_RING(chan, 0);
|
||||
OUT_RING(chan, image->dy);
|
||||
|
||||
dwords = ALIGN(image->width * image->height, 32) >> 5;
|
||||
while (dwords) {
|
||||
int push = dwords > 2047 ? 2047 : dwords;
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
struct nouveau_fbdev *nfbdev = info->par;
|
||||
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
|
||||
struct nouveau_channel *chan = drm->channel;
|
||||
uint32_t width, dwords, *data = (uint32_t *)image->data;
|
||||
uint32_t dwords, *data = (uint32_t *)image->data;
|
||||
uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
|
||||
uint32_t *palette = info->pseudo_palette;
|
||||
int ret;
|
||||
|
@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
width = ALIGN(image->width, 32);
|
||||
dwords = (width * image->height) >> 5;
|
||||
|
||||
BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
|
||||
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
|
||||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
|
||||
|
@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
|
|||
OUT_RING (chan, 0);
|
||||
OUT_RING (chan, image->dy);
|
||||
|
||||
dwords = ALIGN(image->width * image->height, 32) >> 5;
|
||||
while (dwords) {
|
||||
int push = dwords > 2047 ? 2047 : dwords;
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ static int
|
|||
gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
|
||||
{
|
||||
struct nvkm_device *device = outp->base.disp->engine.subdev.device;
|
||||
const u32 loff = gf119_sor_loff(outp);
|
||||
nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
|
||||
const u32 soff = gf119_sor_soff(outp);
|
||||
nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -874,22 +874,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc)
|
|||
}
|
||||
|
||||
static const struct nvkm_enum gf100_mp_warp_error[] = {
|
||||
{ 0x00, "NO_ERROR" },
|
||||
{ 0x01, "STACK_MISMATCH" },
|
||||
{ 0x01, "STACK_ERROR" },
|
||||
{ 0x02, "API_STACK_ERROR" },
|
||||
{ 0x03, "RET_EMPTY_STACK_ERROR" },
|
||||
{ 0x04, "PC_WRAP" },
|
||||
{ 0x05, "MISALIGNED_PC" },
|
||||
{ 0x08, "MISALIGNED_GPR" },
|
||||
{ 0x09, "INVALID_OPCODE" },
|
||||
{ 0x0d, "GPR_OUT_OF_BOUNDS" },
|
||||
{ 0x0e, "MEM_OUT_OF_BOUNDS" },
|
||||
{ 0x0f, "UNALIGNED_MEM_ACCESS" },
|
||||
{ 0x06, "PC_OVERFLOW" },
|
||||
{ 0x07, "MISALIGNED_IMMC_ADDR" },
|
||||
{ 0x08, "MISALIGNED_REG" },
|
||||
{ 0x09, "ILLEGAL_INSTR_ENCODING" },
|
||||
{ 0x0a, "ILLEGAL_SPH_INSTR_COMBO" },
|
||||
{ 0x0b, "ILLEGAL_INSTR_PARAM" },
|
||||
{ 0x0c, "INVALID_CONST_ADDR" },
|
||||
{ 0x0d, "OOR_REG" },
|
||||
{ 0x0e, "OOR_ADDR" },
|
||||
{ 0x0f, "MISALIGNED_ADDR" },
|
||||
{ 0x10, "INVALID_ADDR_SPACE" },
|
||||
{ 0x11, "INVALID_PARAM" },
|
||||
{ 0x11, "ILLEGAL_INSTR_PARAM2" },
|
||||
{ 0x12, "INVALID_CONST_ADDR_LDC" },
|
||||
{ 0x13, "GEOMETRY_SM_ERROR" },
|
||||
{ 0x14, "DIVERGENT" },
|
||||
{ 0x15, "WARP_EXIT" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_bitfield gf100_mp_global_error[] = {
|
||||
{ 0x00000001, "SM_TO_SM_FAULT" },
|
||||
{ 0x00000002, "L1_ERROR" },
|
||||
{ 0x00000004, "MULTIPLE_WARP_ERRORS" },
|
||||
{ 0x00000008, "OUT_OF_STACK_SPACE" },
|
||||
{ 0x00000008, "PHYSICAL_STACK_OVERFLOW" },
|
||||
{ 0x00000010, "BPT_INT" },
|
||||
{ 0x00000020, "BPT_PAUSE" },
|
||||
{ 0x00000040, "SINGLE_STEP_COMPLETE" },
|
||||
{ 0x20000000, "ECC_SEC_ERROR" },
|
||||
{ 0x40000000, "ECC_DED_ERROR" },
|
||||
{ 0x80000000, "TIMEOUT" },
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
|
|||
/*
|
||||
* GPU helpers function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* radeon_device_is_virtual - check if we are running is a virtual environment
|
||||
*
|
||||
* Check if the asic has been passed through to a VM (all asics).
|
||||
* Used at driver startup.
|
||||
* Returns true if virtual or false if not.
|
||||
*/
|
||||
static bool radeon_device_is_virtual(void)
|
||||
{
|
||||
#ifdef CONFIG_X86
|
||||
return boot_cpu_has(X86_FEATURE_HYPERVISOR);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_card_posted - check if the hw has already been initialized
|
||||
*
|
||||
|
@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_device *rdev)
|
|||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* for pass through, always force asic_init */
|
||||
if (radeon_device_is_virtual())
|
||||
return false;
|
||||
|
||||
/* required for EFI mode on macbook2,1 which uses an r5xx asic */
|
||||
if (efi_enabled(EFI_BOOT) &&
|
||||
(rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
|
||||
|
|
|
@ -1004,9 +1004,9 @@ out_unlock:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
||||
struct ttm_mem_reg *mem,
|
||||
uint32_t *new_flags)
|
||||
bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
||||
struct ttm_mem_reg *mem,
|
||||
uint32_t *new_flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1038,6 +1038,7 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement,
|
|||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_mem_compat);
|
||||
|
||||
int ttm_bo_validate(struct ttm_buffer_object *bo,
|
||||
struct ttm_placement *placement,
|
||||
|
|
|
@ -49,6 +49,7 @@ int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
|
|||
{
|
||||
struct ttm_buffer_object *bo = &buf->base;
|
||||
int ret;
|
||||
uint32_t new_flags;
|
||||
|
||||
ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
|
||||
if (unlikely(ret != 0))
|
||||
|
@ -60,7 +61,12 @@ int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
|
|||
if (unlikely(ret != 0))
|
||||
goto err;
|
||||
|
||||
ret = ttm_bo_validate(bo, placement, interruptible, false);
|
||||
if (buf->pin_count > 0)
|
||||
ret = ttm_bo_mem_compat(placement, &bo->mem,
|
||||
&new_flags) == true ? 0 : -EINVAL;
|
||||
else
|
||||
ret = ttm_bo_validate(bo, placement, interruptible, false);
|
||||
|
||||
if (!ret)
|
||||
vmw_bo_pin_reserved(buf, true);
|
||||
|
||||
|
@ -91,6 +97,7 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
|
|||
{
|
||||
struct ttm_buffer_object *bo = &buf->base;
|
||||
int ret;
|
||||
uint32_t new_flags;
|
||||
|
||||
ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
|
||||
if (unlikely(ret != 0))
|
||||
|
@ -102,6 +109,12 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
|
|||
if (unlikely(ret != 0))
|
||||
goto err;
|
||||
|
||||
if (buf->pin_count > 0) {
|
||||
ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem,
|
||||
&new_flags) == true ? 0 : -EINVAL;
|
||||
goto out_unreserve;
|
||||
}
|
||||
|
||||
ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
|
||||
false);
|
||||
if (likely(ret == 0) || ret == -ERESTARTSYS)
|
||||
|
@ -161,6 +174,7 @@ int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
|
|||
struct ttm_placement placement;
|
||||
struct ttm_place place;
|
||||
int ret = 0;
|
||||
uint32_t new_flags;
|
||||
|
||||
place = vmw_vram_placement.placement[0];
|
||||
place.lpfn = bo->num_pages;
|
||||
|
@ -185,10 +199,15 @@ int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
|
|||
*/
|
||||
if (bo->mem.mem_type == TTM_PL_VRAM &&
|
||||
bo->mem.start < bo->num_pages &&
|
||||
bo->mem.start > 0)
|
||||
bo->mem.start > 0 &&
|
||||
buf->pin_count == 0)
|
||||
(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
|
||||
|
||||
ret = ttm_bo_validate(bo, &placement, interruptible, false);
|
||||
if (buf->pin_count > 0)
|
||||
ret = ttm_bo_mem_compat(&placement, &bo->mem,
|
||||
&new_flags) == true ? 0 : -EINVAL;
|
||||
else
|
||||
ret = ttm_bo_validate(bo, &placement, interruptible, false);
|
||||
|
||||
/* For some reason we didn't end up at the start of vram */
|
||||
WARN_ON(ret == 0 && bo->offset != 0);
|
||||
|
|
|
@ -227,6 +227,7 @@ static int vmw_force_iommu;
|
|||
static int vmw_restrict_iommu;
|
||||
static int vmw_force_coherent;
|
||||
static int vmw_restrict_dma_mask;
|
||||
static int vmw_assume_16bpp;
|
||||
|
||||
static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
|
||||
static void vmw_master_init(struct vmw_master *);
|
||||
|
@ -243,6 +244,8 @@ MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
|
|||
module_param_named(force_coherent, vmw_force_coherent, int, 0600);
|
||||
MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
|
||||
module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
|
||||
MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
|
||||
module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);
|
||||
|
||||
|
||||
static void vmw_print_capabilities(uint32_t capabilities)
|
||||
|
@ -652,6 +655,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
|||
dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
|
||||
dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
|
||||
|
||||
dev_priv->assume_16bpp = !!vmw_assume_16bpp;
|
||||
|
||||
dev_priv->enable_fb = enable_fbdev;
|
||||
|
||||
vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
|
||||
|
@ -698,6 +703,13 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
|||
vmw_read(dev_priv,
|
||||
SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
|
||||
|
||||
/*
|
||||
* Workaround for low memory 2D VMs to compensate for the
|
||||
* allocation taken by fbdev
|
||||
*/
|
||||
if (!(dev_priv->capabilities & SVGA_CAP_3D))
|
||||
mem_size *= 2;
|
||||
|
||||
dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
|
||||
dev_priv->prim_bb_mem =
|
||||
vmw_read(dev_priv,
|
||||
|
|
|
@ -387,6 +387,7 @@ struct vmw_private {
|
|||
spinlock_t hw_lock;
|
||||
spinlock_t cap_lock;
|
||||
bool has_dx;
|
||||
bool assume_16bpp;
|
||||
|
||||
/*
|
||||
* VGA registers.
|
||||
|
|
|
@ -517,28 +517,6 @@ static int vmw_fb_kms_framebuffer(struct fb_info *info)
|
|||
|
||||
par->set_fb = &vfb->base;
|
||||
|
||||
if (!par->bo_ptr) {
|
||||
/*
|
||||
* Pin before mapping. Since we don't know in what placement
|
||||
* to pin, call into KMS to do it for us.
|
||||
*/
|
||||
ret = vfb->pin(vfb);
|
||||
if (ret) {
|
||||
DRM_ERROR("Could not pin the fbdev framebuffer.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
|
||||
par->vmw_bo->base.num_pages, &par->map);
|
||||
if (ret) {
|
||||
vfb->unpin(vfb);
|
||||
DRM_ERROR("Could not map the fbdev framebuffer.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -601,6 +579,31 @@ static int vmw_fb_set_par(struct fb_info *info)
|
|||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
if (!par->bo_ptr) {
|
||||
struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb);
|
||||
|
||||
/*
|
||||
* Pin before mapping. Since we don't know in what placement
|
||||
* to pin, call into KMS to do it for us.
|
||||
*/
|
||||
ret = vfb->pin(vfb);
|
||||
if (ret) {
|
||||
DRM_ERROR("Could not pin the fbdev framebuffer.\n");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
|
||||
par->vmw_bo->base.num_pages, &par->map);
|
||||
if (ret) {
|
||||
vfb->unpin(vfb);
|
||||
DRM_ERROR("Could not map the fbdev framebuffer.\n");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
|
||||
}
|
||||
|
||||
|
||||
vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
|
||||
par->set_fb->width, par->set_fb->height);
|
||||
|
||||
|
|
|
@ -1538,14 +1538,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
|
|||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
|
||||
};
|
||||
int i;
|
||||
u32 assumed_bpp = 2;
|
||||
u32 assumed_bpp = 4;
|
||||
|
||||
/*
|
||||
* If using screen objects, then assume 32-bpp because that's what the
|
||||
* SVGA device is assuming
|
||||
*/
|
||||
if (dev_priv->active_display_unit == vmw_du_screen_object)
|
||||
assumed_bpp = 4;
|
||||
if (dev_priv->assume_16bpp)
|
||||
assumed_bpp = 2;
|
||||
|
||||
if (dev_priv->active_display_unit == vmw_du_screen_target) {
|
||||
max_width = min(max_width, dev_priv->stdu_max_width);
|
||||
|
|
|
@ -261,7 +261,7 @@ static void elo_remove(struct hid_device *hdev)
|
|||
struct elo_priv *priv = hid_get_drvdata(hdev);
|
||||
|
||||
hid_hw_stop(hdev);
|
||||
flush_workqueue(wq);
|
||||
cancel_delayed_work_sync(&priv->work);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ MODULE_LICENSE("GPL");
|
|||
#define MT_QUIRK_ALWAYS_VALID (1 << 4)
|
||||
#define MT_QUIRK_VALID_IS_INRANGE (1 << 5)
|
||||
#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6)
|
||||
#define MT_QUIRK_CONFIDENCE (1 << 7)
|
||||
#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8)
|
||||
#define MT_QUIRK_NO_AREA (1 << 9)
|
||||
#define MT_QUIRK_IGNORE_DUPLICATES (1 << 10)
|
||||
|
@ -78,6 +79,7 @@ struct mt_slot {
|
|||
__s32 contactid; /* the device ContactID assigned to this slot */
|
||||
bool touch_state; /* is the touch valid? */
|
||||
bool inrange_state; /* is the finger in proximity of the sensor? */
|
||||
bool confidence_state; /* is the touch made by a finger? */
|
||||
};
|
||||
|
||||
struct mt_class {
|
||||
|
@ -502,6 +504,9 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
|||
mt_store_field(usage, td, hi);
|
||||
return 1;
|
||||
case HID_DG_CONFIDENCE:
|
||||
if (cls->name == MT_CLS_WIN_8 &&
|
||||
field->application == HID_DG_TOUCHPAD)
|
||||
cls->quirks |= MT_QUIRK_CONFIDENCE;
|
||||
mt_store_field(usage, td, hi);
|
||||
return 1;
|
||||
case HID_DG_TIPSWITCH:
|
||||
|
@ -614,6 +619,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
|
|||
return;
|
||||
|
||||
if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
|
||||
int active;
|
||||
int slotnum = mt_compute_slot(td, input);
|
||||
struct mt_slot *s = &td->curdata;
|
||||
struct input_mt *mt = input->mt;
|
||||
|
@ -628,10 +634,14 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE))
|
||||
s->confidence_state = 1;
|
||||
active = (s->touch_state || s->inrange_state) &&
|
||||
s->confidence_state;
|
||||
|
||||
input_mt_slot(input, slotnum);
|
||||
input_mt_report_slot_state(input, MT_TOOL_FINGER,
|
||||
s->touch_state || s->inrange_state);
|
||||
if (s->touch_state || s->inrange_state) {
|
||||
input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
|
||||
if (active) {
|
||||
/* this finger is in proximity of the sensor */
|
||||
int wide = (s->w > s->h);
|
||||
/* divided by two to match visual scale of touch */
|
||||
|
@ -696,6 +706,8 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
|
|||
td->curdata.touch_state = value;
|
||||
break;
|
||||
case HID_DG_CONFIDENCE:
|
||||
if (quirks & MT_QUIRK_CONFIDENCE)
|
||||
td->curdata.confidence_state = value;
|
||||
if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
|
||||
td->curvalid = value;
|
||||
break;
|
||||
|
|
|
@ -516,13 +516,13 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
|
|||
goto inval;
|
||||
} else if (uref->usage_index >= field->report_count)
|
||||
goto inval;
|
||||
|
||||
else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
|
||||
(uref_multi->num_values > HID_MAX_MULTI_USAGES ||
|
||||
uref->usage_index + uref_multi->num_values > field->report_count))
|
||||
goto inval;
|
||||
}
|
||||
|
||||
if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
|
||||
(uref_multi->num_values > HID_MAX_MULTI_USAGES ||
|
||||
uref->usage_index + uref_multi->num_values > field->report_count))
|
||||
goto inval;
|
||||
|
||||
switch (cmd) {
|
||||
case HIDIOCGUSAGE:
|
||||
uref->value = field->value[uref->usage_index];
|
||||
|
|
|
@ -66,11 +66,13 @@
|
|||
|
||||
static DEFINE_MUTEX(i8k_mutex);
|
||||
static char bios_version[4];
|
||||
static char bios_machineid[16];
|
||||
static struct device *i8k_hwmon_dev;
|
||||
static u32 i8k_hwmon_flags;
|
||||
static uint i8k_fan_mult = I8K_FAN_MULT;
|
||||
static uint i8k_pwm_mult;
|
||||
static uint i8k_fan_max = I8K_FAN_HIGH;
|
||||
static bool disallow_fan_type_call;
|
||||
|
||||
#define I8K_HWMON_HAVE_TEMP1 (1 << 0)
|
||||
#define I8K_HWMON_HAVE_TEMP2 (1 << 1)
|
||||
|
@ -94,13 +96,13 @@ module_param(ignore_dmi, bool, 0);
|
|||
MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
|
||||
|
||||
#if IS_ENABLED(CONFIG_I8K)
|
||||
static bool restricted;
|
||||
static bool restricted = true;
|
||||
module_param(restricted, bool, 0);
|
||||
MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
|
||||
MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");
|
||||
|
||||
static bool power_status;
|
||||
module_param(power_status, bool, 0600);
|
||||
MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
|
||||
MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");
|
||||
#endif
|
||||
|
||||
static uint fan_mult;
|
||||
|
@ -235,14 +237,28 @@ static int i8k_get_fan_speed(int fan)
|
|||
/*
|
||||
* Read the fan type.
|
||||
*/
|
||||
static int i8k_get_fan_type(int fan)
|
||||
static int _i8k_get_fan_type(int fan)
|
||||
{
|
||||
struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
|
||||
|
||||
if (disallow_fan_type_call)
|
||||
return -EINVAL;
|
||||
|
||||
regs.ebx = fan & 0xff;
|
||||
return i8k_smm(®s) ? : regs.eax & 0xff;
|
||||
}
|
||||
|
||||
static int i8k_get_fan_type(int fan)
|
||||
{
|
||||
/* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */
|
||||
static int types[2] = { INT_MIN, INT_MIN };
|
||||
|
||||
if (types[fan] == INT_MIN)
|
||||
types[fan] = _i8k_get_fan_type(fan);
|
||||
|
||||
return types[fan];
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the fan nominal rpm for specific fan speed.
|
||||
*/
|
||||
|
@ -392,9 +408,11 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
|
|||
break;
|
||||
|
||||
case I8K_MACHINE_ID:
|
||||
memset(buff, 0, 16);
|
||||
strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
|
||||
sizeof(buff));
|
||||
if (restricted && !capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
memset(buff, 0, sizeof(buff));
|
||||
strlcpy(buff, bios_machineid, sizeof(buff));
|
||||
break;
|
||||
|
||||
case I8K_FN_STATUS:
|
||||
|
@ -511,7 +529,7 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
|
|||
seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
|
||||
I8K_PROC_FMT,
|
||||
bios_version,
|
||||
i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
|
||||
(restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : bios_machineid,
|
||||
cpu_temp,
|
||||
left_fan, right_fan, left_speed, right_speed,
|
||||
ac_power, fn_key);
|
||||
|
@ -718,6 +736,9 @@ static struct attribute *i8k_attrs[] = {
|
|||
static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
|
||||
int index)
|
||||
{
|
||||
if (disallow_fan_type_call &&
|
||||
(index == 9 || index == 12))
|
||||
return 0;
|
||||
if (index >= 0 && index <= 1 &&
|
||||
!(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
|
||||
return 0;
|
||||
|
@ -767,13 +788,17 @@ static int __init i8k_init_hwmon(void)
|
|||
if (err >= 0)
|
||||
i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
|
||||
|
||||
/* First fan attributes, if fan type is OK */
|
||||
err = i8k_get_fan_type(0);
|
||||
/* First fan attributes, if fan status or type is OK */
|
||||
err = i8k_get_fan_status(0);
|
||||
if (err < 0)
|
||||
err = i8k_get_fan_type(0);
|
||||
if (err >= 0)
|
||||
i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
|
||||
|
||||
/* Second fan attributes, if fan type is OK */
|
||||
err = i8k_get_fan_type(1);
|
||||
/* Second fan attributes, if fan status or type is OK */
|
||||
err = i8k_get_fan_status(1);
|
||||
if (err < 0)
|
||||
err = i8k_get_fan_type(1);
|
||||
if (err >= 0)
|
||||
i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
|
||||
|
||||
|
@ -929,12 +954,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
|
|||
|
||||
MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
|
||||
|
||||
static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
|
||||
/*
|
||||
* On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed
|
||||
* randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist
|
||||
* of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call.
|
||||
* See bug: https://bugzilla.kernel.org/show_bug.cgi?id=100121
|
||||
*/
|
||||
static struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initdata = {
|
||||
{
|
||||
/*
|
||||
* CPU fan speed going up and down on Dell Studio XPS 8000
|
||||
* for unknown reasons.
|
||||
*/
|
||||
.ident = "Dell Studio XPS 8000",
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
|
@ -942,16 +969,19 @@ static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
|
|||
},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* CPU fan speed going up and down on Dell Studio XPS 8100
|
||||
* for unknown reasons.
|
||||
*/
|
||||
.ident = "Dell Studio XPS 8100",
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Dell Inspiron 580",
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -966,8 +996,7 @@ static int __init i8k_probe(void)
|
|||
/*
|
||||
* Get DMI information
|
||||
*/
|
||||
if (!dmi_check_system(i8k_dmi_table) ||
|
||||
dmi_check_system(i8k_blacklist_dmi_table)) {
|
||||
if (!dmi_check_system(i8k_dmi_table)) {
|
||||
if (!ignore_dmi && !force)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -978,8 +1007,13 @@ static int __init i8k_probe(void)
|
|||
i8k_get_dmi_data(DMI_BIOS_VERSION));
|
||||
}
|
||||
|
||||
if (dmi_check_system(i8k_blacklist_fan_type_dmi_table))
|
||||
disallow_fan_type_call = true;
|
||||
|
||||
strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
|
||||
sizeof(bios_version));
|
||||
strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
|
||||
sizeof(bios_machineid));
|
||||
|
||||
/*
|
||||
* Get SMM Dell signature
|
||||
|
|
|
@ -81,7 +81,7 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
|
|||
|
||||
mutex_lock(&st->buf_lock);
|
||||
ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto error_ret;
|
||||
st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
|
||||
st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
|
||||
|
@ -163,7 +163,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
|
|||
break;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto error_ret;
|
||||
*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
|
||||
ret = IIO_VAL_INT_PLUS_MICRO;
|
||||
|
|
|
@ -396,8 +396,8 @@ static int ad7266_probe(struct spi_device *spi)
|
|||
|
||||
st = iio_priv(indio_dev);
|
||||
|
||||
st->reg = devm_regulator_get(&spi->dev, "vref");
|
||||
if (!IS_ERR_OR_NULL(st->reg)) {
|
||||
st->reg = devm_regulator_get_optional(&spi->dev, "vref");
|
||||
if (!IS_ERR(st->reg)) {
|
||||
ret = regulator_enable(st->reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -408,6 +408,9 @@ static int ad7266_probe(struct spi_device *spi)
|
|||
|
||||
st->vref_mv = ret / 1000;
|
||||
} else {
|
||||
/* Any other error indicates that the regulator does exist */
|
||||
if (PTR_ERR(st->reg) != -ENODEV)
|
||||
return PTR_ERR(st->reg);
|
||||
/* Use internal reference */
|
||||
st->vref_mv = 2500;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ static const struct {
|
|||
},
|
||||
{ /* IIO_HUMIDITYRELATIVE channel */
|
||||
.shift = 8,
|
||||
.mask = 2,
|
||||
.mask = 3,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -164,14 +164,14 @@ static int hdc100x_get_measurement(struct hdc100x_data *data,
|
|||
dev_err(&client->dev, "cannot read high byte measurement");
|
||||
return ret;
|
||||
}
|
||||
val = ret << 6;
|
||||
val = ret << 8;
|
||||
|
||||
ret = i2c_smbus_read_byte(client);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev, "cannot read low byte measurement");
|
||||
return ret;
|
||||
}
|
||||
val |= ret >> 2;
|
||||
val |= ret;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -211,18 +211,18 @@ static int hdc100x_read_raw(struct iio_dev *indio_dev,
|
|||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
if (chan->type == IIO_TEMP) {
|
||||
*val = 165;
|
||||
*val2 = 65536 >> 2;
|
||||
*val = 165000;
|
||||
*val2 = 65536;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
} else {
|
||||
*val = 0;
|
||||
*val2 = 10000;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
*val = 100;
|
||||
*val2 = 65536;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
}
|
||||
break;
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
*val = -3971;
|
||||
*val2 = 879096;
|
||||
*val = -15887;
|
||||
*val2 = 515151;
|
||||
return IIO_VAL_INT_PLUS_MICRO;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
|
@ -210,22 +210,35 @@ static int iio_trigger_attach_poll_func(struct iio_trigger *trig,
|
|||
|
||||
/* Prevent the module from being removed whilst attached to a trigger */
|
||||
__module_get(pf->indio_dev->info->driver_module);
|
||||
|
||||
/* Get irq number */
|
||||
pf->irq = iio_trigger_get_irq(trig);
|
||||
if (pf->irq < 0)
|
||||
goto out_put_module;
|
||||
|
||||
/* Request irq */
|
||||
ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
|
||||
pf->type, pf->name,
|
||||
pf);
|
||||
if (ret < 0) {
|
||||
module_put(pf->indio_dev->info->driver_module);
|
||||
return ret;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto out_put_irq;
|
||||
|
||||
/* Enable trigger in driver */
|
||||
if (trig->ops && trig->ops->set_trigger_state && notinuse) {
|
||||
ret = trig->ops->set_trigger_state(trig, true);
|
||||
if (ret < 0)
|
||||
module_put(pf->indio_dev->info->driver_module);
|
||||
goto out_free_irq;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
out_free_irq:
|
||||
free_irq(pf->irq, pf);
|
||||
out_put_irq:
|
||||
iio_trigger_put_irq(trig, pf->irq);
|
||||
out_put_module:
|
||||
module_put(pf->indio_dev->info->driver_module);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iio_trigger_detach_poll_func(struct iio_trigger *trig,
|
||||
|
|
|
@ -1005,6 +1005,7 @@ static int apds9960_probe(struct i2c_client *client,
|
|||
|
||||
iio_device_attach_buffer(indio_dev, buffer);
|
||||
|
||||
indio_dev->dev.parent = &client->dev;
|
||||
indio_dev->info = &apds9960_info;
|
||||
indio_dev->name = APDS9960_DRV_NAME;
|
||||
indio_dev->channels = apds9960_channels;
|
||||
|
|
|
@ -28,15 +28,21 @@
|
|||
#include <linux/iio/common/st_sensors.h>
|
||||
#include "st_pressure.h"
|
||||
|
||||
#define MCELSIUS_PER_CELSIUS 1000
|
||||
|
||||
/* Default pressure sensitivity */
|
||||
#define ST_PRESS_LSB_PER_MBAR 4096UL
|
||||
#define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
|
||||
ST_PRESS_LSB_PER_MBAR)
|
||||
|
||||
/* Default temperature sensitivity */
|
||||
#define ST_PRESS_LSB_PER_CELSIUS 480UL
|
||||
#define ST_PRESS_CELSIUS_NANO_SCALE (1000000000UL / \
|
||||
ST_PRESS_LSB_PER_CELSIUS)
|
||||
#define ST_PRESS_MILLI_CELSIUS_OFFSET 42500UL
|
||||
|
||||
#define ST_PRESS_NUMBER_DATA_CHANNELS 1
|
||||
|
||||
/* FULLSCALE */
|
||||
#define ST_PRESS_FS_AVL_1100MB 1100
|
||||
#define ST_PRESS_FS_AVL_1260MB 1260
|
||||
|
||||
#define ST_PRESS_1_OUT_XL_ADDR 0x28
|
||||
|
@ -54,18 +60,20 @@
|
|||
#define ST_PRESS_LPS331AP_PW_MASK 0x80
|
||||
#define ST_PRESS_LPS331AP_FS_ADDR 0x23
|
||||
#define ST_PRESS_LPS331AP_FS_MASK 0x30
|
||||
#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL 0x00
|
||||
#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
|
||||
#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
|
||||
#define ST_PRESS_LPS331AP_BDU_ADDR 0x20
|
||||
#define ST_PRESS_LPS331AP_BDU_MASK 0x04
|
||||
#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR 0x22
|
||||
#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK 0x04
|
||||
#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK 0x20
|
||||
#define ST_PRESS_LPS331AP_MULTIREAD_BIT true
|
||||
#define ST_PRESS_LPS331AP_TEMP_OFFSET 42500
|
||||
|
||||
/* CUSTOM VALUES FOR LPS001WP SENSOR */
|
||||
|
||||
/* LPS001WP pressure resolution */
|
||||
#define ST_PRESS_LPS001WP_LSB_PER_MBAR 16UL
|
||||
/* LPS001WP temperature resolution */
|
||||
#define ST_PRESS_LPS001WP_LSB_PER_CELSIUS 64UL
|
||||
|
||||
#define ST_PRESS_LPS001WP_WAI_EXP 0xba
|
||||
#define ST_PRESS_LPS001WP_ODR_ADDR 0x20
|
||||
#define ST_PRESS_LPS001WP_ODR_MASK 0x30
|
||||
|
@ -74,6 +82,8 @@
|
|||
#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL 0x03
|
||||
#define ST_PRESS_LPS001WP_PW_ADDR 0x20
|
||||
#define ST_PRESS_LPS001WP_PW_MASK 0x40
|
||||
#define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
|
||||
(100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
|
||||
#define ST_PRESS_LPS001WP_BDU_ADDR 0x20
|
||||
#define ST_PRESS_LPS001WP_BDU_MASK 0x04
|
||||
#define ST_PRESS_LPS001WP_MULTIREAD_BIT true
|
||||
|
@ -90,18 +100,12 @@
|
|||
#define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL 0x04
|
||||
#define ST_PRESS_LPS25H_PW_ADDR 0x20
|
||||
#define ST_PRESS_LPS25H_PW_MASK 0x80
|
||||
#define ST_PRESS_LPS25H_FS_ADDR 0x00
|
||||
#define ST_PRESS_LPS25H_FS_MASK 0x00
|
||||
#define ST_PRESS_LPS25H_FS_AVL_1260_VAL 0x00
|
||||
#define ST_PRESS_LPS25H_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
|
||||
#define ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
|
||||
#define ST_PRESS_LPS25H_BDU_ADDR 0x20
|
||||
#define ST_PRESS_LPS25H_BDU_MASK 0x04
|
||||
#define ST_PRESS_LPS25H_DRDY_IRQ_ADDR 0x23
|
||||
#define ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK 0x01
|
||||
#define ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK 0x10
|
||||
#define ST_PRESS_LPS25H_MULTIREAD_BIT true
|
||||
#define ST_PRESS_LPS25H_TEMP_OFFSET 42500
|
||||
#define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28
|
||||
#define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b
|
||||
|
||||
|
@ -153,7 +157,9 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
|
|||
.storagebits = 16,
|
||||
.endianness = IIO_LE,
|
||||
},
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||
.info_mask_separate =
|
||||
BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.modified = 0,
|
||||
},
|
||||
{
|
||||
|
@ -169,7 +175,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
|
|||
},
|
||||
.info_mask_separate =
|
||||
BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_OFFSET),
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.modified = 0,
|
||||
},
|
||||
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||
|
@ -204,11 +210,14 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
|
|||
.addr = ST_PRESS_LPS331AP_FS_ADDR,
|
||||
.mask = ST_PRESS_LPS331AP_FS_MASK,
|
||||
.fs_avl = {
|
||||
/*
|
||||
* Pressure and temperature sensitivity values
|
||||
* as defined in table 3 of LPS331AP datasheet.
|
||||
*/
|
||||
[0] = {
|
||||
.num = ST_PRESS_FS_AVL_1260MB,
|
||||
.value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
|
||||
.gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
|
||||
.gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
|
||||
.gain = ST_PRESS_KPASCAL_NANO_SCALE,
|
||||
.gain2 = ST_PRESS_LSB_PER_CELSIUS,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -248,7 +257,17 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
|
|||
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||
},
|
||||
.fs = {
|
||||
.addr = 0,
|
||||
.fs_avl = {
|
||||
/*
|
||||
* Pressure and temperature resolution values
|
||||
* as defined in table 3 of LPS001WP datasheet.
|
||||
*/
|
||||
[0] = {
|
||||
.num = ST_PRESS_FS_AVL_1100MB,
|
||||
.gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
|
||||
.gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
|
||||
},
|
||||
},
|
||||
},
|
||||
.bdu = {
|
||||
.addr = ST_PRESS_LPS001WP_BDU_ADDR,
|
||||
|
@ -285,14 +304,15 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
|
|||
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||
},
|
||||
.fs = {
|
||||
.addr = ST_PRESS_LPS25H_FS_ADDR,
|
||||
.mask = ST_PRESS_LPS25H_FS_MASK,
|
||||
.fs_avl = {
|
||||
/*
|
||||
* Pressure and temperature sensitivity values
|
||||
* as defined in table 3 of LPS25H datasheet.
|
||||
*/
|
||||
[0] = {
|
||||
.num = ST_PRESS_FS_AVL_1260MB,
|
||||
.value = ST_PRESS_LPS25H_FS_AVL_1260_VAL,
|
||||
.gain = ST_PRESS_LPS25H_FS_AVL_1260_GAIN,
|
||||
.gain2 = ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN,
|
||||
.gain = ST_PRESS_KPASCAL_NANO_SCALE,
|
||||
.gain2 = ST_PRESS_LSB_PER_CELSIUS,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -346,26 +366,26 @@ static int st_press_read_raw(struct iio_dev *indio_dev,
|
|||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 0;
|
||||
|
||||
switch (ch->type) {
|
||||
case IIO_PRESSURE:
|
||||
*val = 0;
|
||||
*val2 = press_data->current_fullscale->gain;
|
||||
break;
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
case IIO_TEMP:
|
||||
*val = MCELSIUS_PER_CELSIUS;
|
||||
*val2 = press_data->current_fullscale->gain2;
|
||||
break;
|
||||
return IIO_VAL_FRACTIONAL;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
goto read_error;
|
||||
}
|
||||
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
switch (ch->type) {
|
||||
case IIO_TEMP:
|
||||
*val = 425;
|
||||
*val2 = 10;
|
||||
*val = ST_PRESS_MILLI_CELSIUS_OFFSET *
|
||||
press_data->current_fullscale->gain2;
|
||||
*val2 = MCELSIUS_PER_CELSIUS;
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
|
|
|
@ -64,6 +64,7 @@ struct as3935_state {
|
|||
struct delayed_work work;
|
||||
|
||||
u32 tune_cap;
|
||||
u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
|
||||
u8 buf[2] ____cacheline_aligned;
|
||||
};
|
||||
|
||||
|
@ -72,7 +73,8 @@ static const struct iio_chan_spec as3935_channels[] = {
|
|||
.type = IIO_PROXIMITY,
|
||||
.info_mask_separate =
|
||||
BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_PROCESSED),
|
||||
BIT(IIO_CHAN_INFO_PROCESSED) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.scan_index = 0,
|
||||
.scan_type = {
|
||||
.sign = 'u',
|
||||
|
@ -181,7 +183,12 @@ static int as3935_read_raw(struct iio_dev *indio_dev,
|
|||
/* storm out of range */
|
||||
if (*val == AS3935_DATA_MASK)
|
||||
return -EINVAL;
|
||||
*val *= 1000;
|
||||
|
||||
if (m == IIO_CHAN_INFO_PROCESSED)
|
||||
*val *= 1000;
|
||||
break;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = 1000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -206,10 +213,10 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private)
|
|||
ret = as3935_read(st, AS3935_DATA, &val);
|
||||
if (ret)
|
||||
goto err_read;
|
||||
val &= AS3935_DATA_MASK;
|
||||
val *= 1000;
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
|
||||
st->buffer[0] = val & AS3935_DATA_MASK;
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
|
||||
pf->timestamp);
|
||||
err_read:
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
|
|
|
@ -3430,14 +3430,14 @@ static int cm_establish(struct ib_cm_id *cm_id)
|
|||
work->cm_event.event = IB_CM_USER_ESTABLISHED;
|
||||
|
||||
/* Check if the device started its remove_one */
|
||||
spin_lock_irq(&cm.lock);
|
||||
spin_lock_irqsave(&cm.lock, flags);
|
||||
if (!cm_dev->going_down) {
|
||||
queue_delayed_work(cm.wq, &work->work, 0);
|
||||
} else {
|
||||
kfree(work);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
spin_unlock_irq(&cm.lock);
|
||||
spin_unlock_irqrestore(&cm.lock, flags);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
|
|
@ -47,6 +47,7 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
|
|||
|
||||
ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
|
||||
ah->av.ib.g_slid = ah_attr->src_path_bits;
|
||||
ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
|
||||
if (ah_attr->ah_flags & IB_AH_GRH) {
|
||||
ah->av.ib.g_slid |= 0x80;
|
||||
ah->av.ib.gid_index = ah_attr->grh.sgid_index;
|
||||
|
@ -64,7 +65,6 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
|
|||
!(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support))
|
||||
--ah->av.ib.stat_rate;
|
||||
}
|
||||
ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
|
||||
|
||||
return &ah->ibah;
|
||||
}
|
||||
|
|
|
@ -1363,13 +1363,23 @@ static int __init amd_iommu_init_pci(void)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Order is important here to make sure any unity map requirements are
|
||||
* fulfilled. The unity mappings are created and written to the device
|
||||
* table during the amd_iommu_init_api() call.
|
||||
*
|
||||
* After that we call init_device_table_dma() to make sure any
|
||||
* uninitialized DTE will block DMA, and in the end we flush the caches
|
||||
* of all IOMMUs to make sure the changes to the device table are
|
||||
* active.
|
||||
*/
|
||||
ret = amd_iommu_init_api();
|
||||
|
||||
init_device_table_dma();
|
||||
|
||||
for_each_iommu(iommu)
|
||||
iommu_flush_all_caches(iommu);
|
||||
|
||||
ret = amd_iommu_init_api();
|
||||
|
||||
if (!ret)
|
||||
print_iommu_info();
|
||||
|
||||
|
|
|
@ -1919,6 +1919,7 @@ static struct iommu_ops arm_smmu_ops = {
|
|||
.detach_dev = arm_smmu_detach_dev,
|
||||
.map = arm_smmu_map,
|
||||
.unmap = arm_smmu_unmap,
|
||||
.map_sg = default_iommu_map_sg,
|
||||
.iova_to_phys = arm_smmu_iova_to_phys,
|
||||
.add_device = arm_smmu_add_device,
|
||||
.remove_device = arm_smmu_remove_device,
|
||||
|
|
|
@ -3169,11 +3169,6 @@ static int __init init_dmars(void)
|
|||
}
|
||||
}
|
||||
|
||||
iommu_flush_write_buffer(iommu);
|
||||
iommu_set_root_entry(iommu);
|
||||
iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
|
||||
iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
|
||||
|
||||
if (!ecap_pass_through(iommu->ecap))
|
||||
hw_pass_through = 0;
|
||||
#ifdef CONFIG_INTEL_IOMMU_SVM
|
||||
|
@ -3182,6 +3177,18 @@ static int __init init_dmars(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that qi is enabled on all iommus, set the root entry and flush
|
||||
* caches. This is required on some Intel X58 chipsets, otherwise the
|
||||
* flush_context function will loop forever and the boot hangs.
|
||||
*/
|
||||
for_each_active_iommu(iommu, drhd) {
|
||||
iommu_flush_write_buffer(iommu);
|
||||
iommu_set_root_entry(iommu);
|
||||
iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
|
||||
iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
|
||||
}
|
||||
|
||||
if (iommu_pass_through)
|
||||
iommu_identity_mapping |= IDENTMAP_ALL;
|
||||
|
||||
|
|
|
@ -1388,47 +1388,44 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
|
|||
static long uvc_v4l2_compat_ioctl32(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct uvc_fh *handle = file->private_data;
|
||||
union {
|
||||
struct uvc_xu_control_mapping xmap;
|
||||
struct uvc_xu_control_query xqry;
|
||||
} karg;
|
||||
void __user *up = compat_ptr(arg);
|
||||
mm_segment_t old_fs;
|
||||
long ret;
|
||||
|
||||
switch (cmd) {
|
||||
case UVCIOC_CTRL_MAP32:
|
||||
cmd = UVCIOC_CTRL_MAP;
|
||||
ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
break;
|
||||
|
||||
case UVCIOC_CTRL_QUERY32:
|
||||
cmd = UVCIOC_CTRL_QUERY;
|
||||
ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
old_fs = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
ret = video_ioctl2(file, cmd, (unsigned long)&karg);
|
||||
set_fs(old_fs);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (cmd) {
|
||||
case UVCIOC_CTRL_MAP:
|
||||
ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
|
||||
break;
|
||||
|
||||
case UVCIOC_CTRL_QUERY:
|
||||
ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -394,7 +394,7 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
|
|||
gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
|
||||
GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
|
||||
gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
|
||||
GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
|
||||
GPMC_CONFIG4_WEEXTRADELAY, p->we_extra_delay);
|
||||
gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
|
||||
GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
|
||||
p->cycle2cyclesamecsen);
|
||||
|
|
|
@ -575,6 +575,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
|
|||
int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
|
||||
struct ubi_volume *vol = ubi->volumes[idx];
|
||||
struct ubi_vid_hdr *vid_hdr;
|
||||
uint32_t crc;
|
||||
|
||||
vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
|
||||
if (!vid_hdr)
|
||||
|
@ -599,14 +600,8 @@ retry:
|
|||
goto out_put;
|
||||
}
|
||||
|
||||
vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
|
||||
err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
|
||||
if (err) {
|
||||
up_read(&ubi->fm_eba_sem);
|
||||
goto write_error;
|
||||
}
|
||||
ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);
|
||||
|
||||
data_size = offset + len;
|
||||
mutex_lock(&ubi->buf_mutex);
|
||||
memset(ubi->peb_buf + offset, 0xFF, len);
|
||||
|
||||
|
@ -621,6 +616,19 @@ retry:
|
|||
|
||||
memcpy(ubi->peb_buf + offset, buf, len);
|
||||
|
||||
data_size = offset + len;
|
||||
crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size);
|
||||
vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
|
||||
vid_hdr->copy_flag = 1;
|
||||
vid_hdr->data_size = cpu_to_be32(data_size);
|
||||
vid_hdr->data_crc = cpu_to_be32(crc);
|
||||
err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
|
||||
if (err) {
|
||||
mutex_unlock(&ubi->buf_mutex);
|
||||
up_read(&ubi->fm_eba_sem);
|
||||
goto write_error;
|
||||
}
|
||||
|
||||
err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size);
|
||||
if (err) {
|
||||
mutex_unlock(&ubi->buf_mutex);
|
||||
|
|
|
@ -809,6 +809,13 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
|
|||
if (cdc_ncm_init(dev))
|
||||
goto error2;
|
||||
|
||||
/* Some firmwares need a pause here or they will silently fail
|
||||
* to set up the interface properly. This value was decided
|
||||
* empirically on a Sierra Wireless MC7455 running 02.08.02.00
|
||||
* firmware.
|
||||
*/
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
/* configure data interface */
|
||||
temp = usb_set_interface(dev->udev, iface_no, data_altsetting);
|
||||
if (temp) {
|
||||
|
|
|
@ -2723,6 +2723,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
|||
if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
|
||||
!info->attrs[HWSIM_ATTR_FLAGS] ||
|
||||
!info->attrs[HWSIM_ATTR_COOKIE] ||
|
||||
!info->attrs[HWSIM_ATTR_SIGNAL] ||
|
||||
!info->attrs[HWSIM_ATTR_TX_INFO])
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -386,13 +386,13 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
|
|||
EXPORT_SYMBOL_GPL(of_irq_to_resource);
|
||||
|
||||
/**
|
||||
* of_irq_get - Decode a node's IRQ and return it as a Linux irq number
|
||||
* of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
|
||||
* @dev: pointer to device tree node
|
||||
* @index: zero-based index of the irq
|
||||
*
|
||||
* Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
|
||||
* is not yet created.
|
||||
* @index: zero-based index of the IRQ
|
||||
*
|
||||
* Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
|
||||
* -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
|
||||
* of any other failure.
|
||||
*/
|
||||
int of_irq_get(struct device_node *dev, int index)
|
||||
{
|
||||
|
@ -413,12 +413,13 @@ int of_irq_get(struct device_node *dev, int index)
|
|||
EXPORT_SYMBOL_GPL(of_irq_get);
|
||||
|
||||
/**
|
||||
* of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number
|
||||
* of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
|
||||
* @dev: pointer to device tree node
|
||||
* @name: irq name
|
||||
* @name: IRQ name
|
||||
*
|
||||
* Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
|
||||
* is not yet created, or error code in case of any other failure.
|
||||
* Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
|
||||
* -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
|
||||
* of any other failure.
|
||||
*/
|
||||
int of_irq_get_byname(struct device_node *dev, const char *name)
|
||||
{
|
||||
|
|
|
@ -1122,7 +1122,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
|||
} else {
|
||||
struct scsi_cmnd *SCp;
|
||||
|
||||
SCp = scsi_host_find_tag(SDp->host, SCSI_NO_TAG);
|
||||
SCp = SDp->current_cmnd;
|
||||
if(unlikely(SCp == NULL)) {
|
||||
sdev_printk(KERN_ERR, SDp,
|
||||
"no saved request for untagged cmd\n");
|
||||
|
@ -1826,7 +1826,7 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)
|
|||
slot->tag, slot);
|
||||
} else {
|
||||
slot->tag = SCSI_NO_TAG;
|
||||
/* must populate current_cmnd for scsi_host_find_tag to work */
|
||||
/* save current command for reselection */
|
||||
SCp->device->current_cmnd = SCp;
|
||||
}
|
||||
/* sanity check: some of the commands generated by the mid-layer
|
||||
|
|
|
@ -1127,7 +1127,6 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
|
|||
*/
|
||||
void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
|
||||
{
|
||||
scmd->device->host->host_failed--;
|
||||
scmd->eh_eflags = 0;
|
||||
list_move_tail(&scmd->eh_entry, done_q);
|
||||
}
|
||||
|
@ -2226,6 +2225,9 @@ int scsi_error_handler(void *data)
|
|||
else
|
||||
scsi_unjam_host(shost);
|
||||
|
||||
/* All scmds have been handled */
|
||||
shost->host_failed = 0;
|
||||
|
||||
/*
|
||||
* Note - if the above fails completely, the action is to take
|
||||
* individual devices offline and flush the queue of any
|
||||
|
|
|
@ -595,7 +595,7 @@ static ssize_t sca3000_read_frequency(struct device *dev,
|
|||
goto error_ret_mut;
|
||||
ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
|
||||
mutex_unlock(&st->lock);
|
||||
if (ret)
|
||||
if (ret < 0)
|
||||
goto error_ret;
|
||||
val = ret;
|
||||
if (base_freq > 0)
|
||||
|
|
|
@ -857,14 +857,6 @@ __cpufreq_cooling_register(struct device_node *np,
|
|||
goto free_power_table;
|
||||
}
|
||||
|
||||
snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
|
||||
cpufreq_dev->id);
|
||||
|
||||
cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
|
||||
&cpufreq_cooling_ops);
|
||||
if (IS_ERR(cool_dev))
|
||||
goto remove_idr;
|
||||
|
||||
/* Fill freq-table in descending order of frequencies */
|
||||
for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) {
|
||||
freq = find_next_max(table, freq);
|
||||
|
@ -877,6 +869,14 @@ __cpufreq_cooling_register(struct device_node *np,
|
|||
pr_debug("%s: freq:%u KHz\n", __func__, freq);
|
||||
}
|
||||
|
||||
snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
|
||||
cpufreq_dev->id);
|
||||
|
||||
cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
|
||||
&cpufreq_cooling_ops);
|
||||
if (IS_ERR(cool_dev))
|
||||
goto remove_idr;
|
||||
|
||||
cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0];
|
||||
cpufreq_dev->cool_dev = cool_dev;
|
||||
|
||||
|
|
|
@ -366,34 +366,22 @@ static void to_utf8(struct vc_data *vc, uint c)
|
|||
|
||||
static void do_compute_shiftstate(void)
|
||||
{
|
||||
unsigned int i, j, k, sym, val;
|
||||
unsigned int k, sym, val;
|
||||
|
||||
shift_state = 0;
|
||||
memset(shift_down, 0, sizeof(shift_down));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(key_down); i++) {
|
||||
|
||||
if (!key_down[i])
|
||||
for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
|
||||
sym = U(key_maps[0][k]);
|
||||
if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
|
||||
continue;
|
||||
|
||||
k = i * BITS_PER_LONG;
|
||||
val = KVAL(sym);
|
||||
if (val == KVAL(K_CAPSSHIFT))
|
||||
val = KVAL(K_SHIFT);
|
||||
|
||||
for (j = 0; j < BITS_PER_LONG; j++, k++) {
|
||||
|
||||
if (!test_bit(k, key_down))
|
||||
continue;
|
||||
|
||||
sym = U(key_maps[0][k]);
|
||||
if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
|
||||
continue;
|
||||
|
||||
val = KVAL(sym);
|
||||
if (val == KVAL(K_CAPSSHIFT))
|
||||
val = KVAL(K_SHIFT);
|
||||
|
||||
shift_down[val]++;
|
||||
shift_state |= (1 << val);
|
||||
}
|
||||
shift_down[val]++;
|
||||
shift_state |= BIT(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -750,6 +750,7 @@ static void visual_init(struct vc_data *vc, int num, int init)
|
|||
vc->vc_complement_mask = 0;
|
||||
vc->vc_can_do_color = 0;
|
||||
vc->vc_panic_force_write = false;
|
||||
vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
|
||||
vc->vc_sw->con_init(vc, init);
|
||||
if (!vc->vc_complement_mask)
|
||||
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue