Merge 5ac73f8191 ("RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds") into android14-6.1

Steps on the way to 6.1.113

Change-Id: I338cf59b70c299c2b01d9e3d192b6db4bbb349aa
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-10-17 15:32:21 +00:00
199 changed files with 2081 additions and 1100 deletions

View File

@@ -540,7 +540,7 @@ at module load time (for a module) with::
alerts_broken alerts_broken
The addresses are normal I2C addresses. The adapter is the string The addresses are normal I2C addresses. The adapter is the string
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name. name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
spaces, so if the name is "This is an I2C chip" you can say spaces, so if the name is "This is an I2C chip" you can say
adapter_name=ThisisanI2cchip. This is because it's hard to pass in adapter_name=ThisisanI2cchip. This is because it's hard to pass in

View File

@@ -350,7 +350,7 @@
&iomuxc_lpsr { &iomuxc_lpsr {
pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp { pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp {
fsl,phy = < fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08 MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08
>; >;
}; };

View File

@@ -690,7 +690,7 @@
compatible = "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt"; compatible = "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
reg = <0xfffffe20 0x20>; reg = <0xfffffe20 0x20>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
clocks = <&clk32k 0>; clocks = <&clk32k 1>;
}; };
pit: timer@fffffe40 { pit: timer@fffffe40 {
@@ -716,7 +716,7 @@
compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc"; compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc";
reg = <0xfffffea8 0x100>; reg = <0xfffffea8 0x100>;
interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
clocks = <&clk32k 0>; clocks = <&clk32k 1>;
}; };
watchdog: watchdog@ffffff80 { watchdog: watchdog@ffffff80 {

View File

@@ -221,7 +221,7 @@
compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt"; compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
reg = <0xe001d020 0x30>; reg = <0xe001d020 0x30>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk32k 0>; clocks = <&clk32k 1>;
}; };
clk32k: clock-controller@e001d050 { clk32k: clock-controller@e001d050 {

View File

@@ -66,6 +66,7 @@ static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
return; return;
} }
map = syscon_node_to_regmap(np); map = syscon_node_to_regmap(np);
of_node_put(np);
if (IS_ERR(map)) { if (IS_ERR(map)) {
pr_err("PLATSMP: No syscon regmap\n"); pr_err("PLATSMP: No syscon regmap\n");
return; return;

View File

@@ -31,7 +31,7 @@
device_type = "memory"; device_type = "memory";
reg = <0x0 0x80000000 0x3da00000>, reg = <0x0 0x80000000 0x3da00000>,
<0x0 0xc0000000 0x40000000>, <0x0 0xc0000000 0x40000000>,
<0x8 0x80000000 0x40000000>; <0x8 0x80000000 0x80000000>;
}; };
gpio-keys { gpio-keys {

View File

@@ -135,8 +135,8 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
#address-cells = <0>; #address-cells = <0>;
interrupt-controller; interrupt-controller;
reg = <0x0 0x11900000 0 0x40000>, reg = <0x0 0x11900000 0 0x20000>,
<0x0 0x11940000 0 0x60000>; <0x0 0x11940000 0 0x40000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
}; };
}; };

View File

@@ -788,8 +788,8 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
#address-cells = <0>; #address-cells = <0>;
interrupt-controller; interrupt-controller;
reg = <0x0 0x11900000 0 0x40000>, reg = <0x0 0x11900000 0 0x20000>,
<0x0 0x11940000 0 0x60000>; <0x0 0x11940000 0 0x40000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
}; };

View File

@@ -794,8 +794,8 @@
#interrupt-cells = <3>; #interrupt-cells = <3>;
#address-cells = <0>; #address-cells = <0>;
interrupt-controller; interrupt-controller;
reg = <0x0 0x11900000 0 0x40000>, reg = <0x0 0x11900000 0 0x20000>,
<0x0 0x11940000 0 0x60000>; <0x0 0x11940000 0 0x40000>;
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
}; };

View File

@@ -111,7 +111,7 @@
no-map; no-map;
}; };
c66_1_dma_memory_region: c66-dma-memory@a6000000 { c66_0_dma_memory_region: c66-dma-memory@a6000000 {
compatible = "shared-dma-pool"; compatible = "shared-dma-pool";
reg = <0x00 0xa6000000 0x00 0x100000>; reg = <0x00 0xa6000000 0x00 0x100000>;
no-map; no-map;
@@ -123,7 +123,7 @@
no-map; no-map;
}; };
c66_0_dma_memory_region: c66-dma-memory@a7000000 { c66_1_dma_memory_region: c66-dma-memory@a7000000 {
compatible = "shared-dma-pool"; compatible = "shared-dma-pool";
reg = <0x00 0xa7000000 0x00 0x100000>; reg = <0x00 0xa7000000 0x00 0x100000>;
no-map; no-map;

View File

@@ -115,7 +115,7 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
{ {
/* regs will be equal to current_pt_regs() */ /* regs will be equal to current_pt_regs() */
struct kernel_clone_args args = { struct kernel_clone_args args = {
.flags = regs->d1 & ~CSIGNAL, .flags = (u32)(regs->d1) & ~CSIGNAL,
.pidfd = (int __user *)regs->d3, .pidfd = (int __user *)regs->d3,
.child_tid = (int __user *)regs->d4, .child_tid = (int __user *)regs->d4,
.parent_tid = (int __user *)regs->d3, .parent_tid = (int __user *)regs->d3,

View File

@@ -40,12 +40,12 @@
#include "head_32.h" #include "head_32.h"
.macro compare_to_kernel_boundary scratch, addr .macro compare_to_kernel_boundary scratch, addr
#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000 #if CONFIG_TASK_SIZE <= 0x80000000 && MODULES_VADDR >= 0x80000000
/* By simply checking Address >= 0x80000000, we know if its a kernel address */ /* By simply checking Address >= 0x80000000, we know if its a kernel address */
not. \scratch, \addr not. \scratch, \addr
#else #else
rlwinm \scratch, \addr, 16, 0xfff8 rlwinm \scratch, \addr, 16, 0xfff8
cmpli cr0, \scratch, PAGE_OFFSET@h cmpli cr0, \scratch, TASK_SIZE@h
#endif #endif
.endm .endm
@@ -403,7 +403,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
mfspr r10, SPRN_SRR0 mfspr r10, SPRN_SRR0
mtspr SPRN_MD_EPN, r10 mtspr SPRN_MD_EPN, r10
rlwinm r11, r10, 16, 0xfff8 rlwinm r11, r10, 16, 0xfff8
cmpli cr1, r11, PAGE_OFFSET@h cmpli cr1, r11, TASK_SIZE@h
mfspr r11, SPRN_M_TWB /* Get level 1 table */ mfspr r11, SPRN_M_TWB /* Get level 1 table */
blt+ cr1, 3f blt+ cr1, 3f

View File

@@ -147,11 +147,11 @@ unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
mmu_mapin_immr(); mmu_mapin_immr();
mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, true); mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_X, true);
if (debug_pagealloc_enabled_or_kfence()) { if (debug_pagealloc_enabled_or_kfence()) {
top = boundary; top = boundary;
} else { } else {
mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_TEXT, true); mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_X, true);
mmu_mapin_ram_chunk(einittext8, top, PAGE_KERNEL, true); mmu_mapin_ram_chunk(einittext8, top, PAGE_KERNEL, true);
} }

View File

@@ -67,8 +67,8 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->riscv_sbi.args[3] = cp->a3; run->riscv_sbi.args[3] = cp->a3;
run->riscv_sbi.args[4] = cp->a4; run->riscv_sbi.args[4] = cp->a4;
run->riscv_sbi.args[5] = cp->a5; run->riscv_sbi.args[5] = cp->a5;
run->riscv_sbi.ret[0] = cp->a0; run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
run->riscv_sbi.ret[1] = cp->a1; run->riscv_sbi.ret[1] = 0;
} }
void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,

View File

@@ -474,24 +474,25 @@ struct sgx_epc_page *__sgx_alloc_epc_page(void)
{ {
struct sgx_epc_page *page; struct sgx_epc_page *page;
int nid_of_current = numa_node_id(); int nid_of_current = numa_node_id();
int nid = nid_of_current; int nid_start, nid;
if (node_isset(nid_of_current, sgx_numa_mask)) { /*
page = __sgx_alloc_epc_page_from_node(nid_of_current); * Try local node first. If it doesn't have an EPC section,
if (page) * fall back to the non-local NUMA nodes.
return page; */
} if (node_isset(nid_of_current, sgx_numa_mask))
nid_start = nid_of_current;
/* Fall back to the non-local NUMA nodes: */ else
while (true) { nid_start = next_node_in(nid_of_current, sgx_numa_mask);
nid = next_node_in(nid, sgx_numa_mask);
if (nid == nid_of_current)
break;
nid = nid_start;
do {
page = __sgx_alloc_epc_page_from_node(nid); page = __sgx_alloc_epc_page_from_node(nid);
if (page) if (page)
return page; return page;
}
nid = next_node_in(nid, sgx_numa_mask);
} while (nid != nid_start);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }

View File

@@ -853,7 +853,7 @@ char * __init xen_memory_setup(void)
* to relocating (and even reusing) pages with kernel text or data. * to relocating (and even reusing) pages with kernel text or data.
*/ */
if (xen_is_e820_reserved(__pa_symbol(_text), if (xen_is_e820_reserved(__pa_symbol(_text),
__pa_symbol(__bss_stop) - __pa_symbol(_text))) { __pa_symbol(_end) - __pa_symbol(_text))) {
xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n"); xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
BUG(); BUG();
} }

View File

@@ -2889,8 +2889,12 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
struct bfq_queue *in_service_bfqq, *new_bfqq; struct bfq_queue *in_service_bfqq, *new_bfqq;
/* if a merge has already been setup, then proceed with that first */ /* if a merge has already been setup, then proceed with that first */
if (bfqq->new_bfqq) new_bfqq = bfqq->new_bfqq;
return bfqq->new_bfqq; if (new_bfqq) {
while (new_bfqq->new_bfqq)
new_bfqq = new_bfqq->new_bfqq;
return new_bfqq;
}
/* /*
* Check delayed stable merge for rotational or non-queueing * Check delayed stable merge for rotational or non-queueing
@@ -6624,7 +6628,7 @@ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
{ {
bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
if (bfqq_process_refs(bfqq) == 1) { if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
bfqq->pid = current->pid; bfqq->pid = current->pid;
bfq_clear_bfqq_coop(bfqq); bfq_clear_bfqq_coop(bfqq);
bfq_clear_bfqq_split_coop(bfqq); bfq_clear_bfqq_split_coop(bfqq);
@@ -6831,7 +6835,8 @@ static struct bfq_queue *bfq_init_rq(struct request *rq)
* addition, if the queue has also just been split, we have to * addition, if the queue has also just been split, we have to
* resume its state. * resume its state.
*/ */
if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
bfqq_process_refs(bfqq) == 1) {
bfqq->bic = bic; bfqq->bic = bic;
if (split) { if (split) {
/* /*

View File

@@ -580,9 +580,11 @@ static bool blk_add_partition(struct gendisk *disk,
part = add_partition(disk, p, from, size, state->parts[p].flags, part = add_partition(disk, p, from, size, state->parts[p].flags,
&state->parts[p].info); &state->parts[p].info);
if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) { if (IS_ERR(part)) {
printk(KERN_ERR " %s: p%d could not be added: %ld\n", if (PTR_ERR(part) != -ENXIO) {
disk->disk_name, p, -PTR_ERR(part)); printk(KERN_ERR " %s: p%d could not be added: %pe\n",
disk->disk_name, p, part);
}
return true; return true;
} }

View File

@@ -83,33 +83,30 @@ static void __init
do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
{ {
int speed; int speed;
int i, j; unsigned long reps;
ktime_t min, start, diff; ktime_t min, start, t0;
tmpl->next = template_list; tmpl->next = template_list;
template_list = tmpl; template_list = tmpl;
preempt_disable(); preempt_disable();
min = (ktime_t)S64_MAX; reps = 0;
for (i = 0; i < 3; i++) { t0 = ktime_get();
start = ktime_get(); /* delay start until time has advanced */
for (j = 0; j < REPS; j++) { while ((start = ktime_get()) == t0)
mb(); /* prevent loop optimization */ cpu_relax();
tmpl->do_2(BENCH_SIZE, b1, b2); do {
mb(); mb(); /* prevent loop optimization */
} tmpl->do_2(BENCH_SIZE, b1, b2);
diff = ktime_sub(ktime_get(), start); mb();
if (diff < min) } while (reps++ < REPS || (t0 = ktime_get()) == start);
min = diff; min = ktime_sub(t0, start);
}
preempt_enable(); preempt_enable();
// bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s] // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
if (!min) speed = (1000 * reps * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
min = 1;
speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
tmpl->speed = speed; tmpl->speed = speed;
pr_info(" %-16s: %5d MB/sec\n", tmpl->name, speed); pr_info(" %-16s: %5d MB/sec\n", tmpl->name, speed);

View File

@@ -133,14 +133,15 @@ acpi_status acpi_ex_system_do_stall(u32 how_long_us)
* (ACPI specifies 100 usec as max, but this gives some slack in * (ACPI specifies 100 usec as max, but this gives some slack in
* order to support existing BIOSs) * order to support existing BIOSs)
*/ */
ACPI_ERROR((AE_INFO, ACPI_ERROR_ONCE((AE_INFO,
"Time parameter is too large (%u)", how_long_us)); "Time parameter is too large (%u)",
how_long_us));
status = AE_AML_OPERAND_VALUE; status = AE_AML_OPERAND_VALUE;
} else { } else {
if (how_long_us > 100) { if (how_long_us > 100) {
ACPI_WARNING((AE_INFO, ACPI_WARNING_ONCE((AE_INFO,
"Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.", "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",
how_long_us)); how_long_us));
} }
acpi_os_stall(how_long_us); acpi_os_stall(how_long_us);
} }

View File

@@ -167,8 +167,11 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width) #define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
/* Shift and apply the mask for CPC reads/writes */ /* Shift and apply the mask for CPC reads/writes */
#define MASK_VAL(reg, val) (((val) >> (reg)->bit_offset) & \ #define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) & \
GENMASK(((reg)->bit_width) - 1, 0)) GENMASK(((reg)->bit_width) - 1, 0))
#define MASK_VAL_WRITE(reg, prev_val, val) \
((((val) & GENMASK(((reg)->bit_width) - 1, 0)) << (reg)->bit_offset) | \
((prev_val) & ~(GENMASK(((reg)->bit_width) - 1, 0) << (reg)->bit_offset))) \
static ssize_t show_feedback_ctrs(struct kobject *kobj, static ssize_t show_feedback_ctrs(struct kobject *kobj,
struct kobj_attribute *attr, char *buf) struct kobj_attribute *attr, char *buf)
@@ -851,6 +854,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
/* Store CPU Logical ID */ /* Store CPU Logical ID */
cpc_ptr->cpu_id = pr->id; cpc_ptr->cpu_id = pr->id;
spin_lock_init(&cpc_ptr->rmw_lock);
/* Parse PSD data for this CPU */ /* Parse PSD data for this CPU */
ret = acpi_get_psd(cpc_ptr, handle); ret = acpi_get_psd(cpc_ptr, handle);
@@ -1056,7 +1060,7 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
} }
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
*val = MASK_VAL(reg, *val); *val = MASK_VAL_READ(reg, *val);
return 0; return 0;
} }
@@ -1065,9 +1069,11 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
{ {
int ret_val = 0; int ret_val = 0;
int size; int size;
u64 prev_val;
void __iomem *vaddr = NULL; void __iomem *vaddr = NULL;
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
struct cpc_reg *reg = &reg_res->cpc_entry.reg; struct cpc_reg *reg = &reg_res->cpc_entry.reg;
struct cpc_desc *cpc_desc;
size = GET_BIT_WIDTH(reg); size = GET_BIT_WIDTH(reg);
@@ -1100,8 +1106,34 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
return acpi_os_write_memory((acpi_physical_address)reg->address, return acpi_os_write_memory((acpi_physical_address)reg->address,
val, size); val, size);
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
val = MASK_VAL(reg, val); cpc_desc = per_cpu(cpc_desc_ptr, cpu);
if (!cpc_desc) {
pr_debug("No CPC descriptor for CPU:%d\n", cpu);
return -ENODEV;
}
spin_lock(&cpc_desc->rmw_lock);
switch (size) {
case 8:
prev_val = readb_relaxed(vaddr);
break;
case 16:
prev_val = readw_relaxed(vaddr);
break;
case 32:
prev_val = readl_relaxed(vaddr);
break;
case 64:
prev_val = readq_relaxed(vaddr);
break;
default:
spin_unlock(&cpc_desc->rmw_lock);
return -EFAULT;
}
val = MASK_VAL_WRITE(reg, prev_val, val);
val |= prev_val;
}
switch (size) { switch (size) {
case 8: case 8:
@@ -1128,6 +1160,9 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
break; break;
} }
if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
spin_unlock(&cpc_desc->rmw_lock);
return ret_val; return ret_val;
} }

View File

@@ -376,10 +376,8 @@ static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
struct tps68470_pmic_opregion *opregion; struct tps68470_pmic_opregion *opregion;
acpi_status status; acpi_status status;
if (!dev || !tps68470_regmap) { if (!tps68470_regmap)
dev_warn(dev, "dev or regmap is NULL\n"); return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
return -EINVAL;
}
if (!handle) { if (!handle) {
dev_warn(dev, "acpi handle is NULL\n"); dev_warn(dev, "acpi handle is NULL\n");

View File

@@ -3120,7 +3120,7 @@ static int genpd_summary_one(struct seq_file *s,
else else
snprintf(state, sizeof(state), "%s", snprintf(state, sizeof(state), "%s",
status_lookup[genpd->status]); status_lookup[genpd->status]);
seq_printf(s, "%-30s %-50s %u", genpd->name, state, genpd->performance_state); seq_printf(s, "%-30s %-49s %u", genpd->name, state, genpd->performance_state);
/* /*
* Modifications on the list require holding locks on both * Modifications on the list require holding locks on both

View File

@@ -181,6 +181,17 @@ static void nbd_requeue_cmd(struct nbd_cmd *cmd)
{ {
struct request *req = blk_mq_rq_from_pdu(cmd); struct request *req = blk_mq_rq_from_pdu(cmd);
lockdep_assert_held(&cmd->lock);
/*
* Clear INFLIGHT flag so that this cmd won't be completed in
* normal completion path
*
* INFLIGHT flag will be set when the cmd is queued to nbd next
* time.
*/
__clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
if (!test_and_set_bit(NBD_CMD_REQUEUED, &cmd->flags)) if (!test_and_set_bit(NBD_CMD_REQUEUED, &cmd->flags))
blk_mq_requeue_request(req, true); blk_mq_requeue_request(req, true);
} }
@@ -445,8 +456,8 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req)
nbd_mark_nsock_dead(nbd, nsock, 1); nbd_mark_nsock_dead(nbd, nsock, 1);
mutex_unlock(&nsock->tx_lock); mutex_unlock(&nsock->tx_lock);
} }
mutex_unlock(&cmd->lock);
nbd_requeue_cmd(cmd); nbd_requeue_cmd(cmd);
mutex_unlock(&cmd->lock);
nbd_config_put(nbd); nbd_config_put(nbd);
return BLK_EH_DONE; return BLK_EH_DONE;
} }

