Merge linux 6.6.31

Conflicts:
	drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
This commit is contained in:
Jianping Liu 2024-05-20 14:44:58 +08:00
commit c2e704ebf0
348 changed files with 3135 additions and 1844 deletions

View File

@ -42,7 +42,7 @@ allOf:
properties:
compatible:
contains:
const: maxim,max30100
const: maxim,max30102
then:
properties:
maxim,green-led-current-microamp: false

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
/*

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)");

View File

@ -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;

View File

@ -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",

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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,

View File

@ -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);
}
/*

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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))

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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
*

View File

@ -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;

View File

@ -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,

View File

@ -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 },

View File

@ -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);
}

View File

@ -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),
};

View File

@ -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,
},
};

View File

@ -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[] = {

View File

@ -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,

View File

@ -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;

View File

@ -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,
};

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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);

View File

@ -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))

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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 = {

View File

@ -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;
}

View File

@ -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);

View File

@ -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++;

View File

@ -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,

View File

@ -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,

View File

@ -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 = {

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 |

View File

@ -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;

View File

@ -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)),

View File

@ -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)),

View File

@ -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)),

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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,

View File

@ -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.

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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];

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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);
}
/*

View File

@ -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 },
{ }

View File

@ -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) {

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}
}
/*

View File

@ -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);

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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 },
{ }

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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)

View File

@ -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
*/

View File

@ -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, }
};

View File

@ -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;

View File

@ -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