Merge linux 6.6.31
Conflicts: drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
This commit is contained in:
commit
c2e704ebf0
|
@ -42,7 +42,7 @@ allOf:
|
|||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: maxim,max30100
|
||||
const: maxim,max30102
|
||||
then:
|
||||
properties:
|
||||
maxim,green-led-current-microamp: false
|
||||
|
|
|
@ -337,8 +337,8 @@ allOf:
|
|||
minItems: 4
|
||||
|
||||
clocks:
|
||||
minItems: 34
|
||||
maxItems: 34
|
||||
minItems: 24
|
||||
maxItems: 24
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
|
@ -351,18 +351,6 @@ allOf:
|
|||
- const: ethwarp_wocpu1
|
||||
- const: ethwarp_wocpu0
|
||||
- const: esw
|
||||
- const: netsys0
|
||||
- const: netsys1
|
||||
- const: sgmii_tx250m
|
||||
- const: sgmii_rx250m
|
||||
- const: sgmii2_tx250m
|
||||
- const: sgmii2_rx250m
|
||||
- const: top_usxgmii0_sel
|
||||
- const: top_usxgmii1_sel
|
||||
- const: top_sgm0_sel
|
||||
- const: top_sgm1_sel
|
||||
- const: top_xfi_phy0_xtal_sel
|
||||
- const: top_xfi_phy1_xtal_sel
|
||||
- const: top_eth_gmii_sel
|
||||
- const: top_eth_refck_50m_sel
|
||||
- const: top_eth_sys_200m_sel
|
||||
|
@ -375,16 +363,10 @@ allOf:
|
|||
- const: top_netsys_sync_250m_sel
|
||||
- const: top_netsys_ppefb_250m_sel
|
||||
- const: top_netsys_warp_sel
|
||||
- const: wocpu1
|
||||
- const: wocpu0
|
||||
- const: xgp1
|
||||
- const: xgp2
|
||||
- const: xgp3
|
||||
|
||||
mediatek,sgmiisys:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^mac@[0-1]$":
|
||||
type: object
|
||||
|
|
2
Makefile
2
Makefile
|
@ -8,7 +8,7 @@ else
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 30
|
||||
SUBLEVEL = 31
|
||||
EXTRAVERSION =
|
||||
NAME = Hurr durr I'ma ninja sloth
|
||||
|
||||
|
|
|
@ -127,6 +127,10 @@ cpu_resume_after_mmu:
|
|||
instr_sync
|
||||
#endif
|
||||
bl cpu_init @ restore the und/abt/irq banked regs
|
||||
#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
|
||||
mov r0, sp
|
||||
bl kasan_unpoison_task_stack_below
|
||||
#endif
|
||||
mov r0, #0 @ return zero on success
|
||||
ldmfd sp!, {r4 - r11, pc}
|
||||
ENDPROC(cpu_resume_after_mmu)
|
||||
|
|
|
@ -367,6 +367,16 @@
|
|||
};
|
||||
};
|
||||
|
||||
&pmm8155au_1_gpios {
|
||||
pmm8155au_1_sdc2_cd: sdc2-cd-default-state {
|
||||
pins = "gpio4";
|
||||
function = "normal";
|
||||
input-enable;
|
||||
bias-pull-up;
|
||||
power-source = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&qupv3_id_1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -384,10 +394,10 @@
|
|||
&sdhc_2 {
|
||||
status = "okay";
|
||||
|
||||
cd-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
|
||||
cd-gpios = <&pmm8155au_1_gpios 4 GPIO_ACTIVE_LOW>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&sdc2_on>;
|
||||
pinctrl-1 = <&sdc2_off>;
|
||||
pinctrl-0 = <&sdc2_on &pmm8155au_1_sdc2_cd>;
|
||||
pinctrl-1 = <&sdc2_off &pmm8155au_1_sdc2_cd>;
|
||||
vqmmc-supply = <&vreg_l13c_2p96>; /* IO line power */
|
||||
vmmc-supply = <&vreg_l17a_2p96>; /* Card power line */
|
||||
bus-width = <4>;
|
||||
|
@ -505,13 +515,6 @@
|
|||
bias-pull-up; /* pull up */
|
||||
drive-strength = <16>; /* 16 MA */
|
||||
};
|
||||
|
||||
sd-cd-pins {
|
||||
pins = "gpio96";
|
||||
function = "gpio";
|
||||
bias-pull-up; /* pull up */
|
||||
drive-strength = <2>; /* 2 MA */
|
||||
};
|
||||
};
|
||||
|
||||
sdc2_off: sdc2-off-state {
|
||||
|
@ -532,13 +535,6 @@
|
|||
bias-pull-up; /* pull up */
|
||||
drive-strength = <2>; /* 2 MA */
|
||||
};
|
||||
|
||||
sd-cd-pins {
|
||||
pins = "gpio96";
|
||||
function = "gpio";
|
||||
bias-pull-up; /* pull up */
|
||||
drive-strength = <2>; /* 2 MA */
|
||||
};
|
||||
};
|
||||
|
||||
usb2phy_ac_en1_default: usb2phy-ac-en1-default-state {
|
||||
|
|
|
@ -337,16 +337,12 @@ int kvm_register_vgic_device(unsigned long type)
|
|||
int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
|
||||
struct vgic_reg_attr *reg_attr)
|
||||
{
|
||||
int cpuid;
|
||||
int cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);
|
||||
|
||||
cpuid = (attr->attr & KVM_DEV_ARM_VGIC_CPUID_MASK) >>
|
||||
KVM_DEV_ARM_VGIC_CPUID_SHIFT;
|
||||
|
||||
if (cpuid >= atomic_read(&dev->kvm->online_vcpus))
|
||||
return -EINVAL;
|
||||
|
||||
reg_attr->vcpu = kvm_get_vcpu(dev->kvm, cpuid);
|
||||
reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
|
||||
reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);
|
||||
if (!reg_attr->vcpu)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1738,15 +1738,15 @@ static void invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
|
|||
|
||||
emit_call(enter_prog, ctx);
|
||||
|
||||
/* save return value to callee saved register x20 */
|
||||
emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
|
||||
|
||||
/* if (__bpf_prog_enter(prog) == 0)
|
||||
* goto skip_exec_of_prog;
|
||||
*/
|
||||
branch = ctx->image + ctx->idx;
|
||||
emit(A64_NOP, ctx);
|
||||
|
||||
/* save return value to callee saved register x20 */
|
||||
emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
|
||||
|
||||
emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx);
|
||||
if (!p->jited)
|
||||
emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx);
|
||||
|
|
|
@ -159,7 +159,7 @@ extern unsigned long exception_ip(struct pt_regs *regs);
|
|||
#define exception_ip(regs) exception_ip(regs)
|
||||
#define profile_pc(regs) instruction_pointer(regs)
|
||||
|
||||
extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall);
|
||||
extern asmlinkage long syscall_trace_enter(struct pt_regs *regs);
|
||||
extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
|
||||
|
||||
extern void die(const char *, struct pt_regs *) __noreturn;
|
||||
|
|
|
@ -101,6 +101,7 @@ void output_thread_info_defines(void)
|
|||
OFFSET(TI_CPU, thread_info, cpu);
|
||||
OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
|
||||
OFFSET(TI_REGS, thread_info, regs);
|
||||
OFFSET(TI_SYSCALL, thread_info, syscall);
|
||||
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
||||
DEFINE(_THREAD_MASK, THREAD_MASK);
|
||||
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
|
||||
|
|
|
@ -1317,16 +1317,13 @@ long arch_ptrace(struct task_struct *child, long request,
|
|||
* Notification of system call entry/exit
|
||||
* - triggered by current->work.syscall_trace
|
||||
*/
|
||||
asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
|
||||
asmlinkage long syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
user_exit();
|
||||
|
||||
current_thread_info()->syscall = syscall;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE)) {
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
return -1;
|
||||
syscall = current_thread_info()->syscall;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECCOMP
|
||||
|
@ -1335,7 +1332,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
|
|||
struct seccomp_data sd;
|
||||
unsigned long args[6];
|
||||
|
||||
sd.nr = syscall;
|
||||
sd.nr = current_thread_info()->syscall;
|
||||
sd.arch = syscall_get_arch(current);
|
||||
syscall_get_arguments(current, regs, args);
|
||||
for (i = 0; i < 6; i++)
|
||||
|
@ -1345,23 +1342,23 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
|
|||
ret = __secure_computing(&sd);
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
syscall = current_thread_info()->syscall;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
trace_sys_enter(regs, regs->regs[2]);
|
||||
|
||||
audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
|
||||
audit_syscall_entry(current_thread_info()->syscall,
|
||||
regs->regs[4], regs->regs[5],
|
||||
regs->regs[6], regs->regs[7]);
|
||||
|
||||
/*
|
||||
* Negative syscall numbers are mistaken for rejected syscalls, but
|
||||
* won't have had the return value set appropriately, so we do so now.
|
||||
*/
|
||||
if (syscall < 0)
|
||||
if (current_thread_info()->syscall < 0)
|
||||
syscall_set_return_value(current, regs, -ENOSYS, 0);
|
||||
return syscall;
|
||||
return current_thread_info()->syscall;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -77,6 +77,18 @@ loads_done:
|
|||
PTR_WD load_a7, bad_stack_a7
|
||||
.previous
|
||||
|
||||
/*
|
||||
* syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
*/
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number
|
||||
b 2f
|
||||
1:
|
||||
LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number
|
||||
2:
|
||||
|
||||
lw t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
and t0, t1
|
||||
|
@ -114,16 +126,7 @@ syscall_trace_entry:
|
|||
SAVE_STATIC
|
||||
move a0, sp
|
||||
|
||||
/*
|
||||
* syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
*/
|
||||
move a1, v0
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
lw a1, PT_R4(sp)
|
||||
|
||||
1: jal syscall_trace_enter
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ NESTED(handle_sysn32, PT_SIZE, sp)
|
|||
|
||||
sd a3, PT_R26(sp) # save a3 for syscall restarting
|
||||
|
||||
LONG_S v0, TI_SYSCALL($28) # Store syscall number
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
and t0, t1, t0
|
||||
|
@ -72,7 +74,6 @@ syscall_common:
|
|||
n32_syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move a0, sp
|
||||
move a1, v0
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
|
|
@ -46,6 +46,8 @@ NESTED(handle_sys64, PT_SIZE, sp)
|
|||
|
||||
sd a3, PT_R26(sp) # save a3 for syscall restarting
|
||||
|
||||
LONG_S v0, TI_SYSCALL($28) # Store syscall number
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
and t0, t1, t0
|
||||
|
@ -82,7 +84,6 @@ n64_syscall_exit:
|
|||
syscall_trace_entry:
|
||||
SAVE_STATIC
|
||||
move a0, sp
|
||||
move a1, v0
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
|
|
@ -79,6 +79,22 @@ loads_done:
|
|||
PTR_WD load_a7, bad_stack_a7
|
||||
.previous
|
||||
|
||||
/*
|
||||
* absolute syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
* note: NR_syscall is the first O32 syscall but the macro is
|
||||
* only defined when compiling with -mabi=32 (CONFIG_32BIT)
|
||||
* therefore __NR_O32_Linux is used (4000)
|
||||
*/
|
||||
|
||||
subu t2, v0, __NR_O32_Linux
|
||||
bnez t2, 1f /* __NR_syscall at offset 0 */
|
||||
LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number
|
||||
b 2f
|
||||
1:
|
||||
LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number
|
||||
2:
|
||||
|
||||
li t1, _TIF_WORK_SYSCALL_ENTRY
|
||||
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
|
||||
and t0, t1, t0
|
||||
|
@ -113,22 +129,7 @@ trace_a_syscall:
|
|||
sd a7, PT_R11(sp) # For indirect syscalls
|
||||
|
||||
move a0, sp
|
||||
/*
|
||||
* absolute syscall number is in v0 unless we called syscall(__NR_###)
|
||||
* where the real syscall number is in a0
|
||||
* note: NR_syscall is the first O32 syscall but the macro is
|
||||
* only defined when compiling with -mabi=32 (CONFIG_32BIT)
|
||||
* therefore __NR_O32_Linux is used (4000)
|
||||
*/
|
||||
.set push
|
||||
.set reorder
|
||||
subu t1, v0, __NR_O32_Linux
|
||||
move a1, v0
|
||||
bnez t1, 1f /* __NR_syscall at offset 0 */
|
||||
ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
|
||||
.set pop
|
||||
|
||||
1: jal syscall_trace_enter
|
||||
jal syscall_trace_enter
|
||||
|
||||
bltz v0, 1f # seccomp failed? Skip syscall
|
||||
|
||||
|
|
|
@ -197,6 +197,9 @@ static struct skcipher_alg algs[] = {
|
|||
|
||||
static int __init chacha_p10_init(void)
|
||||
{
|
||||
if (!cpu_has_feature(CPU_FTR_ARCH_31))
|
||||
return 0;
|
||||
|
||||
static_branch_enable(&have_p10);
|
||||
|
||||
return crypto_register_skciphers(algs, ARRAY_SIZE(algs));
|
||||
|
@ -204,10 +207,13 @@ static int __init chacha_p10_init(void)
|
|||
|
||||
static void __exit chacha_p10_exit(void)
|
||||
{
|
||||
if (!static_branch_likely(&have_p10))
|
||||
return;
|
||||
|
||||
crypto_unregister_skciphers(algs, ARRAY_SIZE(algs));
|
||||
}
|
||||
|
||||
module_cpu_feature_match(PPC_MODULE_FEATURE_P10, chacha_p10_init);
|
||||
module_init(chacha_p10_init);
|
||||
module_exit(chacha_p10_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (P10 accelerated)");
|
||||
|
|
|
@ -44,9 +44,8 @@
|
|||
#define PLPKS_MAX_DATA_SIZE 4000
|
||||
|
||||
// Timeouts for PLPKS operations
|
||||
#define PLPKS_MAX_TIMEOUT 5000 // msec
|
||||
#define PLPKS_FLUSH_SLEEP 10 // msec
|
||||
#define PLPKS_FLUSH_SLEEP_RANGE 400
|
||||
#define PLPKS_MAX_TIMEOUT (5 * USEC_PER_SEC)
|
||||
#define PLPKS_FLUSH_SLEEP 10000 // usec
|
||||
|
||||
struct plpks_var {
|
||||
char *component;
|
||||
|
|
|
@ -786,8 +786,16 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
|
|||
* parent bus. During reboot, there will be ibm,dma-window property to
|
||||
* define DMA window. For kdump, there will at least be default window or DDW
|
||||
* or both.
|
||||
* There is an exception to the above. In case the PE goes into frozen
|
||||
* state, firmware may not provide ibm,dma-window property at the time
|
||||
* of LPAR boot up.
|
||||
*/
|
||||
|
||||
if (!pdn) {
|
||||
pr_debug(" no ibm,dma-window property !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ppci = PCI_DN(pdn);
|
||||
|
||||
pr_debug(" parent is %pOF, iommu_table: 0x%p\n",
|
||||
|
|
|
@ -415,8 +415,7 @@ static int plpks_confirm_object_flushed(struct label *label,
|
|||
break;
|
||||
}
|
||||
|
||||
usleep_range(PLPKS_FLUSH_SLEEP,
|
||||
PLPKS_FLUSH_SLEEP + PLPKS_FLUSH_SLEEP_RANGE);
|
||||
fsleep(PLPKS_FLUSH_SLEEP);
|
||||
timeout = timeout + PLPKS_FLUSH_SLEEP;
|
||||
} while (timeout < PLPKS_MAX_TIMEOUT);
|
||||
|
||||
|
@ -464,9 +463,10 @@ int plpks_signed_update_var(struct plpks_var *var, u64 flags)
|
|||
|
||||
continuetoken = retbuf[0];
|
||||
if (pseries_status_to_err(rc) == -EBUSY) {
|
||||
int delay_ms = get_longbusy_msecs(rc);
|
||||
mdelay(delay_ms);
|
||||
timeout += delay_ms;
|
||||
int delay_us = get_longbusy_msecs(rc) * 1000;
|
||||
|
||||
fsleep(delay_us);
|
||||
timeout += delay_us;
|
||||
}
|
||||
rc = pseries_status_to_err(rc);
|
||||
} while (rc == -EBUSY && timeout < PLPKS_MAX_TIMEOUT);
|
||||
|
|
|
@ -740,6 +740,9 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* store prog start time */
|
||||
emit_mv(RV_REG_S1, RV_REG_A0, ctx);
|
||||
|
||||
/* if (__bpf_prog_enter(prog) == 0)
|
||||
* goto skip_exec_of_prog;
|
||||
*/
|
||||
|
@ -747,9 +750,6 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
|
|||
/* nop reserved for conditional jump */
|
||||
emit(rv_nop(), ctx);
|
||||
|
||||
/* store prog start time */
|
||||
emit_mv(RV_REG_S1, RV_REG_A0, ctx);
|
||||
|
||||
/* arg1: &args_off */
|
||||
emit_addi(RV_REG_A0, RV_REG_FP, -args_off, ctx);
|
||||
if (!p->jited)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define CFI_DEF_CFA_OFFSET .cfi_def_cfa_offset
|
||||
#define CFI_ADJUST_CFA_OFFSET .cfi_adjust_cfa_offset
|
||||
#define CFI_RESTORE .cfi_restore
|
||||
#define CFI_REL_OFFSET .cfi_rel_offset
|
||||
|
||||
#ifdef CONFIG_AS_CFI_VAL_OFFSET
|
||||
#define CFI_VAL_OFFSET .cfi_val_offset
|
||||
|
|
|
@ -24,8 +24,10 @@ __kernel_\func:
|
|||
CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE)
|
||||
CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
|
||||
stg %r14,STACK_FRAME_OVERHEAD(%r15)
|
||||
CFI_REL_OFFSET 14, STACK_FRAME_OVERHEAD
|
||||
brasl %r14,__s390_vdso_\func
|
||||
lg %r14,STACK_FRAME_OVERHEAD(%r15)
|
||||
CFI_RESTORE 14
|
||||
aghi %r15,WRAPPER_FRAME_SIZE
|
||||
CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
|
||||
CFI_RESTORE 15
|
||||
|
|
|
@ -2659,7 +2659,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
|
|||
return 0;
|
||||
|
||||
start = pmd_val(*pmd) & HPAGE_MASK;
|
||||
end = start + HPAGE_SIZE - 1;
|
||||
end = start + HPAGE_SIZE;
|
||||
__storage_key_init_range(start, end);
|
||||
set_bit(PG_arch_1, &page->flags);
|
||||
cond_resched();
|
||||
|
|
|
@ -139,7 +139,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
|
|||
}
|
||||
|
||||
if (!test_and_set_bit(PG_arch_1, &page->flags))
|
||||
__storage_key_init_range(paddr, paddr + size - 1);
|
||||
__storage_key_init_range(paddr, paddr + size);
|
||||
}
|
||||
|
||||
void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
|
|
|
@ -1808,7 +1808,7 @@ void x2apic_setup(void)
|
|||
__x2apic_enable();
|
||||
}
|
||||
|
||||
static __init void apic_set_fixmap(void);
|
||||
static __init void apic_set_fixmap(bool read_apic);
|
||||
|
||||
static __init void x2apic_disable(void)
|
||||
{
|
||||
|
@ -1830,7 +1830,12 @@ static __init void x2apic_disable(void)
|
|||
}
|
||||
|
||||
__x2apic_disable();
|
||||
apic_set_fixmap();
|
||||
/*
|
||||
* Don't reread the APIC ID as it was already done from
|
||||
* check_x2apic() and the APIC driver still is a x2APIC variant,
|
||||
* which fails to do the read after x2APIC was disabled.
|
||||
*/
|
||||
apic_set_fixmap(false);
|
||||
}
|
||||
|
||||
static __init void x2apic_enable(void)
|
||||
|
@ -2095,13 +2100,14 @@ void __init init_apic_mappings(void)
|
|||
}
|
||||
}
|
||||
|
||||
static __init void apic_set_fixmap(void)
|
||||
static __init void apic_set_fixmap(bool read_apic)
|
||||
{
|
||||
set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
|
||||
apic_mmio_base = APIC_BASE;
|
||||
apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
|
||||
apic_mmio_base, mp_lapic_addr);
|
||||
apic_read_boot_cpu_id(false);
|
||||
if (read_apic)
|
||||
apic_read_boot_cpu_id(false);
|
||||
}
|
||||
|
||||
void __init register_lapic_address(unsigned long address)
|
||||
|
@ -2111,7 +2117,7 @@ void __init register_lapic_address(unsigned long address)
|
|||
mp_lapic_addr = address;
|
||||
|
||||
if (!x2apic_mode)
|
||||
apic_set_fixmap();
|
||||
apic_set_fixmap(true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -115,9 +115,9 @@
|
|||
#define MAKE_RA_FOR_CALL(ra,ws) (((ra) & 0x3fffffff) | (ws) << 30)
|
||||
|
||||
/* Convert return address to a valid pc
|
||||
* Note: We assume that the stack pointer is in the same 1GB ranges as the ra
|
||||
* Note: 'text' is the address within the same 1GB range as the ra
|
||||
*/
|
||||
#define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
|
||||
#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000))
|
||||
|
||||
#elif defined(__XTENSA_CALL0_ABI__)
|
||||
|
||||
|
@ -127,9 +127,9 @@
|
|||
#define MAKE_RA_FOR_CALL(ra, ws) (ra)
|
||||
|
||||
/* Convert return address to a valid pc
|
||||
* Note: We assume that the stack pointer is in the same 1GB ranges as the ra
|
||||
* Note: 'text' is not used as 'ra' is always the full address
|
||||
*/
|
||||
#define MAKE_PC_FROM_RA(ra, sp) (ra)
|
||||
#define MAKE_PC_FROM_RA(ra, text) (ra)
|
||||
|
||||
#else
|
||||
#error Unsupported Xtensa ABI
|
||||
|
|
|
@ -87,7 +87,7 @@ struct pt_regs {
|
|||
# define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
|
||||
# define instruction_pointer(regs) ((regs)->pc)
|
||||
# define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
|
||||
(regs)->areg[1]))
|
||||
(regs)->pc))
|
||||
|
||||
# ifndef CONFIG_SMP
|
||||
# define profile_pc(regs) instruction_pointer(regs)
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/regs.h>
|
||||
#include <asm/hw_breakpoint.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
extern void ret_from_fork(void);
|
||||
|
@ -380,7 +381,7 @@ unsigned long __get_wchan(struct task_struct *p)
|
|||
int count = 0;
|
||||
|
||||
sp = p->thread.sp;
|
||||
pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
|
||||
pc = MAKE_PC_FROM_RA(p->thread.ra, _text);
|
||||
|
||||
do {
|
||||
if (sp < stack_page + sizeof(struct task_struct) ||
|
||||
|
@ -392,7 +393,7 @@ unsigned long __get_wchan(struct task_struct *p)
|
|||
|
||||
/* Stack layout: sp-4: ra, sp-3: sp' */
|
||||
|
||||
pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp);
|
||||
pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text);
|
||||
sp = SPILL_SLOT(sp, 1);
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/stacktrace.h>
|
||||
|
||||
#include <asm/ftrace.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/stacktrace.h>
|
||||
#include <asm/traps.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -189,7 +190,7 @@ void walk_stackframe(unsigned long *sp,
|
|||
if (a1 <= (unsigned long)sp)
|
||||
break;
|
||||
|
||||
frame.pc = MAKE_PC_FROM_RA(a0, a1);
|
||||
frame.pc = MAKE_PC_FROM_RA(a0, _text);
|
||||
frame.sp = a1;
|
||||
|
||||
if (fn(&frame, data))
|
||||
|
|
|
@ -1347,7 +1347,7 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now)
|
|||
{
|
||||
struct ioc *ioc = iocg->ioc;
|
||||
struct blkcg_gq *blkg = iocg_to_blkg(iocg);
|
||||
u64 tdelta, delay, new_delay;
|
||||
u64 tdelta, delay, new_delay, shift;
|
||||
s64 vover, vover_pct;
|
||||
u32 hwa;
|
||||
|
||||
|
@ -1362,8 +1362,9 @@ static bool iocg_kick_delay(struct ioc_gq *iocg, struct ioc_now *now)
|
|||
|
||||
/* calculate the current delay in effect - 1/2 every second */
|
||||
tdelta = now->now - iocg->delay_at;
|
||||
if (iocg->delay)
|
||||
delay = iocg->delay >> div64_u64(tdelta, USEC_PER_SEC);
|
||||
shift = div64_u64(tdelta, USEC_PER_SEC);
|
||||
if (iocg->delay && shift < BITS_PER_LONG)
|
||||
delay = iocg->delay >> shift;
|
||||
else
|
||||
delay = 0;
|
||||
|
||||
|
@ -1438,8 +1439,11 @@ static void iocg_pay_debt(struct ioc_gq *iocg, u64 abs_vpay,
|
|||
lockdep_assert_held(&iocg->ioc->lock);
|
||||
lockdep_assert_held(&iocg->waitq.lock);
|
||||
|
||||
/* make sure that nobody messed with @iocg */
|
||||
WARN_ON_ONCE(list_empty(&iocg->active_list));
|
||||
/*
|
||||
* make sure that nobody messed with @iocg. Check iocg->pd.online
|
||||
* to avoid warn when removing blkcg or disk.
|
||||
*/
|
||||
WARN_ON_ONCE(list_empty(&iocg->active_list) && iocg->pd.online);
|
||||
WARN_ON_ONCE(iocg->inuse > 1);
|
||||
|
||||
iocg->abs_vdebt -= min(abs_vpay, iocg->abs_vdebt);
|
||||
|
|
|
@ -89,7 +89,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
|
|||
unsigned long arg)
|
||||
{
|
||||
uint64_t range[2];
|
||||
uint64_t start, len;
|
||||
uint64_t start, len, end;
|
||||
struct inode *inode = bdev->bd_inode;
|
||||
int err;
|
||||
|
||||
|
@ -110,7 +110,8 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
|
|||
if (len & 511)
|
||||
return -EINVAL;
|
||||
|
||||
if (start + len > bdev_nr_bytes(bdev))
|
||||
if (check_add_overflow(start, len, &end) ||
|
||||
end > bdev_nr_bytes(bdev))
|
||||
return -EINVAL;
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
|
|
@ -200,7 +200,10 @@ int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge)
|
|||
pclk = sg->sata0_pclk;
|
||||
else
|
||||
pclk = sg->sata1_pclk;
|
||||
clk_enable(pclk);
|
||||
ret = clk_enable(pclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
msleep(10);
|
||||
|
||||
/* Do not keep clocking a bridge that is not online */
|
||||
|
|
|
@ -2836,6 +2836,43 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_read);
|
||||
|
||||
/**
|
||||
* regmap_read_bypassed() - Read a value from a single register direct
|
||||
* from the device, bypassing the cache
|
||||
*
|
||||
* @map: Register map to read from
|
||||
* @reg: Register to be read from
|
||||
* @val: Pointer to store read value
|
||||
*
|
||||
* A value of zero will be returned on success, a negative errno will
|
||||
* be returned in error cases.
|
||||
*/
|
||||
int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
int ret;
|
||||
bool bypass, cache_only;
|
||||
|
||||
if (!IS_ALIGNED(reg, map->reg_stride))
|
||||
return -EINVAL;
|
||||
|
||||
map->lock(map->lock_arg);
|
||||
|
||||
bypass = map->cache_bypass;
|
||||
cache_only = map->cache_only;
|
||||
map->cache_bypass = true;
|
||||
map->cache_only = false;
|
||||
|
||||
ret = _regmap_read(map, reg, val);
|
||||
|
||||
map->cache_bypass = bypass;
|
||||
map->cache_only = cache_only;
|
||||
|
||||
map->unlock(map->lock_arg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(regmap_read_bypassed);
|
||||
|
||||
/**
|
||||
* regmap_raw_read() - Read raw data from the device
|
||||
*
|
||||
|
|
|
@ -99,7 +99,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
struct edl_event_hdr *edl;
|
||||
char cmd, build_label[QCA_FW_BUILD_VER_LEN];
|
||||
char *build_label;
|
||||
char cmd;
|
||||
int build_lbl_len, err = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "QCA read fw build info");
|
||||
|
@ -114,6 +115,11 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
if (skb->len < sizeof(*edl)) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
edl = (struct edl_event_hdr *)(skb->data);
|
||||
if (!edl) {
|
||||
bt_dev_err(hdev, "QCA read fw build info with no header");
|
||||
|
@ -129,14 +135,25 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
build_lbl_len = edl->data[0];
|
||||
if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) {
|
||||
memcpy(build_label, edl->data + 1, build_lbl_len);
|
||||
*(build_label + build_lbl_len) = '\0';
|
||||
if (skb->len < sizeof(*edl) + 1) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
build_lbl_len = edl->data[0];
|
||||
|
||||
if (skb->len < sizeof(*edl) + 1 + build_lbl_len) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL);
|
||||
if (!build_label)
|
||||
goto out;
|
||||
|
||||
hci_set_fw_info(hdev, "%s", build_label);
|
||||
|
||||
kfree(build_label);
|
||||
out:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
|
@ -205,6 +222,49 @@ static int qca_send_reset(struct hci_dev *hdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int qca_read_fw_board_id(struct hci_dev *hdev, u16 *bid)
|
||||
{
|
||||
u8 cmd;
|
||||
struct sk_buff *skb;
|
||||
struct edl_event_hdr *edl;
|
||||
int err = 0;
|
||||
|
||||
cmd = EDL_GET_BID_REQ_CMD;
|
||||
skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,
|
||||
&cmd, 0, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Reading QCA board ID failed (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
edl = skb_pull_data(skb, sizeof(*edl));
|
||||
if (!edl) {
|
||||
bt_dev_err(hdev, "QCA read board ID with no header");
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
|
||||
edl->rtype != EDL_GET_BID_REQ_CMD) {
|
||||
bt_dev_err(hdev, "QCA Wrong packet: %d %d", edl->cresp, edl->rtype);
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (skb->len < 3) {
|
||||
err = -EILSEQ;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*bid = (edl->data[1] << 8) + edl->data[2];
|
||||
bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);
|
||||
|
||||
out:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
@ -227,9 +287,10 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
|
||||
|
||||
static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
static int qca_tlv_check_data(struct hci_dev *hdev,
|
||||
struct qca_fw_config *config,
|
||||
u8 *fw_data, enum qca_btsoc_type soc_type)
|
||||
u8 *fw_data, size_t fw_size,
|
||||
enum qca_btsoc_type soc_type)
|
||||
{
|
||||
const u8 *data;
|
||||
u32 type_len;
|
||||
|
@ -239,12 +300,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
|||
struct tlv_type_patch *tlv_patch;
|
||||
struct tlv_type_nvm *tlv_nvm;
|
||||
uint8_t nvm_baud_rate = config->user_baud_rate;
|
||||
u8 type;
|
||||
|
||||
config->dnld_mode = QCA_SKIP_EVT_NONE;
|
||||
config->dnld_type = QCA_SKIP_EVT_NONE;
|
||||
|
||||
switch (config->type) {
|
||||
case ELF_TYPE_PATCH:
|
||||
if (fw_size < 7)
|
||||
return -EINVAL;
|
||||
|
||||
config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
|
||||
config->dnld_type = QCA_SKIP_EVT_VSE_CC;
|
||||
|
||||
|
@ -253,6 +318,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
|||
bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]);
|
||||
break;
|
||||
case TLV_TYPE_PATCH:
|
||||
if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch))
|
||||
return -EINVAL;
|
||||
|
||||
tlv = (struct tlv_type_hdr *)fw_data;
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
tlv_patch = (struct tlv_type_patch *)tlv->data;
|
||||
|
@ -292,25 +360,64 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
|||
break;
|
||||
|
||||
case TLV_TYPE_NVM:
|
||||
if (fw_size < sizeof(struct tlv_type_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
tlv = (struct tlv_type_hdr *)fw_data;
|
||||
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
length = (type_len >> 8) & 0x00ffffff;
|
||||
length = type_len >> 8;
|
||||
type = type_len & 0xff;
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
|
||||
/* Some NVM files have more than one set of tags, only parse
|
||||
* the first set when it has type 2 for now. When there is
|
||||
* more than one set there is an enclosing header of type 4.
|
||||
*/
|
||||
if (type == 4) {
|
||||
if (fw_size < 2 * sizeof(struct tlv_type_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
tlv++;
|
||||
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
length = type_len >> 8;
|
||||
type = type_len & 0xff;
|
||||
}
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type);
|
||||
BT_DBG("Length\t\t : %d bytes", length);
|
||||
|
||||
if (type != 2)
|
||||
break;
|
||||
|
||||
if (fw_size < length + (tlv->data - fw_data))
|
||||
return -EINVAL;
|
||||
|
||||
idx = 0;
|
||||
data = tlv->data;
|
||||
while (idx < length) {
|
||||
while (idx < length - sizeof(struct tlv_type_nvm)) {
|
||||
tlv_nvm = (struct tlv_type_nvm *)(data + idx);
|
||||
|
||||
tag_id = le16_to_cpu(tlv_nvm->tag_id);
|
||||
tag_len = le16_to_cpu(tlv_nvm->tag_len);
|
||||
|
||||
if (length < idx + sizeof(struct tlv_type_nvm) + tag_len)
|
||||
return -EINVAL;
|
||||
|
||||
/* Update NVM tags as needed */
|
||||
switch (tag_id) {
|
||||
case EDL_TAG_ID_BD_ADDR:
|
||||
if (tag_len != sizeof(bdaddr_t))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&config->bdaddr, tlv_nvm->data, sizeof(bdaddr_t));
|
||||
|
||||
break;
|
||||
|
||||
case EDL_TAG_ID_HCI:
|
||||
if (tag_len < 3)
|
||||
return -EINVAL;
|
||||
|
||||
/* HCI transport layer parameters
|
||||
* enabling software inband sleep
|
||||
* onto controller side.
|
||||
|
@ -326,6 +433,9 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
|||
break;
|
||||
|
||||
case EDL_TAG_ID_DEEP_SLEEP:
|
||||
if (tag_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Sleep enable mask
|
||||
* enabling deep sleep feature on controller.
|
||||
*/
|
||||
|
@ -334,14 +444,16 @@ static void qca_tlv_check_data(struct hci_dev *hdev,
|
|||
break;
|
||||
}
|
||||
|
||||
idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len);
|
||||
idx += sizeof(struct tlv_type_nvm) + tag_len;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_ERR("Unknown TLV type %d", config->type);
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
|
||||
|
@ -491,7 +603,9 @@ static int qca_download_firmware(struct hci_dev *hdev,
|
|||
memcpy(data, fw->data, size);
|
||||
release_firmware(fw);
|
||||
|
||||
qca_tlv_check_data(hdev, config, data, soc_type);
|
||||
ret = qca_tlv_check_data(hdev, config, data, size, soc_type);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
segment = data;
|
||||
remain = size;
|
||||
|
@ -574,14 +688,64 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
|
||||
|
||||
static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)
|
||||
{
|
||||
struct hci_rp_read_bd_addr *bda;
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
if (bacmp(&hdev->public_addr, BDADDR_ANY))
|
||||
return 0;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to read device address (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*bda)) {
|
||||
bt_dev_err(hdev, "Device address length mismatch");
|
||||
kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
bda = (struct hci_rp_read_bd_addr *)skb->data;
|
||||
if (!bacmp(&bda->bdaddr, &config->bdaddr))
|
||||
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
|
||||
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
|
||||
struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
|
||||
{
|
||||
const char *variant;
|
||||
|
||||
/* hsp gf chip */
|
||||
if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
|
||||
variant = "g";
|
||||
else
|
||||
variant = "";
|
||||
|
||||
if (bid == 0x0)
|
||||
snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant);
|
||||
else
|
||||
snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);
|
||||
}
|
||||
|
||||
int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
|
||||
const char *firmware_name)
|
||||
{
|
||||
struct qca_fw_config config;
|
||||
struct qca_fw_config config = {};
|
||||
int err;
|
||||
u8 rom_ver = 0;
|
||||
u32 soc_ver;
|
||||
u16 boardid = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "QCA setup on UART");
|
||||
|
||||
|
@ -615,6 +779,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/apbtfw%02x.tlv", rom_ver);
|
||||
break;
|
||||
case QCA_QCA2066:
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/hpbtfw%02x.tlv", rom_ver);
|
||||
break;
|
||||
case QCA_QCA6390:
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/htbtfw%02x.tlv", rom_ver);
|
||||
|
@ -649,6 +817,9 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
/* Give the controller some time to get ready to receive the NVM */
|
||||
msleep(10);
|
||||
|
||||
if (soc_type == QCA_QCA2066)
|
||||
qca_read_fw_board_id(hdev, &boardid);
|
||||
|
||||
/* Download NVM configuration */
|
||||
config.type = TLV_TYPE_NVM;
|
||||
if (firmware_name) {
|
||||
|
@ -671,6 +842,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/apnv%02x.bin", rom_ver);
|
||||
break;
|
||||
case QCA_QCA2066:
|
||||
qca_generate_hsp_nvm_name(config.fwname,
|
||||
sizeof(config.fwname), ver, rom_ver, boardid);
|
||||
break;
|
||||
case QCA_QCA6390:
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/htnv%02x.bin", rom_ver);
|
||||
|
@ -702,6 +877,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3991:
|
||||
case QCA_QCA2066:
|
||||
case QCA_QCA6390:
|
||||
case QCA_WCN6750:
|
||||
case QCA_WCN6855:
|
||||
|
@ -750,6 +926,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
break;
|
||||
}
|
||||
|
||||
err = qca_check_bdaddr(hdev, &config);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
bt_dev_info(hdev, "QCA setup on UART is completed");
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define EDL_PATCH_VER_REQ_CMD (0x19)
|
||||
#define EDL_PATCH_TLV_REQ_CMD (0x1E)
|
||||
#define EDL_GET_BUILD_INFO_CMD (0x20)
|
||||
#define EDL_GET_BID_REQ_CMD (0x23)
|
||||
#define EDL_NVM_ACCESS_SET_REQ_CMD (0x01)
|
||||
#define EDL_PATCH_CONFIG_CMD (0x28)
|
||||
#define MAX_SIZE_PER_TLV_SEGMENT (243)
|
||||
|
@ -28,6 +29,7 @@
|
|||
#define EDL_PATCH_CONFIG_RES_EVT (0x00)
|
||||
#define QCA_DISABLE_LOGGING_SUB_OP (0x14)
|
||||
|
||||
#define EDL_TAG_ID_BD_ADDR 2
|
||||
#define EDL_TAG_ID_HCI (17)
|
||||
#define EDL_TAG_ID_DEEP_SLEEP (27)
|
||||
|
||||
|
@ -46,8 +48,8 @@
|
|||
#define get_soc_ver(soc_id, rom_ver) \
|
||||
((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver)))
|
||||
|
||||
#define QCA_FW_BUILD_VER_LEN 255
|
||||
|
||||
#define QCA_HSP_GF_SOC_ID 0x1200
|
||||
#define QCA_HSP_GF_SOC_MASK 0x0000ff00
|
||||
|
||||
enum qca_baudrate {
|
||||
QCA_BAUDRATE_115200 = 0,
|
||||
|
@ -92,6 +94,7 @@ struct qca_fw_config {
|
|||
uint8_t user_baud_rate;
|
||||
enum qca_tlv_dnld_mode dnld_mode;
|
||||
enum qca_tlv_dnld_mode dnld_type;
|
||||
bdaddr_t bdaddr;
|
||||
};
|
||||
|
||||
struct edl_event_hdr {
|
||||
|
@ -146,6 +149,7 @@ enum qca_btsoc_type {
|
|||
QCA_WCN3990,
|
||||
QCA_WCN3998,
|
||||
QCA_WCN3991,
|
||||
QCA_QCA2066,
|
||||
QCA_QCA6390,
|
||||
QCA_WCN6750,
|
||||
QCA_WCN6855,
|
||||
|
|
|
@ -1845,6 +1845,10 @@ static int qca_setup(struct hci_uart *hu)
|
|||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
|
||||
switch (soc_type) {
|
||||
case QCA_QCA2066:
|
||||
soc_name = "qca2066";
|
||||
break;
|
||||
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
|
@ -1886,8 +1890,6 @@ retry:
|
|||
case QCA_WCN6750:
|
||||
case QCA_WCN6855:
|
||||
case QCA_WCN7850:
|
||||
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
|
||||
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
if (qcadev->bdaddr_property_broken)
|
||||
set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks);
|
||||
|
@ -2043,6 +2045,11 @@ static const struct qca_device_data qca_soc_data_wcn3998 __maybe_unused = {
|
|||
.num_vregs = 4,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_qca2066 __maybe_unused = {
|
||||
.soc_type = QCA_QCA2066,
|
||||
.num_vregs = 0,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = {
|
||||
.soc_type = QCA_QCA6390,
|
||||
.num_vregs = 0,
|
||||
|
@ -2582,6 +2589,7 @@ static SIMPLE_DEV_PM_OPS(qca_pm_ops, qca_suspend, qca_resume);
|
|||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id qca_bluetooth_of_match[] = {
|
||||
{ .compatible = "qcom,qca2066-bt", .data = &qca_soc_data_qca2066},
|
||||
{ .compatible = "qcom,qca6174-bt" },
|
||||
{ .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390},
|
||||
{ .compatible = "qcom,qca9377-bt" },
|
||||
|
@ -2599,6 +2607,7 @@ MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);
|
|||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id qca_bluetooth_acpi_match[] = {
|
||||
{ "QCOM2066", (kernel_ulong_t)&qca_soc_data_qca2066 },
|
||||
{ "QCOM6390", (kernel_ulong_t)&qca_soc_data_qca6390 },
|
||||
{ "DLA16390", (kernel_ulong_t)&qca_soc_data_qca6390 },
|
||||
{ "DLB16390", (kernel_ulong_t)&qca_soc_data_qca6390 },
|
||||
|
|
|
@ -4523,7 +4523,8 @@ void clk_unregister(struct clk *clk)
|
|||
if (ops == &clk_nodrv_ops) {
|
||||
pr_err("%s: unregistered clock: %s\n", __func__,
|
||||
clk->core->name);
|
||||
goto unlock;
|
||||
clk_prepare_unlock();
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Assign empty clock ops for consumers that might still hold
|
||||
|
@ -4557,11 +4558,10 @@ void clk_unregister(struct clk *clk)
|
|||
if (clk->core->protect_count)
|
||||
pr_warn("%s: unregistering protected clock: %s\n",
|
||||
__func__, clk->core->name);
|
||||
clk_prepare_unlock();
|
||||
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
free_clk(clk);
|
||||
unlock:
|
||||
clk_prepare_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_unregister);
|
||||
|
||||
|
@ -4720,13 +4720,11 @@ void __clk_put(struct clk *clk)
|
|||
if (clk->min_rate > 0 || clk->max_rate < ULONG_MAX)
|
||||
clk_set_rate_range_nolock(clk, 0, ULONG_MAX);
|
||||
|
||||
owner = clk->core->owner;
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
|
||||
clk_prepare_unlock();
|
||||
|
||||
owner = clk->core->owner;
|
||||
kref_put(&clk->core->ref, __clk_release);
|
||||
module_put(owner);
|
||||
|
||||
free_clk(clk);
|
||||
}
|
||||
|
||||
|
|
|
@ -758,6 +758,7 @@ static struct clk_smd_rpm *msm8976_clks[] = {
|
|||
|
||||
static const struct rpm_smd_clk_desc rpm_clk_msm8976 = {
|
||||
.clks = msm8976_clks,
|
||||
.num_clks = ARRAY_SIZE(msm8976_clks),
|
||||
.icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
|
||||
.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
|
||||
};
|
||||
|
|
|
@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = {
|
|||
&ccu_nkm_ops,
|
||||
CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
|
||||
.features = CCU_FEATURE_CLOSEST_RATE,
|
||||
.min_rate = 500000000,
|
||||
.max_rate = 1400000000,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -1181,11 +1181,18 @@ static const u32 usb2_clk_regs[] = {
|
|||
SUN50I_H6_USB3_CLK_REG,
|
||||
};
|
||||
|
||||
static struct ccu_mux_nb sun50i_h6_cpu_nb = {
|
||||
.common = &cpux_clk.common,
|
||||
.cm = &cpux_clk.mux,
|
||||
.delay_us = 1,
|
||||
.bypass_index = 0, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
int i, ret;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
|
@ -1252,7 +1259,15 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
|||
val |= BIT(24);
|
||||
writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
|
||||
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Reparent CPU during PLL CPUX rate changes */
|
||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||
&sun50i_h6_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sun50i_h6_ccu_ids[] = {
|
||||
|
|
|
@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common,
|
|||
unsigned long current_rate,
|
||||
unsigned long best_rate)
|
||||
{
|
||||
unsigned long min_rate, max_rate;
|
||||
|
||||
clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate);
|
||||
|
||||
if (current_rate > max_rate)
|
||||
return false;
|
||||
|
||||
if (current_rate < min_rate)
|
||||
return false;
|
||||
|
||||
if (common->features & CCU_FEATURE_CLOSEST_RATE)
|
||||
return abs(current_rate - target_rate) < abs(best_rate - target_rate);
|
||||
|
||||
|
@ -122,6 +132,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
|
|||
|
||||
for (i = 0; i < desc->hw_clks->num ; i++) {
|
||||
struct clk_hw *hw = desc->hw_clks->hws[i];
|
||||
struct ccu_common *common = hw_to_ccu_common(hw);
|
||||
const char *name;
|
||||
|
||||
if (!hw)
|
||||
|
@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
|
|||
pr_err("Couldn't register clock %d - %s\n", i, name);
|
||||
goto err_clk_unreg;
|
||||
}
|
||||
|
||||
if (common->max_rate)
|
||||
clk_hw_set_rate_range(hw, common->min_rate,
|
||||
common->max_rate);
|
||||
else
|
||||
WARN(common->min_rate,
|
||||
"No max_rate, ignoring min_rate of clock %d - %s\n",
|
||||
i, name);
|
||||
}
|
||||
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
|
||||
|
|
|
@ -31,6 +31,9 @@ struct ccu_common {
|
|||
u16 lock_reg;
|
||||
u32 prediv;
|
||||
|
||||
unsigned long min_rate;
|
||||
unsigned long max_rate;
|
||||
|
||||
unsigned long features;
|
||||
spinlock_t *lock;
|
||||
struct clk_hw hw;
|
||||
|
|
|
@ -400,6 +400,18 @@ static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
int rc;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s called\n", __func__);
|
||||
|
||||
/*
|
||||
* Due to an erratum in some of the devices supported by the driver,
|
||||
* direct user submission to the device can be unsafe.
|
||||
* (See the INTEL-SA-01084 security advisory)
|
||||
*
|
||||
* For the devices that exhibit this behavior, require that the user
|
||||
* has CAP_SYS_RAWIO capabilities.
|
||||
*/
|
||||
if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
|
||||
rc = check_vma(wq, vma, __func__);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
@ -414,6 +426,70 @@ static int idxd_cdev_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
vma->vm_page_prot);
|
||||
}
|
||||
|
||||
static int idxd_submit_user_descriptor(struct idxd_user_context *ctx,
|
||||
struct dsa_hw_desc __user *udesc)
|
||||
{
|
||||
struct idxd_wq *wq = ctx->wq;
|
||||
struct idxd_dev *idxd_dev = &wq->idxd->idxd_dev;
|
||||
const uint64_t comp_addr_align = is_dsa_dev(idxd_dev) ? 0x20 : 0x40;
|
||||
void __iomem *portal = idxd_wq_portal_addr(wq);
|
||||
struct dsa_hw_desc descriptor __aligned(64);
|
||||
int rc;
|
||||
|
||||
rc = copy_from_user(&descriptor, udesc, sizeof(descriptor));
|
||||
if (rc)
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
* DSA devices are capable of indirect ("batch") command submission.
|
||||
* On devices where direct user submissions are not safe, we cannot
|
||||
* allow this since there is no good way for us to verify these
|
||||
* indirect commands.
|
||||
*/
|
||||
if (is_dsa_dev(idxd_dev) && descriptor.opcode == DSA_OPCODE_BATCH &&
|
||||
!wq->idxd->user_submission_safe)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* As per the programming specification, the completion address must be
|
||||
* aligned to 32 or 64 bytes. If this is violated the hardware
|
||||
* engine can get very confused (security issue).
|
||||
*/
|
||||
if (!IS_ALIGNED(descriptor.completion_addr, comp_addr_align))
|
||||
return -EINVAL;
|
||||
|
||||
if (wq_dedicated(wq))
|
||||
iosubmit_cmds512(portal, &descriptor, 1);
|
||||
else {
|
||||
descriptor.priv = 0;
|
||||
descriptor.pasid = ctx->pasid;
|
||||
rc = idxd_enqcmds(wq, portal, &descriptor);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_t len,
|
||||
loff_t *unused)
|
||||
{
|
||||
struct dsa_hw_desc __user *udesc = (struct dsa_hw_desc __user *)buf;
|
||||
struct idxd_user_context *ctx = filp->private_data;
|
||||
ssize_t written = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) {
|
||||
int rc = idxd_submit_user_descriptor(ctx, udesc + i);
|
||||
|
||||
if (rc)
|
||||
return written ? written : rc;
|
||||
|
||||
written += sizeof(struct dsa_hw_desc);
|
||||
}
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
static __poll_t idxd_cdev_poll(struct file *filp,
|
||||
struct poll_table_struct *wait)
|
||||
{
|
||||
|
@ -436,6 +512,7 @@ static const struct file_operations idxd_cdev_fops = {
|
|||
.open = idxd_cdev_open,
|
||||
.release = idxd_cdev_release,
|
||||
.mmap = idxd_cdev_mmap,
|
||||
.write = idxd_cdev_write,
|
||||
.poll = idxd_cdev_poll,
|
||||
};
|
||||
|
||||
|
|
|
@ -275,6 +275,7 @@ struct idxd_driver_data {
|
|||
int evl_cr_off;
|
||||
int cr_status_off;
|
||||
int cr_result_off;
|
||||
bool user_submission_safe;
|
||||
};
|
||||
|
||||
struct idxd_evl {
|
||||
|
@ -360,6 +361,8 @@ struct idxd_device {
|
|||
|
||||
struct dentry *dbgfs_dir;
|
||||
struct dentry *dbgfs_evl_file;
|
||||
|
||||
bool user_submission_safe;
|
||||
};
|
||||
|
||||
static inline unsigned int evl_ent_size(struct idxd_device *idxd)
|
||||
|
|
|
@ -47,6 +47,7 @@ static struct idxd_driver_data idxd_driver_data[] = {
|
|||
.align = 32,
|
||||
.dev_type = &dsa_device_type,
|
||||
.evl_cr_off = offsetof(struct dsa_evl_entry, cr),
|
||||
.user_submission_safe = false, /* See INTEL-SA-01084 security advisory */
|
||||
.cr_status_off = offsetof(struct dsa_completion_record, status),
|
||||
.cr_result_off = offsetof(struct dsa_completion_record, result),
|
||||
},
|
||||
|
@ -57,6 +58,7 @@ static struct idxd_driver_data idxd_driver_data[] = {
|
|||
.align = 64,
|
||||
.dev_type = &iax_device_type,
|
||||
.evl_cr_off = offsetof(struct iax_evl_entry, cr),
|
||||
.user_submission_safe = false, /* See INTEL-SA-01084 security advisory */
|
||||
.cr_status_off = offsetof(struct iax_completion_record, status),
|
||||
.cr_result_off = offsetof(struct iax_completion_record, error_code),
|
||||
},
|
||||
|
@ -767,6 +769,8 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
|
||||
idxd->hw.version);
|
||||
|
||||
idxd->user_submission_safe = data->user_submission_safe;
|
||||
|
||||
return 0;
|
||||
|
||||
err_dev_register:
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
#include <uapi/linux/idxd.h>
|
||||
|
||||
/* PCI Config */
|
||||
#define PCI_DEVICE_ID_INTEL_DSA_SPR0 0x0b25
|
||||
#define PCI_DEVICE_ID_INTEL_IAX_SPR0 0x0cfe
|
||||
|
||||
#define DEVICE_VERSION_1 0x100
|
||||
#define DEVICE_VERSION_2 0x200
|
||||
|
||||
|
|
|
@ -1197,12 +1197,35 @@ static ssize_t wq_enqcmds_retries_store(struct device *dev, struct device_attrib
|
|||
static struct device_attribute dev_attr_wq_enqcmds_retries =
|
||||
__ATTR(enqcmds_retries, 0644, wq_enqcmds_retries_show, wq_enqcmds_retries_store);
|
||||
|
||||
static ssize_t op_cap_show_common(struct device *dev, char *buf, unsigned long *opcap_bmap)
|
||||
{
|
||||
ssize_t pos;
|
||||
int i;
|
||||
|
||||
pos = 0;
|
||||
for (i = IDXD_MAX_OPCAP_BITS/64 - 1; i >= 0; i--) {
|
||||
unsigned long val = opcap_bmap[i];
|
||||
|
||||
/* On systems where direct user submissions are not safe, we need to clear out
|
||||
* the BATCH capability from the capability mask in sysfs since we cannot support
|
||||
* that command on such systems.
|
||||
*/
|
||||
if (i == DSA_OPCODE_BATCH/64 && !confdev_to_idxd(dev)->user_submission_safe)
|
||||
clear_bit(DSA_OPCODE_BATCH % 64, &val);
|
||||
|
||||
pos += sysfs_emit_at(buf, pos, "%*pb", 64, &val);
|
||||
pos += sysfs_emit_at(buf, pos, "%c", i == 0 ? '\n' : ',');
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static ssize_t wq_op_config_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct idxd_wq *wq = confdev_to_wq(dev);
|
||||
|
||||
return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, wq->opcap_bmap);
|
||||
return op_cap_show_common(dev, buf, wq->opcap_bmap);
|
||||
}
|
||||
|
||||
static int idxd_verify_supported_opcap(struct idxd_device *idxd, unsigned long *opmask)
|
||||
|
@ -1421,7 +1444,7 @@ static ssize_t op_cap_show(struct device *dev,
|
|||
{
|
||||
struct idxd_device *idxd = confdev_to_idxd(dev);
|
||||
|
||||
return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap);
|
||||
return op_cap_show_common(dev, buf, idxd->opcap_bmap);
|
||||
}
|
||||
static DEVICE_ATTR_RO(op_cap);
|
||||
|
||||
|
|
|
@ -148,10 +148,12 @@ packet_buffer_get(struct client *client, char __user *data, size_t user_length)
|
|||
if (atomic_read(&buffer->size) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
/* FIXME: Check length <= user_length. */
|
||||
length = buffer->head->length;
|
||||
|
||||
if (length > user_length)
|
||||
return 0;
|
||||
|
||||
end = buffer->data + buffer->capacity;
|
||||
length = buffer->head->length;
|
||||
|
||||
if (&buffer->head->data[length] < end) {
|
||||
if (copy_to_user(data, buffer->head->data, length))
|
||||
|
|
|
@ -1556,6 +1556,8 @@ static int handle_at_packet(struct context *context,
|
|||
#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
|
||||
#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)
|
||||
|
||||
static u32 get_cycle_time(struct fw_ohci *ohci);
|
||||
|
||||
static void handle_local_rom(struct fw_ohci *ohci,
|
||||
struct fw_packet *packet, u32 csr)
|
||||
{
|
||||
|
@ -1580,6 +1582,8 @@ static void handle_local_rom(struct fw_ohci *ohci,
|
|||
(void *) ohci->config_rom + i, length);
|
||||
}
|
||||
|
||||
// Timestamping on behalf of the hardware.
|
||||
response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
|
||||
fw_core_handle_response(&ohci->card, &response);
|
||||
}
|
||||
|
||||
|
@ -1628,6 +1632,8 @@ static void handle_local_lock(struct fw_ohci *ohci,
|
|||
fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
|
||||
|
||||
out:
|
||||
// Timestamping on behalf of the hardware.
|
||||
response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
|
||||
fw_core_handle_response(&ohci->card, &response);
|
||||
}
|
||||
|
||||
|
@ -1670,8 +1676,6 @@ static void handle_local_request(struct context *ctx, struct fw_packet *packet)
|
|||
}
|
||||
}
|
||||
|
||||
static u32 get_cycle_time(struct fw_ohci *ohci);
|
||||
|
||||
static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -2060,6 +2064,8 @@ static void bus_reset_work(struct work_struct *work)
|
|||
|
||||
ohci->generation = generation;
|
||||
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
|
||||
if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
|
||||
reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
|
||||
|
||||
if (ohci->quirks & QUIRK_RESET_PACKET)
|
||||
ohci->request_generation = generation;
|
||||
|
@ -2125,12 +2131,14 @@ static irqreturn_t irq_handler(int irq, void *data)
|
|||
return IRQ_NONE;
|
||||
|
||||
/*
|
||||
* busReset and postedWriteErr must not be cleared yet
|
||||
* busReset and postedWriteErr events must not be cleared yet
|
||||
* (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
|
||||
*/
|
||||
reg_write(ohci, OHCI1394_IntEventClear,
|
||||
event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
|
||||
log_irqs(ohci, event);
|
||||
if (event & OHCI1394_busReset)
|
||||
reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
|
||||
|
||||
if (event & OHCI1394_selfIDComplete)
|
||||
queue_work(selfid_workqueue, &ohci->bus_reset_work);
|
||||
|
|
|
@ -92,7 +92,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)
|
|||
case 0x5e:
|
||||
return GPIOPANELCTL;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -529,6 +529,7 @@ static const struct of_device_id lpc32xx_gpio_of_match[] = {
|
|||
{ .compatible = "nxp,lpc3220-gpio", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpc32xx_gpio_of_match);
|
||||
|
||||
static struct platform_driver lpc32xx_gpio_driver = {
|
||||
.driver = {
|
||||
|
|
|
@ -104,7 +104,7 @@ static inline int to_reg(int gpio, enum ctrl_register type)
|
|||
unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE;
|
||||
|
||||
if (gpio >= WCOVE_GPIO_NUM)
|
||||
return -EOPNOTSUPP;
|
||||
return -ENOTSUPP;
|
||||
|
||||
return reg + gpio;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <linux/bitmap.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/device.h>
|
||||
|
@ -21,6 +22,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/timekeeping.h>
|
||||
|
@ -461,6 +463,7 @@ out_free_lh:
|
|||
|
||||
/**
|
||||
* struct line - contains the state of a requested line
|
||||
* @node: to store the object in supinfo_tree if supplemental
|
||||
* @desc: the GPIO descriptor for this line.
|
||||
* @req: the corresponding line request
|
||||
* @irq: the interrupt triggered in response to events on this GPIO
|
||||
|
@ -473,6 +476,7 @@ out_free_lh:
|
|||
* @line_seqno: the seqno for the current edge event in the sequence of
|
||||
* events for this line.
|
||||
* @work: the worker that implements software debouncing
|
||||
* @debounce_period_us: the debounce period in microseconds
|
||||
* @sw_debounced: flag indicating if the software debouncer is active
|
||||
* @level: the current debounced physical level of the line
|
||||
* @hdesc: the Hardware Timestamp Engine (HTE) descriptor
|
||||
|
@ -481,6 +485,7 @@ out_free_lh:
|
|||
* @last_seqno: the last sequence number before debounce period expires
|
||||
*/
|
||||
struct line {
|
||||
struct rb_node node;
|
||||
struct gpio_desc *desc;
|
||||
/*
|
||||
* -- edge detector specific fields --
|
||||
|
@ -514,6 +519,15 @@ struct line {
|
|||
* -- debouncer specific fields --
|
||||
*/
|
||||
struct delayed_work work;
|
||||
/*
|
||||
* debounce_period_us is accessed by debounce_irq_handler() and
|
||||
* process_hw_ts() which are disabled when modified by
|
||||
* debounce_setup(), edge_detector_setup() or edge_detector_stop()
|
||||
* or can live with a stale version when updated by
|
||||
* edge_detector_update().
|
||||
* The modifying functions are themselves mutually exclusive.
|
||||
*/
|
||||
unsigned int debounce_period_us;
|
||||
/*
|
||||
* sw_debounce is accessed by linereq_set_config(), which is the
|
||||
* only setter, and linereq_get_values(), which can live with a
|
||||
|
@ -546,6 +560,17 @@ struct line {
|
|||
#endif /* CONFIG_HTE */
|
||||
};
|
||||
|
||||
/*
|
||||
* a rbtree of the struct lines containing supplemental info.
|
||||
* Used to populate gpio_v2_line_info with cdev specific fields not contained
|
||||
* in the struct gpio_desc.
|
||||
* A line is determined to contain supplemental information by
|
||||
* line_has_supinfo().
|
||||
*/
|
||||
static struct rb_root supinfo_tree = RB_ROOT;
|
||||
/* covers supinfo_tree */
|
||||
static DEFINE_SPINLOCK(supinfo_lock);
|
||||
|
||||
/**
|
||||
* struct linereq - contains the state of a userspace line request
|
||||
* @gdev: the GPIO device the line request pertains to
|
||||
|
@ -559,7 +584,8 @@ struct line {
|
|||
* this line request. Note that this is not used when @num_lines is 1, as
|
||||
* the line_seqno is then the same and is cheaper to calculate.
|
||||
* @config_mutex: mutex for serializing ioctl() calls to ensure consistency
|
||||
* of configuration, particularly multi-step accesses to desc flags.
|
||||
* of configuration, particularly multi-step accesses to desc flags and
|
||||
* changes to supinfo status.
|
||||
* @lines: the lines held by this line request, with @num_lines elements.
|
||||
*/
|
||||
struct linereq {
|
||||
|
@ -575,6 +601,103 @@ struct linereq {
|
|||
struct line lines[];
|
||||
};
|
||||
|
||||
static void supinfo_insert(struct line *line)
|
||||
{
|
||||
struct rb_node **new = &(supinfo_tree.rb_node), *parent = NULL;
|
||||
struct line *entry;
|
||||
|
||||
guard(spinlock)(&supinfo_lock);
|
||||
|
||||
while (*new) {
|
||||
entry = container_of(*new, struct line, node);
|
||||
|
||||
parent = *new;
|
||||
if (line->desc < entry->desc) {
|
||||
new = &((*new)->rb_left);
|
||||
} else if (line->desc > entry->desc) {
|
||||
new = &((*new)->rb_right);
|
||||
} else {
|
||||
/* this should never happen */
|
||||
WARN(1, "duplicate line inserted");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rb_link_node(&line->node, parent, new);
|
||||
rb_insert_color(&line->node, &supinfo_tree);
|
||||
}
|
||||
|
||||
static void supinfo_erase(struct line *line)
|
||||
{
|
||||
guard(spinlock)(&supinfo_lock);
|
||||
|
||||
rb_erase(&line->node, &supinfo_tree);
|
||||
}
|
||||
|
||||
static struct line *supinfo_find(struct gpio_desc *desc)
|
||||
{
|
||||
struct rb_node *node = supinfo_tree.rb_node;
|
||||
struct line *line;
|
||||
|
||||
while (node) {
|
||||
line = container_of(node, struct line, node);
|
||||
if (desc < line->desc)
|
||||
node = node->rb_left;
|
||||
else if (desc > line->desc)
|
||||
node = node->rb_right;
|
||||
else
|
||||
return line;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void supinfo_to_lineinfo(struct gpio_desc *desc,
|
||||
struct gpio_v2_line_info *info)
|
||||
{
|
||||
struct gpio_v2_line_attribute *attr;
|
||||
struct line *line;
|
||||
|
||||
guard(spinlock)(&supinfo_lock);
|
||||
|
||||
line = supinfo_find(desc);
|
||||
if (!line)
|
||||
return;
|
||||
|
||||
attr = &info->attrs[info->num_attrs];
|
||||
attr->id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
|
||||
attr->debounce_period_us = READ_ONCE(line->debounce_period_us);
|
||||
info->num_attrs++;
|
||||
}
|
||||
|
||||
static inline bool line_has_supinfo(struct line *line)
|
||||
{
|
||||
return READ_ONCE(line->debounce_period_us);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks line_has_supinfo() before and after the change to avoid unnecessary
|
||||
* supinfo_tree access.
|
||||
* Called indirectly by linereq_create() or linereq_set_config() so line
|
||||
* is already protected from concurrent changes.
|
||||
*/
|
||||
static void line_set_debounce_period(struct line *line,
|
||||
unsigned int debounce_period_us)
|
||||
{
|
||||
bool was_suppl = line_has_supinfo(line);
|
||||
|
||||
WRITE_ONCE(line->debounce_period_us, debounce_period_us);
|
||||
|
||||
/* if supinfo status is unchanged then we're done */
|
||||
if (line_has_supinfo(line) == was_suppl)
|
||||
return;
|
||||
|
||||
/* supinfo status has changed, so update the tree */
|
||||
if (was_suppl)
|
||||
supinfo_erase(line);
|
||||
else
|
||||
supinfo_insert(line);
|
||||
}
|
||||
|
||||
#define GPIO_V2_LINE_BIAS_FLAGS \
|
||||
(GPIO_V2_LINE_FLAG_BIAS_PULL_UP | \
|
||||
GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN | \
|
||||
|
@ -742,7 +865,7 @@ static enum hte_return process_hw_ts(struct hte_ts_data *ts, void *p)
|
|||
line->total_discard_seq++;
|
||||
line->last_seqno = ts->seq;
|
||||
mod_delayed_work(system_wq, &line->work,
|
||||
usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us)));
|
||||
usecs_to_jiffies(READ_ONCE(line->debounce_period_us)));
|
||||
} else {
|
||||
if (unlikely(ts->seq < line->line_seqno))
|
||||
return HTE_CB_HANDLED;
|
||||
|
@ -883,7 +1006,7 @@ static irqreturn_t debounce_irq_handler(int irq, void *p)
|
|||
struct line *line = p;
|
||||
|
||||
mod_delayed_work(system_wq, &line->work,
|
||||
usecs_to_jiffies(READ_ONCE(line->desc->debounce_period_us)));
|
||||
usecs_to_jiffies(READ_ONCE(line->debounce_period_us)));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -966,7 +1089,7 @@ static int debounce_setup(struct line *line, unsigned int debounce_period_us)
|
|||
/* try hardware */
|
||||
ret = gpiod_set_debounce(line->desc, debounce_period_us);
|
||||
if (!ret) {
|
||||
WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us);
|
||||
line_set_debounce_period(line, debounce_period_us);
|
||||
return ret;
|
||||
}
|
||||
if (ret != -ENOTSUPP)
|
||||
|
@ -1051,8 +1174,7 @@ static void edge_detector_stop(struct line *line)
|
|||
cancel_delayed_work_sync(&line->work);
|
||||
WRITE_ONCE(line->sw_debounced, 0);
|
||||
WRITE_ONCE(line->edflags, 0);
|
||||
if (line->desc)
|
||||
WRITE_ONCE(line->desc->debounce_period_us, 0);
|
||||
line_set_debounce_period(line, 0);
|
||||
/* do not change line->level - see comment in debounced_value() */
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1200,7 @@ static int edge_detector_setup(struct line *line,
|
|||
ret = debounce_setup(line, debounce_period_us);
|
||||
if (ret)
|
||||
return ret;
|
||||
WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us);
|
||||
line_set_debounce_period(line, debounce_period_us);
|
||||
}
|
||||
|
||||
/* detection disabled or sw debouncer will provide edge detection */
|
||||
|
@ -1121,17 +1243,31 @@ static int edge_detector_update(struct line *line,
|
|||
struct gpio_v2_line_config *lc,
|
||||
unsigned int line_idx, u64 edflags)
|
||||
{
|
||||
u64 eflags;
|
||||
int ret;
|
||||
u64 active_edflags = READ_ONCE(line->edflags);
|
||||
unsigned int debounce_period_us =
|
||||
gpio_v2_line_config_debounce_period(lc, line_idx);
|
||||
|
||||
if ((active_edflags == edflags) &&
|
||||
(READ_ONCE(line->desc->debounce_period_us) == debounce_period_us))
|
||||
(READ_ONCE(line->debounce_period_us) == debounce_period_us))
|
||||
return 0;
|
||||
|
||||
/* sw debounced and still will be...*/
|
||||
if (debounce_period_us && READ_ONCE(line->sw_debounced)) {
|
||||
WRITE_ONCE(line->desc->debounce_period_us, debounce_period_us);
|
||||
line_set_debounce_period(line, debounce_period_us);
|
||||
/*
|
||||
* ensure event fifo is initialised if edge detection
|
||||
* is now enabled.
|
||||
*/
|
||||
eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
|
||||
if (eflags && !kfifo_initialized(&line->req->events)) {
|
||||
ret = kfifo_alloc(&line->req->events,
|
||||
line->req->event_buffer_size,
|
||||
GFP_KERNEL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1606,6 +1742,7 @@ static ssize_t linereq_read(struct file *file, char __user *buf,
|
|||
|
||||
static void linereq_free(struct linereq *lr)
|
||||
{
|
||||
struct line *line;
|
||||
unsigned int i;
|
||||
|
||||
if (lr->device_unregistered_nb.notifier_call)
|
||||
|
@ -1613,10 +1750,14 @@ static void linereq_free(struct linereq *lr)
|
|||
&lr->device_unregistered_nb);
|
||||
|
||||
for (i = 0; i < lr->num_lines; i++) {
|
||||
if (lr->lines[i].desc) {
|
||||
edge_detector_stop(&lr->lines[i]);
|
||||
gpiod_free(lr->lines[i].desc);
|
||||
}
|
||||
line = &lr->lines[i];
|
||||
if (!line->desc)
|
||||
continue;
|
||||
|
||||
edge_detector_stop(line);
|
||||
if (line_has_supinfo(line))
|
||||
supinfo_erase(line);
|
||||
gpiod_free(line->desc);
|
||||
}
|
||||
kfifo_free(&lr->events);
|
||||
kfree(lr->label);
|
||||
|
@ -2316,8 +2457,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
|
|||
struct gpio_chip *gc = desc->gdev->chip;
|
||||
bool ok_for_pinctrl;
|
||||
unsigned long flags;
|
||||
u32 debounce_period_us;
|
||||
unsigned int num_attrs = 0;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
info->offset = gpio_chip_hwgpio(desc);
|
||||
|
@ -2384,14 +2523,6 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
|
|||
else if (test_bit(FLAG_EVENT_CLOCK_HTE, &desc->flags))
|
||||
info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE;
|
||||
|
||||
debounce_period_us = READ_ONCE(desc->debounce_period_us);
|
||||
if (debounce_period_us) {
|
||||
info->attrs[num_attrs].id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
|
||||
info->attrs[num_attrs].debounce_period_us = debounce_period_us;
|
||||
num_attrs++;
|
||||
}
|
||||
info->num_attrs = num_attrs;
|
||||
|
||||
spin_unlock_irqrestore(&gpio_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -2498,6 +2629,7 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
|
|||
return -EBUSY;
|
||||
}
|
||||
gpio_desc_to_lineinfo(desc, &lineinfo);
|
||||
supinfo_to_lineinfo(desc, &lineinfo);
|
||||
|
||||
if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
|
||||
if (watch)
|
||||
|
@ -2596,6 +2728,7 @@ static int lineinfo_changed_notify(struct notifier_block *nb,
|
|||
chg.event_type = action;
|
||||
chg.timestamp_ns = ktime_get_ns();
|
||||
gpio_desc_to_lineinfo(desc, &chg.info);
|
||||
supinfo_to_lineinfo(desc, &chg.info);
|
||||
|
||||
ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock);
|
||||
if (ret)
|
||||
|
@ -2816,11 +2949,11 @@ static int gpio_chrdev_release(struct inode *inode, struct file *file)
|
|||
struct gpio_chardev_data *cdev = file->private_data;
|
||||
struct gpio_device *gdev = cdev->gdev;
|
||||
|
||||
bitmap_free(cdev->watched_lines);
|
||||
blocking_notifier_chain_unregister(&gdev->device_notifier,
|
||||
&cdev->device_unregistered_nb);
|
||||
blocking_notifier_chain_unregister(&gdev->line_state_notifier,
|
||||
&cdev->lineinfo_changed_nb);
|
||||
bitmap_free(cdev->watched_lines);
|
||||
gpio_device_put(gdev);
|
||||
kfree(cdev);
|
||||
|
||||
|
|
|
@ -300,12 +300,15 @@ static struct dma_fence *amdgpu_job_run(struct drm_sched_job *sched_job)
|
|||
dma_fence_set_error(finished, -ECANCELED);
|
||||
|
||||
if (finished->error < 0) {
|
||||
DRM_INFO("Skip scheduling IBs!\n");
|
||||
dev_dbg(adev->dev, "Skip scheduling IBs in ring(%s)",
|
||||
ring->name);
|
||||
} else {
|
||||
r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job,
|
||||
&fence);
|
||||
if (r)
|
||||
DRM_ERROR("Error scheduling IBs (%d)\n", r);
|
||||
dev_err(adev->dev,
|
||||
"Error scheduling IBs (%d) in ring(%s)", r,
|
||||
ring->name);
|
||||
}
|
||||
|
||||
job->job_run_counter++;
|
||||
|
|
|
@ -1249,14 +1249,18 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
|
|||
* amdgpu_bo_move_notify - notification about a memory move
|
||||
* @bo: pointer to a buffer object
|
||||
* @evict: if this move is evicting the buffer from the graphics address space
|
||||
* @new_mem: new resource for backing the BO
|
||||
*
|
||||
* Marks the corresponding &amdgpu_bo buffer object as invalid, also performs
|
||||
* bookkeeping.
|
||||
* TTM driver callback which is called when ttm moves a buffer.
|
||||
*/
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
|
||||
bool evict,
|
||||
struct ttm_resource *new_mem)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
|
||||
struct ttm_resource *old_mem = bo->resource;
|
||||
struct amdgpu_bo *abo;
|
||||
|
||||
if (!amdgpu_bo_is_amdgpu_bo(bo))
|
||||
|
@ -1268,12 +1272,12 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
|
|||
amdgpu_bo_kunmap(abo);
|
||||
|
||||
if (abo->tbo.base.dma_buf && !abo->tbo.base.import_attach &&
|
||||
bo->resource->mem_type != TTM_PL_SYSTEM)
|
||||
old_mem && old_mem->mem_type != TTM_PL_SYSTEM)
|
||||
dma_buf_move_notify(abo->tbo.base.dma_buf);
|
||||
|
||||
/* remember the eviction */
|
||||
if (evict)
|
||||
atomic64_inc(&adev->num_evictions);
|
||||
/* move_notify is called before move happens */
|
||||
trace_amdgpu_bo_move(abo, new_mem ? new_mem->mem_type : -1,
|
||||
old_mem ? old_mem->mem_type : -1);
|
||||
}
|
||||
|
||||
void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
|
||||
|
|
|
@ -328,7 +328,9 @@ int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata,
|
|||
int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
|
||||
size_t buffer_size, uint32_t *metadata_size,
|
||||
uint64_t *flags);
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict);
|
||||
void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
|
||||
bool evict,
|
||||
struct ttm_resource *new_mem);
|
||||
void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);
|
||||
vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
|
||||
void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
|
||||
|
|
|
@ -424,7 +424,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
|
|||
return false;
|
||||
|
||||
if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT ||
|
||||
res->mem_type == AMDGPU_PL_PREEMPT)
|
||||
res->mem_type == AMDGPU_PL_PREEMPT || res->mem_type == AMDGPU_PL_DOORBELL)
|
||||
return true;
|
||||
|
||||
if (res->mem_type != TTM_PL_VRAM)
|
||||
|
@ -432,7 +432,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
|
|||
|
||||
amdgpu_res_first(res, 0, res->size, &cursor);
|
||||
while (cursor.remaining) {
|
||||
if ((cursor.start + cursor.size) >= adev->gmc.visible_vram_size)
|
||||
if ((cursor.start + cursor.size) > adev->gmc.visible_vram_size)
|
||||
return false;
|
||||
amdgpu_res_next(&cursor, cursor.size);
|
||||
}
|
||||
|
@ -486,14 +486,16 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
|
||||
if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
bo->ttm == NULL)) {
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
if (old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
(new_mem->mem_type == TTM_PL_TT ||
|
||||
new_mem->mem_type == AMDGPU_PL_PREEMPT)) {
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
if ((old_mem->mem_type == TTM_PL_TT ||
|
||||
old_mem->mem_type == AMDGPU_PL_PREEMPT) &&
|
||||
|
@ -503,9 +505,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
return r;
|
||||
|
||||
amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_resource_free(bo, &bo->resource);
|
||||
ttm_bo_assign_mem(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (old_mem->mem_type == AMDGPU_PL_GDS ||
|
||||
|
@ -517,8 +520,9 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
new_mem->mem_type == AMDGPU_PL_OA ||
|
||||
new_mem->mem_type == AMDGPU_PL_DOORBELL) {
|
||||
/* Nothing to save here */
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
ttm_bo_move_null(bo, new_mem);
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bo->type == ttm_bo_type_device &&
|
||||
|
@ -530,23 +534,24 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
|
||||
}
|
||||
|
||||
if (adev->mman.buffer_funcs_enabled) {
|
||||
if (((old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
new_mem->mem_type == TTM_PL_VRAM) ||
|
||||
(old_mem->mem_type == TTM_PL_VRAM &&
|
||||
new_mem->mem_type == TTM_PL_SYSTEM))) {
|
||||
hop->fpfn = 0;
|
||||
hop->lpfn = 0;
|
||||
hop->mem_type = TTM_PL_TT;
|
||||
hop->flags = TTM_PL_FLAG_TEMPORARY;
|
||||
return -EMULTIHOP;
|
||||
}
|
||||
|
||||
r = amdgpu_move_blit(bo, evict, new_mem, old_mem);
|
||||
} else {
|
||||
r = -ENODEV;
|
||||
if (adev->mman.buffer_funcs_enabled &&
|
||||
((old_mem->mem_type == TTM_PL_SYSTEM &&
|
||||
new_mem->mem_type == TTM_PL_VRAM) ||
|
||||
(old_mem->mem_type == TTM_PL_VRAM &&
|
||||
new_mem->mem_type == TTM_PL_SYSTEM))) {
|
||||
hop->fpfn = 0;
|
||||
hop->lpfn = 0;
|
||||
hop->mem_type = TTM_PL_TT;
|
||||
hop->flags = TTM_PL_FLAG_TEMPORARY;
|
||||
return -EMULTIHOP;
|
||||
}
|
||||
|
||||
amdgpu_bo_move_notify(bo, evict, new_mem);
|
||||
if (adev->mman.buffer_funcs_enabled)
|
||||
r = amdgpu_move_blit(bo, evict, new_mem, old_mem);
|
||||
else
|
||||
r = -ENODEV;
|
||||
|
||||
if (r) {
|
||||
/* Check that all memory is CPU accessible */
|
||||
if (!amdgpu_res_copyable(adev, old_mem) ||
|
||||
|
@ -560,11 +565,10 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
|
|||
return r;
|
||||
}
|
||||
|
||||
trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
|
||||
out:
|
||||
/* update statistics */
|
||||
/* update statistics after the move */
|
||||
if (evict)
|
||||
atomic64_inc(&adev->num_evictions);
|
||||
atomic64_add(bo->base.size, &adev->num_bytes_moved);
|
||||
amdgpu_bo_move_notify(bo, evict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1568,7 +1572,7 @@ static int amdgpu_ttm_access_memory(struct ttm_buffer_object *bo,
|
|||
static void
|
||||
amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo)
|
||||
{
|
||||
amdgpu_bo_move_notify(bo, false);
|
||||
amdgpu_bo_move_notify(bo, false, NULL);
|
||||
}
|
||||
|
||||
static struct ttm_device_funcs amdgpu_bo_driver = {
|
||||
|
|
|
@ -61,6 +61,11 @@ void aqua_vanjaram_doorbell_index_init(struct amdgpu_device *adev)
|
|||
adev->doorbell_index.max_assignment = AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT << 1;
|
||||
}
|
||||
|
||||
static bool aqua_vanjaram_xcp_vcn_shared(struct amdgpu_device *adev)
|
||||
{
|
||||
return (adev->xcp_mgr->num_xcps > adev->vcn.num_vcn_inst);
|
||||
}
|
||||
|
||||
static void aqua_vanjaram_set_xcp_id(struct amdgpu_device *adev,
|
||||
uint32_t inst_idx, struct amdgpu_ring *ring)
|
||||
{
|
||||
|
@ -86,7 +91,7 @@ static void aqua_vanjaram_set_xcp_id(struct amdgpu_device *adev,
|
|||
case AMDGPU_RING_TYPE_VCN_ENC:
|
||||
case AMDGPU_RING_TYPE_VCN_JPEG:
|
||||
ip_blk = AMDGPU_XCP_VCN;
|
||||
if (adev->xcp_mgr->mode == AMDGPU_CPX_PARTITION_MODE)
|
||||
if (aqua_vanjaram_xcp_vcn_shared(adev))
|
||||
inst_mask = 1 << (inst_idx * 2);
|
||||
break;
|
||||
default:
|
||||
|
@ -139,10 +144,12 @@ static int aqua_vanjaram_xcp_sched_list_update(
|
|||
|
||||
aqua_vanjaram_xcp_gpu_sched_update(adev, ring, ring->xcp_id);
|
||||
|
||||
/* VCN is shared by two partitions under CPX MODE */
|
||||
/* VCN may be shared by two partitions under CPX MODE in certain
|
||||
* configs.
|
||||
*/
|
||||
if ((ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC ||
|
||||
ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) &&
|
||||
adev->xcp_mgr->mode == AMDGPU_CPX_PARTITION_MODE)
|
||||
ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) &&
|
||||
aqua_vanjaram_xcp_vcn_shared(adev))
|
||||
aqua_vanjaram_xcp_gpu_sched_update(adev, ring, ring->xcp_id + 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1613,19 +1613,9 @@ static int sdma_v4_4_2_set_ecc_irq_state(struct amdgpu_device *adev,
|
|||
u32 sdma_cntl;
|
||||
|
||||
sdma_cntl = RREG32_SDMA(type, regSDMA_CNTL);
|
||||
switch (state) {
|
||||
case AMDGPU_IRQ_STATE_DISABLE:
|
||||
sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL,
|
||||
DRAM_ECC_INT_ENABLE, 0);
|
||||
WREG32_SDMA(type, regSDMA_CNTL, sdma_cntl);
|
||||
break;
|
||||
/* sdma ecc interrupt is enabled by default
|
||||
* driver doesn't need to do anything to
|
||||
* enable the interrupt */
|
||||
case AMDGPU_IRQ_STATE_ENABLE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL, DRAM_ECC_INT_ENABLE,
|
||||
state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
|
||||
WREG32_SDMA(type, regSDMA_CNTL, sdma_cntl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1138,7 +1138,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
|
|||
goto err_unlock;
|
||||
}
|
||||
offset = dev->adev->rmmio_remap.bus_addr;
|
||||
if (!offset) {
|
||||
if (!offset || (PAGE_SIZE > 4096)) {
|
||||
err = -ENOMEM;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
@ -1516,7 +1516,7 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep,
|
|||
|
||||
/* Find a KFD GPU device that supports the get_dmabuf_info query */
|
||||
for (i = 0; kfd_topology_enum_kfd_devices(i, &dev) == 0; i++)
|
||||
if (dev)
|
||||
if (dev && !kfd_devcgroup_check_permission(dev))
|
||||
break;
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
@ -1538,7 +1538,7 @@ static int kfd_ioctl_get_dmabuf_info(struct file *filep,
|
|||
if (xcp_id >= 0)
|
||||
args->gpu_id = dmabuf_adev->kfd.dev->nodes[xcp_id]->id;
|
||||
else
|
||||
args->gpu_id = dmabuf_adev->kfd.dev->nodes[0]->id;
|
||||
args->gpu_id = dev->id;
|
||||
args->flags = flags;
|
||||
|
||||
/* Copy metadata buffer to user mode */
|
||||
|
@ -2307,7 +2307,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
|
|||
return -EINVAL;
|
||||
}
|
||||
offset = pdd->dev->adev->rmmio_remap.bus_addr;
|
||||
if (!offset) {
|
||||
if (!offset || (PAGE_SIZE > 4096)) {
|
||||
pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -3348,6 +3348,9 @@ static int kfd_mmio_mmap(struct kfd_node *dev, struct kfd_process *process,
|
|||
if (vma->vm_end - vma->vm_start != PAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (PAGE_SIZE > 4096)
|
||||
return -EINVAL;
|
||||
|
||||
address = dev->adev->rmmio_remap.bus_addr;
|
||||
|
||||
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
|
||||
|
|
|
@ -935,7 +935,6 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
|
|||
{
|
||||
struct kfd_node *node;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
if (!kfd->init_complete)
|
||||
return;
|
||||
|
@ -943,12 +942,10 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
|
|||
/* for runtime suspend, skip locking kfd */
|
||||
if (!run_pm) {
|
||||
mutex_lock(&kfd_processes_mutex);
|
||||
count = ++kfd_locked;
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
|
||||
/* For first KFD device suspend all the KFD processes */
|
||||
if (count == 1)
|
||||
if (++kfd_locked == 1)
|
||||
kfd_suspend_all_processes();
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
}
|
||||
|
||||
for (i = 0; i < kfd->num_nodes; i++) {
|
||||
|
@ -959,7 +956,7 @@ void kgd2kfd_suspend(struct kfd_dev *kfd, bool run_pm)
|
|||
|
||||
int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
|
||||
{
|
||||
int ret, count, i;
|
||||
int ret, i;
|
||||
|
||||
if (!kfd->init_complete)
|
||||
return 0;
|
||||
|
@ -973,12 +970,10 @@ int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
|
|||
/* for runtime resume, skip unlocking kfd */
|
||||
if (!run_pm) {
|
||||
mutex_lock(&kfd_processes_mutex);
|
||||
count = --kfd_locked;
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
|
||||
WARN_ONCE(count < 0, "KFD suspend / resume ref. error");
|
||||
if (count == 0)
|
||||
if (--kfd_locked == 0)
|
||||
ret = kfd_resume_all_processes();
|
||||
WARN_ONCE(kfd_locked < 0, "KFD suspend / resume ref. error");
|
||||
mutex_unlock(&kfd_processes_mutex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -336,7 +336,8 @@ static void event_interrupt_wq_v10(struct kfd_node *dev,
|
|||
break;
|
||||
}
|
||||
kfd_signal_event_interrupt(pasid, context_id0 & 0x7fffff, 23);
|
||||
} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) {
|
||||
} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE &&
|
||||
KFD_DBG_EC_TYPE_IS_PACKET(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0))) {
|
||||
kfd_set_dbg_ev_from_interrupt(dev, pasid,
|
||||
KFD_DEBUG_DOORBELL_ID(context_id0),
|
||||
KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)),
|
||||
|
|
|
@ -325,7 +325,8 @@ static void event_interrupt_wq_v11(struct kfd_node *dev,
|
|||
/* CP */
|
||||
if (source_id == SOC15_INTSRC_CP_END_OF_PIPE)
|
||||
kfd_signal_event_interrupt(pasid, context_id0, 32);
|
||||
else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE)
|
||||
else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE &&
|
||||
KFD_DBG_EC_TYPE_IS_PACKET(KFD_CTXID0_CP_BAD_OP_ECODE(context_id0)))
|
||||
kfd_set_dbg_ev_from_interrupt(dev, pasid,
|
||||
KFD_CTXID0_DOORBELL_ID(context_id0),
|
||||
KFD_EC_MASK(KFD_CTXID0_CP_BAD_OP_ECODE(context_id0)),
|
||||
|
|
|
@ -385,7 +385,8 @@ static void event_interrupt_wq_v9(struct kfd_node *dev,
|
|||
break;
|
||||
}
|
||||
kfd_signal_event_interrupt(pasid, sq_int_data, 24);
|
||||
} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) {
|
||||
} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE &&
|
||||
KFD_DBG_EC_TYPE_IS_PACKET(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0))) {
|
||||
kfd_set_dbg_ev_from_interrupt(dev, pasid,
|
||||
KFD_DEBUG_DOORBELL_ID(context_id0),
|
||||
KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)),
|
||||
|
|
|
@ -2974,6 +2974,10 @@ static int dm_resume(void *handle)
|
|||
/* Do mst topology probing after resuming cached state*/
|
||||
drm_connector_list_iter_begin(ddev, &iter);
|
||||
drm_for_each_connector_iter(connector, &iter) {
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
|
||||
continue;
|
||||
|
||||
aconnector = to_amdgpu_dm_connector(connector);
|
||||
if (aconnector->dc_link->type != dc_connection_mst_branch ||
|
||||
aconnector->mst_root)
|
||||
|
@ -5756,6 +5760,9 @@ get_highest_refresh_rate_mode(struct amdgpu_dm_connector *aconnector,
|
|||
&aconnector->base.probed_modes :
|
||||
&aconnector->base.modes;
|
||||
|
||||
if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
|
||||
return NULL;
|
||||
|
||||
if (aconnector->freesync_vid_base.clock != 0)
|
||||
return &aconnector->freesync_vid_base;
|
||||
|
||||
|
@ -8445,6 +8452,9 @@ static void amdgpu_dm_commit_audio(struct drm_device *dev,
|
|||
continue;
|
||||
|
||||
notify:
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
|
||||
continue;
|
||||
|
||||
aconnector = to_amdgpu_dm_connector(connector);
|
||||
|
||||
mutex_lock(&adev->dm.audio_lock);
|
||||
|
|
|
@ -1465,7 +1465,9 @@ static ssize_t dp_dsc_clock_en_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1566,7 +1568,9 @@ static ssize_t dp_dsc_clock_en_write(struct file *f, const char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1651,7 +1655,9 @@ static ssize_t dp_dsc_slice_width_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1750,7 +1756,9 @@ static ssize_t dp_dsc_slice_width_write(struct file *f, const char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1835,7 +1843,9 @@ static ssize_t dp_dsc_slice_height_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1934,7 +1944,9 @@ static ssize_t dp_dsc_slice_height_write(struct file *f, const char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2015,7 +2027,9 @@ static ssize_t dp_dsc_bits_per_pixel_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2111,7 +2125,9 @@ static ssize_t dp_dsc_bits_per_pixel_write(struct file *f, const char __user *bu
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2190,7 +2206,9 @@ static ssize_t dp_dsc_pic_width_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2246,7 +2264,9 @@ static ssize_t dp_dsc_pic_height_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2317,7 +2337,9 @@ static ssize_t dp_dsc_chunk_size_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2388,7 +2410,9 @@ static ssize_t dp_dsc_slice_bpg_offset_read(struct file *f, char __user *buf,
|
|||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx->stream &&
|
||||
pipe_ctx->stream->link == aconnector->dc_link)
|
||||
pipe_ctx->stream->link == aconnector->dc_link &&
|
||||
pipe_ctx->stream->sink &&
|
||||
pipe_ctx->stream->sink == aconnector->dc_sink)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -2961,6 +2961,7 @@ static enum bp_result construct_integrated_info(
|
|||
result = get_integrated_info_v2_1(bp, info);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
result = get_integrated_info_v2_2(bp, info);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -395,6 +395,12 @@ void dcn31_hpo_dp_link_enc_set_throttled_vcp_size(
|
|||
x),
|
||||
25));
|
||||
|
||||
// If y rounds up to integer, carry it over to x.
|
||||
if (y >> 25) {
|
||||
x += 1;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
switch (stream_encoder_inst) {
|
||||
case 0:
|
||||
REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0,
|
||||
|
|
|
@ -226,7 +226,7 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en)
|
|||
struct amdgpu_device *adev = smu->adev;
|
||||
int ret = 0;
|
||||
|
||||
if (!en && !adev->in_s0ix) {
|
||||
if (!en && adev->in_s4) {
|
||||
/* Adds a GFX reset as workaround just before sending the
|
||||
* MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
|
||||
* an invalid state.
|
||||
|
|
|
@ -2925,7 +2925,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
|
|||
dev->mode_config.max_width,
|
||||
dev->mode_config.max_height);
|
||||
else
|
||||
drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe",
|
||||
drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe\n",
|
||||
connector->base.id, connector->name);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,19 +75,6 @@ struct intel_audio_funcs {
|
|||
struct intel_crtc_state *crtc_state);
|
||||
};
|
||||
|
||||
/* DP N/M table */
|
||||
#define LC_810M 810000
|
||||
#define LC_540M 540000
|
||||
#define LC_270M 270000
|
||||
#define LC_162M 162000
|
||||
|
||||
struct dp_aud_n_m {
|
||||
int sample_rate;
|
||||
int clock;
|
||||
u16 m;
|
||||
u16 n;
|
||||
};
|
||||
|
||||
struct hdmi_aud_ncts {
|
||||
int sample_rate;
|
||||
int clock;
|
||||
|
@ -95,60 +82,6 @@ struct hdmi_aud_ncts {
|
|||
int cts;
|
||||
};
|
||||
|
||||
/* Values according to DP 1.4 Table 2-104 */
|
||||
static const struct dp_aud_n_m dp_aud_n_m[] = {
|
||||
{ 32000, LC_162M, 1024, 10125 },
|
||||
{ 44100, LC_162M, 784, 5625 },
|
||||
{ 48000, LC_162M, 512, 3375 },
|
||||
{ 64000, LC_162M, 2048, 10125 },
|
||||
{ 88200, LC_162M, 1568, 5625 },
|
||||
{ 96000, LC_162M, 1024, 3375 },
|
||||
{ 128000, LC_162M, 4096, 10125 },
|
||||
{ 176400, LC_162M, 3136, 5625 },
|
||||
{ 192000, LC_162M, 2048, 3375 },
|
||||
{ 32000, LC_270M, 1024, 16875 },
|
||||
{ 44100, LC_270M, 784, 9375 },
|
||||
{ 48000, LC_270M, 512, 5625 },
|
||||
{ 64000, LC_270M, 2048, 16875 },
|
||||
{ 88200, LC_270M, 1568, 9375 },
|
||||
{ 96000, LC_270M, 1024, 5625 },
|
||||
{ 128000, LC_270M, 4096, 16875 },
|
||||
{ 176400, LC_270M, 3136, 9375 },
|
||||
{ 192000, LC_270M, 2048, 5625 },
|
||||
{ 32000, LC_540M, 1024, 33750 },
|
||||
{ 44100, LC_540M, 784, 18750 },
|
||||
{ 48000, LC_540M, 512, 11250 },
|
||||
{ 64000, LC_540M, 2048, 33750 },
|
||||
{ 88200, LC_540M, 1568, 18750 },
|
||||
{ 96000, LC_540M, 1024, 11250 },
|
||||
{ 128000, LC_540M, 4096, 33750 },
|
||||
{ 176400, LC_540M, 3136, 18750 },
|
||||
{ 192000, LC_540M, 2048, 11250 },
|
||||
{ 32000, LC_810M, 1024, 50625 },
|
||||
{ 44100, LC_810M, 784, 28125 },
|
||||
{ 48000, LC_810M, 512, 16875 },
|
||||
{ 64000, LC_810M, 2048, 50625 },
|
||||
{ 88200, LC_810M, 1568, 28125 },
|
||||
{ 96000, LC_810M, 1024, 16875 },
|
||||
{ 128000, LC_810M, 4096, 50625 },
|
||||
{ 176400, LC_810M, 3136, 28125 },
|
||||
{ 192000, LC_810M, 2048, 16875 },
|
||||
};
|
||||
|
||||
static const struct dp_aud_n_m *
|
||||
audio_config_dp_get_n_m(const struct intel_crtc_state *crtc_state, int rate)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) {
|
||||
if (rate == dp_aud_n_m[i].sample_rate &&
|
||||
crtc_state->port_clock == dp_aud_n_m[i].clock)
|
||||
return &dp_aud_n_m[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
int clock;
|
||||
u32 config;
|
||||
|
@ -386,47 +319,17 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
|
|||
const struct intel_crtc_state *crtc_state)
|
||||
{
|
||||
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
|
||||
struct i915_audio_component *acomp = i915->display.audio.component;
|
||||
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
|
||||
enum port port = encoder->port;
|
||||
const struct dp_aud_n_m *nm;
|
||||
int rate;
|
||||
u32 tmp;
|
||||
|
||||
rate = acomp ? acomp->aud_sample_rate[port] : 0;
|
||||
nm = audio_config_dp_get_n_m(crtc_state, rate);
|
||||
if (nm)
|
||||
drm_dbg_kms(&i915->drm, "using Maud %u, Naud %u\n", nm->m,
|
||||
nm->n);
|
||||
else
|
||||
drm_dbg_kms(&i915->drm, "using automatic Maud, Naud\n");
|
||||
/* Enable time stamps. Let HW calculate Maud/Naud values */
|
||||
intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
|
||||
AUD_CONFIG_N_VALUE_INDEX |
|
||||
AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK |
|
||||
AUD_CONFIG_UPPER_N_MASK |
|
||||
AUD_CONFIG_LOWER_N_MASK |
|
||||
AUD_CONFIG_N_PROG_ENABLE,
|
||||
AUD_CONFIG_N_VALUE_INDEX);
|
||||
|
||||
tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
|
||||
tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
|
||||
tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
|
||||
tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
|
||||
tmp |= AUD_CONFIG_N_VALUE_INDEX;
|
||||
|
||||
if (nm) {
|
||||
tmp &= ~AUD_CONFIG_N_MASK;
|
||||
tmp |= AUD_CONFIG_N(nm->n);
|
||||
tmp |= AUD_CONFIG_N_PROG_ENABLE;
|
||||
}
|
||||
|
||||
intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
|
||||
|
||||
tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
|
||||
tmp &= ~AUD_CONFIG_M_MASK;
|
||||
tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
|
||||
tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
|
||||
|
||||
if (nm) {
|
||||
tmp |= nm->m;
|
||||
tmp |= AUD_M_CTS_M_VALUE_INDEX;
|
||||
tmp |= AUD_M_CTS_M_PROG_ENABLE;
|
||||
}
|
||||
|
||||
intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1035,22 +1035,11 @@ parse_lfp_backlight(struct drm_i915_private *i915,
|
|||
panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
|
||||
panel->vbt.backlight.controller = 0;
|
||||
if (i915->display.vbt.version >= 191) {
|
||||
size_t exp_size;
|
||||
const struct lfp_backlight_control_method *method;
|
||||
|
||||
if (i915->display.vbt.version >= 236)
|
||||
exp_size = sizeof(struct bdb_lfp_backlight_data);
|
||||
else if (i915->display.vbt.version >= 234)
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
|
||||
else
|
||||
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
|
||||
|
||||
if (get_blocksize(backlight_data) >= exp_size) {
|
||||
const struct lfp_backlight_control_method *method;
|
||||
|
||||
method = &backlight_data->backlight_control[panel_type];
|
||||
panel->vbt.backlight.type = method->type;
|
||||
panel->vbt.backlight.controller = method->controller;
|
||||
}
|
||||
method = &backlight_data->backlight_control[panel_type];
|
||||
panel->vbt.backlight.type = method->type;
|
||||
panel->vbt.backlight.controller = method->controller;
|
||||
}
|
||||
|
||||
panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
|
||||
|
|
|
@ -897,11 +897,6 @@ struct lfp_brightness_level {
|
|||
u16 reserved;
|
||||
} __packed;
|
||||
|
||||
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
|
||||
offsetof(struct bdb_lfp_backlight_data, brightness_level)
|
||||
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
|
||||
offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
|
||||
|
||||
struct bdb_lfp_backlight_data {
|
||||
u8 entry_size;
|
||||
struct lfp_backlight_data_entry data[16];
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
#include "intel_gt_ccs_mode.h"
|
||||
#include "intel_gt_regs.h"
|
||||
|
||||
void intel_gt_apply_ccs_mode(struct intel_gt *gt)
|
||||
unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt)
|
||||
{
|
||||
int cslice;
|
||||
u32 mode = 0;
|
||||
int first_ccs = __ffs(CCS_MASK(gt));
|
||||
|
||||
if (!IS_DG2(gt->i915))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
/* Build the value for the fixed CCS load balancing */
|
||||
for (cslice = 0; cslice < I915_MAX_CCS; cslice++) {
|
||||
|
@ -35,5 +35,5 @@ void intel_gt_apply_ccs_mode(struct intel_gt *gt)
|
|||
XEHP_CCS_MODE_CSLICE_MASK);
|
||||
}
|
||||
|
||||
intel_uncore_write(gt->uncore, XEHP_CCS_MODE, mode);
|
||||
return mode;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
|
||||
struct intel_gt;
|
||||
|
||||
void intel_gt_apply_ccs_mode(struct intel_gt *gt);
|
||||
unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt);
|
||||
|
||||
#endif /* __INTEL_GT_CCS_MODE_H__ */
|
||||
|
|
|
@ -2828,6 +2828,7 @@ add_render_compute_tuning_settings(struct intel_gt *gt,
|
|||
static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)
|
||||
{
|
||||
struct intel_gt *gt = engine->gt;
|
||||
u32 mode;
|
||||
|
||||
if (!IS_DG2(gt->i915))
|
||||
return;
|
||||
|
@ -2844,7 +2845,8 @@ static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_li
|
|||
* After having disabled automatic load balancing we need to
|
||||
* assign all slices to a single CCS. We will call it CCS mode 1
|
||||
*/
|
||||
intel_gt_apply_ccs_mode(gt);
|
||||
mode = intel_gt_apply_ccs_mode(gt);
|
||||
wa_masked_en(wal, XEHP_CCS_MODE, mode);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -106,6 +106,8 @@
|
|||
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */
|
||||
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */
|
||||
#define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */
|
||||
#define PHY_CNTL1_INIT 0x03900000
|
||||
#define PHY_INVERT BIT(17)
|
||||
#define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */
|
||||
#define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */
|
||||
#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */
|
||||
|
@ -130,6 +132,8 @@ struct meson_dw_hdmi_data {
|
|||
unsigned int addr);
|
||||
void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
|
||||
unsigned int addr, unsigned int data);
|
||||
u32 cntl0_init;
|
||||
u32 cntl1_init;
|
||||
};
|
||||
|
||||
struct meson_dw_hdmi {
|
||||
|
@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
|||
dw_hdmi_bus_fmt_is_420(hdmi))
|
||||
mode_is_420 = true;
|
||||
|
||||
/* Enable clocks */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
|
||||
|
||||
/* Bring HDMITX MEM output of power down */
|
||||
regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
|
||||
|
||||
/* Bring out of reset */
|
||||
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0);
|
||||
|
||||
/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
|
||||
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
|
||||
0x3, 0x3);
|
||||
|
||||
/* Enable cec_clk and hdcp22_tmdsclk_en */
|
||||
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
|
||||
0x3 << 4, 0x3 << 4);
|
||||
|
||||
/* Enable normal output to PHY */
|
||||
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
|
||||
|
||||
/* TMDS pattern setup */
|
||||
if (mode->clock > 340000 && !mode_is_420) {
|
||||
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
|
||||
|
@ -425,20 +409,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
|
|||
/* Setup PHY parameters */
|
||||
meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420);
|
||||
|
||||
/* Setup PHY */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
|
||||
0xffff << 16, 0x0390 << 16);
|
||||
|
||||
/* BIT_INVERT */
|
||||
if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
|
||||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
|
||||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
|
||||
BIT(17), 0);
|
||||
else
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
|
||||
BIT(17), BIT(17));
|
||||
|
||||
/* Disable clock, fifo, fifo_wr */
|
||||
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
|
||||
|
||||
|
@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
|
|||
|
||||
DRM_DEBUG_DRIVER("\n");
|
||||
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
|
||||
/* Fallback to init mode */
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init);
|
||||
}
|
||||
|
||||
static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
|
||||
|
@ -610,11 +582,22 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
|
|||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = {
|
||||
.top_read = dw_hdmi_top_read,
|
||||
.top_write = dw_hdmi_top_write,
|
||||
.dwc_read = dw_hdmi_dwc_read,
|
||||
.dwc_write = dw_hdmi_dwc_write,
|
||||
.cntl0_init = 0x0,
|
||||
.cntl1_init = PHY_CNTL1_INIT | PHY_INVERT,
|
||||
};
|
||||
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
|
||||
.top_read = dw_hdmi_top_read,
|
||||
.top_write = dw_hdmi_top_write,
|
||||
.dwc_read = dw_hdmi_dwc_read,
|
||||
.dwc_write = dw_hdmi_dwc_write,
|
||||
.cntl0_init = 0x0,
|
||||
.cntl1_init = PHY_CNTL1_INIT,
|
||||
};
|
||||
|
||||
static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
|
||||
|
@ -622,6 +605,8 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
|
|||
.top_write = dw_hdmi_g12a_top_write,
|
||||
.dwc_read = dw_hdmi_g12a_dwc_read,
|
||||
.dwc_write = dw_hdmi_g12a_dwc_write,
|
||||
.cntl0_init = 0x000b4242, /* Bandgap */
|
||||
.cntl1_init = PHY_CNTL1_INIT,
|
||||
};
|
||||
|
||||
static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
|
||||
|
@ -656,6 +641,13 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
|
|||
meson_dw_hdmi->data->top_write(meson_dw_hdmi,
|
||||
HDMITX_TOP_CLK_CNTL, 0xff);
|
||||
|
||||
/* Enable normal output to PHY */
|
||||
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
|
||||
|
||||
/* Setup PHY */
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init);
|
||||
|
||||
/* Enable HDMI-TX Interrupt */
|
||||
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
|
||||
HDMITX_TOP_INTR_CORE);
|
||||
|
@ -865,11 +857,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = {
|
|||
|
||||
static const struct of_device_id meson_dw_hdmi_of_table[] = {
|
||||
{ .compatible = "amlogic,meson-gxbb-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_gx_data },
|
||||
.data = &meson_dw_hdmi_gxbb_data },
|
||||
{ .compatible = "amlogic,meson-gxl-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_gx_data },
|
||||
.data = &meson_dw_hdmi_gxl_data },
|
||||
{ .compatible = "amlogic,meson-gxm-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_gx_data },
|
||||
.data = &meson_dw_hdmi_gxl_data },
|
||||
{ .compatible = "amlogic,meson-g12a-dw-hdmi",
|
||||
.data = &meson_dw_hdmi_g12a_data },
|
||||
{ }
|
||||
|
|
|
@ -108,12 +108,15 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
|
|||
u8 *dpcd = nv_encoder->dp.dpcd;
|
||||
int ret = NOUVEAU_DP_NONE, hpd;
|
||||
|
||||
/* If we've already read the DPCD on an eDP device, we don't need to
|
||||
* reread it as it won't change
|
||||
/* eDP ports don't support hotplugging - so there's no point in probing eDP ports unless we
|
||||
* haven't probed them once before.
|
||||
*/
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP &&
|
||||
dpcd[DP_DPCD_REV] != 0)
|
||||
return NOUVEAU_DP_SST;
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
if (connector->status == connector_status_connected)
|
||||
return NOUVEAU_DP_SST;
|
||||
else if (connector->status == connector_status_disconnected)
|
||||
return NOUVEAU_DP_NONE;
|
||||
}
|
||||
|
||||
mutex_lock(&nv_encoder->dp.hpd_irq_lock);
|
||||
if (mstm) {
|
||||
|
|
|
@ -184,7 +184,7 @@ config DRM_PANEL_ILITEK_IL9322
|
|||
|
||||
config DRM_PANEL_ILITEK_ILI9341
|
||||
tristate "Ilitek ILI9341 240x320 QVGA panels"
|
||||
depends on OF && SPI
|
||||
depends on SPI
|
||||
select DRM_KMS_HELPER
|
||||
select DRM_GEM_DMA_HELPER
|
||||
depends on BACKLIGHT_CLASS_DEVICE
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
#include <linux/bitops.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
||||
|
@ -421,7 +422,7 @@ static int ili9341_dpi_prepare(struct drm_panel *panel)
|
|||
|
||||
ili9341_dpi_init(ili);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ili9341_dpi_enable(struct drm_panel *panel)
|
||||
|
@ -691,7 +692,7 @@ static int ili9341_dpi_probe(struct spi_device *spi, struct gpio_desc *dc,
|
|||
* Every new incarnation of this display must have a unique
|
||||
* data entry for the system in this driver.
|
||||
*/
|
||||
ili->conf = of_device_get_match_data(dev);
|
||||
ili->conf = device_get_match_data(dev);
|
||||
if (!ili->conf) {
|
||||
dev_err(dev, "missing device configuration\n");
|
||||
return -ENODEV;
|
||||
|
@ -714,18 +715,18 @@ static int ili9341_probe(struct spi_device *spi)
|
|||
|
||||
reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(reset))
|
||||
dev_err(dev, "Failed to get gpio 'reset'\n");
|
||||
return dev_err_probe(dev, PTR_ERR(reset), "Failed to get gpio 'reset'\n");
|
||||
|
||||
dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(dc))
|
||||
dev_err(dev, "Failed to get gpio 'dc'\n");
|
||||
return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n");
|
||||
|
||||
if (!strcmp(id->name, "sf-tc240t-9370-t"))
|
||||
return ili9341_dpi_probe(spi, dc, reset);
|
||||
else if (!strcmp(id->name, "yx240qv29"))
|
||||
return ili9341_dbi_probe(spi, dc, reset);
|
||||
|
||||
return -1;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void ili9341_remove(struct spi_device *spi)
|
||||
|
|
|
@ -58,56 +58,16 @@ static long qxl_fence_wait(struct dma_fence *fence, bool intr,
|
|||
signed long timeout)
|
||||
{
|
||||
struct qxl_device *qdev;
|
||||
struct qxl_release *release;
|
||||
int count = 0, sc = 0;
|
||||
bool have_drawable_releases;
|
||||
unsigned long cur, end = jiffies + timeout;
|
||||
|
||||
qdev = container_of(fence->lock, struct qxl_device, release_lock);
|
||||
release = container_of(fence, struct qxl_release, base);
|
||||
have_drawable_releases = release->type == QXL_RELEASE_DRAWABLE;
|
||||
|
||||
retry:
|
||||
sc++;
|
||||
if (!wait_event_timeout(qdev->release_event,
|
||||
(dma_fence_is_signaled(fence) ||
|
||||
(qxl_io_notify_oom(qdev), 0)),
|
||||
timeout))
|
||||
return 0;
|
||||
|
||||
if (dma_fence_is_signaled(fence))
|
||||
goto signaled;
|
||||
|
||||
qxl_io_notify_oom(qdev);
|
||||
|
||||
for (count = 0; count < 11; count++) {
|
||||
if (!qxl_queue_garbage_collect(qdev, true))
|
||||
break;
|
||||
|
||||
if (dma_fence_is_signaled(fence))
|
||||
goto signaled;
|
||||
}
|
||||
|
||||
if (dma_fence_is_signaled(fence))
|
||||
goto signaled;
|
||||
|
||||
if (have_drawable_releases || sc < 4) {
|
||||
if (sc > 2)
|
||||
/* back off */
|
||||
usleep_range(500, 1000);
|
||||
|
||||
if (time_after(jiffies, end))
|
||||
return 0;
|
||||
|
||||
if (have_drawable_releases && sc > 300) {
|
||||
DMA_FENCE_WARN(fence,
|
||||
"failed to wait on release %llu after spincount %d\n",
|
||||
fence->context & ~0xf0000000, sc);
|
||||
goto signaled;
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
/*
|
||||
* yeah, original sync_obj_wait gave up after 3 spins when
|
||||
* have_drawable_releases is not set.
|
||||
*/
|
||||
|
||||
signaled:
|
||||
cur = jiffies;
|
||||
if (time_after(cur, end))
|
||||
return 0;
|
||||
|
|
|
@ -424,7 +424,7 @@ typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{
|
|||
typedef struct _ATOM_PPLIB_STATE_V2
|
||||
{
|
||||
//number of valid dpm levels in this state; Driver uses it to calculate the whole
|
||||
//size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR)
|
||||
//size of the state: struct_size(ATOM_PPLIB_STATE_V2, clockInfoIndex, ucNumDPMLevels)
|
||||
UCHAR ucNumDPMLevels;
|
||||
|
||||
//a index to the array of nonClockInfos
|
||||
|
@ -432,14 +432,14 @@ typedef struct _ATOM_PPLIB_STATE_V2
|
|||
/**
|
||||
* Driver will read the first ucNumDPMLevels in this array
|
||||
*/
|
||||
UCHAR clockInfoIndex[1];
|
||||
UCHAR clockInfoIndex[] __counted_by(ucNumDPMLevels);
|
||||
} ATOM_PPLIB_STATE_V2;
|
||||
|
||||
typedef struct _StateArray{
|
||||
//how many states we have
|
||||
UCHAR ucNumEntries;
|
||||
|
||||
ATOM_PPLIB_STATE_V2 states[1];
|
||||
ATOM_PPLIB_STATE_V2 states[] __counted_by(ucNumEntries);
|
||||
}StateArray;
|
||||
|
||||
|
||||
|
@ -450,7 +450,7 @@ typedef struct _ClockInfoArray{
|
|||
//sizeof(ATOM_PPLIB_CLOCK_INFO)
|
||||
UCHAR ucEntrySize;
|
||||
|
||||
UCHAR clockInfo[1];
|
||||
UCHAR clockInfo[] __counted_by(ucNumEntries);
|
||||
}ClockInfoArray;
|
||||
|
||||
typedef struct _NonClockInfoArray{
|
||||
|
@ -460,7 +460,7 @@ typedef struct _NonClockInfoArray{
|
|||
//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
|
||||
UCHAR ucEntrySize;
|
||||
|
||||
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1];
|
||||
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries);
|
||||
}NonClockInfoArray;
|
||||
|
||||
typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
|
||||
|
|
|
@ -92,7 +92,7 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc)
|
|||
*/
|
||||
if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
|
||||
page_flags |= TTM_TT_FLAG_DECRYPTED;
|
||||
drm_info(ddev, "TT memory decryption enabled.");
|
||||
drm_info_once(ddev, "TT memory decryption enabled.");
|
||||
}
|
||||
|
||||
bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags);
|
||||
|
|
|
@ -204,6 +204,7 @@ int vmw_bo_pin_in_start_of_vram(struct vmw_private *dev_priv,
|
|||
VMW_BO_DOMAIN_VRAM,
|
||||
VMW_BO_DOMAIN_VRAM);
|
||||
buf->places[0].lpfn = PFN_UP(bo->resource->size);
|
||||
buf->busy_places[0].lpfn = PFN_UP(bo->resource->size);
|
||||
ret = ttm_bo_validate(bo, &buf->placement, &ctx);
|
||||
|
||||
/* For some reason we didn't end up at the start of vram */
|
||||
|
|
|
@ -991,7 +991,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv,
|
|||
}
|
||||
|
||||
event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
|
||||
event->event.base.length = sizeof(*event);
|
||||
event->event.base.length = sizeof(event->event);
|
||||
event->event.user_data = user_data;
|
||||
|
||||
ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
|
||||
|
|
|
@ -351,11 +351,6 @@ static int host1x_device_uevent(const struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int host1x_dma_configure(struct device *dev)
|
||||
{
|
||||
return of_dma_configure(dev, dev->of_node, true);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops host1x_device_pm_ops = {
|
||||
.suspend = pm_generic_suspend,
|
||||
.resume = pm_generic_resume,
|
||||
|
@ -369,7 +364,6 @@ struct bus_type host1x_bus_type = {
|
|||
.name = "host1x",
|
||||
.match = host1x_device_match,
|
||||
.uevent = host1x_device_uevent,
|
||||
.dma_configure = host1x_dma_configure,
|
||||
.pm = &host1x_device_pm_ops,
|
||||
};
|
||||
|
||||
|
@ -458,8 +452,6 @@ static int host1x_device_add(struct host1x *host1x,
|
|||
device->dev.bus = &host1x_bus_type;
|
||||
device->dev.parent = host1x->dev;
|
||||
|
||||
of_dma_configure(&device->dev, host1x->dev->of_node, true);
|
||||
|
||||
device->dev.dma_parms = &device->dma_parms;
|
||||
dma_set_max_seg_size(&device->dev, UINT_MAX);
|
||||
|
||||
|
|
|
@ -153,7 +153,9 @@ void vmbus_free_ring(struct vmbus_channel *channel)
|
|||
hv_ringbuffer_cleanup(&channel->inbound);
|
||||
|
||||
if (channel->ringbuffer_page) {
|
||||
__free_pages(channel->ringbuffer_page,
|
||||
/* In a CoCo VM leak the memory if it didn't get re-encrypted */
|
||||
if (!channel->ringbuffer_gpadlhandle.decrypted)
|
||||
__free_pages(channel->ringbuffer_page,
|
||||
get_order(channel->ringbuffer_pagecount
|
||||
<< PAGE_SHIFT));
|
||||
channel->ringbuffer_page = NULL;
|
||||
|
@ -472,9 +474,18 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel,
|
|||
(atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1);
|
||||
|
||||
ret = create_gpadl_header(type, kbuffer, size, send_offset, &msginfo);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
gpadl->decrypted = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the "decrypted" flag to true for the set_memory_decrypted()
|
||||
* success case. In the failure case, the encryption state of the
|
||||
* memory is unknown. Leave "decrypted" as true to ensure the
|
||||
* memory will be leaked instead of going back on the free list.
|
||||
*/
|
||||
gpadl->decrypted = true;
|
||||
ret = set_memory_decrypted((unsigned long)kbuffer,
|
||||
PFN_UP(size));
|
||||
if (ret) {
|
||||
|
@ -563,9 +574,15 @@ cleanup:
|
|||
|
||||
kfree(msginfo);
|
||||
|
||||
if (ret)
|
||||
set_memory_encrypted((unsigned long)kbuffer,
|
||||
PFN_UP(size));
|
||||
if (ret) {
|
||||
/*
|
||||
* If set_memory_encrypted() fails, the decrypted flag is
|
||||
* left as true so the memory is leaked instead of being
|
||||
* put back on the free list.
|
||||
*/
|
||||
if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size)))
|
||||
gpadl->decrypted = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -886,6 +903,8 @@ post_msg_err:
|
|||
if (ret)
|
||||
pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret);
|
||||
|
||||
gpadl->decrypted = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
|
||||
|
|
|
@ -237,8 +237,17 @@ int vmbus_connect(void)
|
|||
vmbus_connection.monitor_pages[0], 1);
|
||||
ret |= set_memory_decrypted((unsigned long)
|
||||
vmbus_connection.monitor_pages[1], 1);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
/*
|
||||
* If set_memory_decrypted() fails, the encryption state
|
||||
* of the memory is unknown. So leak the memory instead
|
||||
* of risking returning decrypted memory to the free list.
|
||||
* For simplicity, always handle both pages the same.
|
||||
*/
|
||||
vmbus_connection.monitor_pages[0] = NULL;
|
||||
vmbus_connection.monitor_pages[1] = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set_memory_decrypted() will change the memory contents if
|
||||
|
@ -337,13 +346,19 @@ void vmbus_disconnect(void)
|
|||
vmbus_connection.int_page = NULL;
|
||||
}
|
||||
|
||||
set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
|
||||
set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);
|
||||
if (vmbus_connection.monitor_pages[0]) {
|
||||
if (!set_memory_encrypted(
|
||||
(unsigned long)vmbus_connection.monitor_pages[0], 1))
|
||||
hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
|
||||
vmbus_connection.monitor_pages[0] = NULL;
|
||||
}
|
||||
|
||||
hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
|
||||
hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
|
||||
vmbus_connection.monitor_pages[0] = NULL;
|
||||
vmbus_connection.monitor_pages[1] = NULL;
|
||||
if (vmbus_connection.monitor_pages[1]) {
|
||||
if (!set_memory_encrypted(
|
||||
(unsigned long)vmbus_connection.monitor_pages[1], 1))
|
||||
hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
|
||||
vmbus_connection.monitor_pages[1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define USB_VENDOR_ID_CORSAIR 0x1b1c
|
||||
|
@ -77,8 +78,11 @@
|
|||
struct ccp_device {
|
||||
struct hid_device *hdev;
|
||||
struct device *hwmon_dev;
|
||||
/* For reinitializing the completion below */
|
||||
spinlock_t wait_input_report_lock;
|
||||
struct completion wait_input_report;
|
||||
struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
|
||||
u8 *cmd_buffer;
|
||||
u8 *buffer;
|
||||
int target[6];
|
||||
DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
|
||||
|
@ -111,15 +115,23 @@ static int send_usb_cmd(struct ccp_device *ccp, u8 command, u8 byte1, u8 byte2,
|
|||
unsigned long t;
|
||||
int ret;
|
||||
|
||||
memset(ccp->buffer, 0x00, OUT_BUFFER_SIZE);
|
||||
ccp->buffer[0] = command;
|
||||
ccp->buffer[1] = byte1;
|
||||
ccp->buffer[2] = byte2;
|
||||
ccp->buffer[3] = byte3;
|
||||
memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE);
|
||||
ccp->cmd_buffer[0] = command;
|
||||
ccp->cmd_buffer[1] = byte1;
|
||||
ccp->cmd_buffer[2] = byte2;
|
||||
ccp->cmd_buffer[3] = byte3;
|
||||
|
||||
/*
|
||||
* Disable raw event parsing for a moment to safely reinitialize the
|
||||
* completion. Reinit is done because hidraw could have triggered
|
||||
* the raw event parsing and marked the ccp->wait_input_report
|
||||
* completion as done.
|
||||
*/
|
||||
spin_lock_bh(&ccp->wait_input_report_lock);
|
||||
reinit_completion(&ccp->wait_input_report);
|
||||
spin_unlock_bh(&ccp->wait_input_report_lock);
|
||||
|
||||
ret = hid_hw_output_report(ccp->hdev, ccp->buffer, OUT_BUFFER_SIZE);
|
||||
ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -135,11 +147,12 @@ static int ccp_raw_event(struct hid_device *hdev, struct hid_report *report, u8
|
|||
struct ccp_device *ccp = hid_get_drvdata(hdev);
|
||||
|
||||
/* only copy buffer when requested */
|
||||
if (completion_done(&ccp->wait_input_report))
|
||||
return 0;
|
||||
|
||||
memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
|
||||
complete(&ccp->wait_input_report);
|
||||
spin_lock(&ccp->wait_input_report_lock);
|
||||
if (!completion_done(&ccp->wait_input_report)) {
|
||||
memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
|
||||
complete_all(&ccp->wait_input_report);
|
||||
}
|
||||
spin_unlock(&ccp->wait_input_report_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -492,7 +505,11 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
if (!ccp)
|
||||
return -ENOMEM;
|
||||
|
||||
ccp->buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
|
||||
ccp->cmd_buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
|
||||
if (!ccp->cmd_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
ccp->buffer = devm_kmalloc(&hdev->dev, IN_BUFFER_SIZE, GFP_KERNEL);
|
||||
if (!ccp->buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -510,7 +527,9 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
|
||||
ccp->hdev = hdev;
|
||||
hid_set_drvdata(hdev, ccp);
|
||||
|
||||
mutex_init(&ccp->mutex);
|
||||
spin_lock_init(&ccp->wait_input_report_lock);
|
||||
init_completion(&ccp->wait_input_report);
|
||||
|
||||
hid_device_io_start(hdev);
|
||||
|
|
|
@ -80,11 +80,11 @@ struct ucd9000_debugfs_entry {
|
|||
* It has been observed that the UCD90320 randomly fails register access when
|
||||
* doing another access right on the back of a register write. To mitigate this
|
||||
* make sure that there is a minimum delay between a write access and the
|
||||
* following access. The 250us is based on experimental data. At a delay of
|
||||
* 200us the issue seems to go away. Add a bit of extra margin to allow for
|
||||
* following access. The 500 is based on experimental data. At a delay of
|
||||
* 350us the issue seems to go away. Add a bit of extra margin to allow for
|
||||
* system to system differences.
|
||||
*/
|
||||
#define UCD90320_WAIT_DELAY_US 250
|
||||
#define UCD90320_WAIT_DELAY_US 500
|
||||
|
||||
static inline void ucd90320_wait(const struct ucd9000_data *data)
|
||||
{
|
||||
|
|
|
@ -27,9 +27,13 @@
|
|||
#define MXC4005_REG_ZOUT_UPPER 0x07
|
||||
#define MXC4005_REG_ZOUT_LOWER 0x08
|
||||
|
||||
#define MXC4005_REG_INT_MASK0 0x0A
|
||||
|
||||
#define MXC4005_REG_INT_MASK1 0x0B
|
||||
#define MXC4005_REG_INT_MASK1_BIT_DRDYE 0x01
|
||||
|
||||
#define MXC4005_REG_INT_CLR0 0x00
|
||||
|
||||
#define MXC4005_REG_INT_CLR1 0x01
|
||||
#define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01
|
||||
|
||||
|
@ -113,7 +117,9 @@ static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
|
|||
static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case MXC4005_REG_INT_CLR0:
|
||||
case MXC4005_REG_INT_CLR1:
|
||||
case MXC4005_REG_INT_MASK0:
|
||||
case MXC4005_REG_INT_MASK1:
|
||||
case MXC4005_REG_CONTROL:
|
||||
return true;
|
||||
|
@ -330,17 +336,13 @@ static int mxc4005_set_trigger_state(struct iio_trigger *trig,
|
|||
{
|
||||
struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
|
||||
struct mxc4005_data *data = iio_priv(indio_dev);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
if (state) {
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
|
||||
MXC4005_REG_INT_MASK1_BIT_DRDYE);
|
||||
} else {
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
|
||||
~MXC4005_REG_INT_MASK1_BIT_DRDYE);
|
||||
}
|
||||
|
||||
val = state ? MXC4005_REG_INT_MASK1_BIT_DRDYE : 0;
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, val);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&data->mutex);
|
||||
dev_err(data->dev, "failed to update reg_int_mask1");
|
||||
|
@ -382,6 +384,14 @@ static int mxc4005_chip_init(struct mxc4005_data *data)
|
|||
|
||||
dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
|
||||
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(data->dev, ret, "writing INT_MASK0\n");
|
||||
|
||||
ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, 0);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(data->dev, ret, "writing INT_MASK1\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1127,6 +1127,7 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
|
|||
struct device *dev = &st->adis.spi->dev;
|
||||
const struct adis16475_sync *sync;
|
||||
u32 sync_mode;
|
||||
u16 val;
|
||||
|
||||
/* default to internal clk */
|
||||
st->clk_freq = st->info->int_clk * 1000;
|
||||
|
@ -1188,8 +1189,9 @@ static int adis16475_config_sync_mode(struct adis16475 *st)
|
|||
* I'm keeping this for simplicity and avoiding extra variables
|
||||
* in chip_info.
|
||||
*/
|
||||
val = ADIS16475_SYNC_MODE(sync->sync_mode);
|
||||
ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
|
||||
ADIS16475_SYNC_MODE_MASK, sync->sync_mode);
|
||||
ADIS16475_SYNC_MODE_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ static const struct of_device_id bmp280_of_spi_match[] = {
|
|||
{ .compatible = "bosch,bmp180", .data = &bmp180_chip_info },
|
||||
{ .compatible = "bosch,bmp181", .data = &bmp180_chip_info },
|
||||
{ .compatible = "bosch,bmp280", .data = &bmp280_chip_info },
|
||||
{ .compatible = "bosch,bme280", .data = &bmp280_chip_info },
|
||||
{ .compatible = "bosch,bme280", .data = &bme280_chip_info },
|
||||
{ .compatible = "bosch,bmp380", .data = &bmp380_chip_info },
|
||||
{ .compatible = "bosch,bmp580", .data = &bmp580_chip_info },
|
||||
{ },
|
||||
|
@ -95,7 +95,7 @@ static const struct spi_device_id bmp280_spi_id[] = {
|
|||
{ "bmp180", (kernel_ulong_t)&bmp180_chip_info },
|
||||
{ "bmp181", (kernel_ulong_t)&bmp180_chip_info },
|
||||
{ "bmp280", (kernel_ulong_t)&bmp280_chip_info },
|
||||
{ "bme280", (kernel_ulong_t)&bmp280_chip_info },
|
||||
{ "bme280", (kernel_ulong_t)&bme280_chip_info },
|
||||
{ "bmp380", (kernel_ulong_t)&bmp380_chip_info },
|
||||
{ "bmp580", (kernel_ulong_t)&bmp580_chip_info },
|
||||
{ }
|
||||
|
|
|
@ -439,6 +439,7 @@ static int remove_device_files(struct super_block *sb,
|
|||
return PTR_ERR(dir);
|
||||
}
|
||||
simple_recursive_removal(dir, NULL);
|
||||
dput(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1773,6 +1773,7 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
|
|||
{ .compatible = "mediatek,mt8365-m4u", .data = &mt8365_data},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_iommu_of_ids);
|
||||
|
||||
static struct platform_driver mtk_iommu_driver = {
|
||||
.probe = mtk_iommu_probe,
|
||||
|
|
|
@ -600,6 +600,7 @@ static const struct of_device_id mtk_iommu_v1_of_ids[] = {
|
|||
{ .compatible = "mediatek,mt2701-m4u", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids);
|
||||
|
||||
static const struct component_master_ops mtk_iommu_v1_com_ops = {
|
||||
.bind = mtk_iommu_v1_bind,
|
||||
|
|
|
@ -581,6 +581,31 @@ static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
|
|||
}
|
||||
}
|
||||
|
||||
static void at24_probe_temp_sensor(struct i2c_client *client)
|
||||
{
|
||||
struct at24_data *at24 = i2c_get_clientdata(client);
|
||||
struct i2c_board_info info = { .type = "jc42" };
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
/*
|
||||
* Byte 2 has value 11 for DDR3, earlier versions don't
|
||||
* support the thermal sensor present flag
|
||||
*/
|
||||
ret = at24_read(at24, 2, &val, 1);
|
||||
if (ret || val != 11)
|
||||
return;
|
||||
|
||||
/* Byte 32, bit 7 is set if temp sensor is present */
|
||||
ret = at24_read(at24, 32, &val, 1);
|
||||
if (ret || !(val & BIT(7)))
|
||||
return;
|
||||
|
||||
info.addr = 0x18 | (client->addr & 7);
|
||||
|
||||
i2c_new_client_device(client->adapter, &info);
|
||||
}
|
||||
|
||||
static int at24_probe(struct i2c_client *client)
|
||||
{
|
||||
struct regmap_config regmap_config = { };
|
||||
|
@ -756,15 +781,6 @@ static int at24_probe(struct i2c_client *client)
|
|||
}
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
|
||||
if (IS_ERR(at24->nvmem)) {
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return dev_err_probe(dev, PTR_ERR(at24->nvmem),
|
||||
"failed to register nvmem\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a one-byte test read to verify that the chip is functional,
|
||||
* unless powering on the device is to be avoided during probe (i.e.
|
||||
|
@ -780,6 +796,19 @@ static int at24_probe(struct i2c_client *client)
|
|||
}
|
||||
}
|
||||
|
||||
at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
|
||||
if (IS_ERR(at24->nvmem)) {
|
||||
pm_runtime_disable(dev);
|
||||
if (!pm_runtime_status_suspended(dev))
|
||||
regulator_disable(at24->vcc_reg);
|
||||
return dev_err_probe(dev, PTR_ERR(at24->nvmem),
|
||||
"failed to register nvmem\n");
|
||||
}
|
||||
|
||||
/* If this a SPD EEPROM, probe for DDR3 thermal sensor */
|
||||
if (cdata == &at24_data_spd)
|
||||
at24_probe_temp_sensor(client);
|
||||
|
||||
pm_runtime_idle(dev);
|
||||
|
||||
if (writable)
|
||||
|
|
|
@ -115,6 +115,8 @@
|
|||
#define MEI_DEV_ID_ARL_S 0x7F68 /* Arrow Lake Point S */
|
||||
#define MEI_DEV_ID_ARL_H 0x7770 /* Arrow Lake Point H */
|
||||
|
||||
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
|
||||
|
||||
/*
|
||||
* MEI HW Section
|
||||
*/
|
||||
|
|
|
@ -122,6 +122,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
|||
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
|
||||
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
|
||||
|
||||
/* required last entry */
|
||||
{0, }
|
||||
};
|
||||
|
|
|
@ -552,6 +552,7 @@ static int mtd_nvmem_add(struct mtd_info *mtd)
|
|||
config.dev = &mtd->dev;
|
||||
config.name = dev_name(&mtd->dev);
|
||||
config.owner = THIS_MODULE;
|
||||
config.add_legacy_fixed_of_cells = of_device_is_compatible(node, "nvmem-cells");
|
||||
config.reg_read = mtd_nvmem_reg_read;
|
||||
config.size = mtd->size;
|
||||
config.word_size = 1;
|
||||
|
@ -898,6 +899,7 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd,
|
|||
config.name = compatible;
|
||||
config.id = NVMEM_DEVID_AUTO;
|
||||
config.owner = THIS_MODULE;
|
||||
config.add_legacy_fixed_of_cells = !mtd_type_is_nand(mtd);
|
||||
config.type = NVMEM_TYPE_OTP;
|
||||
config.root_only = true;
|
||||
config.ignore_wp = true;
|
||||
|
|
|
@ -697,6 +697,18 @@ static void mv88e6352_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
|
|||
}
|
||||
}
|
||||
|
||||
static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
unsigned long *supported = config->supported_interfaces;
|
||||
|
||||
/* Translate the default cmode */
|
||||
mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
|
||||
|
||||
config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
|
||||
MAC_1000FD;
|
||||
}
|
||||
|
||||
static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
|
@ -4976,7 +4988,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_get_caps = mv88e6185_phylink_get_caps,
|
||||
.phylink_get_caps = mv88e632x_phylink_get_caps,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
|
@ -5022,7 +5034,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_get_caps = mv88e6185_phylink_get_caps,
|
||||
.phylink_get_caps = mv88e632x_phylink_get_caps,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
|
@ -5588,7 +5600,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
|
||||
.family = MV88E6XXX_FAMILY_6341,
|
||||
.name = "Marvell 88E6141",
|
||||
.num_databases = 4096,
|
||||
.num_databases = 256,
|
||||
.num_macs = 2048,
|
||||
.num_ports = 6,
|
||||
.num_internal_phys = 5,
|
||||
|
@ -6047,7 +6059,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
|
||||
.family = MV88E6XXX_FAMILY_6341,
|
||||
.name = "Marvell 88E6341",
|
||||
.num_databases = 4096,
|
||||
.num_databases = 256,
|
||||
.num_macs = 2048,
|
||||
.num_internal_phys = 5,
|
||||
.num_ports = 6,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue