mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 05:55:44 +02:00
Merge 34816d20f1 ("Merge tag 'gfs2-v5.10-rc5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2") into android-mainline
Steps on the way to 5.10-rc7 Resolves a merge issue in: arch/arm64/kernel/process.c Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: If22f5ca1f09e08cdb95f841f3381eda5cd31ee00
This commit is contained in:
commit
0ba6450eb7
|
|
@ -140,7 +140,9 @@ Since the boot configuration file is loaded with initrd, it will be added
|
|||
to the end of the initrd (initramfs) image file with padding, size,
|
||||
checksum and 12-byte magic word as below.
|
||||
|
||||
[initrd][bootconfig][padding][size(u32)][checksum(u32)][#BOOTCONFIG\n]
|
||||
[initrd][bootconfig][padding][size(le32)][checksum(le32)][#BOOTCONFIG\n]
|
||||
|
||||
The size and checksum fields are unsigned 32bit little endian value.
|
||||
|
||||
When the boot configuration is added to the initrd image, the total
|
||||
file size is aligned to 4 bytes. To fill the gap, null characters
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ static inline void local_daif_inherit(struct pt_regs *regs)
|
|||
{
|
||||
unsigned long flags = regs->pstate & DAIF_MASK;
|
||||
|
||||
if (interrupts_enabled(regs))
|
||||
trace_hardirqs_on();
|
||||
|
||||
/*
|
||||
* We can't use local_daif_restore(regs->pstate) here as
|
||||
* system_has_prio_mask_debugging() won't restore the I bit if it can
|
||||
|
|
|
|||
|
|
@ -31,7 +31,12 @@ static inline u32 disr_to_esr(u64 disr)
|
|||
return esr;
|
||||
}
|
||||
|
||||
asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs);
|
||||
asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs);
|
||||
asmlinkage void enter_from_user_mode(void);
|
||||
asmlinkage void exit_to_user_mode(void);
|
||||
void arm64_enter_nmi(struct pt_regs *regs);
|
||||
void arm64_exit_nmi(struct pt_regs *regs);
|
||||
void do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
|
||||
void do_undefinstr(struct pt_regs *regs);
|
||||
void do_bti(struct pt_regs *regs);
|
||||
|
|
|
|||
|
|
@ -193,6 +193,10 @@ struct pt_regs {
|
|||
/* Only valid when ARM64_HAS_IRQ_PRIO_MASKING is enabled. */
|
||||
u64 pmr_save;
|
||||
u64 stackframe[2];
|
||||
|
||||
/* Only valid for some EL1 exceptions. */
|
||||
u64 lockdep_hardirqs;
|
||||
u64 exit_rcu;
|
||||
};
|
||||
|
||||
static inline bool in_syscall(struct pt_regs const *regs)
|
||||
|
|
|
|||
|
|
@ -987,7 +987,7 @@
|
|||
#define SYS_TFSR_EL1_TF0_SHIFT 0
|
||||
#define SYS_TFSR_EL1_TF1_SHIFT 1
|
||||
#define SYS_TFSR_EL1_TF0 (UL(1) << SYS_TFSR_EL1_TF0_SHIFT)
|
||||
#define SYS_TFSR_EL1_TF1 (UK(2) << SYS_TFSR_EL1_TF1_SHIFT)
|
||||
#define SYS_TFSR_EL1_TF1 (UL(1) << SYS_TFSR_EL1_TF1_SHIFT)
|
||||
|
||||
/* Safe value for MPIDR_EL1: Bit31:RES1, Bit30:U:0, Bit24:MT:0 */
|
||||
#define SYS_MPIDR_SAFE_VAL (BIT(31))
|
||||
|
|
|
|||
|
|
@ -17,40 +17,164 @@
|
|||
#include <asm/mmu.h>
|
||||
#include <asm/sysreg.h>
|
||||
|
||||
static void notrace el1_abort(struct pt_regs *regs, unsigned long esr)
|
||||
/*
|
||||
* This is intended to match the logic in irqentry_enter(), handling the kernel
|
||||
* mode transitions only.
|
||||
*/
|
||||
static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
|
||||
{
|
||||
regs->exit_rcu = false;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TINY_RCU) && is_idle_task(current)) {
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
rcu_irq_enter();
|
||||
trace_hardirqs_off_finish();
|
||||
|
||||
regs->exit_rcu = true;
|
||||
return;
|
||||
}
|
||||
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
rcu_irq_enter_check_tick();
|
||||
trace_hardirqs_off_finish();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is intended to match the logic in irqentry_exit(), handling the kernel
|
||||
* mode transitions only, and with preemption handled elsewhere.
|
||||
*/
|
||||
static void noinstr exit_to_kernel_mode(struct pt_regs *regs)
|
||||
{
|
||||
lockdep_assert_irqs_disabled();
|
||||
|
||||
if (interrupts_enabled(regs)) {
|
||||
if (regs->exit_rcu) {
|
||||
trace_hardirqs_on_prepare();
|
||||
lockdep_hardirqs_on_prepare(CALLER_ADDR0);
|
||||
rcu_irq_exit();
|
||||
lockdep_hardirqs_on(CALLER_ADDR0);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_hardirqs_on();
|
||||
} else {
|
||||
if (regs->exit_rcu)
|
||||
rcu_irq_exit();
|
||||
}
|
||||
}
|
||||
|
||||
void noinstr arm64_enter_nmi(struct pt_regs *regs)
|
||||
{
|
||||
regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
|
||||
|
||||
__nmi_enter();
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
lockdep_hardirq_enter();
|
||||
rcu_nmi_enter();
|
||||
|
||||
trace_hardirqs_off_finish();
|
||||
ftrace_nmi_enter();
|
||||
}
|
||||
|
||||
void noinstr arm64_exit_nmi(struct pt_regs *regs)
|
||||
{
|
||||
bool restore = regs->lockdep_hardirqs;
|
||||
|
||||
ftrace_nmi_exit();
|
||||
if (restore) {
|
||||
trace_hardirqs_on_prepare();
|
||||
lockdep_hardirqs_on_prepare(CALLER_ADDR0);
|
||||
}
|
||||
|
||||
rcu_nmi_exit();
|
||||
lockdep_hardirq_exit();
|
||||
if (restore)
|
||||
lockdep_hardirqs_on(CALLER_ADDR0);
|
||||
__nmi_exit();
|
||||
}
|
||||
|
||||
asmlinkage void noinstr enter_el1_irq_or_nmi(struct pt_regs *regs)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
|
||||
arm64_enter_nmi(regs);
|
||||
else
|
||||
enter_from_kernel_mode(regs);
|
||||
}
|
||||
|
||||
asmlinkage void noinstr exit_el1_irq_or_nmi(struct pt_regs *regs)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
|
||||
arm64_exit_nmi(regs);
|
||||
else
|
||||
exit_to_kernel_mode(regs);
|
||||
}
|
||||
|
||||
static void noinstr el1_abort(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
enter_from_kernel_mode(regs);
|
||||
local_daif_inherit(regs);
|
||||
far = untagged_addr(far);
|
||||
do_mem_abort(far, esr, regs);
|
||||
local_daif_mask();
|
||||
exit_to_kernel_mode(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_abort);
|
||||
|
||||
static void notrace el1_pc(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el1_pc(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
enter_from_kernel_mode(regs);
|
||||
local_daif_inherit(regs);
|
||||
do_sp_pc_abort(far, esr, regs);
|
||||
local_daif_mask();
|
||||
exit_to_kernel_mode(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_pc);
|
||||
|
||||
static void notrace el1_undef(struct pt_regs *regs)
|
||||
static void noinstr el1_undef(struct pt_regs *regs)
|
||||
{
|
||||
enter_from_kernel_mode(regs);
|
||||
local_daif_inherit(regs);
|
||||
do_undefinstr(regs);
|
||||
local_daif_mask();
|
||||
exit_to_kernel_mode(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_undef);
|
||||
|
||||
static void notrace el1_inv(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el1_inv(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
enter_from_kernel_mode(regs);
|
||||
local_daif_inherit(regs);
|
||||
bad_mode(regs, 0, esr);
|
||||
local_daif_mask();
|
||||
exit_to_kernel_mode(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_inv);
|
||||
|
||||
static void notrace el1_dbg(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr arm64_enter_el1_dbg(struct pt_regs *regs)
|
||||
{
|
||||
regs->lockdep_hardirqs = lockdep_hardirqs_enabled();
|
||||
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
rcu_nmi_enter();
|
||||
|
||||
trace_hardirqs_off_finish();
|
||||
}
|
||||
|
||||
static void noinstr arm64_exit_el1_dbg(struct pt_regs *regs)
|
||||
{
|
||||
bool restore = regs->lockdep_hardirqs;
|
||||
|
||||
if (restore) {
|
||||
trace_hardirqs_on_prepare();
|
||||
lockdep_hardirqs_on_prepare(CALLER_ADDR0);
|
||||
}
|
||||
|
||||
rcu_nmi_exit();
|
||||
if (restore)
|
||||
lockdep_hardirqs_on(CALLER_ADDR0);
|
||||
}
|
||||
|
||||
static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
|
|
@ -62,18 +186,21 @@ static void notrace el1_dbg(struct pt_regs *regs, unsigned long esr)
|
|||
if (system_uses_irq_prio_masking())
|
||||
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||
|
||||
arm64_enter_el1_dbg(regs);
|
||||
do_debug_exception(far, esr, regs);
|
||||
arm64_exit_el1_dbg(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_dbg);
|
||||
|
||||
static void notrace el1_fpac(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el1_fpac(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
enter_from_kernel_mode(regs);
|
||||
local_daif_inherit(regs);
|
||||
do_ptrauth_fault(regs, esr);
|
||||
local_daif_mask();
|
||||
exit_to_kernel_mode(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_fpac);
|
||||
|
||||
asmlinkage void notrace el1_sync_handler(struct pt_regs *regs)
|
||||
asmlinkage void noinstr el1_sync_handler(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long esr = read_sysreg(esr_el1);
|
||||
|
||||
|
|
@ -106,20 +233,34 @@ asmlinkage void notrace el1_sync_handler(struct pt_regs *regs)
|
|||
el1_inv(regs, esr);
|
||||
}
|
||||
}
|
||||
NOKPROBE_SYMBOL(el1_sync_handler);
|
||||
|
||||
static void notrace el0_da(struct pt_regs *regs, unsigned long esr)
|
||||
asmlinkage void noinstr enter_from_user_mode(void)
|
||||
{
|
||||
lockdep_hardirqs_off(CALLER_ADDR0);
|
||||
CT_WARN_ON(ct_state() != CONTEXT_USER);
|
||||
user_exit_irqoff();
|
||||
trace_hardirqs_off_finish();
|
||||
}
|
||||
|
||||
asmlinkage void noinstr exit_to_user_mode(void)
|
||||
{
|
||||
trace_hardirqs_on_prepare();
|
||||
lockdep_hardirqs_on_prepare(CALLER_ADDR0);
|
||||
user_enter_irqoff();
|
||||
lockdep_hardirqs_on(CALLER_ADDR0);
|
||||
}
|
||||
|
||||
static void noinstr el0_da(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
far = untagged_addr(far);
|
||||
do_mem_abort(far, esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_da);
|
||||
|
||||
static void notrace el0_ia(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_ia(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
|
|
@ -131,90 +272,80 @@ static void notrace el0_ia(struct pt_regs *regs, unsigned long esr)
|
|||
if (!is_ttbr0_addr(far))
|
||||
arm64_apply_bp_hardening();
|
||||
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_mem_abort(far, esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_ia);
|
||||
|
||||
static void notrace el0_fpsimd_acc(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_fpsimd_acc(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_fpsimd_acc(esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_fpsimd_acc);
|
||||
|
||||
static void notrace el0_sve_acc(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_sve_acc(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_sve_acc(esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_sve_acc);
|
||||
|
||||
static void notrace el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_fpsimd_exc(esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_fpsimd_exc);
|
||||
|
||||
static void notrace el0_sys(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_sys(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_sysinstr(esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_sys);
|
||||
|
||||
static void notrace el0_pc(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_pc(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
if (!is_ttbr0_addr(instruction_pointer(regs)))
|
||||
arm64_apply_bp_hardening();
|
||||
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_sp_pc_abort(far, esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_pc);
|
||||
|
||||
static void notrace el0_sp(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_sp(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_sp_pc_abort(regs->sp, esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_sp);
|
||||
|
||||
static void notrace el0_undef(struct pt_regs *regs)
|
||||
static void noinstr el0_undef(struct pt_regs *regs)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_undefinstr(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_undef);
|
||||
|
||||
static void notrace el0_bti(struct pt_regs *regs)
|
||||
static void noinstr el0_bti(struct pt_regs *regs)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_bti(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_bti);
|
||||
|
||||
static void notrace el0_inv(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_inv(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
bad_el0_sync(regs, 0, esr);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_inv);
|
||||
|
||||
static void notrace el0_dbg(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
/* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
|
@ -222,30 +353,28 @@ static void notrace el0_dbg(struct pt_regs *regs, unsigned long esr)
|
|||
if (system_uses_irq_prio_masking())
|
||||
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
do_debug_exception(far, esr, regs);
|
||||
local_daif_restore(DAIF_PROCCTX_NOIRQ);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_dbg);
|
||||
|
||||
static void notrace el0_svc(struct pt_regs *regs)
|
||||
static void noinstr el0_svc(struct pt_regs *regs)
|
||||
{
|
||||
if (system_uses_irq_prio_masking())
|
||||
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||
|
||||
enter_from_user_mode();
|
||||
do_el0_svc(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_svc);
|
||||
|
||||
static void notrace el0_fpac(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_fpac(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_ptrauth_fault(regs, esr);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_fpac);
|
||||
|
||||
asmlinkage void notrace el0_sync_handler(struct pt_regs *regs)
|
||||
asmlinkage void noinstr el0_sync_handler(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long esr = read_sysreg(esr_el1);
|
||||
|
||||
|
|
@ -297,27 +426,25 @@ asmlinkage void notrace el0_sync_handler(struct pt_regs *regs)
|
|||
el0_inv(regs, esr);
|
||||
}
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_sync_handler);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
static void notrace el0_cp15(struct pt_regs *regs, unsigned long esr)
|
||||
static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr)
|
||||
{
|
||||
user_exit_irqoff();
|
||||
enter_from_user_mode();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
do_cp15instr(esr, regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_cp15);
|
||||
|
||||
static void notrace el0_svc_compat(struct pt_regs *regs)
|
||||
static void noinstr el0_svc_compat(struct pt_regs *regs)
|
||||
{
|
||||
if (system_uses_irq_prio_masking())
|
||||
gic_write_pmr(GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET);
|
||||
|
||||
enter_from_user_mode();
|
||||
do_el0_svc_compat(regs);
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_svc_compat);
|
||||
|
||||
asmlinkage void notrace el0_sync_compat_handler(struct pt_regs *regs)
|
||||
asmlinkage void noinstr el0_sync_compat_handler(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long esr = read_sysreg(esr_el1);
|
||||
|
||||
|
|
@ -360,5 +487,4 @@ asmlinkage void notrace el0_sync_compat_handler(struct pt_regs *regs)
|
|||
el0_inv(regs, esr);
|
||||
}
|
||||
}
|
||||
NOKPROBE_SYMBOL(el0_sync_compat_handler);
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
|
|
|||
|
|
@ -30,18 +30,18 @@
|
|||
#include <asm/unistd.h>
|
||||
|
||||
/*
|
||||
* Context tracking subsystem. Used to instrument transitions
|
||||
* between user and kernel mode.
|
||||
* Context tracking and irqflag tracing need to instrument transitions between
|
||||
* user and kernel mode.
|
||||
*/
|
||||
.macro ct_user_exit_irqoff
|
||||
#ifdef CONFIG_CONTEXT_TRACKING
|
||||
.macro user_exit_irqoff
|
||||
#if defined(CONFIG_CONTEXT_TRACKING) || defined(CONFIG_TRACE_IRQFLAGS)
|
||||
bl enter_from_user_mode
|
||||
#endif
|
||||
.endm
|
||||
|
||||
.macro ct_user_enter
|
||||
#ifdef CONFIG_CONTEXT_TRACKING
|
||||
bl context_tracking_user_enter
|
||||
.macro user_enter_irqoff
|
||||
#if defined(CONFIG_CONTEXT_TRACKING) || defined(CONFIG_TRACE_IRQFLAGS)
|
||||
bl exit_to_user_mode
|
||||
#endif
|
||||
.endm
|
||||
|
||||
|
|
@ -298,9 +298,6 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
|
|||
alternative_else_nop_endif
|
||||
|
||||
ldp x21, x22, [sp, #S_PC] // load ELR, SPSR
|
||||
.if \el == 0
|
||||
ct_user_enter
|
||||
.endif
|
||||
|
||||
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
|
||||
alternative_if_not ARM64_HAS_PAN
|
||||
|
|
@ -637,16 +634,8 @@ SYM_CODE_START_LOCAL_NOALIGN(el1_irq)
|
|||
gic_prio_irq_setup pmr=x20, tmp=x1
|
||||
enable_da_f
|
||||
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
test_irqs_unmasked res=x0, pmr=x20
|
||||
cbz x0, 1f
|
||||
bl asm_nmi_enter
|
||||
1:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_off
|
||||
#endif
|
||||
mov x0, sp
|
||||
bl enter_el1_irq_or_nmi
|
||||
|
||||
irq_handler
|
||||
|
||||
|
|
@ -665,26 +654,8 @@ alternative_else_nop_endif
|
|||
1:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
/*
|
||||
* When using IRQ priority masking, we can get spurious interrupts while
|
||||
* PMR is set to GIC_PRIO_IRQOFF. An NMI might also have occurred in a
|
||||
* section with interrupts disabled. Skip tracing in those cases.
|
||||
*/
|
||||
test_irqs_unmasked res=x0, pmr=x20
|
||||
cbz x0, 1f
|
||||
bl asm_nmi_exit
|
||||
1:
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
#ifdef CONFIG_ARM64_PSEUDO_NMI
|
||||
test_irqs_unmasked res=x0, pmr=x20
|
||||
cbnz x0, 1f
|
||||
#endif
|
||||
bl trace_hardirqs_on
|
||||
1:
|
||||
#endif
|
||||
mov x0, sp
|
||||
bl exit_el1_irq_or_nmi
|
||||
|
||||
kernel_exit 1
|
||||
SYM_CODE_END(el1_irq)
|
||||
|
|
@ -726,21 +697,14 @@ SYM_CODE_START_LOCAL_NOALIGN(el0_irq)
|
|||
kernel_entry 0
|
||||
el0_irq_naked:
|
||||
gic_prio_irq_setup pmr=x20, tmp=x0
|
||||
ct_user_exit_irqoff
|
||||
user_exit_irqoff
|
||||
enable_da_f
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_off
|
||||
#endif
|
||||
|
||||
tbz x22, #55, 1f
|
||||
bl do_el0_irq_bp_hardening
|
||||
1:
|
||||
irq_handler
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_on
|
||||
#endif
|
||||
b ret_to_user
|
||||
SYM_CODE_END(el0_irq)
|
||||
|
||||
|
|
@ -759,7 +723,7 @@ SYM_CODE_START_LOCAL(el0_error)
|
|||
el0_error_naked:
|
||||
mrs x25, esr_el1
|
||||
gic_prio_kentry_setup tmp=x2
|
||||
ct_user_exit_irqoff
|
||||
user_exit_irqoff
|
||||
enable_dbg
|
||||
mov x0, sp
|
||||
mov x1, x25
|
||||
|
|
@ -774,13 +738,17 @@ SYM_CODE_END(el0_error)
|
|||
SYM_CODE_START_LOCAL(ret_to_user)
|
||||
disable_daif
|
||||
gic_prio_kentry_setup tmp=x3
|
||||
ldr x1, [tsk, #TSK_TI_FLAGS]
|
||||
and x2, x1, #_TIF_WORK_MASK
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_off
|
||||
#endif
|
||||
ldr x19, [tsk, #TSK_TI_FLAGS]
|
||||
and x2, x19, #_TIF_WORK_MASK
|
||||
cbnz x2, work_pending
|
||||
finish_ret_to_user:
|
||||
user_enter_irqoff
|
||||
/* Ignore asynchronous tag check faults in the uaccess routines */
|
||||
clear_mte_async_tcf
|
||||
enable_step_tsk x1, x2
|
||||
enable_step_tsk x19, x2
|
||||
#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
|
||||
bl stackleak_erase
|
||||
#endif
|
||||
|
|
@ -791,11 +759,9 @@ finish_ret_to_user:
|
|||
*/
|
||||
work_pending:
|
||||
mov x0, sp // 'regs'
|
||||
mov x1, x19
|
||||
bl do_notify_resume
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
bl trace_hardirqs_on // enabled while in userspace
|
||||
#endif
|
||||
ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for single-step
|
||||
ldr x19, [tsk, #TSK_TI_FLAGS] // re-check for single-step
|
||||
b finish_ret_to_user
|
||||
SYM_CODE_END(ret_to_user)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,18 +67,3 @@ void __init init_IRQ(void)
|
|||
local_daif_restore(DAIF_PROCCTX_NOIRQ);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Stubs to make nmi_enter/exit() code callable from ASM
|
||||
*/
|
||||
asmlinkage void notrace asm_nmi_enter(void)
|
||||
{
|
||||
nmi_enter();
|
||||
}
|
||||
NOKPROBE_SYMBOL(asm_nmi_enter);
|
||||
|
||||
asmlinkage void notrace asm_nmi_exit(void)
|
||||
{
|
||||
nmi_exit();
|
||||
}
|
||||
NOKPROBE_SYMBOL(asm_nmi_exit);
|
||||
|
|
|
|||
|
|
@ -72,13 +72,13 @@ EXPORT_SYMBOL(__stack_chk_guard);
|
|||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL_GPL(pm_power_off);
|
||||
|
||||
static void __cpu_do_idle(void)
|
||||
static void noinstr __cpu_do_idle(void)
|
||||
{
|
||||
dsb(sy);
|
||||
wfi();
|
||||
}
|
||||
|
||||
static void __cpu_do_idle_irqprio(void)
|
||||
static void noinstr __cpu_do_idle_irqprio(void)
|
||||
{
|
||||
unsigned long pmr;
|
||||
unsigned long daif_bits;
|
||||
|
|
@ -108,7 +108,7 @@ static void __cpu_do_idle_irqprio(void)
|
|||
* ensure that interrupts are not masked at the PMR (because the core will
|
||||
* not wake up if we block the wake up signal in the interrupt controller).
|
||||
*/
|
||||
void cpu_do_idle(void)
|
||||
void noinstr cpu_do_idle(void)
|
||||
{
|
||||
if (system_uses_irq_prio_masking())
|
||||
__cpu_do_idle_irqprio();
|
||||
|
|
@ -119,7 +119,7 @@ void cpu_do_idle(void)
|
|||
/*
|
||||
* This is our default idle handler.
|
||||
*/
|
||||
void arch_cpu_idle(void)
|
||||
void noinstr arch_cpu_idle(void)
|
||||
{
|
||||
/*
|
||||
* This should do all the clock switching and wait for interrupt
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/kprobes.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
|
@ -223,16 +224,16 @@ static __kprobes unsigned long _sdei_handler(struct pt_regs *regs,
|
|||
}
|
||||
|
||||
|
||||
asmlinkage __kprobes notrace unsigned long
|
||||
asmlinkage noinstr unsigned long
|
||||
__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
nmi_enter();
|
||||
arm64_enter_nmi(regs);
|
||||
|
||||
ret = _sdei_handler(regs, arg);
|
||||
|
||||
nmi_exit();
|
||||
arm64_exit_nmi(regs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,7 +121,6 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
|
|||
|
||||
cortex_a76_erratum_1463225_svc_handler();
|
||||
local_daif_restore(DAIF_PROCCTX);
|
||||
user_exit();
|
||||
|
||||
if (system_supports_mte() && (flags & _TIF_MTE_ASYNC_FAULT)) {
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <asm/daifflags.h>
|
||||
#include <asm/debug-monitors.h>
|
||||
#include <asm/esr.h>
|
||||
#include <asm/exception.h>
|
||||
#include <asm/extable.h>
|
||||
#include <asm/insn.h>
|
||||
#include <asm/kprobes.h>
|
||||
|
|
@ -753,8 +754,10 @@ const char *esr_get_class_string(u32 esr)
|
|||
* bad_mode handles the impossible case in the exception vector. This is always
|
||||
* fatal.
|
||||
*/
|
||||
asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
||||
asmlinkage void notrace bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
||||
{
|
||||
arm64_enter_nmi(regs);
|
||||
|
||||
console_verbose();
|
||||
|
||||
pr_crit("Bad mode in %s handler detected on CPU%d, code 0x%08x -- %s\n",
|
||||
|
|
@ -786,7 +789,7 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
|
|||
DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack)
|
||||
__aligned(16);
|
||||
|
||||
asmlinkage void handle_bad_stack(struct pt_regs *regs)
|
||||
asmlinkage void noinstr handle_bad_stack(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long tsk_stk = (unsigned long)current->stack;
|
||||
unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
|
||||
|
|
@ -794,6 +797,8 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
|
|||
unsigned int esr = read_sysreg(esr_el1);
|
||||
unsigned long far = read_sysreg(far_el1);
|
||||
|
||||
arm64_enter_nmi(regs);
|
||||
|
||||
console_verbose();
|
||||
pr_emerg("Insufficient stack space to handle exception!");
|
||||
|
||||
|
|
@ -865,24 +870,17 @@ bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr)
|
|||
}
|
||||
}
|
||||
|
||||
asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
|
||||
asmlinkage void noinstr do_serror(struct pt_regs *regs, unsigned int esr)
|
||||
{
|
||||
nmi_enter();
|
||||
arm64_enter_nmi(regs);
|
||||
|
||||
/* non-RAS errors are not containable */
|
||||
if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(regs, esr))
|
||||
arm64_serror_panic(regs, esr);
|
||||
|
||||
nmi_exit();
|
||||
arm64_exit_nmi(regs);
|
||||
}
|
||||
|
||||
asmlinkage void enter_from_user_mode(void)
|
||||
{
|
||||
CT_WARN_ON(ct_state() != CONTEXT_USER);
|
||||
user_exit_irqoff();
|
||||
}
|
||||
NOKPROBE_SYMBOL(enter_from_user_mode);
|
||||
|
||||
/* GENERIC_BUG traps */
|
||||
|
||||
int is_valid_bugaddr(unsigned long addr)
|
||||
|
|
|
|||
|
|
@ -789,25 +789,6 @@ void __init hook_debug_fault_code(int nr,
|
|||
*/
|
||||
static void debug_exception_enter(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* Tell lockdep we disabled irqs in entry.S. Do nothing if they were
|
||||
* already disabled to preserve the last enabled/disabled addresses.
|
||||
*/
|
||||
if (interrupts_enabled(regs))
|
||||
trace_hardirqs_off();
|
||||
|
||||
if (user_mode(regs)) {
|
||||
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
|
||||
} else {
|
||||
/*
|
||||
* We might have interrupted pretty much anything. In
|
||||
* fact, if we're a debug exception, we can even interrupt
|
||||
* NMI processing. We don't want this code makes in_nmi()
|
||||
* to return true, but we need to notify RCU.
|
||||
*/
|
||||
rcu_nmi_enter();
|
||||
}
|
||||
|
||||
preempt_disable();
|
||||
|
||||
/* This code is a bit fragile. Test it. */
|
||||
|
|
@ -818,12 +799,6 @@ NOKPROBE_SYMBOL(debug_exception_enter);
|
|||
static void debug_exception_exit(struct pt_regs *regs)
|
||||
{
|
||||
preempt_enable_no_resched();
|
||||
|
||||
if (!user_mode(regs))
|
||||
rcu_nmi_exit();
|
||||
|
||||
if (interrupts_enabled(regs))
|
||||
trace_hardirqs_on();
|
||||
}
|
||||
NOKPROBE_SYMBOL(debug_exception_exit);
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ obj-$(CONFIG_OF) += of/
|
|||
obj-$(CONFIG_SSB) += ssb/
|
||||
obj-$(CONFIG_BCMA) += bcma/
|
||||
obj-$(CONFIG_VHOST_RING) += vhost/
|
||||
obj-$(CONFIG_VHOST_IOTLB) += vhost/
|
||||
obj-$(CONFIG_VHOST) += vhost/
|
||||
obj-$(CONFIG_VLYNQ) += vlynq/
|
||||
obj-$(CONFIG_GREYBUS) += greybus/
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ config IFCVF
|
|||
|
||||
config MLX5_VDPA
|
||||
bool
|
||||
select VHOST_IOTLB
|
||||
help
|
||||
Support library for Mellanox VDPA drivers. Provides code that is
|
||||
common for all types of VDPA drivers. The following drivers are planned:
|
||||
|
|
|
|||
|
|
@ -348,7 +348,9 @@ static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp)
|
|||
.last = v->range.last,
|
||||
};
|
||||
|
||||
return copy_to_user(argp, &range, sizeof(range));
|
||||
if (copy_to_user(argp, &range, sizeof(range)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
|
||||
|
|
|
|||
|
|
@ -1035,6 +1035,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
|
|||
gl->gl_node.next = NULL;
|
||||
gl->gl_flags = 0;
|
||||
gl->gl_name = name;
|
||||
lockdep_set_subclass(&gl->gl_lockref.lock, glops->go_subclass);
|
||||
gl->gl_lockref.count = 1;
|
||||
gl->gl_state = LM_ST_UNLOCKED;
|
||||
gl->gl_target = LM_ST_UNLOCKED;
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
|
|||
static void gfs2_rgrp_go_dump(struct seq_file *seq, struct gfs2_glock *gl,
|
||||
const char *fs_id_buf)
|
||||
{
|
||||
struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
|
||||
struct gfs2_rgrpd *rgd = gl->gl_object;
|
||||
|
||||
if (rgd)
|
||||
gfs2_rgrp_dump(seq, rgd, fs_id_buf);
|
||||
|
|
@ -582,7 +582,8 @@ static int freeze_go_sync(struct gfs2_glock *gl)
|
|||
* Once thawed, the work func acquires the freeze glock in
|
||||
* SH and everybody goes back to thawed.
|
||||
*/
|
||||
if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp)) {
|
||||
if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp) &&
|
||||
!test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
|
||||
atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE);
|
||||
error = freeze_super(sdp->sd_vfs);
|
||||
if (error) {
|
||||
|
|
@ -781,6 +782,7 @@ const struct gfs2_glock_operations gfs2_iopen_glops = {
|
|||
.go_callback = iopen_go_callback,
|
||||
.go_demote_ok = iopen_go_demote_ok,
|
||||
.go_flags = GLOF_LRU | GLOF_NONDISK,
|
||||
.go_subclass = 1,
|
||||
};
|
||||
|
||||
const struct gfs2_glock_operations gfs2_flock_glops = {
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ struct gfs2_glock_operations {
|
|||
const char *fs_id_buf);
|
||||
void (*go_callback)(struct gfs2_glock *gl, bool remote);
|
||||
void (*go_free)(struct gfs2_glock *gl);
|
||||
const int go_subclass;
|
||||
const int go_type;
|
||||
const unsigned long go_flags;
|
||||
#define GLOF_ASPACE 1 /* address space attached */
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
|||
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
if (blktype != GFS2_BLKST_UNLINKED)
|
||||
gfs2_cancel_delete_work(io_gl);
|
||||
|
||||
if (type == DT_UNKNOWN || blktype != GFS2_BLKST_FREE) {
|
||||
/*
|
||||
|
|
@ -180,8 +182,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
|
|||
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
|
||||
if (unlikely(error))
|
||||
goto fail;
|
||||
if (blktype != GFS2_BLKST_UNLINKED)
|
||||
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
|
||||
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
gfs2_glock_put(io_gl);
|
||||
io_gl = NULL;
|
||||
|
|
@ -725,13 +725,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
|||
flush_delayed_work(&ip->i_gl->gl_work);
|
||||
glock_set_object(ip->i_gl, ip);
|
||||
|
||||
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
|
||||
error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
|
||||
if (error)
|
||||
goto fail_free_inode;
|
||||
gfs2_cancel_delete_work(io_gl);
|
||||
glock_set_object(io_gl, ip);
|
||||
|
||||
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
|
||||
if (error)
|
||||
goto fail_gunlock2;
|
||||
|
||||
error = gfs2_trans_begin(sdp, blocks, 0);
|
||||
if (error)
|
||||
goto fail_free_inode;
|
||||
goto fail_gunlock2;
|
||||
|
||||
if (blocks > 1) {
|
||||
ip->i_eattr = ip->i_no_addr + 1;
|
||||
|
|
@ -740,18 +746,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
|||
init_dinode(dip, ip, symname);
|
||||
gfs2_trans_end(sdp);
|
||||
|
||||
error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
|
||||
if (error)
|
||||
goto fail_free_inode;
|
||||
|
||||
BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags));
|
||||
|
||||
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
|
||||
if (error)
|
||||
goto fail_gunlock2;
|
||||
|
||||
gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
|
||||
glock_set_object(ip->i_iopen_gh.gh_gl, ip);
|
||||
gfs2_set_iop(inode);
|
||||
insert_inode_hash(inode);
|
||||
|
||||
|
|
@ -803,6 +803,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
|
|||
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
|
||||
fail_gunlock2:
|
||||
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
|
||||
glock_clear_object(io_gl, ip);
|
||||
gfs2_glock_put(io_gl);
|
||||
fail_free_inode:
|
||||
if (ip->i_gl) {
|
||||
|
|
@ -2116,6 +2117,25 @@ loff_t gfs2_seek_hole(struct file *file, loff_t offset)
|
|||
return vfs_setpos(file, ret, inode->i_sb->s_maxbytes);
|
||||
}
|
||||
|
||||
static int gfs2_update_time(struct inode *inode, struct timespec64 *time,
|
||||
int flags)
|
||||
{
|
||||
struct gfs2_inode *ip = GFS2_I(inode);
|
||||
struct gfs2_glock *gl = ip->i_gl;
|
||||
struct gfs2_holder *gh;
|
||||
int error;
|
||||
|
||||
gh = gfs2_glock_is_locked_by_me(gl);
|
||||
if (gh && !gfs2_glock_is_held_excl(gl)) {
|
||||
gfs2_glock_dq(gh);
|
||||
gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, gh);
|
||||
error = gfs2_glock_nq(gh);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
return generic_update_time(inode, time, flags);
|
||||
}
|
||||
|
||||
const struct inode_operations gfs2_file_iops = {
|
||||
.permission = gfs2_permission,
|
||||
.setattr = gfs2_setattr,
|
||||
|
|
@ -2124,6 +2144,7 @@ const struct inode_operations gfs2_file_iops = {
|
|||
.fiemap = gfs2_fiemap,
|
||||
.get_acl = gfs2_get_acl,
|
||||
.set_acl = gfs2_set_acl,
|
||||
.update_time = gfs2_update_time,
|
||||
};
|
||||
|
||||
const struct inode_operations gfs2_dir_iops = {
|
||||
|
|
@ -2143,6 +2164,7 @@ const struct inode_operations gfs2_dir_iops = {
|
|||
.fiemap = gfs2_fiemap,
|
||||
.get_acl = gfs2_get_acl,
|
||||
.set_acl = gfs2_set_acl,
|
||||
.update_time = gfs2_update_time,
|
||||
.atomic_open = gfs2_atomic_open,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -985,6 +985,10 @@ static int gfs2_ri_update(struct gfs2_inode *ip)
|
|||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (RB_EMPTY_ROOT(&sdp->sd_rindex_tree)) {
|
||||
fs_err(sdp, "no resource groups found in the file system.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
set_rgrp_preferences(sdp);
|
||||
|
||||
sdp->sd_rindex_uptodate = 1;
|
||||
|
|
|
|||
|
|
@ -288,8 +288,8 @@ static void * __init get_boot_config_from_initrd(u32 *_size, u32 *_csum)
|
|||
|
||||
found:
|
||||
hdr = (u32 *)(data - 8);
|
||||
size = hdr[0];
|
||||
csum = hdr[1];
|
||||
size = le32_to_cpu(hdr[0]);
|
||||
csum = le32_to_cpu(hdr[1]);
|
||||
|
||||
data = ((void *)hdr) - size;
|
||||
if ((unsigned long)data < initrd_start) {
|
||||
|
|
|
|||
|
|
@ -1364,16 +1364,20 @@ static int try_assign_dacs(struct hda_codec *codec, int num_outs,
|
|||
struct nid_path *path;
|
||||
hda_nid_t pin = pins[i];
|
||||
|
||||
path = snd_hda_get_path_from_idx(codec, path_idx[i]);
|
||||
if (path) {
|
||||
badness += assign_out_path_ctls(codec, path);
|
||||
continue;
|
||||
if (!spec->obey_preferred_dacs) {
|
||||
path = snd_hda_get_path_from_idx(codec, path_idx[i]);
|
||||
if (path) {
|
||||
badness += assign_out_path_ctls(codec, path);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dacs[i] = get_preferred_dac(codec, pin);
|
||||
if (dacs[i]) {
|
||||
if (is_dac_already_used(codec, dacs[i]))
|
||||
badness += bad->shared_primary;
|
||||
} else if (spec->obey_preferred_dacs) {
|
||||
badness += BAD_NO_PRIMARY_DAC;
|
||||
}
|
||||
|
||||
if (!dacs[i])
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ struct hda_gen_spec {
|
|||
unsigned int power_down_unused:1; /* power down unused widgets */
|
||||
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
||||
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
|
||||
unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */
|
||||
|
||||
/* other internal flags */
|
||||
unsigned int no_analog:1; /* digital I/O only */
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ struct alc_spec {
|
|||
unsigned int no_shutup_pins:1;
|
||||
unsigned int ultra_low_power:1;
|
||||
unsigned int has_hs_key:1;
|
||||
unsigned int no_internal_mic_pin:1;
|
||||
|
||||
/* for PLL fix */
|
||||
hda_nid_t pll_nid;
|
||||
|
|
@ -445,6 +446,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
|||
alc_update_coef_idx(codec, 0x7, 1<<5, 0);
|
||||
break;
|
||||
case 0x10ec0892:
|
||||
case 0x10ec0897:
|
||||
alc_update_coef_idx(codec, 0x7, 1<<5, 0);
|
||||
break;
|
||||
case 0x10ec0899:
|
||||
|
|
@ -4523,6 +4525,7 @@ static const struct coef_fw alc225_pre_hsmode[] = {
|
|||
|
||||
static void alc_headset_mode_unplugged(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
static const struct coef_fw coef0255[] = {
|
||||
WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
|
||||
WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
|
||||
|
|
@ -4597,6 +4600,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
|
|||
{}
|
||||
};
|
||||
|
||||
if (spec->no_internal_mic_pin) {
|
||||
alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x10ec0255:
|
||||
alc_process_coef_fw(codec, coef0255);
|
||||
|
|
@ -5163,6 +5171,11 @@ static void alc_determine_headset_type(struct hda_codec *codec)
|
|||
{}
|
||||
};
|
||||
|
||||
if (spec->no_internal_mic_pin) {
|
||||
alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x10ec0255:
|
||||
alc_process_coef_fw(codec, coef0255);
|
||||
|
|
@ -6014,6 +6027,21 @@ static void alc274_fixup_bind_dacs(struct hda_codec *codec,
|
|||
codec->power_save_node = 0;
|
||||
}
|
||||
|
||||
/* avoid DAC 0x06 for bass speaker 0x17; it has no volume control */
|
||||
static void alc289_fixup_asus_ga401(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
static const hda_nid_t preferred_pairs[] = {
|
||||
0x14, 0x02, 0x17, 0x02, 0x21, 0x03, 0
|
||||
};
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
spec->gen.preferred_dacs = preferred_pairs;
|
||||
spec->gen.obey_preferred_dacs = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* The DAC of NID 0x3 will introduce click/pop noise on headphones, so invalidate it */
|
||||
static void alc285_fixup_invalidate_dacs(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
|
|
@ -6121,6 +6149,23 @@ static void alc274_fixup_hp_headset_mic(struct hda_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
static void alc_fixup_no_int_mic(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
switch (action) {
|
||||
case HDA_FIXUP_ACT_PRE_PROBE:
|
||||
/* Mic RING SLEEVE swap for combo jack */
|
||||
alc_update_coef_idx(codec, 0x45, 0xf<<12 | 1<<10, 5<<12);
|
||||
spec->no_internal_mic_pin = true;
|
||||
break;
|
||||
case HDA_FIXUP_ACT_INIT:
|
||||
alc_combo_jack_hp_jd_restart(codec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* for hda_fixup_thinkpad_acpi() */
|
||||
#include "thinkpad_helper.c"
|
||||
|
||||
|
|
@ -6320,6 +6365,7 @@ enum {
|
|||
ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
|
||||
ALC287_FIXUP_HP_GPIO_LED,
|
||||
ALC256_FIXUP_HP_HEADSET_MIC,
|
||||
ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
|
||||
};
|
||||
|
||||
static const struct hda_fixup alc269_fixups[] = {
|
||||
|
|
@ -7569,11 +7615,10 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.chain_id = ALC269_FIXUP_HEADSET_MIC
|
||||
},
|
||||
[ALC289_FIXUP_ASUS_GA401] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
{ 0x19, 0x03a11020 }, /* headset mic with jack detect */
|
||||
{ }
|
||||
},
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc289_fixup_asus_ga401,
|
||||
.chained = true,
|
||||
.chain_id = ALC289_FIXUP_ASUS_GA502,
|
||||
},
|
||||
[ALC289_FIXUP_ASUS_GA502] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
|
|
@ -7697,7 +7742,7 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
{ }
|
||||
},
|
||||
.chained = true,
|
||||
.chain_id = ALC289_FIXUP_ASUS_GA401
|
||||
.chain_id = ALC289_FIXUP_ASUS_GA502
|
||||
},
|
||||
[ALC274_FIXUP_HP_MIC] = {
|
||||
.type = HDA_FIXUP_VERBS,
|
||||
|
|
@ -7738,6 +7783,12 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc274_fixup_hp_headset_mic,
|
||||
},
|
||||
[ALC236_FIXUP_DELL_AIO_HEADSET_MIC] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc_fixup_no_int_mic,
|
||||
.chained = true,
|
||||
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
|
||||
},
|
||||
};
|
||||
|
||||
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
|
|
@ -7815,6 +7866,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
|
||||
SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
|
||||
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
|
||||
|
|
@ -7881,6 +7934,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x103c, 0x820d, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||
SND_PCI_QUIRK(0x103c, 0x8256, "HP", ALC221_FIXUP_HP_FRONT_MIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x827e, "HP x360", ALC295_FIXUP_HP_X360),
|
||||
SND_PCI_QUIRK(0x103c, 0x827f, "HP x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||
SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
|
||||
|
|
@ -8353,6 +8407,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
|||
{0x19, 0x02a11020},
|
||||
{0x1a, 0x02a11030},
|
||||
{0x21, 0x0221101f}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0236, 0x1028, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
|
||||
{0x21, 0x02211010}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0236, 0x103c, "HP", ALC256_FIXUP_HP_HEADSET_MIC,
|
||||
{0x14, 0x90170110},
|
||||
{0x19, 0x02a11020},
|
||||
|
|
@ -8585,6 +8641,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
|||
SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
ALC292_STANDARD_PINS,
|
||||
{0x13, 0x90a60140}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_HPE,
|
||||
{0x17, 0x90170110},
|
||||
{0x21, 0x04211020}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0294, 0x1043, "ASUS", ALC294_FIXUP_ASUS_MIC,
|
||||
{0x14, 0x90170110},
|
||||
{0x1b, 0x90a70130},
|
||||
|
|
@ -10171,6 +10230,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
|||
HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
|
||||
HDA_CODEC_ENTRY(0x10ec0897, "ALC897", patch_alc662),
|
||||
HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
|
||||
HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ static const struct reg_sequence patch_list[] = {
|
|||
{RT5682_DAC_ADC_DIG_VOL1, 0xa020},
|
||||
{RT5682_I2C_CTRL, 0x000f},
|
||||
{RT5682_PLL2_INTERNAL, 0x8266},
|
||||
{RT5682_SAR_IL_CMD_3, 0x8365},
|
||||
};
|
||||
|
||||
void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev)
|
||||
|
|
|
|||
|
|
@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
|
|||
mem = wm_adsp_find_region(dsp, type);
|
||||
if (!mem) {
|
||||
adsp_err(dsp, "No region of type: %x\n", type);
|
||||
ret = -EINVAL;
|
||||
goto out_fw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -520,10 +520,10 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
|||
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* HP Pavilion x2 10-n000nd */
|
||||
{ /* HP Pavilion x2 10-k0XX, 10-n0XX */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
|
||||
},
|
||||
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
|
||||
BYT_RT5640_JD_SRC_JD2_IN4N |
|
||||
|
|
@ -532,6 +532,17 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = {
|
|||
BYT_RT5640_SSP0_AIF1 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* HP Pavilion x2 10-p0XX */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
|
||||
},
|
||||
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
|
||||
BYT_RT5640_JD_SRC_JD1_IN4P |
|
||||
BYT_RT5640_OVCD_TH_1500UA |
|
||||
BYT_RT5640_OVCD_SF_0P75 |
|
||||
BYT_RT5640_MCLK_EN),
|
||||
},
|
||||
{ /* HP Stream 7 */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
|
|
|
|||
|
|
@ -263,28 +263,6 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
|
||||
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
|
||||
unsigned int id = dai->driver->id;
|
||||
int ret;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
ret = regmap_fields_write(i2sctl->spken, id,
|
||||
LPAIF_I2SCTL_SPKEN_ENABLE);
|
||||
} else {
|
||||
ret = regmap_fields_write(i2sctl->micen, id,
|
||||
LPAIF_I2SCTL_MICEN_ENABLE);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(dai->dev, "error writing to i2sctl enable: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
|
|
@ -292,6 +270,18 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
|
|||
struct lpaif_i2sctl *i2sctl = drvdata->i2sctl;
|
||||
unsigned int id = dai->driver->id;
|
||||
int ret = -EINVAL;
|
||||
unsigned int val = 0;
|
||||
|
||||
ret = regmap_read(drvdata->lpaif_map,
|
||||
LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id), &val);
|
||||
if (ret) {
|
||||
dev_err(dai->dev, "error reading from i2sctl reg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (val == LPAIF_I2SCTL_RESET_STATE) {
|
||||
dev_err(dai->dev, "error in i2sctl register state\n");
|
||||
return -ENOTRECOVERABLE;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
|
|
@ -308,11 +298,14 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
|
|||
dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
|
||||
ret);
|
||||
|
||||
ret = clk_enable(drvdata->mi2s_bit_clk[id]);
|
||||
if (ret) {
|
||||
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
|
||||
clk_disable(drvdata->mi2s_osr_clk[id]);
|
||||
return ret;
|
||||
if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_DISABLE) {
|
||||
ret = clk_enable(drvdata->mi2s_bit_clk[id]);
|
||||
if (ret) {
|
||||
dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
|
||||
clk_disable(drvdata->mi2s_osr_clk[id]);
|
||||
return ret;
|
||||
}
|
||||
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_ENABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -329,7 +322,10 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
|
|||
if (ret)
|
||||
dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
|
||||
ret);
|
||||
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
|
||||
if (drvdata->bit_clk_state[id] == LPAIF_BIT_CLK_ENABLE) {
|
||||
clk_disable(drvdata->mi2s_bit_clk[dai->driver->id]);
|
||||
drvdata->bit_clk_state[id] = LPAIF_BIT_CLK_DISABLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -341,7 +337,6 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops = {
|
|||
.startup = lpass_cpu_daiops_startup,
|
||||
.shutdown = lpass_cpu_daiops_shutdown,
|
||||
.hw_params = lpass_cpu_daiops_hw_params,
|
||||
.prepare = lpass_cpu_daiops_prepare,
|
||||
.trigger = lpass_cpu_daiops_trigger,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops);
|
||||
|
|
@ -459,16 +454,20 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
|
|||
struct lpass_variant *v = drvdata->variant;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < v->i2s_ports; ++i)
|
||||
if (reg == LPAIF_I2SCTL_REG(v, i))
|
||||
return true;
|
||||
for (i = 0; i < v->irq_ports; ++i)
|
||||
if (reg == LPAIF_IRQSTAT_REG(v, i))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < v->rdma_channels; ++i)
|
||||
if (reg == LPAIF_RDMACURR_REG(v, i))
|
||||
if (reg == LPAIF_RDMACURR_REG(v, i) || reg == LPAIF_RDMACTL_REG(v, i))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < v->wrdma_channels; ++i)
|
||||
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start))
|
||||
if (reg == LPAIF_WRDMACURR_REG(v, i + v->wrdma_channel_start) ||
|
||||
reg == LPAIF_WRDMACTL_REG(v, i + v->wrdma_channel_start))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -861,6 +860,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
|
|||
PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
|
||||
return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
|
||||
}
|
||||
drvdata->bit_clk_state[dai_id] = LPAIF_BIT_CLK_DISABLE;
|
||||
}
|
||||
|
||||
/* Allocation for i2sctl regmap fields */
|
||||
|
|
|
|||
|
|
@ -60,6 +60,13 @@
|
|||
#define LPAIF_I2SCTL_BITWIDTH_24 1
|
||||
#define LPAIF_I2SCTL_BITWIDTH_32 2
|
||||
|
||||
#define LPAIF_BIT_CLK_DISABLE 0
|
||||
#define LPAIF_BIT_CLK_ENABLE 1
|
||||
|
||||
#define LPAIF_I2SCTL_RESET_STATE 0x003C0004
|
||||
#define LPAIF_DMACTL_RESET_STATE 0x00200000
|
||||
|
||||
|
||||
/* LPAIF IRQ */
|
||||
#define LPAIF_IRQ_REG_ADDR(v, addr, port) \
|
||||
(v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,
|
|||
struct regmap *map;
|
||||
unsigned int dai_id = cpu_dai->driver->id;
|
||||
|
||||
component->id = dai_id;
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
|
@ -451,19 +452,34 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
|
|||
unsigned int reg_irqclr = 0, val_irqclr = 0;
|
||||
unsigned int reg_irqen = 0, val_irqen = 0, val_mask = 0;
|
||||
unsigned int dai_id = cpu_dai->driver->id;
|
||||
unsigned int dma_ctrl_reg = 0;
|
||||
|
||||
ch = pcm_data->dma_ch;
|
||||
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
id = pcm_data->dma_ch;
|
||||
if (dai_id == LPASS_DP_RX)
|
||||
if (dai_id == LPASS_DP_RX) {
|
||||
dmactl = drvdata->hdmi_rd_dmactl;
|
||||
else
|
||||
map = drvdata->hdmiif_map;
|
||||
} else {
|
||||
dmactl = drvdata->rd_dmactl;
|
||||
map = drvdata->lpaif_map;
|
||||
}
|
||||
} else {
|
||||
dmactl = drvdata->wr_dmactl;
|
||||
id = pcm_data->dma_ch - v->wrdma_channel_start;
|
||||
map = drvdata->lpaif_map;
|
||||
}
|
||||
ret = regmap_read(map, LPAIF_DMACTL_REG(v, ch, dir, dai_id), &dma_ctrl_reg);
|
||||
if (ret) {
|
||||
dev_err(soc_runtime->dev, "error reading from rdmactl reg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE ||
|
||||
dma_ctrl_reg == LPAIF_DMACTL_RESET_STATE + 1) {
|
||||
dev_err(soc_runtime->dev, "error in rdmactl register state\n");
|
||||
return -ENOTRECOVERABLE;
|
||||
}
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ struct lpass_data {
|
|||
unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
|
||||
unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
|
||||
int hdmi_port_enable;
|
||||
int bit_clk_state[LPASS_MAX_MI2S_PORTS];
|
||||
|
||||
/* low-power audio interface (LPAIF) registers */
|
||||
void __iomem *lpaif;
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ static int snd_us16x08_eq_put(struct snd_kcontrol *kcontrol,
|
|||
static int snd_us16x08_meter_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
uinfo->count = 1;
|
||||
uinfo->count = 34;
|
||||
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
||||
uinfo->value.integer.max = 0x7FFF;
|
||||
uinfo->value.integer.min = 0;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <endian.h>
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bootconfig.h>
|
||||
|
|
@ -183,9 +184,11 @@ static int load_xbc_from_initrd(int fd, char **buf)
|
|||
|
||||
if (read(fd, &size, sizeof(u32)) < 0)
|
||||
return pr_errno("Failed to read size", -errno);
|
||||
size = le32toh(size);
|
||||
|
||||
if (read(fd, &csum, sizeof(u32)) < 0)
|
||||
return pr_errno("Failed to read checksum", -errno);
|
||||
csum = le32toh(csum);
|
||||
|
||||
/* Wrong size error */
|
||||
if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
|
||||
|
|
@ -407,10 +410,10 @@ static int apply_xbc(const char *path, const char *xbc_path)
|
|||
|
||||
/* Add a footer */
|
||||
p = data + size;
|
||||
*(u32 *)p = size;
|
||||
*(u32 *)p = htole32(size);
|
||||
p += sizeof(u32);
|
||||
|
||||
*(u32 *)p = csum;
|
||||
*(u32 *)p = htole32(csum);
|
||||
p += sizeof(u32);
|
||||
|
||||
memcpy(p, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user