View File

@@ -1189,7 +1189,10 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
if (!urb) if (!urb)
return -ENOMEM; return -ENOMEM;
size = le16_to_cpu(data->intr_ep->wMaxPacketSize); /* Use maximum HCI Event size so the USB stack handles
* ZPL/short-transfer automatically.
*/
size = HCI_MAX_EVENT_SIZE;
buf = kmalloc(size, mem_flags); buf = kmalloc(size, mem_flags);
if (!buf) { if (!buf) {

View File

@@ -47,6 +47,8 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
if (!ret) if (!ret)
ret = tpm2_commit_space(chip, space, buf, &len); ret = tpm2_commit_space(chip, space, buf, &len);
else
tpm2_flush_space(chip);
out_rc: out_rc:
return ret ? ret : len; return ret ? ret : len;

View File

@@ -166,6 +166,9 @@ void tpm2_flush_space(struct tpm_chip *chip)
struct tpm_space *space = &chip->work_space; struct tpm_space *space = &chip->work_space;
int i; int i;
if (!space)
return;
for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++) for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
if (space->context_tbl[i] && ~space->context_tbl[i]) if (space->context_tbl[i] && ~space->context_tbl[i])
tpm2_flush_context(chip, space->context_tbl[i]); tpm2_flush_context(chip, space->context_tbl[i]);

View File

@@ -14,6 +14,7 @@
#include "../clk-fractional-divider.h" #include "../clk-fractional-divider.h"
#include "clk.h" #include "clk.h"
#define PCG_PR_MASK BIT(31)
#define PCG_PCS_SHIFT 24 #define PCG_PCS_SHIFT 24
#define PCG_PCS_MASK 0x7 #define PCG_PCS_MASK 0x7
#define PCG_CGC_SHIFT 30 #define PCG_CGC_SHIFT 30
@@ -80,6 +81,12 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name,
struct clk_hw *hw; struct clk_hw *hw;
u32 val; u32 val;
val = readl(reg);
if (!(val & PCG_PR_MASK)) {
pr_info("PCC PR is 0 for clk:%s, bypass\n", name);
return 0;
}
if (mux_present) { if (mux_present) {
mux = kzalloc(sizeof(*mux), GFP_KERNEL); mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux) if (!mux)

View File

@@ -173,6 +173,34 @@ static const struct clk_ops imx8m_clk_composite_mux_ops = {
.determine_rate = imx8m_clk_composite_mux_determine_rate, .determine_rate = imx8m_clk_composite_mux_determine_rate,
}; };
static int imx8m_clk_composite_gate_enable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
unsigned long flags;
u32 val;
spin_lock_irqsave(gate->lock, flags);
val = readl(gate->reg);
val |= BIT(gate->bit_idx);
writel(val, gate->reg);
spin_unlock_irqrestore(gate->lock, flags);
return 0;
}
static void imx8m_clk_composite_gate_disable(struct clk_hw *hw)
{
/* composite clk requires the disable hook */
}
static const struct clk_ops imx8m_clk_composite_gate_ops = {
.enable = imx8m_clk_composite_gate_enable,
.disable = imx8m_clk_composite_gate_disable,
.is_enabled = clk_gate_is_enabled,
};
struct clk_hw *__imx8m_clk_hw_composite(const char *name, struct clk_hw *__imx8m_clk_hw_composite(const char *name,
const char * const *parent_names, const char * const *parent_names,
int num_parents, void __iomem *reg, int num_parents, void __iomem *reg,
@@ -186,10 +214,11 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
struct clk_mux *mux = NULL; struct clk_mux *mux = NULL;
const struct clk_ops *divider_ops; const struct clk_ops *divider_ops;
const struct clk_ops *mux_ops; const struct clk_ops *mux_ops;
const struct clk_ops *gate_ops;
mux = kzalloc(sizeof(*mux), GFP_KERNEL); mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux) if (!mux)
goto fail; return ERR_CAST(hw);
mux_hw = &mux->hw; mux_hw = &mux->hw;
mux->reg = reg; mux->reg = reg;
@@ -199,7 +228,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
div = kzalloc(sizeof(*div), GFP_KERNEL); div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div) if (!div)
goto fail; goto free_mux;
div_hw = &div->hw; div_hw = &div->hw;
div->reg = reg; div->reg = reg;
@@ -226,28 +255,32 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
div->flags = CLK_DIVIDER_ROUND_CLOSEST; div->flags = CLK_DIVIDER_ROUND_CLOSEST;
/* skip registering the gate ops if M4 is enabled */ /* skip registering the gate ops if M4 is enabled */
if (!mcore_booted) { gate = kzalloc(sizeof(*gate), GFP_KERNEL);
gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate)
if (!gate) goto free_div;
goto fail;
gate_hw = &gate->hw; gate_hw = &gate->hw;
gate->reg = reg; gate->reg = reg;
gate->bit_idx = PCG_CGC_SHIFT; gate->bit_idx = PCG_CGC_SHIFT;
gate->lock = &imx_ccm_lock; gate->lock = &imx_ccm_lock;
} if (!mcore_booted)
gate_ops = &clk_gate_ops;
else
gate_ops = &imx8m_clk_composite_gate_ops;
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, mux_ops, div_hw, mux_hw, mux_ops, div_hw,
divider_ops, gate_hw, &clk_gate_ops, flags); divider_ops, gate_hw, gate_ops, flags);
if (IS_ERR(hw)) if (IS_ERR(hw))
goto fail; goto free_gate;
return hw; return hw;
fail: free_gate:
kfree(gate); kfree(gate);
free_div:
kfree(div); kfree(div);
free_mux:
kfree(mux); kfree(mux);
return ERR_CAST(hw); return ERR_CAST(hw);
} }

View File

@@ -53,11 +53,22 @@
.odiv = (_odiv), \ .odiv = (_odiv), \
} }
#define PLL_FRACN_GP_INTEGER(_rate, _mfi, _rdiv, _odiv) \
{ \
.rate = (_rate), \
.mfi = (_mfi), \
.mfn = 0, \
.mfd = 0, \
.rdiv = (_rdiv), \
.odiv = (_odiv), \
}
struct clk_fracn_gppll { struct clk_fracn_gppll {
struct clk_hw hw; struct clk_hw hw;
void __iomem *base; void __iomem *base;
const struct imx_fracn_gppll_rate_table *rate_table; const struct imx_fracn_gppll_rate_table *rate_table;
int rate_count; int rate_count;
u32 flags;
}; };
/* /*
@@ -83,6 +94,24 @@ struct imx_fracn_gppll_clk imx_fracn_gppll = {
}; };
EXPORT_SYMBOL_GPL(imx_fracn_gppll); EXPORT_SYMBOL_GPL(imx_fracn_gppll);
/*
* Fvco = (Fref / rdiv) * MFI
* Fout = Fvco / odiv
* The (Fref / rdiv) should be in range 20MHz to 40MHz
* The Fvco should be in range 2.5Ghz to 5Ghz
*/
static const struct imx_fracn_gppll_rate_table int_tbl[] = {
PLL_FRACN_GP_INTEGER(1700000000U, 141, 1, 2),
PLL_FRACN_GP_INTEGER(1400000000U, 175, 1, 3),
PLL_FRACN_GP_INTEGER(900000000U, 150, 1, 4),
};
struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
.rate_table = int_tbl,
.rate_count = ARRAY_SIZE(int_tbl),
};
EXPORT_SYMBOL_GPL(imx_fracn_gppll_integer);
static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw) static inline struct clk_fracn_gppll *to_clk_fracn_gppll(struct clk_hw *hw)
{ {
return container_of(hw, struct clk_fracn_gppll, hw); return container_of(hw, struct clk_fracn_gppll, hw);
@@ -169,9 +198,15 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
break; break;
} }
/* Fvco = Fref * (MFI + MFN / MFD) */ if (pll->flags & CLK_FRACN_GPPLL_INTEGER) {
fvco = fvco * mfi * mfd + fvco * mfn; /* Fvco = (Fref / rdiv) * MFI */
do_div(fvco, mfd * rdiv * odiv); fvco = fvco * mfi;
do_div(fvco, rdiv * odiv);
} else {
/* Fvco = (Fref / rdiv) * (MFI + MFN / MFD) */
fvco = fvco * mfi * mfd + fvco * mfn;
do_div(fvco, mfd * rdiv * odiv);
}
return (unsigned long)fvco; return (unsigned long)fvco;
} }
@@ -215,8 +250,10 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv | pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
FIELD_PREP(PLL_MFI_MASK, rate->mfi); FIELD_PREP(PLL_MFI_MASK, rate->mfi);
writel_relaxed(pll_div, pll->base + PLL_DIV); writel_relaxed(pll_div, pll->base + PLL_DIV);
writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR); if (pll->flags & CLK_FRACN_GPPLL_FRACN) {
writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR); writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
}
/* Wait for 5us according to fracn mode pll doc */ /* Wait for 5us according to fracn mode pll doc */
udelay(5); udelay(5);
@@ -252,6 +289,10 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw)
if (val & POWERUP_MASK) if (val & POWERUP_MASK)
return 0; return 0;
if (pll->flags & CLK_FRACN_GPPLL_FRACN)
writel_relaxed(readl_relaxed(pll->base + PLL_NUMERATOR),
pll->base + PLL_NUMERATOR);
val |= CLKMUX_BYPASS; val |= CLKMUX_BYPASS;
writel_relaxed(val, pll->base + PLL_CTRL); writel_relaxed(val, pll->base + PLL_CTRL);
@@ -300,8 +341,10 @@ static const struct clk_ops clk_fracn_gppll_ops = {
.set_rate = clk_fracn_gppll_set_rate, .set_rate = clk_fracn_gppll_set_rate,
}; };
struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base, static struct clk_hw *_imx_clk_fracn_gppll(const char *name, const char *parent_name,
const struct imx_fracn_gppll_clk *pll_clk) void __iomem *base,
const struct imx_fracn_gppll_clk *pll_clk,
u32 pll_flags)
{ {
struct clk_fracn_gppll *pll; struct clk_fracn_gppll *pll;
struct clk_hw *hw; struct clk_hw *hw;
@@ -322,6 +365,7 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
pll->hw.init = &init; pll->hw.init = &init;
pll->rate_table = pll_clk->rate_table; pll->rate_table = pll_clk->rate_table;
pll->rate_count = pll_clk->rate_count; pll->rate_count = pll_clk->rate_count;
pll->flags = pll_flags;
hw = &pll->hw; hw = &pll->hw;
@@ -334,4 +378,18 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
return hw; return hw;
} }
struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
const struct imx_fracn_gppll_clk *pll_clk)
{
return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_FRACN);
}
EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll); EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll);
struct clk_hw *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
void __iomem *base,
const struct imx_fracn_gppll_clk *pll_clk)
{
return _imx_clk_fracn_gppll(name, parent_name, base, pll_clk, CLK_FRACN_GPPLL_INTEGER);
}
EXPORT_SYMBOL_GPL(imx_clk_fracn_gppll_integer);

View File

@@ -550,8 +550,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1); hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000); hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080); hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100); hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180); hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200); hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);

View File

@@ -166,8 +166,8 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER); imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL); imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER); imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
/* Audio SS */ /* Audio SS */
imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL); imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL);
@@ -200,18 +200,18 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC); imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC);
/* Display controller SS */ /* Display controller SS */
imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL); imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL);
imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL); imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL);
imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
imx_clk_scu("dc1_pll0_clk", IMX_SC_R_DC_1_PLL_0, IMX_SC_PM_CLK_PLL); imx_clk_scu("dc1_pll0_clk", IMX_SC_R_DC_1_PLL_0, IMX_SC_PM_CLK_PLL);
imx_clk_scu("dc1_pll1_clk", IMX_SC_R_DC_1_PLL_1, IMX_SC_PM_CLK_PLL); imx_clk_scu("dc1_pll1_clk", IMX_SC_R_DC_1_PLL_1, IMX_SC_PM_CLK_PLL);
imx_clk_scu("dc1_bypass0_clk", IMX_SC_R_DC_1_VIDEO0, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("dc1_bypass0_clk", IMX_SC_R_DC_1_VIDEO0, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
imx_clk_scu("dc1_bypass1_clk", IMX_SC_R_DC_1_VIDEO1, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("dc1_bypass1_clk", IMX_SC_R_DC_1_VIDEO1, IMX_SC_PM_CLK_BYPASS);
/* MIPI-LVDS SS */ /* MIPI-LVDS SS */

View File

@@ -74,6 +74,9 @@ extern struct imx_pll14xx_clk imx_1416x_pll;
extern struct imx_pll14xx_clk imx_1443x_pll; extern struct imx_pll14xx_clk imx_1443x_pll;
extern struct imx_pll14xx_clk imx_1443x_dram_pll; extern struct imx_pll14xx_clk imx_1443x_dram_pll;
#define CLK_FRACN_GPPLL_INTEGER BIT(0)
#define CLK_FRACN_GPPLL_FRACN BIT(1)
/* NOTE: Rate table should be kept sorted in descending order. */ /* NOTE: Rate table should be kept sorted in descending order. */
struct imx_fracn_gppll_rate_table { struct imx_fracn_gppll_rate_table {
unsigned int rate; unsigned int rate;
@@ -92,8 +95,12 @@ struct imx_fracn_gppll_clk {
struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base, struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, void __iomem *base,
const struct imx_fracn_gppll_clk *pll_clk); const struct imx_fracn_gppll_clk *pll_clk);
struct clk_hw *imx_clk_fracn_gppll_integer(const char *name, const char *parent_name,
void __iomem *base,
const struct imx_fracn_gppll_clk *pll_clk);
extern struct imx_fracn_gppll_clk imx_fracn_gppll; extern struct imx_fracn_gppll_clk imx_fracn_gppll;
extern struct imx_fracn_gppll_clk imx_fracn_gppll_integer;
#define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)) to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))

View File

@@ -1700,6 +1700,58 @@ const struct clk_ops clk_alpha_pll_agera_ops = {
}; };
EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops); EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
/**
* clk_lucid_5lpe_pll_configure - configure the lucid 5lpe pll
*
* @pll: clk alpha pll
* @regmap: register map
* @config: configuration to apply for pll
*/
void clk_lucid_5lpe_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config)
{
/*
* If the bootloader left the PLL enabled it's likely that there are
* RCGs that will lock up if we disable the PLL below.
*/
if (trion_pll_is_enabled(pll, regmap)) {
pr_debug("Lucid 5LPE PLL is already enabled, skipping configuration\n");
return;
}
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
config->config_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
config->config_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),
config->config_ctl_hi1_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
config->user_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
config->user_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),
config->user_ctl_hi1_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
config->test_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
config->test_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),
config->test_ctl_hi1_val);
/* Disable PLL output */
regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
/* Set operation mode to OFF */
regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
/* Place the PLL in STANDBY mode */
regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
}
EXPORT_SYMBOL_GPL(clk_lucid_5lpe_pll_configure);
static int alpha_pll_lucid_5lpe_enable(struct clk_hw *hw) static int alpha_pll_lucid_5lpe_enable(struct clk_hw *hw)
{ {
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);

View File

@@ -178,6 +178,8 @@ void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config); const struct alpha_pll_config *config);
void clk_lucid_5lpe_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config); const struct alpha_pll_config *config);
void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,

View File

@@ -1332,8 +1332,13 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev)
disp_cc_pll1.vco_table = lucid_5lpe_vco; disp_cc_pll1.vco_table = lucid_5lpe_vco;
} }
clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8350-dispcc")) {
clk_lucid_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config); clk_lucid_5lpe_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
clk_lucid_5lpe_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
} else {
clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
clk_lucid_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
}
/* Enable clock gating for MDP clocks */ /* Enable clock gating for MDP clocks */
regmap_update_bits(regmap, 0x8000, 0x10, 0x10); regmap_update_bits(regmap, 0x8000, 0x10, 0x10);

View File

@@ -409,7 +409,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = {
RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
FACTOR(0, "xin12m", "xin24m", 0, 1, 2), FACTOR(0, "xin12m", "xin24m", 0, 1, 2),

View File

@@ -233,6 +233,7 @@ static int __init msm_dt_timer_init(struct device_node *np)
} }
if (of_property_read_u32(np, "clock-frequency", &freq)) { if (of_property_read_u32(np, "clock-frequency", &freq)) {
iounmap(cpu0_base);
pr_err("Unknown frequency\n"); pr_err("Unknown frequency\n");
return -EINVAL; return -EINVAL;
} }
@@ -243,7 +244,11 @@ static int __init msm_dt_timer_init(struct device_node *np)
freq /= 4; freq /= 4;
writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
return msm_timer_init(freq, 32, irq, !!percpu_offset); ret = msm_timer_init(freq, 32, irq, !!percpu_offset);
if (ret)
iounmap(cpu0_base);
return ret;
} }
TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);

View File

@@ -53,6 +53,9 @@ struct ti_cpufreq_soc_data {
unsigned long efuse_shift; unsigned long efuse_shift;
unsigned long rev_offset; unsigned long rev_offset;
bool multi_regulator; bool multi_regulator;
/* Backward compatibility hack: Might have missing syscon */
#define TI_QUIRK_SYSCON_MAY_BE_MISSING 0x1
u8 quirks;
}; };
struct ti_cpufreq_data { struct ti_cpufreq_data {
@@ -155,6 +158,7 @@ static struct ti_cpufreq_soc_data omap34xx_soc_data = {
.efuse_mask = BIT(3), .efuse_mask = BIT(3),
.rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE, .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
.multi_regulator = false, .multi_regulator = false,
.quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
}; };
/* /*
@@ -182,6 +186,7 @@ static struct ti_cpufreq_soc_data omap36xx_soc_data = {
.efuse_mask = BIT(9), .efuse_mask = BIT(9),
.rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE, .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
.multi_regulator = true, .multi_regulator = true,
.quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
}; };
/* /*
@@ -196,6 +201,7 @@ static struct ti_cpufreq_soc_data am3517_soc_data = {
.efuse_mask = 0, .efuse_mask = 0,
.rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE, .rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
.multi_regulator = false, .multi_regulator = false,
.quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
}; };
@@ -215,7 +221,7 @@ static int ti_cpufreq_get_efuse(struct ti_cpufreq_data *opp_data,
ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset, ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
&efuse); &efuse);
if (ret == -EIO) { if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
/* not a syscon register! */ /* not a syscon register! */
void __iomem *regs = ioremap(OMAP3_SYSCON_BASE + void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
opp_data->soc_data->efuse_offset, 4); opp_data->soc_data->efuse_offset, 4);
@@ -256,7 +262,7 @@ static int ti_cpufreq_get_rev(struct ti_cpufreq_data *opp_data,
ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset, ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
&revision); &revision);
if (ret == -EIO) { if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
/* not a syscon register! */ /* not a syscon register! */
void __iomem *regs = ioremap(OMAP3_SYSCON_BASE + void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
opp_data->soc_data->rev_offset, 4); opp_data->soc_data->rev_offset, 4);

View File

@@ -14,9 +14,7 @@
#include <linux/uacce.h> #include <linux/uacce.h>
#include "hpre.h" #include "hpre.h"
#define HPRE_QM_ABNML_INT_MASK 0x100004
#define HPRE_CTRL_CNT_CLR_CE_BIT BIT(0) #define HPRE_CTRL_CNT_CLR_CE_BIT BIT(0)
#define HPRE_COMM_CNT_CLR_CE 0x0
#define HPRE_CTRL_CNT_CLR_CE 0x301000 #define HPRE_CTRL_CNT_CLR_CE 0x301000
#define HPRE_FSM_MAX_CNT 0x301008 #define HPRE_FSM_MAX_CNT 0x301008
#define HPRE_VFG_AXQOS 0x30100c #define HPRE_VFG_AXQOS 0x30100c
@@ -43,7 +41,6 @@
#define HPRE_HAC_INT_SET 0x301500 #define HPRE_HAC_INT_SET 0x301500
#define HPRE_RNG_TIMEOUT_NUM 0x301A34 #define HPRE_RNG_TIMEOUT_NUM 0x301A34
#define HPRE_CORE_INT_ENABLE 0 #define HPRE_CORE_INT_ENABLE 0
#define HPRE_CORE_INT_DISABLE GENMASK(21, 0)
#define HPRE_RDCHN_INI_ST 0x301a00 #define HPRE_RDCHN_INI_ST 0x301a00
#define HPRE_CLSTR_BASE 0x302000 #define HPRE_CLSTR_BASE 0x302000
#define HPRE_CORE_EN_OFFSET 0x04 #define HPRE_CORE_EN_OFFSET 0x04
@@ -67,7 +64,6 @@
#define HPRE_CLSTR_ADDR_INTRVL 0x1000 #define HPRE_CLSTR_ADDR_INTRVL 0x1000
#define HPRE_CLUSTER_INQURY 0x100 #define HPRE_CLUSTER_INQURY 0x100
#define HPRE_CLSTR_ADDR_INQRY_RSLT 0x104 #define HPRE_CLSTR_ADDR_INQRY_RSLT 0x104
#define HPRE_TIMEOUT_ABNML_BIT 6
#define HPRE_PASID_EN_BIT 9 #define HPRE_PASID_EN_BIT 9
#define HPRE_REG_RD_INTVRL_US 10 #define HPRE_REG_RD_INTVRL_US 10
#define HPRE_REG_RD_TMOUT_US 1000 #define HPRE_REG_RD_TMOUT_US 1000
@@ -203,9 +199,9 @@ static const struct hisi_qm_cap_info hpre_basic_info[] = {
{HPRE_QM_RESET_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0xC37, 0x6C37}, {HPRE_QM_RESET_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0xC37, 0x6C37},
{HPRE_QM_OOO_SHUTDOWN_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0x4, 0x6C37}, {HPRE_QM_OOO_SHUTDOWN_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0x4, 0x6C37},
{HPRE_QM_CE_MASK_CAP, 0x312C, 0, GENMASK(31, 0), 0x0, 0x8, 0x8}, {HPRE_QM_CE_MASK_CAP, 0x312C, 0, GENMASK(31, 0), 0x0, 0x8, 0x8},
{HPRE_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0xFFFFFE}, {HPRE_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0x1FFFC3E},
{HPRE_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0xBFFFFE}, {HPRE_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0xBFFC3E},
{HPRE_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x22, 0xBFFFFE}, {HPRE_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x22, 0xBFFC3E},
{HPRE_CE_MASK_CAP, 0x3138, 0, GENMASK(31, 0), 0x0, 0x1, 0x1}, {HPRE_CE_MASK_CAP, 0x3138, 0, GENMASK(31, 0), 0x0, 0x1, 0x1},
{HPRE_CLUSTER_NUM_CAP, 0x313c, 20, GENMASK(3, 0), 0x0, 0x4, 0x1}, {HPRE_CLUSTER_NUM_CAP, 0x313c, 20, GENMASK(3, 0), 0x0, 0x4, 0x1},
{HPRE_CORE_TYPE_NUM_CAP, 0x313c, 16, GENMASK(3, 0), 0x0, 0x2, 0x2}, {HPRE_CORE_TYPE_NUM_CAP, 0x313c, 16, GENMASK(3, 0), 0x0, 0x2, 0x2},
@@ -283,6 +279,9 @@ static const struct hpre_hw_error hpre_hw_errors[] = {
}, { }, {
.int_msk = BIT(23), .int_msk = BIT(23),
.msg = "sva_fsm_timeout_int_set" .msg = "sva_fsm_timeout_int_set"
}, {
.int_msk = BIT(24),
.msg = "sva_int_set"
}, { }, {
/* sentinel */ /* sentinel */
} }
@@ -355,6 +354,8 @@ static struct dfx_diff_registers hpre_diff_regs[] = {
}, },
}; };
static const struct hisi_qm_err_ini hpre_err_ini;
bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg)
{ {
u32 cap_val; u32 cap_val;
@@ -651,11 +652,6 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm)
writel(HPRE_QM_USR_CFG_MASK, qm->io_base + QM_AWUSER_M_CFG_ENABLE); writel(HPRE_QM_USR_CFG_MASK, qm->io_base + QM_AWUSER_M_CFG_ENABLE);
writel_relaxed(HPRE_QM_AXI_CFG_MASK, qm->io_base + QM_AXI_M_CFG); writel_relaxed(HPRE_QM_AXI_CFG_MASK, qm->io_base + QM_AXI_M_CFG);
/* HPRE need more time, we close this interrupt */
val = readl_relaxed(qm->io_base + HPRE_QM_ABNML_INT_MASK);
val |= BIT(HPRE_TIMEOUT_ABNML_BIT);
writel_relaxed(val, qm->io_base + HPRE_QM_ABNML_INT_MASK);
if (qm->ver >= QM_HW_V3) if (qm->ver >= QM_HW_V3)
writel(HPRE_RSA_ENB | HPRE_ECC_ENB, writel(HPRE_RSA_ENB | HPRE_ECC_ENB,
qm->io_base + HPRE_TYPES_ENB); qm->io_base + HPRE_TYPES_ENB);
@@ -664,9 +660,7 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm)
writel(HPRE_QM_VFG_AX_MASK, qm->io_base + HPRE_VFG_AXCACHE); writel(HPRE_QM_VFG_AX_MASK, qm->io_base + HPRE_VFG_AXCACHE);
writel(0x0, qm->io_base + HPRE_BD_ENDIAN); writel(0x0, qm->io_base + HPRE_BD_ENDIAN);
writel(0x0, qm->io_base + HPRE_INT_MASK);
writel(0x0, qm->io_base + HPRE_POISON_BYPASS); writel(0x0, qm->io_base + HPRE_POISON_BYPASS);
writel(0x0, qm->io_base + HPRE_COMM_CNT_CLR_CE);
writel(0x0, qm->io_base + HPRE_ECC_BYPASS); writel(0x0, qm->io_base + HPRE_ECC_BYPASS);
writel(HPRE_BD_USR_MASK, qm->io_base + HPRE_BD_ARUSR_CFG); writel(HPRE_BD_USR_MASK, qm->io_base + HPRE_BD_ARUSR_CFG);
@@ -756,7 +750,7 @@ static void hpre_hw_error_disable(struct hisi_qm *qm)
static void hpre_hw_error_enable(struct hisi_qm *qm) static void hpre_hw_error_enable(struct hisi_qm *qm)
{ {
u32 ce, nfe; u32 ce, nfe, err_en;
ce = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CE_MASK_CAP, qm->cap_ver); ce = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CE_MASK_CAP, qm->cap_ver);
nfe = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver); nfe = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
@@ -773,7 +767,8 @@ static void hpre_hw_error_enable(struct hisi_qm *qm)
hpre_master_ooo_ctrl(qm, true); hpre_master_ooo_ctrl(qm, true);
/* enable hpre hw error interrupts */ /* enable hpre hw error interrupts */
writel(HPRE_CORE_INT_ENABLE, qm->io_base + HPRE_INT_MASK); err_en = ce | nfe | HPRE_HAC_RAS_FE_ENABLE;
writel(~err_en, qm->io_base + HPRE_INT_MASK);
} }
static inline struct hisi_qm *hpre_file_to_qm(struct hpre_debugfs_file *file) static inline struct hisi_qm *hpre_file_to_qm(struct hpre_debugfs_file *file)
@@ -1159,6 +1154,7 @@ static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_num = pf_q_num; qm->qp_num = pf_q_num;
qm->debug.curr_qm_qp_num = pf_q_num; qm->debug.curr_qm_qp_num = pf_q_num;
qm->qm_list = &hpre_devices; qm->qm_list = &hpre_devices;
qm->err_ini = &hpre_err_ini;
if (pf_q_num_flag) if (pf_q_num_flag)
set_bit(QM_MODULE_PARAM, &qm->misc_ctl); set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
} }
@@ -1348,8 +1344,6 @@ static int hpre_pf_probe_init(struct hpre *hpre)
hpre_open_sva_prefetch(qm); hpre_open_sva_prefetch(qm);
qm->err_ini = &hpre_err_ini;
qm->err_ini->err_info_init(qm);
hisi_qm_dev_err_init(qm); hisi_qm_dev_err_init(qm);
ret = hpre_show_last_regs_init(qm); ret = hpre_show_last_regs_init(qm);
if (ret) if (ret)
@@ -1378,6 +1372,18 @@ static int hpre_probe_init(struct hpre *hpre)
return 0; return 0;
} }
static void hpre_probe_uninit(struct hisi_qm *qm)
{
if (qm->fun_type == QM_HW_VF)
return;
hpre_cnt_regs_clear(qm);
qm->debug.curr_qm_qp_num = 0;
hpre_show_last_regs_uninit(qm);
hpre_close_sva_prefetch(qm);
hisi_qm_dev_err_uninit(qm);
}
static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct hisi_qm *qm; struct hisi_qm *qm;
@@ -1403,7 +1409,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = hisi_qm_start(qm); ret = hisi_qm_start(qm);
if (ret) if (ret)
goto err_with_err_init; goto err_with_probe_init;
ret = hpre_debugfs_init(qm); ret = hpre_debugfs_init(qm);
if (ret) if (ret)
@@ -1440,9 +1446,8 @@ err_with_qm_start:
hpre_debugfs_exit(qm); hpre_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL); hisi_qm_stop(qm, QM_NORMAL);
err_with_err_init: err_with_probe_init:
hpre_show_last_regs_uninit(qm); hpre_probe_uninit(qm);
hisi_qm_dev_err_uninit(qm);
err_with_qm_init: err_with_qm_init:
hisi_qm_uninit(qm); hisi_qm_uninit(qm);
@@ -1463,13 +1468,7 @@ static void hpre_remove(struct pci_dev *pdev)
hpre_debugfs_exit(qm); hpre_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL); hisi_qm_stop(qm, QM_NORMAL);
if (qm->fun_type == QM_HW_PF) { hpre_probe_uninit(qm);
hpre_cnt_regs_clear(qm);
qm->debug.curr_qm_qp_num = 0;
hpre_show_last_regs_uninit(qm);
hisi_qm_dev_err_uninit(qm);
}
hisi_qm_uninit(qm); hisi_qm_uninit(qm);
} }

View File

@@ -118,7 +118,7 @@
#define QM_SQC_VFT_BASE_SHIFT_V2 28 #define QM_SQC_VFT_BASE_SHIFT_V2 28
#define QM_SQC_VFT_BASE_MASK_V2 GENMASK(15, 0) #define QM_SQC_VFT_BASE_MASK_V2 GENMASK(15, 0)
#define QM_SQC_VFT_NUM_SHIFT_V2 45 #define QM_SQC_VFT_NUM_SHIFT_V2 45
#define QM_SQC_VFT_NUM_MASK_v2 GENMASK(9, 0) #define QM_SQC_VFT_NUM_MASK_V2 GENMASK(9, 0)
#define QM_ABNORMAL_INT_SOURCE 0x100000 #define QM_ABNORMAL_INT_SOURCE 0x100000
#define QM_ABNORMAL_INT_MASK 0x100004 #define QM_ABNORMAL_INT_MASK 0x100004
@@ -240,23 +240,23 @@
#define QM_DEV_ALG_MAX_LEN 256 #define QM_DEV_ALG_MAX_LEN 256
#define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ #define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \
(((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \ (((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \
((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \ ((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \
((buf_sz) << QM_CQ_BUF_SIZE_SHIFT) | \ ((buf_sz) << QM_CQ_BUF_SIZE_SHIFT) | \
((cqe_sz) << QM_CQ_CQE_SIZE_SHIFT)) ((cqe_sz) << QM_CQ_CQE_SIZE_SHIFT))
#define QM_MK_CQC_DW3_V2(cqe_sz, cq_depth) \ #define QM_MK_CQC_DW3_V2(cqe_sz, cq_depth) \
((((u32)cq_depth) - 1) | ((cqe_sz) << QM_CQ_CQE_SIZE_SHIFT)) ((((u32)cq_depth) - 1) | ((cqe_sz) << QM_CQ_CQE_SIZE_SHIFT))
#define QM_MK_SQC_W13(priority, orders, alg_type) \ #define QM_MK_SQC_W13(priority, orders, alg_type) \
(((priority) << QM_SQ_PRIORITY_SHIFT) | \ (((priority) << QM_SQ_PRIORITY_SHIFT) | \
((orders) << QM_SQ_ORDERS_SHIFT) | \ ((orders) << QM_SQ_ORDERS_SHIFT) | \
(((alg_type) & QM_SQ_TYPE_MASK) << QM_SQ_TYPE_SHIFT)) (((alg_type) & QM_SQ_TYPE_MASK) << QM_SQ_TYPE_SHIFT))
#define QM_MK_SQC_DW3_V1(hop_num, pg_sz, buf_sz, sqe_sz) \ #define QM_MK_SQC_DW3_V1(hop_num, pg_sz, buf_sz, sqe_sz) \
(((hop_num) << QM_SQ_HOP_NUM_SHIFT) | \ (((hop_num) << QM_SQ_HOP_NUM_SHIFT) | \
((pg_sz) << QM_SQ_PAGE_SIZE_SHIFT) | \ ((pg_sz) << QM_SQ_PAGE_SIZE_SHIFT) | \
((buf_sz) << QM_SQ_BUF_SIZE_SHIFT) | \ ((buf_sz) << QM_SQ_BUF_SIZE_SHIFT) | \
((u32)ilog2(sqe_sz) << QM_SQ_SQE_SIZE_SHIFT)) ((u32)ilog2(sqe_sz) << QM_SQ_SQE_SIZE_SHIFT))
#define QM_MK_SQC_DW3_V2(sqe_sz, sq_depth) \ #define QM_MK_SQC_DW3_V2(sqe_sz, sq_depth) \
@@ -454,6 +454,7 @@ static struct qm_typical_qos_table shaper_cbs_s[] = {
}; };
static void qm_irqs_unregister(struct hisi_qm *qm); static void qm_irqs_unregister(struct hisi_qm *qm);
static int qm_reset_device(struct hisi_qm *qm);
static bool qm_avail_state(struct hisi_qm *qm, enum qm_state new) static bool qm_avail_state(struct hisi_qm *qm, enum qm_state new)
{ {
@@ -720,7 +721,7 @@ static void qm_db_v2(struct hisi_qm *qm, u16 qn, u8 cmd, u16 index, u8 priority)
doorbell = qn | ((u64)cmd << QM_DB_CMD_SHIFT_V2) | doorbell = qn | ((u64)cmd << QM_DB_CMD_SHIFT_V2) |
((u64)randata << QM_DB_RAND_SHIFT_V2) | ((u64)randata << QM_DB_RAND_SHIFT_V2) |
((u64)index << QM_DB_INDEX_SHIFT_V2) | ((u64)index << QM_DB_INDEX_SHIFT_V2) |
((u64)priority << QM_DB_PRIORITY_SHIFT_V2); ((u64)priority << QM_DB_PRIORITY_SHIFT_V2);
writeq(doorbell, io_base); writeq(doorbell, io_base);
@@ -1354,7 +1355,7 @@ static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number)
sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) | sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) |
((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32); ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32);
*base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2); *base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2);
*number = (QM_SQC_VFT_NUM_MASK_v2 & *number = (QM_SQC_VFT_NUM_MASK_V2 &
(sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1; (sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1;
return 0; return 0;
@@ -3123,7 +3124,6 @@ static int qm_stop_started_qp(struct hisi_qm *qm)
return 0; return 0;
} }
/** /**
* qm_clear_queues() - Clear all queues memory in a qm. * qm_clear_queues() - Clear all queues memory in a qm.
* @qm: The qm in which the queues will be cleared. * @qm: The qm in which the queues will be cleared.
@@ -3609,7 +3609,7 @@ static ssize_t qm_algqos_read(struct file *filp, char __user *buf,
qos_val = ir / QM_QOS_RATE; qos_val = ir / QM_QOS_RATE;
ret = scnprintf(tbuf, QM_DBG_READ_LEN, "%u\n", qos_val); ret = scnprintf(tbuf, QM_DBG_READ_LEN, "%u\n", qos_val);
ret = simple_read_from_buffer(buf, count, pos, tbuf, ret); ret = simple_read_from_buffer(buf, count, pos, tbuf, ret);
err_get_status: err_get_status:
clear_bit(QM_RESETTING, &qm->misc_ctl); clear_bit(QM_RESETTING, &qm->misc_ctl);
@@ -4017,6 +4017,28 @@ static int qm_set_vf_mse(struct hisi_qm *qm, bool set)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
{
u32 nfe_enb = 0;
/* Kunpeng930 hardware automatically close master ooo when NFE occurs */
if (qm->ver >= QM_HW_V3)
return;
if (!qm->err_status.is_dev_ecc_mbit &&
qm->err_status.is_qm_ecc_mbit &&
qm->err_ini->close_axi_master_ooo) {
qm->err_ini->close_axi_master_ooo(qm);
} else if (qm->err_status.is_dev_ecc_mbit &&
!qm->err_status.is_qm_ecc_mbit &&
!qm->err_ini->close_axi_master_ooo) {
nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
qm->io_base + QM_RAS_NFE_ENABLE);
writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
}
}
static int qm_vf_reset_prepare(struct hisi_qm *qm, static int qm_vf_reset_prepare(struct hisi_qm *qm,
enum qm_stop_reason stop_reason) enum qm_stop_reason stop_reason)
{ {
@@ -4081,6 +4103,8 @@ static int qm_controller_reset_prepare(struct hisi_qm *qm)
return ret; return ret;
} }
qm_dev_ecc_mbit_handle(qm);
/* PF obtains the information of VF by querying the register. */ /* PF obtains the information of VF by querying the register. */
qm_cmd_uninit(qm); qm_cmd_uninit(qm);
@@ -4105,36 +4129,26 @@ static int qm_controller_reset_prepare(struct hisi_qm *qm)
return 0; return 0;
} }
static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm) static int qm_master_ooo_check(struct hisi_qm *qm)
{ {
u32 nfe_enb = 0; u32 val;
int ret;
/* Kunpeng930 hardware automatically close master ooo when NFE occurs */ /* Check the ooo register of the device before resetting the device. */
if (qm->ver >= QM_HW_V3) writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
return; ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
val, (val == ACC_MASTER_TRANS_RETURN_RW),
POLL_PERIOD, POLL_TIMEOUT);
if (ret)
pci_warn(qm->pdev, "Bus lock! Please reset system.\n");
if (!qm->err_status.is_dev_ecc_mbit && return ret;
qm->err_status.is_qm_ecc_mbit &&
qm->err_ini->close_axi_master_ooo) {
qm->err_ini->close_axi_master_ooo(qm);
} else if (qm->err_status.is_dev_ecc_mbit &&
!qm->err_status.is_qm_ecc_mbit &&
!qm->err_ini->close_axi_master_ooo) {
nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
qm->io_base + QM_RAS_NFE_ENABLE);
writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
}
} }
static int qm_soft_reset(struct hisi_qm *qm) static int qm_soft_reset_prepare(struct hisi_qm *qm)
{ {
struct pci_dev *pdev = qm->pdev; struct pci_dev *pdev = qm->pdev;
int ret; int ret;
u32 val;
/* Ensure all doorbells and mailboxes received by QM */ /* Ensure all doorbells and mailboxes received by QM */
ret = qm_check_req_recv(qm); ret = qm_check_req_recv(qm);
@@ -4155,30 +4169,23 @@ static int qm_soft_reset(struct hisi_qm *qm)
return ret; return ret;
} }
qm_dev_ecc_mbit_handle(qm); ret = qm_master_ooo_check(qm);
if (ret)
/* OOO register set and check */
writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
qm->io_base + ACC_MASTER_GLOBAL_CTRL);
/* If bus lock, reset chip */
ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
val,
(val == ACC_MASTER_TRANS_RETURN_RW),
POLL_PERIOD, POLL_TIMEOUT);
if (ret) {
pci_emerg(pdev, "Bus lock! Please reset system.\n");
return ret; return ret;
}
if (qm->err_ini->close_sva_prefetch) if (qm->err_ini->close_sva_prefetch)
qm->err_ini->close_sva_prefetch(qm); qm->err_ini->close_sva_prefetch(qm);
ret = qm_set_pf_mse(qm, false); ret = qm_set_pf_mse(qm, false);
if (ret) { if (ret)
pci_err(pdev, "Fails to disable pf MSE bit.\n"); pci_err(pdev, "Fails to disable pf MSE bit.\n");
return ret;
} return ret;
}
static int qm_reset_device(struct hisi_qm *qm)
{
struct pci_dev *pdev = qm->pdev;
/* The reset related sub-control registers are not in PCI BAR */ /* The reset related sub-control registers are not in PCI BAR */
if (ACPI_HANDLE(&pdev->dev)) { if (ACPI_HANDLE(&pdev->dev)) {
@@ -4197,12 +4204,23 @@ static int qm_soft_reset(struct hisi_qm *qm)
pci_err(pdev, "Reset step %llu failed!\n", value); pci_err(pdev, "Reset step %llu failed!\n", value);
return -EIO; return -EIO;
} }
} else {
pci_err(pdev, "No reset method!\n"); return 0;
return -EINVAL;
} }
return 0; pci_err(pdev, "No reset method!\n");
return -EINVAL;
}
static int qm_soft_reset(struct hisi_qm *qm)
{
int ret;
ret = qm_soft_reset_prepare(qm);
if (ret)
return ret;
return qm_reset_device(qm);
} }
static int qm_vf_reset_done(struct hisi_qm *qm) static int qm_vf_reset_done(struct hisi_qm *qm)
@@ -4566,7 +4584,6 @@ static irqreturn_t qm_abnormal_irq(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/** /**
* hisi_qm_dev_shutdown() - Shutdown device. * hisi_qm_dev_shutdown() - Shutdown device.
* @pdev: The device will be shutdown. * @pdev: The device will be shutdown.
@@ -5165,6 +5182,35 @@ err_request_mem_regions:
return ret; return ret;
} }
static int qm_clear_device(struct hisi_qm *qm)
{
acpi_handle handle = ACPI_HANDLE(&qm->pdev->dev);
int ret;
if (qm->fun_type == QM_HW_VF)
return 0;
/* Device does not support reset, return */
if (!qm->err_ini->err_info_init)
return 0;
qm->err_ini->err_info_init(qm);
if (!handle)
return 0;
/* No reset method, return */
if (!acpi_has_method(handle, qm->err_info.acpi_rst))
return 0;
ret = qm_master_ooo_check(qm);
if (ret) {
writel(0x0, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
return ret;
}
return qm_reset_device(qm);
}
static int hisi_qm_pci_init(struct hisi_qm *qm) static int hisi_qm_pci_init(struct hisi_qm *qm)
{ {
struct pci_dev *pdev = qm->pdev; struct pci_dev *pdev = qm->pdev;
@@ -5194,8 +5240,14 @@ static int hisi_qm_pci_init(struct hisi_qm *qm)
goto err_get_pci_res; goto err_get_pci_res;
} }
ret = qm_clear_device(qm);
if (ret)
goto err_free_vectors;
return 0; return 0;
err_free_vectors:
pci_free_irq_vectors(pdev);
err_get_pci_res: err_get_pci_res:
qm_put_pci_res(qm); qm_put_pci_res(qm);
err_disable_pcidev: err_disable_pcidev:
@@ -5462,7 +5514,6 @@ static int qm_prepare_for_suspend(struct hisi_qm *qm)
{ {
struct pci_dev *pdev = qm->pdev; struct pci_dev *pdev = qm->pdev;
int ret; int ret;
u32 val;
ret = qm->ops->set_msi(qm, false); ret = qm->ops->set_msi(qm, false);
if (ret) { if (ret) {
@@ -5470,18 +5521,9 @@ static int qm_prepare_for_suspend(struct hisi_qm *qm)
return ret; return ret;
} }
/* shutdown OOO register */ ret = qm_master_ooo_check(qm);
writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN, if (ret)
qm->io_base + ACC_MASTER_GLOBAL_CTRL);
ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
val,
(val == ACC_MASTER_TRANS_RETURN_RW),
POLL_PERIOD, POLL_TIMEOUT);
if (ret) {
pci_emerg(pdev, "Bus lock! Please reset system.\n");
return ret; return ret;
}
ret = qm_set_pf_mse(qm, false); ret = qm_set_pf_mse(qm, false);
if (ret) if (ret)

View File

@@ -1063,9 +1063,6 @@ static int sec_pf_probe_init(struct sec_dev *sec)
struct hisi_qm *qm = &sec->qm; struct hisi_qm *qm = &sec->qm;
int ret; int ret;
qm->err_ini = &sec_err_ini;
qm->err_ini->err_info_init(qm);
ret = sec_set_user_domain_and_cache(qm); ret = sec_set_user_domain_and_cache(qm);
if (ret) if (ret)
return ret; return ret;
@@ -1120,6 +1117,7 @@ static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_num = pf_q_num; qm->qp_num = pf_q_num;
qm->debug.curr_qm_qp_num = pf_q_num; qm->debug.curr_qm_qp_num = pf_q_num;
qm->qm_list = &sec_devices; qm->qm_list = &sec_devices;
qm->err_ini = &sec_err_ini;
if (pf_q_num_flag) if (pf_q_num_flag)
set_bit(QM_MODULE_PARAM, &qm->misc_ctl); set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) { } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
@@ -1184,6 +1182,12 @@ static int sec_probe_init(struct sec_dev *sec)
static void sec_probe_uninit(struct hisi_qm *qm) static void sec_probe_uninit(struct hisi_qm *qm)
{ {
if (qm->fun_type == QM_HW_VF)
return;
sec_debug_regs_clear(qm);
sec_show_last_regs_uninit(qm);
sec_close_sva_prefetch(qm);
hisi_qm_dev_err_uninit(qm); hisi_qm_dev_err_uninit(qm);
} }
@@ -1276,7 +1280,6 @@ err_qm_stop:
sec_debugfs_exit(qm); sec_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL); hisi_qm_stop(qm, QM_NORMAL);
err_probe_uninit: err_probe_uninit:
sec_show_last_regs_uninit(qm);
sec_probe_uninit(qm); sec_probe_uninit(qm);
err_qm_uninit: err_qm_uninit:
sec_qm_uninit(qm); sec_qm_uninit(qm);
@@ -1298,11 +1301,6 @@ static void sec_remove(struct pci_dev *pdev)
sec_debugfs_exit(qm); sec_debugfs_exit(qm);
(void)hisi_qm_stop(qm, QM_NORMAL); (void)hisi_qm_stop(qm, QM_NORMAL);
if (qm->fun_type == QM_HW_PF)
sec_debug_regs_clear(qm);
sec_show_last_regs_uninit(qm);
sec_probe_uninit(qm); sec_probe_uninit(qm);
sec_qm_uninit(qm); sec_qm_uninit(qm);

View File

@@ -249,7 +249,6 @@ hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev,
dev_err(dev, "Get SGL error!\n"); dev_err(dev, "Get SGL error!\n");
dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr); curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr);
curr_hw_sge = curr_hw_sgl->sge_entries; curr_hw_sge = curr_hw_sgl->sge_entries;

View File

@@ -1151,8 +1151,6 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
hisi_zip->ctrl = ctrl; hisi_zip->ctrl = ctrl;
ctrl->hisi_zip = hisi_zip; ctrl->hisi_zip = hisi_zip;
qm->err_ini = &hisi_zip_err_ini;
qm->err_ini->err_info_init(qm);
ret = hisi_zip_set_user_domain_and_cache(qm); ret = hisi_zip_set_user_domain_and_cache(qm);
if (ret) if (ret)
@@ -1213,6 +1211,7 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_num = pf_q_num; qm->qp_num = pf_q_num;
qm->debug.curr_qm_qp_num = pf_q_num; qm->debug.curr_qm_qp_num = pf_q_num;
qm->qm_list = &zip_devices; qm->qm_list = &zip_devices;
qm->err_ini = &hisi_zip_err_ini;
if (pf_q_num_flag) if (pf_q_num_flag)
set_bit(QM_MODULE_PARAM, &qm->misc_ctl); set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) { } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
@@ -1279,6 +1278,16 @@ static int hisi_zip_probe_init(struct hisi_zip *hisi_zip)
return 0; return 0;
} }
static void hisi_zip_probe_uninit(struct hisi_qm *qm)
{
if (qm->fun_type == QM_HW_VF)
return;
hisi_zip_show_last_regs_uninit(qm);
hisi_zip_close_sva_prefetch(qm);
hisi_qm_dev_err_uninit(qm);
}
static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{ {
struct hisi_zip *hisi_zip; struct hisi_zip *hisi_zip;
@@ -1305,7 +1314,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ret = hisi_qm_start(qm); ret = hisi_qm_start(qm);
if (ret) if (ret)
goto err_dev_err_uninit; goto err_probe_uninit;
ret = hisi_zip_debugfs_init(qm); ret = hisi_zip_debugfs_init(qm);
if (ret) if (ret)
@@ -1342,9 +1351,8 @@ err_qm_stop:
hisi_zip_debugfs_exit(qm); hisi_zip_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL); hisi_qm_stop(qm, QM_NORMAL);
err_dev_err_uninit: err_probe_uninit:
hisi_zip_show_last_regs_uninit(qm); hisi_zip_probe_uninit(qm);
hisi_qm_dev_err_uninit(qm);
err_qm_uninit: err_qm_uninit:
hisi_zip_qm_uninit(qm); hisi_zip_qm_uninit(qm);
@@ -1365,8 +1373,7 @@ static void hisi_zip_remove(struct pci_dev *pdev)
hisi_zip_debugfs_exit(qm); hisi_zip_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL); hisi_qm_stop(qm, QM_NORMAL);
hisi_zip_show_last_regs_uninit(qm); hisi_zip_probe_uninit(qm);
hisi_qm_dev_err_uninit(qm);
hisi_zip_qm_uninit(qm); hisi_zip_qm_uninit(qm);
} }

View File

@@ -9,6 +9,8 @@
#include <linux/edac.h> #include <linux/edac.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/sizes.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
@@ -300,6 +302,7 @@ struct synps_ecc_status {
/** /**
* struct synps_edac_priv - DDR memory controller private instance data. * struct synps_edac_priv - DDR memory controller private instance data.
* @baseaddr: Base address of the DDR controller. * @baseaddr: Base address of the DDR controller.
* @reglock: Concurrent CSRs access lock.
* @message: Buffer for framing the event specific info. * @message: Buffer for framing the event specific info.
* @stat: ECC status information. * @stat: ECC status information.
* @p_data: Platform data. * @p_data: Platform data.
@@ -314,6 +317,7 @@ struct synps_ecc_status {
*/ */
struct synps_edac_priv { struct synps_edac_priv {
void __iomem *baseaddr; void __iomem *baseaddr;
spinlock_t reglock;
char message[SYNPS_EDAC_MSG_SIZE]; char message[SYNPS_EDAC_MSG_SIZE];
struct synps_ecc_status stat; struct synps_ecc_status stat;
const struct synps_platform_data *p_data; const struct synps_platform_data *p_data;
@@ -335,6 +339,7 @@ struct synps_edac_priv {
* @get_mtype: Get mtype. * @get_mtype: Get mtype.
* @get_dtype: Get dtype. * @get_dtype: Get dtype.
* @get_ecc_state: Get ECC state. * @get_ecc_state: Get ECC state.
* @get_mem_info: Get EDAC memory info
* @quirks: To differentiate IPs. * @quirks: To differentiate IPs.
*/ */
struct synps_platform_data { struct synps_platform_data {
@@ -342,6 +347,9 @@ struct synps_platform_data {
enum mem_type (*get_mtype)(const void __iomem *base); enum mem_type (*get_mtype)(const void __iomem *base);
enum dev_type (*get_dtype)(const void __iomem *base); enum dev_type (*get_dtype)(const void __iomem *base);
bool (*get_ecc_state)(void __iomem *base); bool (*get_ecc_state)(void __iomem *base);
#ifdef CONFIG_EDAC_DEBUG
u64 (*get_mem_info)(struct synps_edac_priv *priv);
#endif
int quirks; int quirks;
}; };
@@ -400,6 +408,25 @@ out:
return 0; return 0;
} }
#ifdef CONFIG_EDAC_DEBUG
/**
* zynqmp_get_mem_info - Get the current memory info.
* @priv: DDR memory controller private instance data.
*
* Return: host interface address.
*/
static u64 zynqmp_get_mem_info(struct synps_edac_priv *priv)
{
u64 hif_addr = 0, linear_addr;
linear_addr = priv->poison_addr;
if (linear_addr >= SZ_32G)
linear_addr = linear_addr - SZ_32G + SZ_2G;
hif_addr = linear_addr >> 3;
return hif_addr;
}
#endif
/** /**
* zynqmp_get_error_info - Get the current ECC error info. * zynqmp_get_error_info - Get the current ECC error info.
* @priv: DDR memory controller private instance data. * @priv: DDR memory controller private instance data.
@@ -409,7 +436,8 @@ out:
static int zynqmp_get_error_info(struct synps_edac_priv *priv) static int zynqmp_get_error_info(struct synps_edac_priv *priv)
{ {
struct synps_ecc_status *p; struct synps_ecc_status *p;
u32 regval, clearval = 0; u32 regval, clearval;
unsigned long flags;
void __iomem *base; void __iomem *base;
base = priv->baseaddr; base = priv->baseaddr;
@@ -453,10 +481,14 @@ ue_err:
p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK); p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
p->ueinfo.data = readl(base + ECC_UESYND0_OFST); p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
out: out:
clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT; spin_lock_irqsave(&priv->reglock, flags);
clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
clearval = readl(base + ECC_CLR_OFST) |
ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
writel(clearval, base + ECC_CLR_OFST); writel(clearval, base + ECC_CLR_OFST);
writel(0x0, base + ECC_CLR_OFST);
spin_unlock_irqrestore(&priv->reglock, flags);
return 0; return 0;
} }
@@ -516,24 +548,41 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p)
static void enable_intr(struct synps_edac_priv *priv) static void enable_intr(struct synps_edac_priv *priv)
{ {
unsigned long flags;
/* Enable UE/CE Interrupts */ /* Enable UE/CE Interrupts */
if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
writel(DDR_UE_MASK | DDR_CE_MASK,
priv->baseaddr + ECC_CLR_OFST);
else
writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
priv->baseaddr + DDR_QOS_IRQ_EN_OFST); priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
return;
}
spin_lock_irqsave(&priv->reglock, flags);
writel(DDR_UE_MASK | DDR_CE_MASK,
priv->baseaddr + ECC_CLR_OFST);
spin_unlock_irqrestore(&priv->reglock, flags);
} }
static void disable_intr(struct synps_edac_priv *priv) static void disable_intr(struct synps_edac_priv *priv)
{ {
unsigned long flags;
/* Disable UE/CE Interrupts */ /* Disable UE/CE Interrupts */
if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR) if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
writel(0x0, priv->baseaddr + ECC_CLR_OFST);
else
writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK, writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
priv->baseaddr + DDR_QOS_IRQ_DB_OFST); priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
return;
}
spin_lock_irqsave(&priv->reglock, flags);
writel(0, priv->baseaddr + ECC_CLR_OFST);
spin_unlock_irqrestore(&priv->reglock, flags);
} }
/** /**
@@ -577,8 +626,6 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
/* v3.0 of the controller does not have this register */ /* v3.0 of the controller does not have this register */
if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST); writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
else
enable_intr(priv);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@@ -900,6 +947,9 @@ static const struct synps_platform_data zynqmp_edac_def = {
.get_mtype = zynqmp_get_mtype, .get_mtype = zynqmp_get_mtype,
.get_dtype = zynqmp_get_dtype, .get_dtype = zynqmp_get_dtype,
.get_ecc_state = zynqmp_get_ecc_state, .get_ecc_state = zynqmp_get_ecc_state,
#ifdef CONFIG_EDAC_DEBUG
.get_mem_info = zynqmp_get_mem_info,
#endif
.quirks = (DDR_ECC_INTR_SUPPORT .quirks = (DDR_ECC_INTR_SUPPORT
#ifdef CONFIG_EDAC_DEBUG #ifdef CONFIG_EDAC_DEBUG
| DDR_ECC_DATA_POISON_SUPPORT | DDR_ECC_DATA_POISON_SUPPORT
@@ -953,10 +1003,16 @@ MODULE_DEVICE_TABLE(of, synps_edac_match);
static void ddr_poison_setup(struct synps_edac_priv *priv) static void ddr_poison_setup(struct synps_edac_priv *priv)
{ {
int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval; int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval;
const struct synps_platform_data *p_data;
int index; int index;
ulong hif_addr = 0; ulong hif_addr = 0;
hif_addr = priv->poison_addr >> 3; p_data = priv->p_data;
if (p_data->get_mem_info)
hif_addr = p_data->get_mem_info(priv);
else
hif_addr = priv->poison_addr >> 3;
for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) { for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) {
if (priv->row_shift[index]) if (priv->row_shift[index])
@@ -1360,6 +1416,7 @@ static int mc_probe(struct platform_device *pdev)
priv = mci->pvt_info; priv = mci->pvt_info;
priv->baseaddr = baseaddr; priv->baseaddr = baseaddr;
priv->p_data = p_data; priv->p_data = p_data;
spin_lock_init(&priv->reglock);
mc_init(mci, pdev); mc_init(mci, pdev);

View File

@@ -467,6 +467,13 @@ static int scmi_optee_chan_free(int id, void *p, void *data)
struct scmi_chan_info *cinfo = p; struct scmi_chan_info *cinfo = p;
struct scmi_optee_channel *channel = cinfo->transport_info; struct scmi_optee_channel *channel = cinfo->transport_info;
/*
* Different protocols might share the same chan info, so a previous
* call might have already freed the structure.
*/
if (!channel)
return 0;
mutex_lock(&scmi_optee_private->mu); mutex_lock(&scmi_optee_private->mu);
list_del(&channel->link); list_del(&channel->link);
mutex_unlock(&scmi_optee_private->mu); mutex_unlock(&scmi_optee_private->mu);

View File

@@ -209,7 +209,7 @@ struct amd_sriov_msg_pf2vf_info {
uint32_t pcie_atomic_ops_support_flags; uint32_t pcie_atomic_ops_support_flags;
/* reserved */ /* reserved */
uint32_t reserved[256 - AMD_SRIOV_MSG_PF2VF_INFO_FILLED_SIZE]; uint32_t reserved[256 - AMD_SRIOV_MSG_PF2VF_INFO_FILLED_SIZE];
}; } __packed;
struct amd_sriov_msg_vf2pf_info_header { struct amd_sriov_msg_vf2pf_info_header {
/* the total structure size in byte */ /* the total structure size in byte */
@@ -267,7 +267,7 @@ struct amd_sriov_msg_vf2pf_info {
/* reserved */ /* reserved */
uint32_t reserved[256 - AMD_SRIOV_MSG_VF2PF_INFO_FILLED_SIZE]; uint32_t reserved[256 - AMD_SRIOV_MSG_VF2PF_INFO_FILLED_SIZE];
}; } __packed;
/* mailbox message send from guest to host */ /* mailbox message send from guest to host */
enum amd_sriov_mailbox_request_message { enum amd_sriov_mailbox_request_message {

View File

@@ -2066,23 +2066,29 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder)
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) { if (fake_edid_record->ucFakeEDIDLength) {
struct edid *edid; struct edid *edid;
int edid_size = int edid_size;
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
edid = kmalloc(edid_size, GFP_KERNEL);
if (edid) {
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
fake_edid_record->ucFakeEDIDLength);
if (fake_edid_record->ucFakeEDIDLength == 128)
edid_size = fake_edid_record->ucFakeEDIDLength;
else
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
edid_size, GFP_KERNEL);
if (edid) {
if (drm_edid_is_valid(edid)) { if (drm_edid_is_valid(edid)) {
adev->mode_info.bios_hardcoded_edid = edid; adev->mode_info.bios_hardcoded_edid = edid;
adev->mode_info.bios_hardcoded_edid_size = edid_size; adev->mode_info.bios_hardcoded_edid_size = edid_size;
} else } else {
kfree(edid); kfree(edid);
}
} }
record += struct_size(fake_edid_record,
ucFakeEDIDString,
edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
} }
record += fake_edid_record->ucFakeEDIDLength ?
fake_edid_record->ucFakeEDIDLength + 2 :
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
break; break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE: case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;

View File

@@ -215,7 +215,11 @@ bool dcn30_set_output_transfer_func(struct dc *dc,
} }
} }
mpc->funcs->set_output_gamma(mpc, mpcc_id, params); if (mpc->funcs->set_output_gamma)
mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
else
DC_LOG_ERROR("%s: set_output_gamma function pointer is NULL.\n", __func__);
return ret; return ret;
} }

View File

@@ -4107,7 +4107,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
{ {
UCHAR ucRecordType; UCHAR ucRecordType;
UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128 UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
} ATOM_FAKE_EDID_PATCH_RECORD; } ATOM_FAKE_EDID_PATCH_RECORD;
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD

View File

@@ -411,22 +411,6 @@ static const struct drm_connector_funcs lt8912_connector_funcs = {
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
}; };
static enum drm_mode_status
lt8912_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
if (mode->clock > 150000)
return MODE_CLOCK_HIGH;
if (mode->hdisplay > 1920)
return MODE_BAD_HVALUE;
if (mode->vdisplay > 1080)
return MODE_BAD_VVALUE;
return MODE_OK;
}
static int lt8912_connector_get_modes(struct drm_connector *connector) static int lt8912_connector_get_modes(struct drm_connector *connector)
{ {
struct edid *edid; struct edid *edid;
@@ -454,7 +438,6 @@ static int lt8912_connector_get_modes(struct drm_connector *connector)
static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = { static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
.get_modes = lt8912_connector_get_modes, .get_modes = lt8912_connector_get_modes,
.mode_valid = lt8912_connector_mode_valid,
}; };
static void lt8912_bridge_mode_set(struct drm_bridge *bridge, static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
@@ -596,6 +579,23 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)
drm_bridge_hpd_disable(lt->hdmi_port); drm_bridge_hpd_disable(lt->hdmi_port);
} }
static enum drm_mode_status
lt8912_bridge_mode_valid(struct drm_bridge *bridge,
const struct drm_display_info *info,
const struct drm_display_mode *mode)
{
if (mode->clock > 150000)
return MODE_CLOCK_HIGH;
if (mode->hdisplay > 1920)
return MODE_BAD_HVALUE;
if (mode->vdisplay > 1080)
return MODE_BAD_VVALUE;
return MODE_OK;
}
static enum drm_connector_status static enum drm_connector_status
lt8912_bridge_detect(struct drm_bridge *bridge) lt8912_bridge_detect(struct drm_bridge *bridge)
{ {
@@ -626,6 +626,7 @@ static struct edid *lt8912_bridge_get_edid(struct drm_bridge *bridge,
static const struct drm_bridge_funcs lt8912_bridge_funcs = { static const struct drm_bridge_funcs lt8912_bridge_funcs = {
.attach = lt8912_bridge_attach, .attach = lt8912_bridge_attach,
.detach = lt8912_bridge_detach, .detach = lt8912_bridge_detach,
.mode_valid = lt8912_bridge_mode_valid,
.mode_set = lt8912_bridge_mode_set, .mode_set = lt8912_bridge_mode_set,
.enable = lt8912_bridge_enable, .enable = lt8912_bridge_enable,
.detect = lt8912_bridge_detect, .detect = lt8912_bridge_detect,

View File

@@ -1173,7 +1173,7 @@ static int gsc_bind(struct device *dev, struct device *master, void *data)
struct exynos_drm_ipp *ipp = &ctx->ipp; struct exynos_drm_ipp *ipp = &ctx->ipp;
ctx->drm_dev = drm_dev; ctx->drm_dev = drm_dev;
ctx->drm_dev = drm_dev; ipp->drm_dev = drm_dev;
exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
exynos_drm_ipp_register(dev, ipp, &ipp_funcs, exynos_drm_ipp_register(dev, ipp, &ipp_funcs,

View File

@@ -65,6 +65,8 @@ struct mtk_drm_crtc {
/* lock for display hardware access */ /* lock for display hardware access */
struct mutex hw_lock; struct mutex hw_lock;
bool config_updating; bool config_updating;
/* lock for config_updating to cmd buffer */
spinlock_t config_lock;
}; };
struct mtk_crtc_state { struct mtk_crtc_state {
@@ -102,11 +104,16 @@ static void mtk_drm_crtc_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
{ {
unsigned long flags;
drm_crtc_handle_vblank(&mtk_crtc->base); drm_crtc_handle_vblank(&mtk_crtc->base);
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) { if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
mtk_drm_crtc_finish_page_flip(mtk_crtc); mtk_drm_crtc_finish_page_flip(mtk_crtc);
mtk_crtc->pending_needs_vblank = false; mtk_crtc->pending_needs_vblank = false;
} }
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
} }
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #if IS_REACHABLE(CONFIG_MTK_CMDQ)
@@ -289,12 +296,19 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client); struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
struct mtk_crtc_state *state; struct mtk_crtc_state *state;
unsigned int i; unsigned int i;
unsigned long flags;
if (data->sta < 0) if (data->sta < 0)
return; return;
state = to_mtk_crtc_state(mtk_crtc->base.state); state = to_mtk_crtc_state(mtk_crtc->base.state);
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
if (mtk_crtc->config_updating) {
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
goto ddp_cmdq_cb_out;
}
state->pending_config = false; state->pending_config = false;
if (mtk_crtc->pending_planes) { if (mtk_crtc->pending_planes) {
@@ -321,6 +335,10 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
mtk_crtc->pending_async_planes = false; mtk_crtc->pending_async_planes = false;
} }
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
ddp_cmdq_cb_out:
mtk_crtc->cmdq_vblank_cnt = 0; mtk_crtc->cmdq_vblank_cnt = 0;
wake_up(&mtk_crtc->cb_blocking_queue); wake_up(&mtk_crtc->cb_blocking_queue);
} }
@@ -426,6 +444,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
{ {
struct drm_device *drm = mtk_crtc->base.dev; struct drm_device *drm = mtk_crtc->base.dev;
struct drm_crtc *crtc = &mtk_crtc->base; struct drm_crtc *crtc = &mtk_crtc->base;
unsigned long flags;
int i; int i;
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) { for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
@@ -452,10 +471,10 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
pm_runtime_put(drm->dev); pm_runtime_put(drm->dev);
if (crtc->state->event && !crtc->state->active) { if (crtc->state->event && !crtc->state->active) {
spin_lock_irq(&crtc->dev->event_lock); spin_lock_irqsave(&crtc->dev->event_lock, flags);
drm_crtc_send_vblank_event(crtc, crtc->state->event); drm_crtc_send_vblank_event(crtc, crtc->state->event);
crtc->state->event = NULL; crtc->state->event = NULL;
spin_unlock_irq(&crtc->dev->event_lock); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
} }
} }
@@ -544,9 +563,14 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
struct mtk_drm_private *priv = crtc->dev->dev_private; struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int pending_planes = 0, pending_async_planes = 0; unsigned int pending_planes = 0, pending_async_planes = 0;
int i; int i;
unsigned long flags;
mutex_lock(&mtk_crtc->hw_lock); mutex_lock(&mtk_crtc->hw_lock);
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
mtk_crtc->config_updating = true; mtk_crtc->config_updating = true;
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
if (needs_vblank) if (needs_vblank)
mtk_crtc->pending_needs_vblank = true; mtk_crtc->pending_needs_vblank = true;
@@ -600,7 +624,10 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0); mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
} }
#endif #endif
spin_lock_irqsave(&mtk_crtc->config_lock, flags);
mtk_crtc->config_updating = false; mtk_crtc->config_updating = false;
spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
mutex_unlock(&mtk_crtc->hw_lock); mutex_unlock(&mtk_crtc->hw_lock);
} }
@@ -971,6 +998,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size); drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
priv->num_pipes++; priv->num_pipes++;
mutex_init(&mtk_crtc->hw_lock); mutex_init(&mtk_crtc->hw_lock);
spin_lock_init(&mtk_crtc->config_lock);
#if IS_REACHABLE(CONFIG_MTK_CMDQ) #if IS_REACHABLE(CONFIG_MTK_CMDQ)
mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev; mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;

View File

@@ -65,6 +65,8 @@ void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit) static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit)
{ {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
struct msm_ringbuffer *ring = submit->ring; struct msm_ringbuffer *ring = submit->ring;
struct msm_gem_object *obj; struct msm_gem_object *obj;
uint32_t *ptr, dwords; uint32_t *ptr, dwords;
@@ -109,6 +111,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit
} }
} }
a5xx_gpu->last_seqno[ring->id] = submit->seqno;
a5xx_flush(gpu, ring, true); a5xx_flush(gpu, ring, true);
a5xx_preempt_trigger(gpu); a5xx_preempt_trigger(gpu);
@@ -150,9 +153,13 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
OUT_RING(ring, 1); OUT_RING(ring, 1);
/* Enable local preemption for finegrain preemption */ /*
* Disable local preemption by default because it requires
* user-space to be aware of it and provide additional handling
* to restore rendering state or do various flushes on switch.
*/
OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1); OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
OUT_RING(ring, 0x1); OUT_RING(ring, 0x0);
/* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */ /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
OUT_PKT7(ring, CP_YIELD_ENABLE, 1); OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
@@ -206,6 +213,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
/* Write the fence to the scratch register */ /* Write the fence to the scratch register */
OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1); OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
OUT_RING(ring, submit->seqno); OUT_RING(ring, submit->seqno);
a5xx_gpu->last_seqno[ring->id] = submit->seqno;
/* /*
* Execute a CACHE_FLUSH_TS event. This will ensure that the * Execute a CACHE_FLUSH_TS event. This will ensure that the

View File

@@ -34,8 +34,10 @@ struct a5xx_gpu {
struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS]; struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS];
struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS]; struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS];
uint64_t preempt_iova[MSM_GPU_MAX_RINGS]; uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
uint32_t last_seqno[MSM_GPU_MAX_RINGS];
atomic_t preempt_state; atomic_t preempt_state;
spinlock_t preempt_start_lock;
struct timer_list preempt_timer; struct timer_list preempt_timer;
struct drm_gem_object *shadow_bo; struct drm_gem_object *shadow_bo;

View File

@@ -55,6 +55,8 @@ static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
/* Return the highest priority ringbuffer with something in it */ /* Return the highest priority ringbuffer with something in it */
static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu) static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
{ {
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
unsigned long flags; unsigned long flags;
int i; int i;
@@ -64,6 +66,8 @@ static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
spin_lock_irqsave(&ring->preempt_lock, flags); spin_lock_irqsave(&ring->preempt_lock, flags);
empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring)); empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
if (!empty && ring == a5xx_gpu->cur_ring)
empty = ring->memptrs->fence == a5xx_gpu->last_seqno[i];
spin_unlock_irqrestore(&ring->preempt_lock, flags); spin_unlock_irqrestore(&ring->preempt_lock, flags);
if (!empty) if (!empty)
@@ -97,12 +101,19 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
if (gpu->nr_rings == 1) if (gpu->nr_rings == 1)
return; return;
/*
* Serialize preemption start to ensure that we always make
* decision on latest state. Otherwise we can get stuck in
* lower priority or empty ring.
*/
spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags);
/* /*
* Try to start preemption by moving from NONE to START. If * Try to start preemption by moving from NONE to START. If
* unsuccessful, a preemption is already in flight * unsuccessful, a preemption is already in flight
*/ */
if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START)) if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
return; goto out;
/* Get the next ring to preempt to */ /* Get the next ring to preempt to */
ring = get_next_ring(gpu); ring = get_next_ring(gpu);
@@ -127,9 +138,11 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
set_preempt_state(a5xx_gpu, PREEMPT_ABORT); set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
update_wptr(gpu, a5xx_gpu->cur_ring); update_wptr(gpu, a5xx_gpu->cur_ring);
set_preempt_state(a5xx_gpu, PREEMPT_NONE); set_preempt_state(a5xx_gpu, PREEMPT_NONE);
return; goto out;
} }
spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
/* Make sure the wptr doesn't update while we're in motion */ /* Make sure the wptr doesn't update while we're in motion */
spin_lock_irqsave(&ring->preempt_lock, flags); spin_lock_irqsave(&ring->preempt_lock, flags);
a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring); a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
@@ -152,6 +165,10 @@ void a5xx_preempt_trigger(struct msm_gpu *gpu)
/* And actually start the preemption */ /* And actually start the preemption */
gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1); gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
return;
out:
spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
} }
void a5xx_preempt_irq(struct msm_gpu *gpu) void a5xx_preempt_irq(struct msm_gpu *gpu)
@@ -188,6 +205,12 @@ void a5xx_preempt_irq(struct msm_gpu *gpu)
update_wptr(gpu, a5xx_gpu->cur_ring); update_wptr(gpu, a5xx_gpu->cur_ring);
set_preempt_state(a5xx_gpu, PREEMPT_NONE); set_preempt_state(a5xx_gpu, PREEMPT_NONE);
/*
* Try to trigger preemption again in case there was a submit or
* retire during ring switch
*/
a5xx_preempt_trigger(gpu);
} }
void a5xx_preempt_hw_init(struct msm_gpu *gpu) void a5xx_preempt_hw_init(struct msm_gpu *gpu)
@@ -204,6 +227,8 @@ void a5xx_preempt_hw_init(struct msm_gpu *gpu)
return; return;
for (i = 0; i < gpu->nr_rings; i++) { for (i = 0; i < gpu->nr_rings; i++) {
a5xx_gpu->preempt[i]->data = 0;
a5xx_gpu->preempt[i]->info = 0;
a5xx_gpu->preempt[i]->wptr = 0; a5xx_gpu->preempt[i]->wptr = 0;
a5xx_gpu->preempt[i]->rptr = 0; a5xx_gpu->preempt[i]->rptr = 0;
a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova; a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
@@ -298,5 +323,6 @@ void a5xx_preempt_init(struct msm_gpu *gpu)
} }
} }
spin_lock_init(&a5xx_gpu->preempt_start_lock);
timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0); timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
} }

View File

@@ -418,7 +418,7 @@ adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
ret = request_firmware_direct(&fw, fwname, drm->dev); ret = request_firmware_direct(&fw, fwname, drm->dev);
if (!ret) { if (!ret) {
DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n", DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n",
newname); fwname);
adreno_gpu->fwloc = FW_LOCATION_LEGACY; adreno_gpu->fwloc = FW_LOCATION_LEGACY;
goto out; goto out;
} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {

View File

@@ -356,7 +356,7 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
drm_printf(p, "%s:%d\t%d\t%s\n", drm_printf(p, "%s:%d\t%d\t%s\n",
pipe2name(pipe), j, inuse, pipe2name(pipe), j, inuse,
plane ? plane->name : NULL); plane ? plane->name : "(null)");
total += inuse; total += inuse;
} }

View File

@@ -3615,7 +3615,7 @@ typedef struct _ATOM_FAKE_EDID_PATCH_RECORD
{ {
UCHAR ucRecordType; UCHAR ucRecordType;
UCHAR ucFakeEDIDLength; UCHAR ucFakeEDIDLength;
UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements.
} ATOM_FAKE_EDID_PATCH_RECORD; } ATOM_FAKE_EDID_PATCH_RECORD;
typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD

View File

@@ -395,7 +395,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
struct evergreen_cs_track *track = p->track; struct evergreen_cs_track *track = p->track;
struct eg_surface surf; struct eg_surface surf;
unsigned pitch, slice, mslice; unsigned pitch, slice, mslice;
unsigned long offset; u64 offset;
int r; int r;
mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1; mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
@@ -433,14 +433,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
return r; return r;
} }
offset = track->cb_color_bo_offset[id] << 8; offset = (u64)track->cb_color_bo_offset[id] << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d cb[%d] bo base %llu not aligned with %ld\n",
__func__, __LINE__, id, offset, surf.base_align); __func__, __LINE__, id, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->cb_color_bo[id])) { if (offset > radeon_bo_size(track->cb_color_bo[id])) {
/* old ddx are broken they allocate bo with w*h*bpp but /* old ddx are broken they allocate bo with w*h*bpp but
* program slice with ALIGN(h, 8), catch this and patch * program slice with ALIGN(h, 8), catch this and patch
@@ -448,14 +448,14 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
*/ */
if (!surf.mode) { if (!surf.mode) {
uint32_t *ib = p->ib.ptr; uint32_t *ib = p->ib.ptr;
unsigned long tmp, nby, bsize, size, min = 0; u64 tmp, nby, bsize, size, min = 0;
/* find the height the ddx wants */ /* find the height the ddx wants */
if (surf.nby > 8) { if (surf.nby > 8) {
min = surf.nby - 8; min = surf.nby - 8;
} }
bsize = radeon_bo_size(track->cb_color_bo[id]); bsize = radeon_bo_size(track->cb_color_bo[id]);
tmp = track->cb_color_bo_offset[id] << 8; tmp = (u64)track->cb_color_bo_offset[id] << 8;
for (nby = surf.nby; nby > min; nby--) { for (nby = surf.nby; nby > min; nby--) {
size = nby * surf.nbx * surf.bpe * surf.nsamples; size = nby * surf.nbx * surf.bpe * surf.nsamples;
if ((tmp + size * mslice) <= bsize) { if ((tmp + size * mslice) <= bsize) {
@@ -467,7 +467,7 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
slice = ((nby * surf.nbx) / 64) - 1; slice = ((nby * surf.nbx) / 64) - 1;
if (!evergreen_surface_check(p, &surf, "cb")) { if (!evergreen_surface_check(p, &surf, "cb")) {
/* check if this one works */ /* check if this one works */
tmp += surf.layer_size * mslice; tmp += (u64)surf.layer_size * mslice;
if (tmp <= bsize) { if (tmp <= bsize) {
ib[track->cb_color_slice_idx[id]] = slice; ib[track->cb_color_slice_idx[id]] = slice;
goto old_ddx_ok; goto old_ddx_ok;
@@ -476,9 +476,9 @@ static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned i
} }
} }
dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
"offset %d, max layer %d, bo size %ld, slice %d)\n", "offset %llu, max layer %d, bo size %ld, slice %d)\n",
__func__, __LINE__, id, surf.layer_size, __func__, __LINE__, id, surf.layer_size,
track->cb_color_bo_offset[id] << 8, mslice, (u64)track->cb_color_bo_offset[id] << 8, mslice,
radeon_bo_size(track->cb_color_bo[id]), slice); radeon_bo_size(track->cb_color_bo[id]), slice);
dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
__func__, __LINE__, surf.nbx, surf.nby, __func__, __LINE__, surf.nbx, surf.nby,
@@ -562,7 +562,7 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
struct evergreen_cs_track *track = p->track; struct evergreen_cs_track *track = p->track;
struct eg_surface surf; struct eg_surface surf;
unsigned pitch, slice, mslice; unsigned pitch, slice, mslice;
unsigned long offset; u64 offset;
int r; int r;
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
@@ -608,18 +608,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
return r; return r;
} }
offset = track->db_s_read_offset << 8; offset = (u64)track->db_s_read_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_s_read_bo)) { if (offset > radeon_bo_size(track->db_s_read_bo)) {
dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, " dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_s_read_offset << 8, mslice, (u64)track->db_s_read_offset << 8, mslice,
radeon_bo_size(track->db_s_read_bo)); radeon_bo_size(track->db_s_read_bo));
dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
__func__, __LINE__, track->db_depth_size, __func__, __LINE__, track->db_depth_size,
@@ -627,18 +627,18 @@ static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
return -EINVAL; return -EINVAL;
} }
offset = track->db_s_write_offset << 8; offset = (u64)track->db_s_write_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_s_write_bo)) { if (offset > radeon_bo_size(track->db_s_write_bo)) {
dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, " dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_s_write_offset << 8, mslice, (u64)track->db_s_write_offset << 8, mslice,
radeon_bo_size(track->db_s_write_bo)); radeon_bo_size(track->db_s_write_bo));
return -EINVAL; return -EINVAL;
} }
@@ -659,7 +659,7 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
struct evergreen_cs_track *track = p->track; struct evergreen_cs_track *track = p->track;
struct eg_surface surf; struct eg_surface surf;
unsigned pitch, slice, mslice; unsigned pitch, slice, mslice;
unsigned long offset; u64 offset;
int r; int r;
mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
@@ -706,34 +706,34 @@ static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
return r; return r;
} }
offset = track->db_z_read_offset << 8; offset = (u64)track->db_z_read_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_z_read_bo)) { if (offset > radeon_bo_size(track->db_z_read_bo)) {
dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, " dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_z_read_offset << 8, mslice, (u64)track->db_z_read_offset << 8, mslice,
radeon_bo_size(track->db_z_read_bo)); radeon_bo_size(track->db_z_read_bo));
return -EINVAL; return -EINVAL;
} }
offset = track->db_z_write_offset << 8; offset = (u64)track->db_z_write_offset << 8;
if (offset & (surf.base_align - 1)) { if (offset & (surf.base_align - 1)) {
dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
__func__, __LINE__, offset, surf.base_align); __func__, __LINE__, offset, surf.base_align);
return -EINVAL; return -EINVAL;
} }
offset += surf.layer_size * mslice; offset += (u64)surf.layer_size * mslice;
if (offset > radeon_bo_size(track->db_z_write_bo)) { if (offset > radeon_bo_size(track->db_z_write_bo)) {
dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, " dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
"offset %ld, max layer %d, bo size %ld)\n", "offset %llu, max layer %d, bo size %ld)\n",
__func__, __LINE__, surf.layer_size, __func__, __LINE__, surf.layer_size,
(unsigned long)track->db_z_write_offset << 8, mslice, (u64)track->db_z_write_offset << 8, mslice,
radeon_bo_size(track->db_z_write_bo)); radeon_bo_size(track->db_z_write_bo));
return -EINVAL; return -EINVAL;
} }

View File

@@ -1712,23 +1712,29 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct
fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
if (fake_edid_record->ucFakeEDIDLength) { if (fake_edid_record->ucFakeEDIDLength) {
struct edid *edid; struct edid *edid;
int edid_size = int edid_size;
max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
edid = kmalloc(edid_size, GFP_KERNEL);
if (edid) {
memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
fake_edid_record->ucFakeEDIDLength);
if (fake_edid_record->ucFakeEDIDLength == 128)
edid_size = fake_edid_record->ucFakeEDIDLength;
else
edid_size = fake_edid_record->ucFakeEDIDLength * 128;
edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
edid_size, GFP_KERNEL);
if (edid) {
if (drm_edid_is_valid(edid)) { if (drm_edid_is_valid(edid)) {
rdev->mode_info.bios_hardcoded_edid = edid; rdev->mode_info.bios_hardcoded_edid = edid;
rdev->mode_info.bios_hardcoded_edid_size = edid_size; rdev->mode_info.bios_hardcoded_edid_size = edid_size;
} else } else {
kfree(edid); kfree(edid);
}
} }
record += struct_size(fake_edid_record,
ucFakeEDIDString,
edid_size);
} else {
/* empty fake edid record must be 3 bytes long */
record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
} }
record += fake_edid_record->ucFakeEDIDLength ?
fake_edid_record->ucFakeEDIDLength + 2 :
sizeof(ATOM_FAKE_EDID_PATCH_RECORD);
break; break;
case LCD_PANEL_RESOLUTION_RECORD_TYPE: case LCD_PANEL_RESOLUTION_RECORD_TYPE:
panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;

View File

@@ -410,6 +410,8 @@ static void dw_hdmi_rk3328_setup_hpd(struct dw_hdmi *dw_hdmi, void *data)
HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK, HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK,
RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK | RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK |
RK3328_HDMI_HPD_IOE)); RK3328_HDMI_HPD_IOE));
dw_hdmi_rk3328_read_hpd(dw_hdmi, data);
} }
static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = {

View File

@@ -385,8 +385,8 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
if (info->is_yuv) if (info->is_yuv)
is_yuv = true; is_yuv = true;
if (dst_w > 3840) { if (dst_w > 4096) {
DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n"); DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n");
return; return;
} }

View File

@@ -201,12 +201,14 @@ static int stm_drm_platform_probe(struct platform_device *pdev)
ret = drm_dev_register(ddev, 0); ret = drm_dev_register(ddev, 0);
if (ret) if (ret)
goto err_put; goto err_unload;
drm_fbdev_generic_setup(ddev, 16); drm_fbdev_generic_setup(ddev, 16);
return 0; return 0;
err_unload:
drv_unload(ddev);
err_put: err_put:
drm_dev_put(ddev); drm_dev_put(ddev);

View File

@@ -1581,6 +1581,8 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) + ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) +
ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp)) * ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp)) *
sizeof(*formats), GFP_KERNEL); sizeof(*formats), GFP_KERNEL);
if (!formats)
return NULL;
for (i = 0; i < ldev->caps.pix_fmt_nb; i++) { for (i = 0; i < ldev->caps.pix_fmt_nb; i++) {
drm_fmt = ldev->caps.pix_fmt_drm[i]; drm_fmt = ldev->caps.pix_fmt_drm[i];

View File

@@ -448,6 +448,7 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
{ {
struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
enum drm_connector_status status = connector_status_disconnected; enum drm_connector_status status = connector_status_disconnected;
int ret;
/* /*
* NOTE: This function should really take vc4_hdmi->mutex, but * NOTE: This function should really take vc4_hdmi->mutex, but
@@ -460,7 +461,12 @@ static int vc4_hdmi_connector_detect_ctx(struct drm_connector *connector,
* the lock for now. * the lock for now.
*/ */
WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev)); ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
if (ret) {
drm_err_once(connector->dev, "Failed to retain HDMI power domain: %d\n",
ret);
return connector_status_unknown;
}
if (vc4_hdmi->hpd_gpio) { if (vc4_hdmi->hpd_gpio) {
if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio))

View File

@@ -2365,6 +2365,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0); wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0);
features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3; features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3;
break; break;
case WACOM_HID_WD_SEQUENCENUMBER:
wacom_wac->hid_data.sequence_number = -1;
break;
} }
} }
@@ -2489,9 +2492,15 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
wacom_wac->hid_data.barrelswitch3 = value; wacom_wac->hid_data.barrelswitch3 = value;
return; return;
case WACOM_HID_WD_SEQUENCENUMBER: case WACOM_HID_WD_SEQUENCENUMBER:
if (wacom_wac->hid_data.sequence_number != value) if (wacom_wac->hid_data.sequence_number != value &&
hid_warn(hdev, "Dropped %hu packets", (unsigned short)(value - wacom_wac->hid_data.sequence_number)); wacom_wac->hid_data.sequence_number >= 0) {
int sequence_size = field->logical_maximum - field->logical_minimum + 1;
int drop_count = (value - wacom_wac->hid_data.sequence_number) % sequence_size;
hid_warn(hdev, "Dropped %d packets", drop_count);
}
wacom_wac->hid_data.sequence_number = value + 1; wacom_wac->hid_data.sequence_number = value + 1;
if (wacom_wac->hid_data.sequence_number > field->logical_maximum)
wacom_wac->hid_data.sequence_number = field->logical_minimum;
return; return;
} }

View File

@@ -324,7 +324,7 @@ struct hid_data {
int bat_connected; int bat_connected;
int ps_connected; int ps_connected;
bool pad_input_event_flag; bool pad_input_event_flag;
unsigned short sequence_number; int sequence_number;
ktime_t time_delayed; ktime_t time_delayed;
}; };

View File

@@ -79,7 +79,7 @@ static const bool max16065_have_current[] = {
}; };
struct max16065_data { struct max16065_data {
enum chips type; enum chips chip;
struct i2c_client *client; struct i2c_client *client;
const struct attribute_group *groups[4]; const struct attribute_group *groups[4];
struct mutex update_lock; struct mutex update_lock;
@@ -114,9 +114,10 @@ static inline int LIMIT_TO_MV(int limit, int range)
return limit * range / 256; return limit * range / 256;
} }
static inline int MV_TO_LIMIT(int mv, int range) static inline int MV_TO_LIMIT(unsigned long mv, int range)
{ {
return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255); mv = clamp_val(mv, 0, ULONG_MAX / 256);
return DIV_ROUND_CLOSEST(clamp_val(mv * 256, 0, range * 255), range);
} }
static inline int ADC_TO_CURR(int adc, int gain) static inline int ADC_TO_CURR(int adc, int gain)
@@ -161,10 +162,17 @@ static struct max16065_data *max16065_update_device(struct device *dev)
MAX16065_CURR_SENSE); MAX16065_CURR_SENSE);
} }
for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++) for (i = 0; i < 2; i++)
data->fault[i] data->fault[i]
= i2c_smbus_read_byte_data(client, MAX16065_FAULT(i)); = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i));
/*
* MAX16067 and MAX16068 have separate undervoltage and
* overvoltage alarm bits. Squash them together.
*/
if (data->chip == max16067 || data->chip == max16068)
data->fault[0] |= data->fault[1];
data->last_updated = jiffies; data->last_updated = jiffies;
data->valid = true; data->valid = true;
} }
@@ -493,8 +501,6 @@ static const struct attribute_group max16065_max_group = {
.is_visible = max16065_secondary_is_visible, .is_visible = max16065_secondary_is_visible,
}; };
static const struct i2c_device_id max16065_id[];
static int max16065_probe(struct i2c_client *client) static int max16065_probe(struct i2c_client *client)
{ {
struct i2c_adapter *adapter = client->adapter; struct i2c_adapter *adapter = client->adapter;
@@ -505,7 +511,7 @@ static int max16065_probe(struct i2c_client *client)
bool have_secondary; /* true if chip has secondary limits */ bool have_secondary; /* true if chip has secondary limits */
bool secondary_is_max = false; /* secondary limits reflect max */ bool secondary_is_max = false; /* secondary limits reflect max */
int groups = 0; int groups = 0;
const struct i2c_device_id *id = i2c_match_id(max16065_id, client); enum chips chip = (uintptr_t)i2c_get_match_data(client);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
| I2C_FUNC_SMBUS_READ_WORD_DATA)) | I2C_FUNC_SMBUS_READ_WORD_DATA))
@@ -515,12 +521,13 @@ static int max16065_probe(struct i2c_client *client)
if (unlikely(!data)) if (unlikely(!data))
return -ENOMEM; return -ENOMEM;
data->chip = chip;
data->client = client; data->client = client;
mutex_init(&data->update_lock); mutex_init(&data->update_lock);
data->num_adc = max16065_num_adc[id->driver_data]; data->num_adc = max16065_num_adc[chip];
data->have_current = max16065_have_current[id->driver_data]; data->have_current = max16065_have_current[chip];
have_secondary = max16065_have_secondary[id->driver_data]; have_secondary = max16065_have_secondary[chip];
if (have_secondary) { if (have_secondary) {
val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE); val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE);

View File

@@ -62,6 +62,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
[NTC_SSG1404001221] = { "ssg1404_001221", TYPE_NCPXXWB473 }, [NTC_SSG1404001221] = { "ssg1404_001221", TYPE_NCPXXWB473 },
[NTC_LAST] = { }, [NTC_LAST] = { },
}; };
MODULE_DEVICE_TABLE(platform, ntc_thermistor_id);
/* /*
* A compensation table should be sorted by the values of .ohm * A compensation table should be sorted by the values of .ohm

View File

@@ -113,6 +113,25 @@ const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
} }
EXPORT_SYMBOL_GPL(i2c_match_id); EXPORT_SYMBOL_GPL(i2c_match_id);
const void *i2c_get_match_data(const struct i2c_client *client)
{
struct i2c_driver *driver = to_i2c_driver(client->dev.driver);
const struct i2c_device_id *match;
const void *data;
data = device_get_match_data(&client->dev);
if (!data) {
match = i2c_match_id(driver->id_table, client);
if (!match)
return NULL;
data = (const void *)match->driver_data;
}
return data;
}
EXPORT_SYMBOL(i2c_get_match_data);
static int i2c_device_match(struct device *dev, struct device_driver *drv) static int i2c_device_match(struct device *dev, struct device_driver *drv)
{ {
struct i2c_client *client = i2c_verify_client(dev); struct i2c_client *client = i2c_verify_client(dev);

View File

@@ -1191,7 +1191,7 @@ static int __init iw_cm_init(void)
if (ret) if (ret)
return ret; return ret;
iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0); iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM);
if (!iwcm_wq) if (!iwcm_wq)
goto err_alloc; goto err_alloc;

View File

@@ -624,6 +624,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
*/ */
if (WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done)) if (WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done))
return; return;
clt_path->s.hb_missed_cnt = 0;
rtrs_from_imm(be32_to_cpu(wc->ex.imm_data), rtrs_from_imm(be32_to_cpu(wc->ex.imm_data),
&imm_type, &imm_payload); &imm_type, &imm_payload);
if (imm_type == RTRS_IO_RSP_IMM || if (imm_type == RTRS_IO_RSP_IMM ||
@@ -641,7 +642,6 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
return rtrs_clt_recv_done(con, wc); return rtrs_clt_recv_done(con, wc);
} else if (imm_type == RTRS_HB_ACK_IMM) { } else if (imm_type == RTRS_HB_ACK_IMM) {
WARN_ON(con->c.cid); WARN_ON(con->c.cid);
clt_path->s.hb_missed_cnt = 0;
clt_path->s.hb_cur_latency = clt_path->s.hb_cur_latency =
ktime_sub(ktime_get(), clt_path->s.hb_last_sent); ktime_sub(ktime_get(), clt_path->s.hb_last_sent);
if (clt_path->flags & RTRS_MSG_NEW_RKEY_F) if (clt_path->flags & RTRS_MSG_NEW_RKEY_F)
@@ -668,6 +668,7 @@ static void rtrs_clt_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
/* /*
* Key invalidations from server side * Key invalidations from server side
*/ */
clt_path->s.hb_missed_cnt = 0;
WARN_ON(!(wc->wc_flags & IB_WC_WITH_INVALIDATE || WARN_ON(!(wc->wc_flags & IB_WC_WITH_INVALIDATE ||
wc->wc_flags & IB_WC_WITH_IMM)); wc->wc_flags & IB_WC_WITH_IMM));
WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done); WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done);
@@ -2342,6 +2343,12 @@ static int init_conns(struct rtrs_clt_path *clt_path)
if (err) if (err)
goto destroy; goto destroy;
} }
/*
* Set the cid to con_num - 1, since if we fail later, we want to stay in bounds.
*/
cid = clt_path->s.con_num - 1;
err = alloc_path_reqs(clt_path); err = alloc_path_reqs(clt_path);
if (err) if (err)
goto destroy; goto destroy;

View File

@@ -1234,6 +1234,7 @@ static void rtrs_srv_rdma_done(struct ib_cq *cq, struct ib_wc *wc)
*/ */
if (WARN_ON(wc->wr_cqe != &io_comp_cqe)) if (WARN_ON(wc->wr_cqe != &io_comp_cqe))
return; return;
srv_path->s.hb_missed_cnt = 0;
err = rtrs_post_recv_empty(&con->c, &io_comp_cqe); err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
if (err) { if (err) {
rtrs_err(s, "rtrs_post_recv(), err: %d\n", err); rtrs_err(s, "rtrs_post_recv(), err: %d\n", err);

View File

@@ -37,6 +37,8 @@
#define ILITEK_TP_CMD_GET_MCU_VER 0x61 #define ILITEK_TP_CMD_GET_MCU_VER 0x61
#define ILITEK_TP_CMD_GET_IC_MODE 0xC0 #define ILITEK_TP_CMD_GET_IC_MODE 0xC0
#define ILITEK_TP_I2C_REPORT_ID 0x48
#define REPORT_COUNT_ADDRESS 61 #define REPORT_COUNT_ADDRESS 61
#define ILITEK_SUPPORT_MAX_POINT 40 #define ILITEK_SUPPORT_MAX_POINT 40
@@ -160,15 +162,19 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64); error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
if (error) { if (error) {
dev_err(dev, "get touch info failed, err:%d\n", error); dev_err(dev, "get touch info failed, err:%d\n", error);
goto err_sync_frame; return error;
}
if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
return -EINVAL;
} }
report_max_point = buf[REPORT_COUNT_ADDRESS]; report_max_point = buf[REPORT_COUNT_ADDRESS];
if (report_max_point > ts->max_tp) { if (report_max_point > ts->max_tp) {
dev_err(dev, "FW report max point:%d > panel info. max:%d\n", dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
report_max_point, ts->max_tp); report_max_point, ts->max_tp);
error = -EINVAL; return -EINVAL;
goto err_sync_frame;
} }
count = DIV_ROUND_UP(report_max_point, packet_max_point); count = DIV_ROUND_UP(report_max_point, packet_max_point);
@@ -178,7 +184,7 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
if (error) { if (error) {
dev_err(dev, "get touch info. failed, cnt:%d, err:%d\n", dev_err(dev, "get touch info. failed, cnt:%d, err:%d\n",
count, error); count, error);
goto err_sync_frame; return error;
} }
} }
@@ -203,10 +209,10 @@ static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
ilitek_touch_down(ts, id, x, y); ilitek_touch_down(ts, id, x, y);
} }
err_sync_frame:
input_mt_sync_frame(input); input_mt_sync_frame(input);
input_sync(input); input_sync(input);
return error;
return 0;
} }
/* APIs of cmds for ILITEK Touch IC */ /* APIs of cmds for ILITEK Touch IC */

View File

@@ -56,7 +56,7 @@ static inline u64 set_pgtable_attr(u64 *page)
u64 prot; u64 prot;
prot = IOMMU_PAGE_PRESENT | IOMMU_PAGE_RW | IOMMU_PAGE_USER; prot = IOMMU_PAGE_PRESENT | IOMMU_PAGE_RW | IOMMU_PAGE_USER;
prot |= IOMMU_PAGE_ACCESS | IOMMU_PAGE_DIRTY; prot |= IOMMU_PAGE_ACCESS;
return (iommu_virt_to_phys(page) | prot); return (iommu_virt_to_phys(page) | prot);
} }

View File

@@ -609,7 +609,7 @@ static int rtl2830_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, int on
index, pid, onoff); index, pid, onoff);
/* skip invalid PIDs (0x2000) */ /* skip invalid PIDs (0x2000) */
if (pid > 0x1fff || index > 32) if (pid > 0x1fff || index >= 32)
return 0; return 0;
if (onoff) if (onoff)

View File

@@ -983,7 +983,7 @@ static int rtl2832_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid,
index, pid, onoff, dev->slave_ts); index, pid, onoff, dev->slave_ts);
/* skip invalid PIDs (0x2000) */ /* skip invalid PIDs (0x2000) */
if (pid > 0x1fff || index > 32) if (pid > 0x1fff || index >= 32)
return 0; return 0;
if (onoff) if (onoff)

View File

@@ -207,6 +207,9 @@ static int powernv_flash_set_driver_info(struct device *dev,
* get them * get them
*/ */
mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node); mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
if (!mtd->name)
return -ENOMEM;
mtd->type = MTD_NORFLASH; mtd->type = MTD_NORFLASH;
mtd->flags = MTD_WRITEABLE; mtd->flags = MTD_WRITEABLE;
mtd->size = size; mtd->size = size;

View File

@@ -296,10 +296,12 @@ static int __init init_slram(void)
T("slram: devname = %s\n", devname); T("slram: devname = %s\n", devname);
if ((!map) || (!(devstart = strsep(&map, ",")))) { if ((!map) || (!(devstart = strsep(&map, ",")))) {
E("slram: No devicestart specified.\n"); E("slram: No devicestart specified.\n");
break;
} }
T("slram: devstart = %s\n", devstart); T("slram: devstart = %s\n", devstart);
if ((!map) || (!(devlength = strsep(&map, ",")))) { if ((!map) || (!(devlength = strsep(&map, ",")))) {
E("slram: No devicelength / -end specified.\n"); E("slram: No devicelength / -end specified.\n");
break;
} }
T("slram: devlength = %s\n", devlength); T("slram: devlength = %s\n", devlength);
if (parse_cmdline(devname, devstart, devlength) != 0) { if (parse_cmdline(devname, devstart, devlength) != 0) {

View File

@@ -1456,16 +1456,32 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc,
return 0; return 0;
} }
static void mtk_nfc_nand_chips_cleanup(struct mtk_nfc *nfc)
{
struct mtk_nfc_nand_chip *mtk_chip;
struct nand_chip *chip;
int ret;
while (!list_empty(&nfc->chips)) {
mtk_chip = list_first_entry(&nfc->chips,
struct mtk_nfc_nand_chip, node);
chip = &mtk_chip->nand;
ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
nand_cleanup(chip);
list_del(&mtk_chip->node);
}
}
static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc) static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc)
{ {
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct device_node *nand_np;
int ret; int ret;
for_each_child_of_node(np, nand_np) { for_each_child_of_node_scoped(np, nand_np) {
ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np); ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np);
if (ret) { if (ret) {
of_node_put(nand_np); mtk_nfc_nand_chips_cleanup(nfc);
return ret; return ret;
} }
} }
@@ -1604,20 +1620,8 @@ release_ecc:
static int mtk_nfc_remove(struct platform_device *pdev) static int mtk_nfc_remove(struct platform_device *pdev)
{ {
struct mtk_nfc *nfc = platform_get_drvdata(pdev); struct mtk_nfc *nfc = platform_get_drvdata(pdev);
struct mtk_nfc_nand_chip *mtk_chip;
struct nand_chip *chip;
int ret;
while (!list_empty(&nfc->chips)) {
mtk_chip = list_first_entry(&nfc->chips,
struct mtk_nfc_nand_chip, node);
chip = &mtk_chip->nand;
ret = mtd_device_unregister(nand_to_mtd(chip));
WARN_ON(ret);
nand_cleanup(chip);
list_del(&mtk_chip->node);
}
mtk_nfc_nand_chips_cleanup(nfc);
mtk_ecc_release(nfc->ecc); mtk_ecc_release(nfc->ecc);
mtk_nfc_disable_clk(&nfc->clk); mtk_nfc_disable_clk(&nfc->clk);

View File

@@ -67,6 +67,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
__be16 proto; __be16 proto;
void *oiph; void *oiph;
int err; int err;
int nh;
bareudp = rcu_dereference_sk_user_data(sk); bareudp = rcu_dereference_sk_user_data(sk);
if (!bareudp) if (!bareudp)
@@ -144,10 +145,25 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
} }
skb_dst_set(skb, &tun_dst->dst); skb_dst_set(skb, &tun_dst->dst);
skb->dev = bareudp->dev; skb->dev = bareudp->dev;
oiph = skb_network_header(skb);
skb_reset_network_header(skb);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
/* Save offset of outer header relative to skb->head,
* because we are going to reset the network header to the inner header
* and might change skb->head.
*/
nh = skb_network_header(skb) - skb->head;
skb_reset_network_header(skb);
if (!pskb_inet_may_pull(skb)) {
DEV_STATS_INC(bareudp->dev, rx_length_errors);
DEV_STATS_INC(bareudp->dev, rx_errors);
goto drop;
}
/* Get the outer header. */
oiph = skb->head + nh;
if (!ipv6_mod_enabled() || family == AF_INET) if (!ipv6_mod_enabled() || family == AF_INET)
err = IP_ECN_decapsulate(oiph, skb); err = IP_ECN_decapsulate(oiph, skb);
else else
@@ -303,6 +319,9 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
__be32 saddr; __be32 saddr;
int err; int err;
if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
return -EINVAL;
if (!sock) if (!sock)
return -ESHUTDOWN; return -ESHUTDOWN;
@@ -366,6 +385,9 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
__be16 sport; __be16 sport;
int err; int err;
if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
return -EINVAL;
if (!sock) if (!sock)
return -ESHUTDOWN; return -ESHUTDOWN;

View File

@@ -1555,24 +1555,21 @@ static int m_can_close(struct net_device *dev)
netif_stop_queue(dev); netif_stop_queue(dev);
if (!cdev->is_peripheral)
napi_disable(&cdev->napi);
m_can_stop(dev); m_can_stop(dev);
m_can_clk_stop(cdev);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
if (cdev->is_peripheral) { if (cdev->is_peripheral) {
cdev->tx_skb = NULL; cdev->tx_skb = NULL;
destroy_workqueue(cdev->tx_wq); destroy_workqueue(cdev->tx_wq);
cdev->tx_wq = NULL; cdev->tx_wq = NULL;
}
if (cdev->is_peripheral)
can_rx_offload_disable(&cdev->offload); can_rx_offload_disable(&cdev->offload);
} else {
napi_disable(&cdev->napi);
}
close_candev(dev); close_candev(dev);
m_can_clk_stop(cdev);
phy_power_off(cdev->transceiver); phy_power_off(cdev->transceiver);
return 0; return 0;
@@ -1786,6 +1783,8 @@ static int m_can_open(struct net_device *dev)
if (cdev->is_peripheral) if (cdev->is_peripheral)
can_rx_offload_enable(&cdev->offload); can_rx_offload_enable(&cdev->offload);
else
napi_enable(&cdev->napi);
/* register interrupt handler */ /* register interrupt handler */
if (cdev->is_peripheral) { if (cdev->is_peripheral) {
@@ -1817,9 +1816,6 @@ static int m_can_open(struct net_device *dev)
if (err) if (err)
goto exit_start_fail; goto exit_start_fail;
if (!cdev->is_peripheral)
napi_enable(&cdev->napi);
netif_start_queue(dev); netif_start_queue(dev);
return 0; return 0;
@@ -1833,6 +1829,8 @@ exit_irq_fail:
out_wq_fail: out_wq_fail:
if (cdev->is_peripheral) if (cdev->is_peripheral)
can_rx_offload_disable(&cdev->offload); can_rx_offload_disable(&cdev->offload);
else
napi_disable(&cdev->napi);
close_candev(dev); close_candev(dev);
exit_disable_clks: exit_disable_clks:
m_can_clk_stop(cdev); m_can_clk_stop(cdev);

View File

@@ -2181,12 +2181,11 @@ static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
snprintf(v->name, sizeof(v->name), "%s-rxtx%d", snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
priv->ndev->name, i); priv->ndev->name, i);
err = request_irq(irq, enetc_msix, 0, v->name, v); err = request_irq(irq, enetc_msix, IRQF_NO_AUTOEN, v->name, v);
if (err) { if (err) {
dev_err(priv->dev, "request_irq() failed!\n"); dev_err(priv->dev, "request_irq() failed!\n");
goto irq_err; goto irq_err;
} }
disable_irq(irq);
v->tbier_base = hw->reg + ENETC_BDR(TX, 0, ENETC_TBIER); v->tbier_base = hw->reg + ENETC_BDR(TX, 0, ENETC_TBIER);
v->rbier = hw->reg + ENETC_BDR(RX, i, ENETC_RBIER); v->rbier = hw->reg + ENETC_BDR(RX, i, ENETC_RBIER);

View File

@@ -1060,6 +1060,7 @@ static void rtl8125a_2_hw_phy_config(struct rtl8169_private *tp,
phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000); phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
rtl8168g_enable_gphy_10m(phydev); rtl8168g_enable_gphy_10m(phydev);
rtl8168g_disable_aldps(phydev);
rtl8125a_config_eee_phy(phydev); rtl8125a_config_eee_phy(phydev);
} }
@@ -1099,6 +1100,7 @@ static void rtl8125b_hw_phy_config(struct rtl8169_private *tp,
phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000); phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000);
rtl8125_legacy_force_mode(phydev); rtl8125_legacy_force_mode(phydev);
rtl8168g_disable_aldps(phydev);
rtl8125b_config_eee_phy(phydev); rtl8125b_config_eee_phy(phydev);
} }

View File

@@ -35,6 +35,9 @@ static int loongson_default_data(struct plat_stmmacenet_data *plat)
/* Disable RX queues routing by default */ /* Disable RX queues routing by default */
plat->rx_queues_cfg[0].pkt_route = 0x0; plat->rx_queues_cfg[0].pkt_route = 0x0;
plat->clk_ref_rate = 125000000;
plat->clk_ptp_rate = 125000000;
/* Default to phy auto-detection */ /* Default to phy auto-detection */
plat->phy_addr = -1; plat->phy_addr = -1;

View File

@@ -1420,8 +1420,6 @@ int ath9k_init_debug(struct ath_hw *ah)
sc->debug.debugfs_phy = debugfs_create_dir("ath9k", sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
sc->hw->wiphy->debugfsdir); sc->hw->wiphy->debugfsdir);
if (!sc->debug.debugfs_phy)
return -ENOMEM;
#ifdef CONFIG_ATH_DEBUG #ifdef CONFIG_ATH_DEBUG
debugfs_create_file("debug", 0600, sc->debug.debugfs_phy, debugfs_create_file("debug", 0600, sc->debug.debugfs_phy,

View File

@@ -491,8 +491,6 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
priv->hw->wiphy->debugfsdir); priv->hw->wiphy->debugfsdir);
if (IS_ERR(priv->debug.debugfs_phy))
return -ENOMEM;
ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);

View File

@@ -103,7 +103,7 @@
#define IWL_MVM_FTM_INITIATOR_SECURE_LTF false #define IWL_MVM_FTM_INITIATOR_SECURE_LTF false
#define IWL_MVM_FTM_RESP_NDP_SUPPORT true #define IWL_MVM_FTM_RESP_NDP_SUPPORT true
#define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true #define IWL_MVM_FTM_RESP_LMR_FEEDBACK_SUPPORT true
#define IWL_MVM_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 5 #define IWL_MVM_FTM_NON_TB_MIN_TIME_BETWEEN_MSR 7
#define IWL_MVM_FTM_NON_TB_MAX_TIME_BETWEEN_MSR 1000 #define IWL_MVM_FTM_NON_TB_MAX_TIME_BETWEEN_MSR 1000
#define IWL_MVM_D3_DEBUG false #define IWL_MVM_D3_DEBUG false
#define IWL_MVM_USE_TWT true #define IWL_MVM_USE_TWT true

View File

@@ -540,8 +540,7 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS | MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |
MT_WF_RFCR_DROP_RTS | MT_WF_RFCR_DROP_RTS |
MT_WF_RFCR_DROP_CTL_RSV | MT_WF_RFCR_DROP_CTL_RSV);
MT_WF_RFCR_DROP_NDPA);
*total_flags = flags; *total_flags = flags;
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter); mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);

View File

@@ -381,6 +381,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
struct wilc_join_bss_param *param; struct wilc_join_bss_param *param;
u8 rates_len = 0; u8 rates_len = 0;
int ies_len; int ies_len;
u64 ies_tsf;
int ret; int ret;
param = kzalloc(sizeof(*param), GFP_KERNEL); param = kzalloc(sizeof(*param), GFP_KERNEL);
@@ -396,6 +397,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
return NULL; return NULL;
} }
ies_len = ies->len; ies_len = ies->len;
ies_tsf = ies->tsf;
rcu_read_unlock(); rcu_read_unlock();
param->beacon_period = cpu_to_le16(bss->beacon_interval); param->beacon_period = cpu_to_le16(bss->beacon_interval);
@@ -451,7 +453,7 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE, IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
(u8 *)&noa_attr, sizeof(noa_attr)); (u8 *)&noa_attr, sizeof(noa_attr));
if (ret > 0) { if (ret > 0) {
param->tsf_lo = cpu_to_le32(ies->tsf); param->tsf_lo = cpu_to_le32(ies_tsf);
param->noa_enabled = 1; param->noa_enabled = 1;
param->idx = noa_attr.index; param->idx = noa_attr.index;
if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) { if (noa_attr.oppps_ctwindow & IEEE80211_P2P_OPPPS_ENABLE_BIT) {

View File

@@ -2195,7 +2195,6 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
struct rtw_coex_stat *coex_stat = &coex->stat; struct rtw_coex_stat *coex_stat = &coex->stat;
struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_efuse *efuse = &rtwdev->efuse;
u8 table_case, tdma_case; u8 table_case, tdma_case;
bool wl_cpt_test = false, bt_cpt_test = false;
rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__); rtw_dbg(rtwdev, RTW_DBG_COEX, "[BTCoex], %s()\n", __func__);
@@ -2203,29 +2202,16 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
if (efuse->share_ant) { if (efuse->share_ant) {
/* Shared-Ant */ /* Shared-Ant */
if (wl_cpt_test) { if (coex_stat->wl_gl_busy &&
if (coex_stat->wl_gl_busy) { coex_stat->wl_noisy_level == 0)
table_case = 20; table_case = 14;
tdma_case = 17; else
} else { table_case = 10;
table_case = 10;
tdma_case = 15;
}
} else if (bt_cpt_test) {
table_case = 26;
tdma_case = 26;
} else {
if (coex_stat->wl_gl_busy &&
coex_stat->wl_noisy_level == 0)
table_case = 14;
else
table_case = 10;
if (coex_stat->wl_gl_busy) if (coex_stat->wl_gl_busy)
tdma_case = 15; tdma_case = 15;
else else
tdma_case = 20; tdma_case = 20;
}
} else { } else {
/* Non-Shared-Ant */ /* Non-Shared-Ant */
table_case = 112; table_case = 112;
@@ -2236,11 +2222,7 @@ static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
tdma_case = 120; tdma_case = 120;
} }
if (wl_cpt_test) rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[1]);
else
rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
rtw_coex_table(rtwdev, false, table_case); rtw_coex_table(rtwdev, false, table_case);
rtw_coex_tdma(rtwdev, false, tdma_case); rtw_coex_tdma(rtwdev, false, tdma_case);
} }

View File

@@ -1286,20 +1286,21 @@ static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev)
{ {
const struct rtw_chip_info *chip = rtwdev->chip; const struct rtw_chip_info *chip = rtwdev->chip;
struct rtw_fw_state *fw; struct rtw_fw_state *fw;
int ret = 0;
fw = &rtwdev->fw; fw = &rtwdev->fw;
wait_for_completion(&fw->completion); wait_for_completion(&fw->completion);
if (!fw->firmware) if (!fw->firmware)
return -EINVAL; ret = -EINVAL;
if (chip->wow_fw_name) { if (chip->wow_fw_name) {
fw = &rtwdev->wow_fw; fw = &rtwdev->wow_fw;
wait_for_completion(&fw->completion); wait_for_completion(&fw->completion);
if (!fw->firmware) if (!fw->firmware)
return -EINVAL; ret = -EINVAL;
} }
return 0; return ret;
} }
static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev,

View File

@@ -1926,12 +1926,16 @@ static int cmp_dpa(const void *a, const void *b)
static struct device **scan_labels(struct nd_region *nd_region) static struct device **scan_labels(struct nd_region *nd_region)
{ {
int i, count = 0; int i, count = 0;
struct device *dev, **devs = NULL; struct device *dev, **devs;
struct nd_label_ent *label_ent, *e; struct nd_label_ent *label_ent, *e;
struct nd_mapping *nd_mapping = &nd_region->mapping[0]; struct nd_mapping *nd_mapping = &nd_region->mapping[0];
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1; resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1;
devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
if (!devs)
return NULL;
/* "safe" because create_namespace_pmem() might list_move() label_ent */ /* "safe" because create_namespace_pmem() might list_move() label_ent */
list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) { list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
struct nd_namespace_label *nd_label = label_ent->label; struct nd_namespace_label *nd_label = label_ent->label;
@@ -1950,12 +1954,14 @@ static struct device **scan_labels(struct nd_region *nd_region)
goto err; goto err;
if (i < count) if (i < count)
continue; continue;
__devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL); if (count) {
if (!__devs) __devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL);
goto err; if (!__devs)
memcpy(__devs, devs, sizeof(dev) * count); goto err;
kfree(devs); memcpy(__devs, devs, sizeof(dev) * count);
devs = __devs; kfree(devs);
devs = __devs;
}
dev = create_namespace_pmem(nd_region, nd_mapping, nd_label); dev = create_namespace_pmem(nd_region, nd_mapping, nd_label);
if (IS_ERR(dev)) { if (IS_ERR(dev)) {
@@ -1982,11 +1988,6 @@ static struct device **scan_labels(struct nd_region *nd_region)
/* Publish a zero-sized namespace for userspace to configure. */ /* Publish a zero-sized namespace for userspace to configure. */
nd_mapping_free_labels(nd_mapping); nd_mapping_free_labels(nd_mapping);
devs = kcalloc(2, sizeof(dev), GFP_KERNEL);
if (!devs)
goto err;
nspm = kzalloc(sizeof(*nspm), GFP_KERNEL); nspm = kzalloc(sizeof(*nspm), GFP_KERNEL);
if (!nspm) if (!nspm)
goto err; goto err;
@@ -2025,11 +2026,10 @@ static struct device **scan_labels(struct nd_region *nd_region)
return devs; return devs;
err: err:
if (devs) { for (i = 0; devs[i]; i++)
for (i = 0; devs[i]; i++) namespace_pmem_release(devs[i]);
namespace_pmem_release(devs[i]); kfree(devs);
kfree(devs);
}
return NULL; return NULL;
} }

View File

@@ -580,7 +580,7 @@ static void ks_pcie_quirk(struct pci_dev *dev)
*/ */
if (pci_match_id(am6_pci_devids, bridge)) { if (pci_match_id(am6_pci_devids, bridge)) {
bridge_dev = pci_get_host_bridge_device(dev); bridge_dev = pci_get_host_bridge_device(dev);
if (!bridge_dev && !bridge_dev->parent) if (!bridge_dev || !bridge_dev->parent)
return; return;
ks_pcie = dev_get_drvdata(bridge_dev->parent); ks_pcie = dev_get_drvdata(bridge_dev->parent);

View File

@@ -81,8 +81,8 @@
#define MSGF_MISC_SR_NON_FATAL_DEV BIT(22) #define MSGF_MISC_SR_NON_FATAL_DEV BIT(22)
#define MSGF_MISC_SR_FATAL_DEV BIT(23) #define MSGF_MISC_SR_FATAL_DEV BIT(23)
#define MSGF_MISC_SR_LINK_DOWN BIT(24) #define MSGF_MISC_SR_LINK_DOWN BIT(24)
#define MSGF_MSIC_SR_LINK_AUTO_BWIDTH BIT(25) #define MSGF_MISC_SR_LINK_AUTO_BWIDTH BIT(25)
#define MSGF_MSIC_SR_LINK_BWIDTH BIT(26) #define MSGF_MISC_SR_LINK_BWIDTH BIT(26)
#define MSGF_MISC_SR_MASKALL (MSGF_MISC_SR_RXMSG_AVAIL | \ #define MSGF_MISC_SR_MASKALL (MSGF_MISC_SR_RXMSG_AVAIL | \
MSGF_MISC_SR_RXMSG_OVER | \ MSGF_MISC_SR_RXMSG_OVER | \
@@ -97,8 +97,8 @@
MSGF_MISC_SR_NON_FATAL_DEV | \ MSGF_MISC_SR_NON_FATAL_DEV | \
MSGF_MISC_SR_FATAL_DEV | \ MSGF_MISC_SR_FATAL_DEV | \
MSGF_MISC_SR_LINK_DOWN | \ MSGF_MISC_SR_LINK_DOWN | \
MSGF_MSIC_SR_LINK_AUTO_BWIDTH | \ MSGF_MISC_SR_LINK_AUTO_BWIDTH | \
MSGF_MSIC_SR_LINK_BWIDTH) MSGF_MISC_SR_LINK_BWIDTH)
/* Legacy interrupt status mask bits */ /* Legacy interrupt status mask bits */
#define MSGF_LEG_SR_INTA BIT(0) #define MSGF_LEG_SR_INTA BIT(0)
@@ -302,10 +302,10 @@ static irqreturn_t nwl_pcie_misc_handler(int irq, void *data)
if (misc_stat & MSGF_MISC_SR_FATAL_DEV) if (misc_stat & MSGF_MISC_SR_FATAL_DEV)
dev_err(dev, "Fatal Error Detected\n"); dev_err(dev, "Fatal Error Detected\n");
if (misc_stat & MSGF_MSIC_SR_LINK_AUTO_BWIDTH) if (misc_stat & MSGF_MISC_SR_LINK_AUTO_BWIDTH)
dev_info(dev, "Link Autonomous Bandwidth Management Status bit set\n"); dev_info(dev, "Link Autonomous Bandwidth Management Status bit set\n");
if (misc_stat & MSGF_MSIC_SR_LINK_BWIDTH) if (misc_stat & MSGF_MISC_SR_LINK_BWIDTH)
dev_info(dev, "Link Bandwidth Management Status bit set\n"); dev_info(dev, "Link Bandwidth Management Status bit set\n");
/* Clear misc interrupt status */ /* Clear misc interrupt status */
@@ -792,6 +792,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
pcie = pci_host_bridge_priv(bridge); pcie = pci_host_bridge_priv(bridge);
platform_set_drvdata(pdev, pcie);
pcie->dev = dev; pcie->dev = dev;
pcie->ecam_value = NWL_ECAM_VALUE_DEFAULT; pcie->ecam_value = NWL_ECAM_VALUE_DEFAULT;
@@ -815,13 +816,13 @@ static int nwl_pcie_probe(struct platform_device *pdev)
err = nwl_pcie_bridge_init(pcie); err = nwl_pcie_bridge_init(pcie);
if (err) { if (err) {
dev_err(dev, "HW Initialization failed\n"); dev_err(dev, "HW Initialization failed\n");
return err; goto err_clk;
} }
err = nwl_pcie_init_irq_domain(pcie); err = nwl_pcie_init_irq_domain(pcie);
if (err) { if (err) {
dev_err(dev, "Failed creating IRQ Domain\n"); dev_err(dev, "Failed creating IRQ Domain\n");
return err; goto err_clk;
} }
bridge->sysdata = pcie; bridge->sysdata = pcie;
@@ -831,11 +832,24 @@ static int nwl_pcie_probe(struct platform_device *pdev)
err = nwl_pcie_enable_msi(pcie); err = nwl_pcie_enable_msi(pcie);
if (err < 0) { if (err < 0) {
dev_err(dev, "failed to enable MSI support: %d\n", err); dev_err(dev, "failed to enable MSI support: %d\n", err);
return err; goto err_clk;
} }
} }
return pci_host_probe(bridge); err = pci_host_probe(bridge);
if (!err)
return 0;
err_clk:
clk_disable_unprepare(pcie->clk);
return err;
}
static void nwl_pcie_remove(struct platform_device *pdev)
{
struct nwl_pcie *pcie = platform_get_drvdata(pdev);
clk_disable_unprepare(pcie->clk);
} }
static struct platform_driver nwl_pcie_driver = { static struct platform_driver nwl_pcie_driver = {
@@ -845,5 +859,6 @@ static struct platform_driver nwl_pcie_driver = {
.of_match_table = nwl_pcie_of_match, .of_match_table = nwl_pcie_of_match,
}, },
.probe = nwl_pcie_probe, .probe = nwl_pcie_probe,
.remove_new = nwl_pcie_remove,
}; };
builtin_platform_driver(nwl_pcie_driver); builtin_platform_driver(nwl_pcie_driver);

View File

@@ -579,7 +579,8 @@ static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev) static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
{ {
pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); pci_bridge_wait_for_secondary_bus(pci_dev, "resume");
/* /*
* When powering on a bridge from D3cold, the whole hierarchy may be * When powering on a bridge from D3cold, the whole hierarchy may be
* powered on into D0uninitialized state, resume them to give them a * powered on into D0uninitialized state, resume them to give them a

View File

@@ -64,6 +64,14 @@ struct pci_pme_device {
#define PME_TIMEOUT 1000 /* How long between PME checks */ #define PME_TIMEOUT 1000 /* How long between PME checks */
/*
* Devices may extend the 1 sec period through Request Retry Status
* completions (PCIe r6.0 sec 2.3.1). The spec does not provide an upper
* limit, but 60 sec ought to be enough for any device to become
* responsive.
*/
#define PCIE_RESET_READY_POLL_MS 60000 /* msec */
static void pci_dev_d3_sleep(struct pci_dev *dev) static void pci_dev_d3_sleep(struct pci_dev *dev)
{ {
unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay); unsigned int delay_ms = max(dev->d3hot_delay, pci_pm_d3hot_delay);
@@ -4991,7 +4999,6 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus)
* pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible
* @dev: PCI bridge * @dev: PCI bridge
* @reset_type: reset type in human-readable form * @reset_type: reset type in human-readable form
* @timeout: maximum time to wait for devices on secondary bus (milliseconds)
* *
* Handle necessary delays before access to the devices on the secondary * Handle necessary delays before access to the devices on the secondary
* side of the bridge are permitted after D3cold to D0 transition * side of the bridge are permitted after D3cold to D0 transition
@@ -5004,8 +5011,7 @@ static int pci_bus_max_d3cold_delay(const struct pci_bus *bus)
* Return 0 on success or -ENOTTY if the first device on the secondary bus * Return 0 on success or -ENOTTY if the first device on the secondary bus
* failed to become accessible. * failed to become accessible.
*/ */
int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type)
int timeout)
{ {
struct pci_dev *child __free(pci_dev_put) = NULL; struct pci_dev *child __free(pci_dev_put) = NULL;
int delay; int delay;
@@ -5083,7 +5089,8 @@ int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type,
} }
} }
return pci_dev_wait(child, reset_type, timeout - delay); return pci_dev_wait(child, reset_type,
PCIE_RESET_READY_POLL_MS - delay);
} }
void pci_reset_secondary_bus(struct pci_dev *dev) void pci_reset_secondary_bus(struct pci_dev *dev)
@@ -5120,8 +5127,7 @@ int pci_bridge_secondary_bus_reset(struct pci_dev *dev)
{ {
pcibios_reset_secondary_bus(dev); pcibios_reset_secondary_bus(dev);
return pci_bridge_wait_for_secondary_bus(dev, "bus reset", return pci_bridge_wait_for_secondary_bus(dev, "bus reset");
PCIE_RESET_READY_POLL_MS);
} }
EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset);
@@ -5741,8 +5747,10 @@ static void pci_bus_restore_locked(struct pci_bus *bus)
list_for_each_entry(dev, &bus->devices, bus_list) { list_for_each_entry(dev, &bus->devices, bus_list) {
pci_dev_restore(dev); pci_dev_restore(dev);
if (dev->subordinate) if (dev->subordinate) {
pci_bridge_wait_for_secondary_bus(dev, "bus reset");
pci_bus_restore_locked(dev->subordinate); pci_bus_restore_locked(dev->subordinate);
}
} }
} }
@@ -5776,8 +5784,10 @@ static void pci_slot_restore_locked(struct pci_slot *slot)
if (!dev->slot || dev->slot != slot) if (!dev->slot || dev->slot != slot)
continue; continue;
pci_dev_restore(dev); pci_dev_restore(dev);
if (dev->subordinate) if (dev->subordinate) {
pci_bridge_wait_for_secondary_bus(dev, "slot reset");
pci_bus_restore_locked(dev->subordinate); pci_bus_restore_locked(dev->subordinate);
}
} }
} }

View File

@@ -70,12 +70,6 @@ struct pci_cap_saved_state *pci_find_saved_ext_cap(struct pci_dev *dev,
* Reset (PCIe r6.0 sec 5.8). * Reset (PCIe r6.0 sec 5.8).
*/ */
#define PCI_RESET_WAIT 1000 /* msec */ #define PCI_RESET_WAIT 1000 /* msec */
/*
* Devices may extend the 1 sec period through Request Retry Status completions
* (PCIe r6.0 sec 2.3.1). The spec does not provide an upper limit, but 60 sec
* ought to be enough for any device to become responsive.
*/
#define PCIE_RESET_READY_POLL_MS 60000 /* msec */
void pci_update_current_state(struct pci_dev *dev, pci_power_t state); void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
void pci_refresh_power_state(struct pci_dev *dev); void pci_refresh_power_state(struct pci_dev *dev);
@@ -100,8 +94,7 @@ void pci_msix_init(struct pci_dev *dev);
bool pci_bridge_d3_possible(struct pci_dev *dev); bool pci_bridge_d3_possible(struct pci_dev *dev);
void pci_bridge_d3_update(struct pci_dev *dev); void pci_bridge_d3_update(struct pci_dev *dev);
void pci_bridge_reconfigure_ltr(struct pci_dev *dev); void pci_bridge_reconfigure_ltr(struct pci_dev *dev);
int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type);
int timeout);
static inline void pci_wakeup_event(struct pci_dev *dev) static inline void pci_wakeup_event(struct pci_dev *dev)
{ {

View File

@@ -171,8 +171,7 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS, pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
PCI_EXP_DPC_STATUS_TRIGGER); PCI_EXP_DPC_STATUS_TRIGGER);
if (pci_bridge_wait_for_secondary_bus(pdev, "DPC", if (pci_bridge_wait_for_secondary_bus(pdev, "DPC")) {
PCIE_RESET_READY_POLL_MS)) {
clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags); clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags);
ret = PCI_ERS_RESULT_DISCONNECT; ret = PCI_ERS_RESULT_DISCONNECT;
} else { } else {

Some files were not shown because too many files have changed in this diff Show More