mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge b778b52404 ("scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()") into android14-6.1-lts
Steps on the way to 6.1.121 Change-Id: I0d6ffc4a476fc41f8497fd860e08e5230f04d27d Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -23,8 +23,8 @@ properties:
|
||||
Indicates how many data pins are used to transmit two channels of PDM
|
||||
signal. 0 means two wires, 1 means one wire. Default value is 0.
|
||||
enum:
|
||||
- 0 # one wire
|
||||
- 1 # two wires
|
||||
- 0 # two wires
|
||||
- 1 # one wire
|
||||
|
||||
mediatek,mic-type-0:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
@@ -53,9 +53,9 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mt6359codec: mt6359codec {
|
||||
mediatek,dmic-mode = <0>;
|
||||
mediatek,mic-type-0 = <2>;
|
||||
mt6359codec: audio-codec {
|
||||
mediatek,dmic-mode = <0>;
|
||||
mediatek,mic-type-0 = <2>;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
@@ -869,6 +869,8 @@ patternProperties:
|
||||
description: National Semiconductor
|
||||
"^nec,.*":
|
||||
description: NEC LCD Technologies, Ltd.
|
||||
"^neofidelity,.*":
|
||||
description: Neofidelity Inc.
|
||||
"^neonode,.*":
|
||||
description: Neonode Inc.
|
||||
"^netgear,.*":
|
||||
|
||||
@@ -1757,6 +1757,12 @@ static void restore_args(struct jit_ctx *ctx, int args_off, int nargs)
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
|
||||
{
|
||||
return fentry_links->nr_links == 1 &&
|
||||
fentry_links->links[0]->link.type == BPF_LINK_TYPE_STRUCT_OPS;
|
||||
}
|
||||
|
||||
/* Based on the x86's implementation of arch_prepare_bpf_trampoline().
|
||||
*
|
||||
* bpf prog and function entry before bpf trampoline hooked:
|
||||
@@ -1786,6 +1792,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
|
||||
struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
|
||||
bool save_ret;
|
||||
__le32 **branches = NULL;
|
||||
bool is_struct_ops = is_struct_ops_tramp(fentry);
|
||||
|
||||
/* trampoline stack layout:
|
||||
* [ parent ip ]
|
||||
@@ -1854,11 +1861,14 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
|
||||
*/
|
||||
emit_bti(A64_BTI_JC, ctx);
|
||||
|
||||
/* frame for parent function */
|
||||
emit(A64_PUSH(A64_FP, A64_R(9), A64_SP), ctx);
|
||||
emit(A64_MOV(1, A64_FP, A64_SP), ctx);
|
||||
/* x9 is not set for struct_ops */
|
||||
if (!is_struct_ops) {
|
||||
/* frame for parent function */
|
||||
emit(A64_PUSH(A64_FP, A64_R(9), A64_SP), ctx);
|
||||
emit(A64_MOV(1, A64_FP, A64_SP), ctx);
|
||||
}
|
||||
|
||||
/* frame for patched function */
|
||||
/* frame for patched function for tracing, or caller for struct_ops */
|
||||
emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
|
||||
emit(A64_MOV(1, A64_FP, A64_SP), ctx);
|
||||
|
||||
@@ -1944,19 +1954,24 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
|
||||
/* reset SP */
|
||||
emit(A64_MOV(1, A64_SP, A64_FP), ctx);
|
||||
|
||||
/* pop frames */
|
||||
emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
|
||||
emit(A64_POP(A64_FP, A64_R(9), A64_SP), ctx);
|
||||
|
||||
if (flags & BPF_TRAMP_F_SKIP_FRAME) {
|
||||
/* skip patched function, return to parent */
|
||||
emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
|
||||
emit(A64_RET(A64_R(9)), ctx);
|
||||
if (is_struct_ops) {
|
||||
emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
|
||||
emit(A64_RET(A64_LR), ctx);
|
||||
} else {
|
||||
/* return to patched function */
|
||||
emit(A64_MOV(1, A64_R(10), A64_LR), ctx);
|
||||
emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
|
||||
emit(A64_RET(A64_R(10)), ctx);
|
||||
/* pop frames */
|
||||
emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
|
||||
emit(A64_POP(A64_FP, A64_R(9), A64_SP), ctx);
|
||||
|
||||
if (flags & BPF_TRAMP_F_SKIP_FRAME) {
|
||||
/* skip patched function, return to parent */
|
||||
emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
|
||||
emit(A64_RET(A64_R(9)), ctx);
|
||||
} else {
|
||||
/* return to patched function */
|
||||
emit(A64_MOV(1, A64_R(10), A64_LR), ctx);
|
||||
emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
|
||||
emit(A64_RET(A64_R(10)), ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->image)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef _ASM_POWERPC_DTL_H
|
||||
#define _ASM_POWERPC_DTL_H
|
||||
|
||||
#include <linux/rwsem.h>
|
||||
#include <asm/lppaca.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
|
||||
/*
|
||||
* Layout of entries in the hypervisor's dispatch trace log buffer.
|
||||
@@ -35,7 +35,7 @@ struct dtl_entry {
|
||||
#define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)
|
||||
|
||||
extern struct kmem_cache *dtl_cache;
|
||||
extern rwlock_t dtl_access_lock;
|
||||
extern struct rw_semaphore dtl_access_lock;
|
||||
|
||||
extern void register_dtl_buffer(int cpu);
|
||||
extern void alloc_dtl_buffers(unsigned long *time_limit);
|
||||
|
||||
@@ -32,4 +32,11 @@ extern int early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
|
||||
int depth, void *data);
|
||||
extern int fadump_reserve_mem(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FA_DUMP) && defined(CONFIG_CMA)
|
||||
void fadump_cma_init(void);
|
||||
#else
|
||||
static inline void fadump_cma_init(void) { }
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_POWERPC_FADUMP_H */
|
||||
|
||||
@@ -25,6 +25,7 @@ int vdso_getcpu_init(void);
|
||||
#ifdef __VDSO64__
|
||||
#define V_FUNCTION_BEGIN(name) \
|
||||
.globl name; \
|
||||
.type name,@function; \
|
||||
name: \
|
||||
|
||||
#define V_FUNCTION_END(name) \
|
||||
|
||||
@@ -80,27 +80,23 @@ static struct cma *fadump_cma;
|
||||
* But for some reason even if it fails we still have the memory reservation
|
||||
* with us and we can still continue doing fadump.
|
||||
*/
|
||||
static int __init fadump_cma_init(void)
|
||||
void __init fadump_cma_init(void)
|
||||
{
|
||||
unsigned long long base, size;
|
||||
int rc;
|
||||
|
||||
if (!fw_dump.fadump_enabled)
|
||||
return 0;
|
||||
|
||||
if (!fw_dump.fadump_supported || !fw_dump.fadump_enabled ||
|
||||
fw_dump.dump_active)
|
||||
return;
|
||||
/*
|
||||
* Do not use CMA if user has provided fadump=nocma kernel parameter.
|
||||
* Return 1 to continue with fadump old behaviour.
|
||||
*/
|
||||
if (fw_dump.nocma)
|
||||
return 1;
|
||||
if (fw_dump.nocma || !fw_dump.boot_memory_size)
|
||||
return;
|
||||
|
||||
base = fw_dump.reserve_dump_area_start;
|
||||
size = fw_dump.boot_memory_size;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
rc = cma_init_reserved_mem(base, size, 0, "fadump_cma", &fadump_cma);
|
||||
if (rc) {
|
||||
pr_err("Failed to init cma area for firmware-assisted dump,%d\n", rc);
|
||||
@@ -110,7 +106,7 @@ static int __init fadump_cma_init(void)
|
||||
* blocked from production system usage. Hence return 1,
|
||||
* so that we can continue with fadump.
|
||||
*/
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -127,10 +123,7 @@ static int __init fadump_cma_init(void)
|
||||
cma_get_size(fadump_cma),
|
||||
(unsigned long)cma_get_base(fadump_cma) >> 20,
|
||||
fw_dump.reserve_dump_area_size);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static int __init fadump_cma_init(void) { return 1; }
|
||||
#endif /* CONFIG_CMA */
|
||||
|
||||
/* Scan the Firmware Assisted dump configuration details. */
|
||||
@@ -647,8 +640,6 @@ int __init fadump_reserve_mem(void)
|
||||
|
||||
pr_info("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n",
|
||||
(size >> 20), base, (memblock_phys_mem_size() >> 20));
|
||||
|
||||
ret = fadump_cma_init();
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -982,9 +982,11 @@ void __init setup_arch(char **cmdline_p)
|
||||
initmem_init();
|
||||
|
||||
/*
|
||||
* Reserve large chunks of memory for use by CMA for KVM and hugetlb. These must
|
||||
* be called after initmem_init(), so that pageblock_order is initialised.
|
||||
* Reserve large chunks of memory for use by CMA for fadump, KVM and
|
||||
* hugetlb. These must be called after initmem_init(), so that
|
||||
* pageblock_order is initialised.
|
||||
*/
|
||||
fadump_cma_init();
|
||||
kvm_cma_reserve();
|
||||
gigantic_hugetlb_cma_reserve();
|
||||
|
||||
|
||||
@@ -431,10 +431,16 @@ static int ___do_page_fault(struct pt_regs *regs, unsigned long address,
|
||||
/*
|
||||
* The kernel should never take an execute fault nor should it
|
||||
* take a page fault to a kernel address or a page fault to a user
|
||||
* address outside of dedicated places
|
||||
* address outside of dedicated places.
|
||||
*
|
||||
* Rather than kfence directly reporting false negatives, search whether
|
||||
* the NIP belongs to the fixup table for cases where fault could come
|
||||
* from functions like copy_from_kernel_nofault().
|
||||
*/
|
||||
if (unlikely(!is_user && bad_kernel_fault(regs, error_code, address, is_write))) {
|
||||
if (kfence_handle_page_fault(address, is_write, regs))
|
||||
if (is_kfence_address((void *)address) &&
|
||||
!search_exception_tables(instruction_pointer(regs)) &&
|
||||
kfence_handle_page_fault(address, is_write, regs))
|
||||
return 0;
|
||||
|
||||
return SIGSEGV;
|
||||
|
||||
@@ -191,7 +191,7 @@ static int dtl_enable(struct dtl *dtl)
|
||||
return -EBUSY;
|
||||
|
||||
/* ensure there are no other conflicting dtl users */
|
||||
if (!read_trylock(&dtl_access_lock))
|
||||
if (!down_read_trylock(&dtl_access_lock))
|
||||
return -EBUSY;
|
||||
|
||||
n_entries = dtl_buf_entries;
|
||||
@@ -199,7 +199,7 @@ static int dtl_enable(struct dtl *dtl)
|
||||
if (!buf) {
|
||||
printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
|
||||
__func__, dtl->cpu);
|
||||
read_unlock(&dtl_access_lock);
|
||||
up_read(&dtl_access_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ static int dtl_enable(struct dtl *dtl)
|
||||
spin_unlock(&dtl->lock);
|
||||
|
||||
if (rc) {
|
||||
read_unlock(&dtl_access_lock);
|
||||
up_read(&dtl_access_lock);
|
||||
kmem_cache_free(dtl_cache, buf);
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ static void dtl_disable(struct dtl *dtl)
|
||||
dtl->buf = NULL;
|
||||
dtl->buf_entries = 0;
|
||||
spin_unlock(&dtl->lock);
|
||||
read_unlock(&dtl_access_lock);
|
||||
up_read(&dtl_access_lock);
|
||||
}
|
||||
|
||||
/* file interface */
|
||||
|
||||
@@ -167,7 +167,7 @@ struct vcpu_dispatch_data {
|
||||
*/
|
||||
#define NR_CPUS_H NR_CPUS
|
||||
|
||||
DEFINE_RWLOCK(dtl_access_lock);
|
||||
DECLARE_RWSEM(dtl_access_lock);
|
||||
static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data);
|
||||
static DEFINE_PER_CPU(u64, dtl_entry_ridx);
|
||||
static DEFINE_PER_CPU(struct dtl_worker, dtl_workers);
|
||||
@@ -461,7 +461,7 @@ static int dtl_worker_enable(unsigned long *time_limit)
|
||||
{
|
||||
int rc = 0, state;
|
||||
|
||||
if (!write_trylock(&dtl_access_lock)) {
|
||||
if (!down_write_trylock(&dtl_access_lock)) {
|
||||
rc = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ static int dtl_worker_enable(unsigned long *time_limit)
|
||||
pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n");
|
||||
free_dtl_buffers(time_limit);
|
||||
reset_global_dtl_mask();
|
||||
write_unlock(&dtl_access_lock);
|
||||
up_write(&dtl_access_lock);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -492,7 +492,7 @@ static void dtl_worker_disable(unsigned long *time_limit)
|
||||
cpuhp_remove_state(dtl_worker_state);
|
||||
free_dtl_buffers(time_limit);
|
||||
reset_global_dtl_mask();
|
||||
write_unlock(&dtl_access_lock);
|
||||
up_write(&dtl_access_lock);
|
||||
}
|
||||
|
||||
static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
|
||||
|
||||
@@ -250,9 +250,11 @@ 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 |
|
||||
FIELD_PREP(PLL_MFI_MASK, rate->mfi);
|
||||
writel_relaxed(pll_div, pll->base + PLL_DIV);
|
||||
readl(pll->base + PLL_DIV);
|
||||
if (pll->flags & CLK_FRACN_GPPLL_FRACN) {
|
||||
writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
|
||||
writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
|
||||
readl(pll->base + PLL_NUMERATOR);
|
||||
}
|
||||
|
||||
/* Wait for 5us according to fracn mode pll doc */
|
||||
@@ -261,6 +263,7 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
/* Enable Powerup */
|
||||
tmp |= POWERUP_MASK;
|
||||
writel_relaxed(tmp, pll->base + PLL_CTRL);
|
||||
readl(pll->base + PLL_CTRL);
|
||||
|
||||
/* Wait Lock */
|
||||
ret = clk_fracn_gppll_wait_lock(pll);
|
||||
@@ -298,14 +301,15 @@ static int clk_fracn_gppll_prepare(struct clk_hw *hw)
|
||||
|
||||
val |= POWERUP_MASK;
|
||||
writel_relaxed(val, pll->base + PLL_CTRL);
|
||||
|
||||
val |= CLKMUX_EN;
|
||||
writel_relaxed(val, pll->base + PLL_CTRL);
|
||||
readl(pll->base + PLL_CTRL);
|
||||
|
||||
ret = clk_fracn_gppll_wait_lock(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val |= CLKMUX_EN;
|
||||
writel_relaxed(val, pll->base + PLL_CTRL);
|
||||
|
||||
val &= ~CLKMUX_BYPASS;
|
||||
writel_relaxed(val, pll->base + PLL_CTRL);
|
||||
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "clk-scu.h"
|
||||
|
||||
@@ -41,6 +43,29 @@ struct clk_lpcg_scu {
|
||||
|
||||
#define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw)
|
||||
|
||||
/* e10858 -LPCG clock gating register synchronization errata */
|
||||
static void lpcg_e10858_writel(unsigned long rate, void __iomem *reg, u32 val)
|
||||
{
|
||||
writel(val, reg);
|
||||
|
||||
if (rate >= 24 * HZ_PER_MHZ || rate == 0) {
|
||||
/*
|
||||
* The time taken to access the LPCG registers from the AP core
|
||||
* through the interconnect is longer than the minimum delay
|
||||
* of 4 clock cycles required by the errata.
|
||||
* Adding a readl will provide sufficient delay to prevent
|
||||
* back-to-back writes.
|
||||
*/
|
||||
readl(reg);
|
||||
} else {
|
||||
/*
|
||||
* For clocks running below 24MHz, wait a minimum of
|
||||
* 4 clock cycles.
|
||||
*/
|
||||
ndelay(4 * (DIV_ROUND_UP(1000 * HZ_PER_MHZ, rate)));
|
||||
}
|
||||
}
|
||||
|
||||
static int clk_lpcg_scu_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw);
|
||||
@@ -57,7 +82,8 @@ static int clk_lpcg_scu_enable(struct clk_hw *hw)
|
||||
val |= CLK_GATE_SCU_LPCG_HW_SEL;
|
||||
|
||||
reg |= val << clk->bit_idx;
|
||||
writel(reg, clk->reg);
|
||||
|
||||
lpcg_e10858_writel(clk_hw_get_rate(hw), clk->reg, reg);
|
||||
|
||||
spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
|
||||
|
||||
@@ -74,7 +100,7 @@ static void clk_lpcg_scu_disable(struct clk_hw *hw)
|
||||
|
||||
reg = readl_relaxed(clk->reg);
|
||||
reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx);
|
||||
writel(reg, clk->reg);
|
||||
lpcg_e10858_writel(clk_hw_get_rate(hw), clk->reg, reg);
|
||||
|
||||
spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
|
||||
}
|
||||
@@ -145,13 +171,8 @@ static int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev)
|
||||
{
|
||||
struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
|
||||
|
||||
/*
|
||||
* FIXME: Sometimes writes don't work unless the CPU issues
|
||||
* them twice
|
||||
*/
|
||||
|
||||
writel(clk->state, clk->reg);
|
||||
writel(clk->state, clk->reg);
|
||||
lpcg_e10858_writel(0, clk->reg, clk->state);
|
||||
dev_dbg(dev, "restore lpcg state 0x%x\n", clk->state);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -577,7 +577,7 @@ static int __maybe_unused imx_clk_scu_suspend(struct device *dev)
|
||||
clk->rate = clk_scu_recalc_rate(&clk->hw, 0);
|
||||
else
|
||||
clk->rate = clk_hw_get_rate(&clk->hw);
|
||||
clk->is_enabled = clk_hw_is_enabled(&clk->hw);
|
||||
clk->is_enabled = clk_hw_is_prepared(&clk->hw);
|
||||
|
||||
if (clk->parent)
|
||||
dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent),
|
||||
|
||||
@@ -289,7 +289,7 @@ static unsigned long
|
||||
rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
|
||||
unsigned long rate)
|
||||
{
|
||||
unsigned long foutpostdiv_rate;
|
||||
unsigned long foutpostdiv_rate, foutvco_rate;
|
||||
|
||||
params->pl5_intin = rate / MEGA;
|
||||
params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA);
|
||||
@@ -298,10 +298,11 @@ rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
|
||||
params->pl5_postdiv2 = 1;
|
||||
params->pl5_spread = 0x16;
|
||||
|
||||
foutpostdiv_rate =
|
||||
EXTAL_FREQ_IN_MEGA_HZ * MEGA / params->pl5_refdiv *
|
||||
((((params->pl5_intin << 24) + params->pl5_fracin)) >> 24) /
|
||||
(params->pl5_postdiv1 * params->pl5_postdiv2);
|
||||
foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA,
|
||||
(params->pl5_intin << 24) + params->pl5_fracin),
|
||||
params->pl5_refdiv) >> 24;
|
||||
foutpostdiv_rate = DIV_ROUND_CLOSEST_ULL(foutvco_rate,
|
||||
params->pl5_postdiv1 * params->pl5_postdiv2);
|
||||
|
||||
return foutpostdiv_rate;
|
||||
}
|
||||
|
||||
@@ -1360,7 +1360,7 @@ static int sun20i_d1_ccu_probe(struct platform_device *pdev)
|
||||
|
||||
/* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */
|
||||
val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
|
||||
val &= ~BIT(1) | BIT(0);
|
||||
val &= ~(BIT(1) | BIT(0));
|
||||
writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
|
||||
|
||||
/* Force fanout-27M factor N to 0. */
|
||||
|
||||
@@ -422,6 +422,9 @@ static int cppc_get_cpu_power(struct device *cpu_dev,
|
||||
struct cppc_cpudata *cpu_data;
|
||||
|
||||
policy = cpufreq_cpu_get_raw(cpu_dev->id);
|
||||
if (!policy)
|
||||
return 0;
|
||||
|
||||
cpu_data = policy->driver_data;
|
||||
perf_caps = &cpu_data->perf_caps;
|
||||
max_cap = arch_scale_cpu_capacity(cpu_dev->id);
|
||||
@@ -489,6 +492,9 @@ static int cppc_get_cpu_cost(struct device *cpu_dev, unsigned long KHz,
|
||||
int step;
|
||||
|
||||
policy = cpufreq_cpu_get_raw(cpu_dev->id);
|
||||
if (!policy)
|
||||
return 0;
|
||||
|
||||
cpu_data = policy->driver_data;
|
||||
perf_caps = &cpu_data->perf_caps;
|
||||
max_cap = arch_scale_cpu_capacity(cpu_dev->id);
|
||||
|
||||
@@ -154,7 +154,9 @@ static int __init cpufreq_init(void)
|
||||
|
||||
ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
|
||||
|
||||
if (!ret && !nowait) {
|
||||
if (ret) {
|
||||
platform_driver_unregister(&platform_driver);
|
||||
} else if (!nowait) {
|
||||
saved_cpu_wait = cpu_wait;
|
||||
cpu_wait = loongson2_cpu_wait;
|
||||
}
|
||||
|
||||
@@ -314,8 +314,8 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
|
||||
attr_sdma);
|
||||
struct kfd_sdma_activity_handler_workarea sdma_activity_work_handler;
|
||||
|
||||
INIT_WORK(&sdma_activity_work_handler.sdma_activity_work,
|
||||
kfd_sdma_activity_worker);
|
||||
INIT_WORK_ONSTACK(&sdma_activity_work_handler.sdma_activity_work,
|
||||
kfd_sdma_activity_worker);
|
||||
|
||||
sdma_activity_work_handler.pdd = pdd;
|
||||
sdma_activity_work_handler.sdma_activity_counter = 0;
|
||||
@@ -323,6 +323,7 @@ static ssize_t kfd_procfs_show(struct kobject *kobj, struct attribute *attr,
|
||||
schedule_work(&sdma_activity_work_handler.sdma_activity_work);
|
||||
|
||||
flush_work(&sdma_activity_work_handler.sdma_activity_work);
|
||||
destroy_work_on_stack(&sdma_activity_work_handler.sdma_activity_work);
|
||||
|
||||
return snprintf(buffer, PAGE_SIZE, "%llu\n",
|
||||
(sdma_activity_work_handler.sdma_activity_counter)/
|
||||
|
||||
@@ -2567,6 +2567,8 @@ static int __maybe_unused anx7625_runtime_pm_suspend(struct device *dev)
|
||||
mutex_lock(&ctx->lock);
|
||||
|
||||
anx7625_stop_dp_work(ctx);
|
||||
if (!ctx->pdata.panel_bridge)
|
||||
anx7625_remove_edid(ctx);
|
||||
anx7625_power_standby(ctx);
|
||||
|
||||
mutex_unlock(&ctx->lock);
|
||||
|
||||
@@ -1579,6 +1579,13 @@ static struct edid *tc_get_edid(struct drm_bridge *bridge,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct tc_data *tc = bridge_to_tc(bridge);
|
||||
int ret;
|
||||
|
||||
ret = tc_get_display_props(tc);
|
||||
if (ret < 0) {
|
||||
dev_err(tc->dev, "failed to read display props: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return drm_get_edid(connector, &tc->aux.ddc);
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ static void show_leaks(struct drm_mm *mm) { }
|
||||
|
||||
INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
|
||||
u64, __subtree_last,
|
||||
START, LAST, static inline, drm_mm_interval_tree)
|
||||
START, LAST, static inline __maybe_unused, drm_mm_interval_tree)
|
||||
|
||||
struct drm_mm_node *
|
||||
__drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last)
|
||||
|
||||
@@ -519,6 +519,16 @@ static int etnaviv_bind(struct device *dev)
|
||||
priv->num_gpus = 0;
|
||||
priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
|
||||
|
||||
/*
|
||||
* If the GPU is part of a system with DMA addressing limitations,
|
||||
* request pages for our SHM backend buffers from the DMA32 zone to
|
||||
* hopefully avoid performance killing SWIOTLB bounce buffering.
|
||||
*/
|
||||
if (dma_addressing_limited(dev)) {
|
||||
priv->shm_gfp_mask |= GFP_DMA32;
|
||||
priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
|
||||
}
|
||||
|
||||
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
|
||||
if (IS_ERR(priv->cmdbuf_suballoc)) {
|
||||
dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
|
||||
|
||||
@@ -83,10 +83,15 @@ static void etnaviv_core_dump_registers(struct core_dump_iterator *iter,
|
||||
{
|
||||
struct etnaviv_dump_registers *reg = iter->data;
|
||||
unsigned int i;
|
||||
u32 read_addr;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) {
|
||||
read_addr = etnaviv_dump_registers[i];
|
||||
if (read_addr >= VIVS_PM_POWER_CONTROLS &&
|
||||
read_addr <= VIVS_PM_PULSE_EATER)
|
||||
read_addr = gpu_fix_power_address(gpu, read_addr);
|
||||
reg->reg = cpu_to_le32(etnaviv_dump_registers[i]);
|
||||
reg->value = cpu_to_le32(gpu_read(gpu, etnaviv_dump_registers[i]));
|
||||
reg->value = cpu_to_le32(gpu_read(gpu, read_addr));
|
||||
}
|
||||
|
||||
etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg);
|
||||
|
||||
@@ -590,7 +590,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
|
||||
u32 pmc, ppc;
|
||||
|
||||
/* enable clock gating */
|
||||
ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
|
||||
|
||||
/* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */
|
||||
@@ -598,9 +598,9 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
|
||||
gpu->identity.revision == 0x4302)
|
||||
ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING;
|
||||
|
||||
gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc);
|
||||
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc);
|
||||
|
||||
pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS);
|
||||
pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS);
|
||||
|
||||
/* Disable PA clock gating for GC400+ without bugfix except for GC420 */
|
||||
if (gpu->identity.model >= chipModel_GC400 &&
|
||||
@@ -635,7 +635,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu)
|
||||
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ;
|
||||
pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ;
|
||||
|
||||
gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
|
||||
gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc);
|
||||
}
|
||||
|
||||
void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch)
|
||||
@@ -695,11 +695,11 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu)
|
||||
(gpu->identity.features & chipFeatures_PIPE_3D))
|
||||
{
|
||||
/* Performance fix: disable internal DFS */
|
||||
pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER);
|
||||
pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER);
|
||||
pulse_eater |= BIT(18);
|
||||
}
|
||||
|
||||
gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
|
||||
gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater);
|
||||
}
|
||||
|
||||
static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu)
|
||||
@@ -798,14 +798,6 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* If the GPU is part of a system with DMA addressing limitations,
|
||||
* request pages for our SHM backend buffers from the DMA32 zone to
|
||||
* hopefully avoid performance killing SWIOTLB bounce buffering.
|
||||
*/
|
||||
if (dma_addressing_limited(gpu->dev))
|
||||
priv->shm_gfp_mask |= GFP_DMA32;
|
||||
|
||||
/* Create buffer: */
|
||||
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
|
||||
PAGE_SIZE);
|
||||
@@ -1300,10 +1292,12 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
|
||||
{
|
||||
u32 val;
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
/* disable clock gating */
|
||||
val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
|
||||
gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
|
||||
/* enable debug register */
|
||||
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
|
||||
@@ -1311,6 +1305,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
|
||||
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
|
||||
|
||||
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
|
||||
|
||||
mutex_unlock(&gpu->lock);
|
||||
}
|
||||
|
||||
static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
|
||||
@@ -1320,23 +1316,27 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
|
||||
unsigned int i;
|
||||
u32 val;
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
|
||||
|
||||
for (i = 0; i < submit->nr_pmrs; i++) {
|
||||
const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
|
||||
|
||||
*pmr->bo_vma = pmr->sequence;
|
||||
}
|
||||
|
||||
/* disable debug register */
|
||||
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
|
||||
val |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
|
||||
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
|
||||
|
||||
/* enable clock gating */
|
||||
val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
|
||||
gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
|
||||
mutex_unlock(&gpu->lock);
|
||||
|
||||
for (i = 0; i < submit->nr_pmrs; i++) {
|
||||
const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
|
||||
|
||||
*pmr->bo_vma = pmr->sequence;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "etnaviv_gem.h"
|
||||
#include "etnaviv_mmu.h"
|
||||
#include "etnaviv_drv.h"
|
||||
#include "common.xml.h"
|
||||
|
||||
struct etnaviv_gem_submit;
|
||||
struct etnaviv_vram_mapping;
|
||||
@@ -159,6 +160,26 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
|
||||
return readl(gpu->mmio + reg);
|
||||
}
|
||||
|
||||
static inline u32 gpu_fix_power_address(struct etnaviv_gpu *gpu, u32 reg)
|
||||
{
|
||||
/* Power registers in GC300 < 2.0 are offset by 0x100 */
|
||||
if (gpu->identity.model == chipModel_GC300 &&
|
||||
gpu->identity.revision < 0x2000)
|
||||
reg += 0x100;
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline void gpu_write_power(struct etnaviv_gpu *gpu, u32 reg, u32 data)
|
||||
{
|
||||
writel(data, gpu->mmio + gpu_fix_power_address(gpu, reg));
|
||||
}
|
||||
|
||||
static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg)
|
||||
{
|
||||
return readl(gpu->mmio + gpu_fix_power_address(gpu, reg));
|
||||
}
|
||||
|
||||
int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
|
||||
|
||||
int etnaviv_gpu_init(struct etnaviv_gpu *gpu);
|
||||
|
||||
@@ -8,6 +8,7 @@ config DRM_FSL_DCU
|
||||
select DRM_PANEL
|
||||
select REGMAP_MMIO
|
||||
select VIDEOMODE_HELPERS
|
||||
select MFD_SYSCON if SOC_LS1021A
|
||||
help
|
||||
Choose this option if you have an Freescale DCU chipset.
|
||||
If M is selected the module will be called fsl-dcu-drm.
|
||||
|
||||
@@ -100,6 +100,7 @@ static void fsl_dcu_irq_uninstall(struct drm_device *dev)
|
||||
static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
|
||||
{
|
||||
struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
|
||||
struct regmap *scfg;
|
||||
int ret;
|
||||
|
||||
ret = fsl_dcu_drm_modeset_init(fsl_dev);
|
||||
@@ -108,6 +109,20 @@ static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg");
|
||||
if (PTR_ERR(scfg) != -ENODEV) {
|
||||
/*
|
||||
* For simplicity, enable the PIXCLK unconditionally,
|
||||
* resulting in increased power consumption. Disabling
|
||||
* the clock in PM or on unload could be implemented as
|
||||
* a future improvement.
|
||||
*/
|
||||
ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN,
|
||||
SCFG_PIXCLKCR_PXCEN);
|
||||
if (ret < 0)
|
||||
return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n");
|
||||
}
|
||||
|
||||
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
|
||||
if (ret < 0) {
|
||||
dev_err(dev->dev, "failed to initialize vblank\n");
|
||||
|
||||
@@ -160,6 +160,9 @@
|
||||
#define FSL_DCU_ARGB4444 12
|
||||
#define FSL_DCU_YUV422 14
|
||||
|
||||
#define SCFG_PIXCLKCR 0x28
|
||||
#define SCFG_PIXCLKCR_PXCEN BIT(31)
|
||||
|
||||
#define VF610_LAYER_REG_NUM 9
|
||||
#define LS1021A_LAYER_REG_NUM 10
|
||||
|
||||
|
||||
@@ -206,15 +206,13 @@ int dcss_crtc_init(struct dcss_crtc *crtc, struct drm_device *drm)
|
||||
if (crtc->irq < 0)
|
||||
return crtc->irq;
|
||||
|
||||
ret = request_irq(crtc->irq, dcss_crtc_irq_handler,
|
||||
0, "dcss_drm", crtc);
|
||||
ret = request_irq(crtc->irq, dcss_crtc_irq_handler, IRQF_NO_AUTOEN,
|
||||
"dcss_drm", crtc);
|
||||
if (ret) {
|
||||
dev_err(dcss->dev, "irq request failed with %d.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
disable_irq(crtc->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -410,14 +410,12 @@ static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
|
||||
}
|
||||
|
||||
ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
|
||||
ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
|
||||
"imx_drm", ipu_crtc);
|
||||
ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler,
|
||||
IRQF_NO_AUTOEN, "imx_drm", ipu_crtc);
|
||||
if (ret < 0) {
|
||||
dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
/* Only enable IRQ when we actually need it to trigger work. */
|
||||
disable_irq(ipu_crtc->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ config DRM_MSM
|
||||
select SHMEM
|
||||
select TMPFS
|
||||
select QCOM_SCM
|
||||
select DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
select WANT_DEV_COREDUMP
|
||||
select SND_SOC_HDMI_CODEC if SND_SOC
|
||||
select SYNC_FILE
|
||||
|
||||
@@ -1462,15 +1462,13 @@ static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
|
||||
|
||||
irq = platform_get_irq_byname(pdev, name);
|
||||
|
||||
ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu);
|
||||
ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, name, gmu);
|
||||
if (ret) {
|
||||
DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n",
|
||||
name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
disable_irq(irq);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
||||
|
||||
@@ -2056,7 +2056,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
|
||||
* to cause power supply issues:
|
||||
*/
|
||||
if (adreno_is_a618(adreno_gpu) || adreno_is_7c3(adreno_gpu))
|
||||
gpu->clamp_to_idle = true;
|
||||
priv->gpu_clamp_to_idle = true;
|
||||
|
||||
/* Check if there is a GMU phandle and set it up */
|
||||
node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0);
|
||||
|
||||
@@ -80,7 +80,7 @@ static u64 _dpu_core_perf_calc_clk(struct dpu_kms *kms,
|
||||
|
||||
mode = &state->adjusted_mode;
|
||||
|
||||
crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
|
||||
crtc_clk = (u64)mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
|
||||
|
||||
drm_atomic_crtc_for_each_plane(plane, crtc) {
|
||||
pstate = to_dpu_plane_state(plane->state);
|
||||
|
||||
@@ -305,6 +305,7 @@ void msm_debugfs_init(struct drm_minor *minor)
|
||||
{
|
||||
struct drm_device *dev = minor->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct dentry *gpu_devfreq;
|
||||
|
||||
drm_debugfs_create_files(msm_debugfs_list,
|
||||
ARRAY_SIZE(msm_debugfs_list),
|
||||
@@ -325,6 +326,17 @@ void msm_debugfs_init(struct drm_minor *minor)
|
||||
debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root,
|
||||
dev, &shrink_fops);
|
||||
|
||||
gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root);
|
||||
|
||||
debugfs_create_bool("idle_clamp",0600, gpu_devfreq,
|
||||
&priv->gpu_clamp_to_idle);
|
||||
|
||||
debugfs_create_u32("upthreshold",0600, gpu_devfreq,
|
||||
&priv->gpu_devfreq_config.upthreshold);
|
||||
|
||||
debugfs_create_u32("downdifferential",0600, gpu_devfreq,
|
||||
&priv->gpu_devfreq_config.downdifferential);
|
||||
|
||||
if (priv->kms && priv->kms->funcs->debugfs_init)
|
||||
priv->kms->funcs->debugfs_init(priv->kms, minor);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/component.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -233,6 +234,14 @@ struct msm_drm_private {
|
||||
*/
|
||||
unsigned int hangcheck_period;
|
||||
|
||||
/** gpu_devfreq_config: Devfreq tuning config for the GPU. */
|
||||
struct devfreq_simple_ondemand_data gpu_devfreq_config;
|
||||
|
||||
/**
|
||||
* gpu_clamp_to_idle: Enable clamping to idle freq when inactive
|
||||
*/
|
||||
bool gpu_clamp_to_idle;
|
||||
|
||||
/**
|
||||
* disable_err_irq:
|
||||
*
|
||||
|
||||
@@ -109,11 +109,15 @@ struct msm_gpu_devfreq {
|
||||
struct mutex lock;
|
||||
|
||||
/**
|
||||
* idle_constraint:
|
||||
* idle_freq:
|
||||
*
|
||||
* A PM QoS constraint to limit max freq while the GPU is idle.
|
||||
* Shadow frequency used while the GPU is idle. From the PoV of
|
||||
* the devfreq governor, we are continuing to sample busyness and
|
||||
* adjust frequency while the GPU is idle, but we use this shadow
|
||||
* value as the GPU is actually clamped to minimum frequency while
|
||||
* it is inactive.
|
||||
*/
|
||||
struct dev_pm_qos_request idle_freq;
|
||||
unsigned long idle_freq;
|
||||
|
||||
/**
|
||||
* boost_constraint:
|
||||
@@ -135,8 +139,6 @@ struct msm_gpu_devfreq {
|
||||
/** idle_time: Time of last transition to idle: */
|
||||
ktime_t idle_time;
|
||||
|
||||
struct devfreq_dev_status average_status;
|
||||
|
||||
/**
|
||||
* idle_work:
|
||||
*
|
||||
@@ -275,9 +277,6 @@ struct msm_gpu {
|
||||
|
||||
struct msm_gpu_state *crashstate;
|
||||
|
||||
/* Enable clamping to idle freq when inactive: */
|
||||
bool clamp_to_idle;
|
||||
|
||||
/* True if the hardware supports expanded apriv (a650 and newer) */
|
||||
bool hw_apriv;
|
||||
|
||||
|
||||
@@ -33,6 +33,16 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
|
||||
|
||||
trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp));
|
||||
|
||||
/*
|
||||
* If the GPU is idle, devfreq is not aware, so just stash
|
||||
* the new target freq (to use when we return to active)
|
||||
*/
|
||||
if (df->idle_freq) {
|
||||
df->idle_freq = *freq;
|
||||
dev_pm_opp_put(opp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gpu->funcs->gpu_set_freq) {
|
||||
mutex_lock(&df->lock);
|
||||
gpu->funcs->gpu_set_freq(gpu, opp, df->suspended);
|
||||
@@ -48,15 +58,26 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq,
|
||||
|
||||
static unsigned long get_freq(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
|
||||
/*
|
||||
* If the GPU is idle, use the shadow/saved freq to avoid
|
||||
* confusing devfreq (which is unaware that we are switching
|
||||
* to lowest freq until the device is active again)
|
||||
*/
|
||||
if (df->idle_freq)
|
||||
return df->idle_freq;
|
||||
|
||||
if (gpu->funcs->gpu_get_freq)
|
||||
return gpu->funcs->gpu_get_freq(gpu);
|
||||
|
||||
return clk_get_rate(gpu->core_clk);
|
||||
}
|
||||
|
||||
static void get_raw_dev_status(struct msm_gpu *gpu,
|
||||
static int msm_devfreq_get_dev_status(struct device *dev,
|
||||
struct devfreq_dev_status *status)
|
||||
{
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
u64 busy_cycles, busy_time;
|
||||
unsigned long sample_rate;
|
||||
@@ -72,7 +93,7 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
|
||||
if (df->suspended) {
|
||||
mutex_unlock(&df->lock);
|
||||
status->busy_time = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
|
||||
@@ -87,71 +108,6 @@ static void get_raw_dev_status(struct msm_gpu *gpu,
|
||||
busy_time = ~0LU;
|
||||
|
||||
status->busy_time = busy_time;
|
||||
}
|
||||
|
||||
static void update_average_dev_status(struct msm_gpu *gpu,
|
||||
const struct devfreq_dev_status *raw)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
const u32 polling_ms = df->devfreq->profile->polling_ms;
|
||||
const u32 max_history_ms = polling_ms * 11 / 10;
|
||||
struct devfreq_dev_status *avg = &df->average_status;
|
||||
u64 avg_freq;
|
||||
|
||||
/* simple_ondemand governor interacts poorly with gpu->clamp_to_idle.
|
||||
* When we enforce the constraint on idle, it calls get_dev_status
|
||||
* which would normally reset the stats. When we remove the
|
||||
* constraint on active, it calls get_dev_status again where busy_time
|
||||
* would be 0.
|
||||
*
|
||||
* To remedy this, we always return the average load over the past
|
||||
* polling_ms.
|
||||
*/
|
||||
|
||||
/* raw is longer than polling_ms or avg has no history */
|
||||
if (div_u64(raw->total_time, USEC_PER_MSEC) >= polling_ms ||
|
||||
!avg->total_time) {
|
||||
*avg = *raw;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Truncate the oldest history first.
|
||||
*
|
||||
* Because we keep the history with a single devfreq_dev_status,
|
||||
* rather than a list of devfreq_dev_status, we have to assume freq
|
||||
* and load are the same over avg->total_time. We can scale down
|
||||
* avg->busy_time and avg->total_time by the same factor to drop
|
||||
* history.
|
||||
*/
|
||||
if (div_u64(avg->total_time + raw->total_time, USEC_PER_MSEC) >=
|
||||
max_history_ms) {
|
||||
const u32 new_total_time = polling_ms * USEC_PER_MSEC -
|
||||
raw->total_time;
|
||||
avg->busy_time = div_u64(
|
||||
mul_u32_u32(avg->busy_time, new_total_time),
|
||||
avg->total_time);
|
||||
avg->total_time = new_total_time;
|
||||
}
|
||||
|
||||
/* compute the average freq over avg->total_time + raw->total_time */
|
||||
avg_freq = mul_u32_u32(avg->current_frequency, avg->total_time);
|
||||
avg_freq += mul_u32_u32(raw->current_frequency, raw->total_time);
|
||||
do_div(avg_freq, avg->total_time + raw->total_time);
|
||||
|
||||
avg->current_frequency = avg_freq;
|
||||
avg->busy_time += raw->busy_time;
|
||||
avg->total_time += raw->total_time;
|
||||
}
|
||||
|
||||
static int msm_devfreq_get_dev_status(struct device *dev,
|
||||
struct devfreq_dev_status *status)
|
||||
{
|
||||
struct msm_gpu *gpu = dev_to_gpu(dev);
|
||||
struct devfreq_dev_status raw;
|
||||
|
||||
get_raw_dev_status(gpu, &raw);
|
||||
update_average_dev_status(gpu, &raw);
|
||||
*status = gpu->devfreq.average_status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -183,6 +139,8 @@ static bool has_devfreq(struct msm_gpu *gpu)
|
||||
void msm_devfreq_init(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
struct msm_drm_private *priv = gpu->dev->dev_private;
|
||||
int ret;
|
||||
|
||||
/* We need target support to do devfreq */
|
||||
if (!gpu->funcs->gpu_busy)
|
||||
@@ -190,11 +148,12 @@ void msm_devfreq_init(struct msm_gpu *gpu)
|
||||
|
||||
mutex_init(&df->lock);
|
||||
|
||||
dev_pm_qos_add_request(&gpu->pdev->dev, &df->idle_freq,
|
||||
DEV_PM_QOS_MAX_FREQUENCY,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
|
||||
DEV_PM_QOS_MIN_FREQUENCY, 0);
|
||||
ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
|
||||
DEV_PM_QOS_MIN_FREQUENCY, 0);
|
||||
if (ret < 0) {
|
||||
DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize QoS\n");
|
||||
return;
|
||||
}
|
||||
|
||||
msm_devfreq_profile.initial_freq = gpu->fast_rate;
|
||||
|
||||
@@ -209,11 +168,10 @@ void msm_devfreq_init(struct msm_gpu *gpu)
|
||||
|
||||
df->devfreq = devm_devfreq_add_device(&gpu->pdev->dev,
|
||||
&msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND,
|
||||
NULL);
|
||||
&priv->gpu_devfreq_config);
|
||||
|
||||
if (IS_ERR(df->devfreq)) {
|
||||
DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n");
|
||||
dev_pm_qos_remove_request(&df->idle_freq);
|
||||
dev_pm_qos_remove_request(&df->boost_freq);
|
||||
df->devfreq = NULL;
|
||||
return;
|
||||
@@ -255,7 +213,6 @@ void msm_devfreq_cleanup(struct msm_gpu *gpu)
|
||||
|
||||
devfreq_cooling_unregister(gpu->cooling);
|
||||
dev_pm_qos_remove_request(&df->boost_freq);
|
||||
dev_pm_qos_remove_request(&df->idle_freq);
|
||||
}
|
||||
|
||||
void msm_devfreq_resume(struct msm_gpu *gpu)
|
||||
@@ -328,6 +285,7 @@ void msm_devfreq_active(struct msm_gpu *gpu)
|
||||
{
|
||||
struct msm_gpu_devfreq *df = &gpu->devfreq;
|
||||
unsigned int idle_time;
|
||||
unsigned long target_freq;
|
||||
|
||||
if (!has_devfreq(gpu))
|
||||
return;
|
||||
@@ -337,8 +295,28 @@ void msm_devfreq_active(struct msm_gpu *gpu)
|
||||
*/
|
||||
cancel_idle_work(df);
|
||||
|
||||
/*
|
||||
* Hold devfreq lock to synchronize with get_dev_status()/
|
||||
* target() callbacks
|
||||
*/
|
||||
mutex_lock(&df->devfreq->lock);
|
||||
|
||||
target_freq = df->idle_freq;
|
||||
|
||||
idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time));
|
||||
|
||||
df->idle_freq = 0;
|
||||
|
||||
/*
|
||||
* We could have become active again before the idle work had a
|
||||
* chance to run, in which case the df->idle_freq would have
|
||||
* still been zero. In this case, no need to change freq.
|
||||
*/
|
||||
if (target_freq)
|
||||
msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
|
||||
|
||||
mutex_unlock(&df->devfreq->lock);
|
||||
|
||||
/*
|
||||
* If we've been idle for a significant fraction of a polling
|
||||
* interval, then we won't meet the threshold of busyness for
|
||||
@@ -347,9 +325,6 @@ void msm_devfreq_active(struct msm_gpu *gpu)
|
||||
if (idle_time > msm_devfreq_profile.polling_ms) {
|
||||
msm_devfreq_boost(gpu, 2);
|
||||
}
|
||||
|
||||
dev_pm_qos_update_request(&df->idle_freq,
|
||||
PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -358,11 +333,24 @@ static void msm_devfreq_idle_work(struct kthread_work *work)
|
||||
struct msm_gpu_devfreq *df = container_of(work,
|
||||
struct msm_gpu_devfreq, idle_work.work);
|
||||
struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);
|
||||
struct msm_drm_private *priv = gpu->dev->dev_private;
|
||||
unsigned long idle_freq, target_freq = 0;
|
||||
|
||||
/*
|
||||
* Hold devfreq lock to synchronize with get_dev_status()/
|
||||
* target() callbacks
|
||||
*/
|
||||
mutex_lock(&df->devfreq->lock);
|
||||
|
||||
idle_freq = get_freq(gpu);
|
||||
|
||||
if (priv->gpu_clamp_to_idle)
|
||||
msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
|
||||
|
||||
df->idle_time = ktime_get();
|
||||
df->idle_freq = idle_freq;
|
||||
|
||||
if (gpu->clamp_to_idle)
|
||||
dev_pm_qos_update_request(&df->idle_freq, 0);
|
||||
mutex_unlock(&df->devfreq->lock);
|
||||
}
|
||||
|
||||
void msm_devfreq_idle(struct msm_gpu *gpu)
|
||||
|
||||
@@ -139,21 +139,13 @@ static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
|
||||
}
|
||||
|
||||
int omapdss_device_connect(struct dss_device *dss,
|
||||
struct omap_dss_device *src,
|
||||
struct omap_dss_device *dst)
|
||||
{
|
||||
dev_dbg(&dss->pdev->dev, "connect(%s, %s)\n",
|
||||
src ? dev_name(src->dev) : "NULL",
|
||||
dev_dbg(&dss->pdev->dev, "connect(%s)\n",
|
||||
dst ? dev_name(dst->dev) : "NULL");
|
||||
|
||||
if (!dst) {
|
||||
/*
|
||||
* The destination is NULL when the source is connected to a
|
||||
* bridge instead of a DSS device. Stop here, we will attach
|
||||
* the bridge later when we will have a DRM encoder.
|
||||
*/
|
||||
return src && src->bridge ? 0 : -EINVAL;
|
||||
}
|
||||
if (!dst)
|
||||
return -EINVAL;
|
||||
|
||||
if (omapdss_device_is_connected(dst))
|
||||
return -EBUSY;
|
||||
@@ -163,19 +155,14 @@ int omapdss_device_connect(struct dss_device *dss,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omapdss_device_disconnect(struct omap_dss_device *src,
|
||||
void omapdss_device_disconnect(struct dss_device *dss,
|
||||
struct omap_dss_device *dst)
|
||||
{
|
||||
struct dss_device *dss = src ? src->dss : dst->dss;
|
||||
|
||||
dev_dbg(&dss->pdev->dev, "disconnect(%s, %s)\n",
|
||||
src ? dev_name(src->dev) : "NULL",
|
||||
dev_dbg(&dss->pdev->dev, "disconnect(%s)\n",
|
||||
dst ? dev_name(dst->dev) : "NULL");
|
||||
|
||||
if (!dst) {
|
||||
WARN_ON(!src->bridge);
|
||||
if (WARN_ON(!dst))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dst->id && !omapdss_device_is_connected(dst)) {
|
||||
WARN_ON(1);
|
||||
|
||||
@@ -242,9 +242,8 @@ struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev);
|
||||
void omapdss_device_put(struct omap_dss_device *dssdev);
|
||||
struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node);
|
||||
int omapdss_device_connect(struct dss_device *dss,
|
||||
struct omap_dss_device *src,
|
||||
struct omap_dss_device *dst);
|
||||
void omapdss_device_disconnect(struct omap_dss_device *src,
|
||||
void omapdss_device_disconnect(struct dss_device *dss,
|
||||
struct omap_dss_device *dst);
|
||||
|
||||
int omap_dss_get_num_overlay_managers(void);
|
||||
|
||||
@@ -307,7 +307,7 @@ static void omap_disconnect_pipelines(struct drm_device *ddev)
|
||||
for (i = 0; i < priv->num_pipes; i++) {
|
||||
struct omap_drm_pipeline *pipe = &priv->pipes[i];
|
||||
|
||||
omapdss_device_disconnect(NULL, pipe->output);
|
||||
omapdss_device_disconnect(priv->dss, pipe->output);
|
||||
|
||||
omapdss_device_put(pipe->output);
|
||||
pipe->output = NULL;
|
||||
@@ -325,7 +325,7 @@ static int omap_connect_pipelines(struct drm_device *ddev)
|
||||
int r;
|
||||
|
||||
for_each_dss_output(output) {
|
||||
r = omapdss_device_connect(priv->dss, NULL, output);
|
||||
r = omapdss_device_connect(priv->dss, output);
|
||||
if (r == -EPROBE_DEFER) {
|
||||
omapdss_device_put(output);
|
||||
return r;
|
||||
|
||||
@@ -1407,8 +1407,6 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
|
||||
|
||||
omap_obj = to_omap_bo(obj);
|
||||
|
||||
mutex_lock(&omap_obj->lock);
|
||||
|
||||
omap_obj->sgt = sgt;
|
||||
|
||||
if (sgt->orig_nents == 1) {
|
||||
@@ -1423,21 +1421,17 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size,
|
||||
pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
|
||||
if (!pages) {
|
||||
omap_gem_free_object(obj);
|
||||
obj = ERR_PTR(-ENOMEM);
|
||||
goto done;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
omap_obj->pages = pages;
|
||||
ret = drm_prime_sg_to_page_array(sgt, pages, npages);
|
||||
if (ret) {
|
||||
omap_gem_free_object(obj);
|
||||
obj = ERR_PTR(-ENOMEM);
|
||||
goto done;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&omap_obj->lock);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,6 @@ static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev)
|
||||
struct panfrost_model {
|
||||
const char *name;
|
||||
u32 id;
|
||||
u32 id_mask;
|
||||
u64 features;
|
||||
u64 issues;
|
||||
struct {
|
||||
|
||||
@@ -34,32 +34,23 @@ static int v3d_mmu_flush_all(struct v3d_dev *v3d)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Make sure that another flush isn't already running when we
|
||||
* start this one.
|
||||
*/
|
||||
ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
|
||||
V3D_MMU_CTL_TLB_CLEARING), 100);
|
||||
if (ret)
|
||||
dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n");
|
||||
V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH |
|
||||
V3D_MMUC_CONTROL_ENABLE);
|
||||
|
||||
ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
|
||||
V3D_MMUC_CONTROL_FLUSHING), 100);
|
||||
if (ret) {
|
||||
dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
|
||||
V3D_MMU_CTL_TLB_CLEAR);
|
||||
|
||||
V3D_WRITE(V3D_MMUC_CONTROL,
|
||||
V3D_MMUC_CONTROL_FLUSH |
|
||||
V3D_MMUC_CONTROL_ENABLE);
|
||||
|
||||
ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
|
||||
V3D_MMU_CTL_TLB_CLEARING), 100);
|
||||
if (ret) {
|
||||
dev_err(v3d->drm.dev, "TLB clear wait idle failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
|
||||
V3D_MMUC_CONTROL_FLUSHING), 100);
|
||||
if (ret)
|
||||
dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
|
||||
dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -323,6 +323,7 @@ struct vc4_hvs {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *regs;
|
||||
u32 __iomem *dlist;
|
||||
unsigned int dlist_mem_size;
|
||||
|
||||
struct clk *core_clk;
|
||||
|
||||
|
||||
@@ -170,6 +170,8 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
|
||||
if (!drm_dev_enter(drm, &idx))
|
||||
return -ENODEV;
|
||||
|
||||
WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
|
||||
|
||||
drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
|
||||
drm_print_regset32(&p, &vc4_hdmi->hd_regset);
|
||||
drm_print_regset32(&p, &vc4_hdmi->cec_regset);
|
||||
@@ -179,6 +181,8 @@ static int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused)
|
||||
drm_print_regset32(&p, &vc4_hdmi->ram_regset);
|
||||
drm_print_regset32(&p, &vc4_hdmi->rm_regset);
|
||||
|
||||
pm_runtime_put(&vc4_hdmi->pdev->dev);
|
||||
|
||||
drm_dev_exit(idx);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -108,7 +108,8 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data)
|
||||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||
struct vc4_hvs *hvs = vc4->hvs;
|
||||
struct drm_printer p = drm_seq_file_printer(m);
|
||||
unsigned int next_entry_start = 0;
|
||||
unsigned int dlist_mem_size = hvs->dlist_mem_size;
|
||||
unsigned int next_entry_start;
|
||||
unsigned int i, j;
|
||||
u32 dlist_word, dispstat;
|
||||
|
||||
@@ -122,8 +123,9 @@ static int vc4_hvs_debugfs_dlist(struct seq_file *m, void *data)
|
||||
}
|
||||
|
||||
drm_printf(&p, "HVS chan %u:\n", i);
|
||||
next_entry_start = 0;
|
||||
|
||||
for (j = HVS_READ(SCALER_DISPLISTX(i)); j < 256; j++) {
|
||||
for (j = HVS_READ(SCALER_DISPLISTX(i)); j < dlist_mem_size; j++) {
|
||||
dlist_word = readl((u32 __iomem *)vc4->hvs->dlist + j);
|
||||
drm_printf(&p, "dlist: %02d: 0x%08x\n", j,
|
||||
dlist_word);
|
||||
@@ -220,6 +222,9 @@ static void vc4_hvs_lut_load(struct vc4_hvs *hvs,
|
||||
if (!drm_dev_enter(drm, &idx))
|
||||
return;
|
||||
|
||||
if (hvs->vc4->is_vc5)
|
||||
return;
|
||||
|
||||
/* The LUT memory is laid out with each HVS channel in order,
|
||||
* each of which takes 256 writes for R, 256 for G, then 256
|
||||
* for B.
|
||||
@@ -413,13 +418,11 @@ void vc4_hvs_stop_channel(struct vc4_hvs *hvs, unsigned int chan)
|
||||
if (!drm_dev_enter(drm, &idx))
|
||||
return;
|
||||
|
||||
if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE)
|
||||
if (!(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE))
|
||||
goto out;
|
||||
|
||||
HVS_WRITE(SCALER_DISPCTRLX(chan),
|
||||
HVS_READ(SCALER_DISPCTRLX(chan)) | SCALER_DISPCTRLX_RESET);
|
||||
HVS_WRITE(SCALER_DISPCTRLX(chan),
|
||||
HVS_READ(SCALER_DISPCTRLX(chan)) & ~SCALER_DISPCTRLX_ENABLE);
|
||||
HVS_WRITE(SCALER_DISPCTRLX(chan), SCALER_DISPCTRLX_RESET);
|
||||
HVS_WRITE(SCALER_DISPCTRLX(chan), 0);
|
||||
|
||||
/* Once we leave, the scaler should be disabled and its fifo empty. */
|
||||
WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET);
|
||||
@@ -823,9 +826,10 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
|
||||
* our 16K), since we don't want to scramble the screen when
|
||||
* transitioning from the firmware's boot setup to runtime.
|
||||
*/
|
||||
hvs->dlist_mem_size = (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END;
|
||||
drm_mm_init(&hvs->dlist_mm,
|
||||
HVS_BOOTLOADER_DLIST_END,
|
||||
(SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END);
|
||||
hvs->dlist_mem_size);
|
||||
|
||||
/* Set up the HVS LBM memory manager. We could have some more
|
||||
* complicated data structure that allowed reuse of LBM areas
|
||||
|
||||
@@ -3340,7 +3340,7 @@ static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp,
|
||||
wc->byte_len = orig_cqe->length;
|
||||
wc->qp = &gsi_qp->ib_qp;
|
||||
|
||||
wc->ex.imm_data = cpu_to_be32(le32_to_cpu(orig_cqe->immdata));
|
||||
wc->ex.imm_data = cpu_to_be32(orig_cqe->immdata);
|
||||
wc->src_qp = orig_cqe->src_qp;
|
||||
memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
|
||||
if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
|
||||
@@ -3476,7 +3476,10 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc)
|
||||
(unsigned long)(cqe->qp_handle),
|
||||
struct bnxt_re_qp, qplib_qp);
|
||||
wc->qp = &qp->ib_qp;
|
||||
wc->ex.imm_data = cpu_to_be32(le32_to_cpu(cqe->immdata));
|
||||
if (cqe->flags & CQ_RES_RC_FLAGS_IMM)
|
||||
wc->ex.imm_data = cpu_to_be32(cqe->immdata);
|
||||
else
|
||||
wc->ex.invalidate_rkey = cqe->invrkey;
|
||||
wc->src_qp = cqe->src_qp;
|
||||
memcpy(wc->smac, cqe->smac, ETH_ALEN);
|
||||
wc->port_num = 1;
|
||||
|
||||
@@ -374,7 +374,7 @@ struct bnxt_qplib_cqe {
|
||||
u16 cfa_meta;
|
||||
u64 wr_id;
|
||||
union {
|
||||
__le32 immdata;
|
||||
u32 immdata;
|
||||
u32 invrkey;
|
||||
};
|
||||
u64 qp_handle;
|
||||
|
||||
@@ -180,8 +180,8 @@ static void free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq)
|
||||
ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_CQC,
|
||||
hr_cq->cqn);
|
||||
if (ret)
|
||||
dev_err(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n", ret,
|
||||
hr_cq->cqn);
|
||||
dev_err_ratelimited(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n",
|
||||
ret, hr_cq->cqn);
|
||||
|
||||
xa_erase_irq(&cq_table->array, hr_cq->cqn);
|
||||
|
||||
|
||||
@@ -1228,6 +1228,7 @@ void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn);
|
||||
void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type);
|
||||
void flush_cqe(struct hns_roce_dev *dev, struct hns_roce_qp *qp);
|
||||
void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type);
|
||||
void hns_roce_flush_cqe(struct hns_roce_dev *hr_dev, u32 qpn);
|
||||
void hns_roce_srq_event(struct hns_roce_dev *hr_dev, u32 srqn, int event_type);
|
||||
u8 hns_get_gid_index(struct hns_roce_dev *hr_dev, u32 port, int gid_index);
|
||||
void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev);
|
||||
|
||||
@@ -337,7 +337,7 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_mhop *mhop,
|
||||
struct hns_roce_hem_index *index)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long mhop_obj = obj;
|
||||
u32 l0_idx, l1_idx, l2_idx;
|
||||
u32 chunk_ba_num;
|
||||
@@ -368,14 +368,14 @@ static int calc_hem_config(struct hns_roce_dev *hr_dev,
|
||||
index->buf = l0_idx;
|
||||
break;
|
||||
default:
|
||||
ibdev_err(ibdev, "table %u not support mhop.hop_num = %u!\n",
|
||||
table->type, mhop->hop_num);
|
||||
dev_err(dev, "table %u not support mhop.hop_num = %u!\n",
|
||||
table->type, mhop->hop_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(index->buf >= table->num_hem)) {
|
||||
ibdev_err(ibdev, "table %u exceed hem limt idx %llu, max %lu!\n",
|
||||
table->type, index->buf, table->num_hem);
|
||||
dev_err(dev, "table %u exceed hem limt idx %llu, max %lu!\n",
|
||||
table->type, index->buf, table->num_hem);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -487,14 +487,14 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_mhop *mhop,
|
||||
struct hns_roce_hem_index *index)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct device *dev = hr_dev->dev;
|
||||
u32 step_idx;
|
||||
int ret = 0;
|
||||
|
||||
if (index->inited & HEM_INDEX_L0) {
|
||||
ret = hr_dev->hw->set_hem(hr_dev, table, obj, 0);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "set HEM step 0 failed!\n");
|
||||
dev_err(dev, "set HEM step 0 failed!\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -502,7 +502,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,
|
||||
if (index->inited & HEM_INDEX_L1) {
|
||||
ret = hr_dev->hw->set_hem(hr_dev, table, obj, 1);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "set HEM step 1 failed!\n");
|
||||
dev_err(dev, "set HEM step 1 failed!\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -514,7 +514,7 @@ static int set_mhop_hem(struct hns_roce_dev *hr_dev,
|
||||
step_idx = mhop->hop_num;
|
||||
ret = hr_dev->hw->set_hem(hr_dev, table, obj, step_idx);
|
||||
if (ret)
|
||||
ibdev_err(ibdev, "set HEM step last failed!\n");
|
||||
dev_err(dev, "set HEM step last failed!\n");
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
@@ -524,14 +524,14 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_table *table,
|
||||
unsigned long obj)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct hns_roce_hem_index index = {};
|
||||
struct hns_roce_hem_mhop mhop = {};
|
||||
struct device *dev = hr_dev->dev;
|
||||
int ret;
|
||||
|
||||
ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "calc hem config failed!\n");
|
||||
dev_err(dev, "calc hem config failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -543,7 +543,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
||||
|
||||
ret = alloc_mhop_hem(hr_dev, table, &mhop, &index);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "alloc mhop hem failed!\n");
|
||||
dev_err(dev, "alloc mhop hem failed!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -551,7 +551,7 @@ static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
|
||||
if (table->type < HEM_TYPE_MTT) {
|
||||
ret = set_mhop_hem(hr_dev, table, obj, &mhop, &index);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "set HEM address to HW failed!\n");
|
||||
dev_err(dev, "set HEM address to HW failed!\n");
|
||||
goto err_alloc;
|
||||
}
|
||||
}
|
||||
@@ -615,10 +615,11 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_hem_mhop *mhop,
|
||||
struct hns_roce_hem_index *index)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct device *dev = hr_dev->dev;
|
||||
u32 hop_num = mhop->hop_num;
|
||||
u32 chunk_ba_num;
|
||||
u32 step_idx;
|
||||
int ret;
|
||||
|
||||
index->inited = HEM_INDEX_BUF;
|
||||
chunk_ba_num = mhop->bt_chunk_size / BA_BYTE_LEN;
|
||||
@@ -642,16 +643,24 @@ static void clear_mhop_hem(struct hns_roce_dev *hr_dev,
|
||||
else
|
||||
step_idx = hop_num;
|
||||
|
||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, step_idx))
|
||||
ibdev_warn(ibdev, "failed to clear hop%u HEM.\n", hop_num);
|
||||
ret = hr_dev->hw->clear_hem(hr_dev, table, obj, step_idx);
|
||||
if (ret)
|
||||
dev_warn(dev, "failed to clear hop%u HEM, ret = %d.\n",
|
||||
hop_num, ret);
|
||||
|
||||
if (index->inited & HEM_INDEX_L1)
|
||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
|
||||
ibdev_warn(ibdev, "failed to clear HEM step 1.\n");
|
||||
if (index->inited & HEM_INDEX_L1) {
|
||||
ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 1);
|
||||
if (ret)
|
||||
dev_warn(dev, "failed to clear HEM step 1, ret = %d.\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
if (index->inited & HEM_INDEX_L0)
|
||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
|
||||
ibdev_warn(ibdev, "failed to clear HEM step 0.\n");
|
||||
if (index->inited & HEM_INDEX_L0) {
|
||||
ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 0);
|
||||
if (ret)
|
||||
dev_warn(dev, "failed to clear HEM step 0, ret = %d.\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,14 +669,14 @@ static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
|
||||
unsigned long obj,
|
||||
int check_refcount)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct hns_roce_hem_index index = {};
|
||||
struct hns_roce_hem_mhop mhop = {};
|
||||
struct device *dev = hr_dev->dev;
|
||||
int ret;
|
||||
|
||||
ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "calc hem config failed!\n");
|
||||
dev_err(dev, "calc hem config failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -688,6 +697,7 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long i;
|
||||
int ret;
|
||||
|
||||
if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
|
||||
hns_roce_table_mhop_put(hr_dev, table, obj, 1);
|
||||
@@ -700,8 +710,10 @@ void hns_roce_table_put(struct hns_roce_dev *hr_dev,
|
||||
&table->mutex))
|
||||
return;
|
||||
|
||||
if (hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT))
|
||||
dev_warn(dev, "failed to clear HEM base address.\n");
|
||||
ret = hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT);
|
||||
if (ret)
|
||||
dev_warn_ratelimited(dev, "failed to clear HEM base address, ret = %d.\n",
|
||||
ret);
|
||||
|
||||
hns_roce_free_hem(hr_dev, table->hem[i]);
|
||||
table->hem[i] = NULL;
|
||||
@@ -917,6 +929,8 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
unsigned long i;
|
||||
int obj;
|
||||
int ret;
|
||||
|
||||
if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
|
||||
hns_roce_cleanup_mhop_hem_table(hr_dev, table);
|
||||
@@ -925,9 +939,11 @@ void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
|
||||
|
||||
for (i = 0; i < table->num_hem; ++i)
|
||||
if (table->hem[i]) {
|
||||
if (hr_dev->hw->clear_hem(hr_dev, table,
|
||||
i * table->table_chunk_size / table->obj_size, 0))
|
||||
dev_err(dev, "clear HEM base address failed.\n");
|
||||
obj = i * table->table_chunk_size / table->obj_size;
|
||||
ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 0);
|
||||
if (ret)
|
||||
dev_err(dev, "clear HEM base address failed, ret = %d.\n",
|
||||
ret);
|
||||
|
||||
hns_roce_free_hem(hr_dev, table->hem[i]);
|
||||
}
|
||||
|
||||
@@ -372,26 +372,12 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,
|
||||
static int check_send_valid(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct ib_qp *ibqp = &hr_qp->ibqp;
|
||||
|
||||
if (unlikely(ibqp->qp_type != IB_QPT_RC &&
|
||||
ibqp->qp_type != IB_QPT_GSI &&
|
||||
ibqp->qp_type != IB_QPT_UD)) {
|
||||
ibdev_err(ibdev, "not supported QP(0x%x)type!\n",
|
||||
ibqp->qp_type);
|
||||
return -EOPNOTSUPP;
|
||||
} else if (unlikely(hr_qp->state == IB_QPS_RESET ||
|
||||
hr_qp->state == IB_QPS_INIT ||
|
||||
hr_qp->state == IB_QPS_RTR)) {
|
||||
ibdev_err(ibdev, "failed to post WQE, QP state %u!\n",
|
||||
hr_qp->state);
|
||||
if (unlikely(hr_qp->state == IB_QPS_RESET ||
|
||||
hr_qp->state == IB_QPS_INIT ||
|
||||
hr_qp->state == IB_QPS_RTR))
|
||||
return -EINVAL;
|
||||
} else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN)) {
|
||||
ibdev_err(ibdev, "failed to post WQE, dev state %d!\n",
|
||||
hr_dev->state);
|
||||
else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -777,17 +763,6 @@ out:
|
||||
static int check_recv_valid(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_qp *hr_qp)
|
||||
{
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
struct ib_qp *ibqp = &hr_qp->ibqp;
|
||||
|
||||
if (unlikely(ibqp->qp_type != IB_QPT_RC &&
|
||||
ibqp->qp_type != IB_QPT_GSI &&
|
||||
ibqp->qp_type != IB_QPT_UD)) {
|
||||
ibdev_err(ibdev, "unsupported qp type, qp_type = %d.\n",
|
||||
ibqp->qp_type);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN))
|
||||
return -EIO;
|
||||
|
||||
@@ -2863,8 +2838,8 @@ static int free_mr_modify_rsv_qp(struct hns_roce_dev *hr_dev,
|
||||
ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
|
||||
IB_QPS_INIT);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n",
|
||||
ret);
|
||||
ibdev_err_ratelimited(ibdev, "failed to modify qp to init, ret = %d.\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3510,8 +3485,8 @@ static int free_mr_post_send_lp_wqe(struct hns_roce_qp *hr_qp)
|
||||
|
||||
ret = hns_roce_v2_post_send(&hr_qp->ibqp, send_wr, &bad_wr);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to post wqe for free mr, ret = %d.\n",
|
||||
ret);
|
||||
ibdev_err_ratelimited(ibdev, "failed to post wqe for free mr, ret = %d.\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3550,9 +3525,9 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
|
||||
|
||||
ret = free_mr_post_send_lp_wqe(hr_qp);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev,
|
||||
"failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
ibdev_err_ratelimited(ibdev,
|
||||
"failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3563,16 +3538,16 @@ static void free_mr_send_cmd_to_hw(struct hns_roce_dev *hr_dev)
|
||||
while (cqe_cnt) {
|
||||
npolled = hns_roce_v2_poll_cq(&free_mr->rsv_cq->ib_cq, cqe_cnt, wc);
|
||||
if (npolled < 0) {
|
||||
ibdev_err(ibdev,
|
||||
"failed to poll cqe for free mr, remain %d cqe.\n",
|
||||
cqe_cnt);
|
||||
ibdev_err_ratelimited(ibdev,
|
||||
"failed to poll cqe for free mr, remain %d cqe.\n",
|
||||
cqe_cnt);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (time_after(jiffies, end)) {
|
||||
ibdev_err(ibdev,
|
||||
"failed to poll cqe for free mr and timeout, remain %d cqe.\n",
|
||||
cqe_cnt);
|
||||
ibdev_err_ratelimited(ibdev,
|
||||
"failed to poll cqe for free mr and timeout, remain %d cqe.\n",
|
||||
cqe_cnt);
|
||||
goto out;
|
||||
}
|
||||
cqe_cnt -= npolled;
|
||||
@@ -5143,10 +5118,8 @@ static int hns_roce_v2_set_abs_fields(struct ib_qp *ibqp,
|
||||
struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
|
||||
int ret = 0;
|
||||
|
||||
if (!check_qp_state(cur_state, new_state)) {
|
||||
ibdev_err(&hr_dev->ib_dev, "Illegal state for QP!\n");
|
||||
if (!check_qp_state(cur_state, new_state))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
||||
memset(qpc_mask, 0, hr_dev->caps.qpc_sz);
|
||||
@@ -5408,7 +5381,7 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp,
|
||||
/* SW pass context to HW */
|
||||
ret = hns_roce_v2_qp_modify(hr_dev, context, qpc_mask, hr_qp);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to modify QP, ret = %d.\n", ret);
|
||||
ibdev_err_ratelimited(ibdev, "failed to modify QP, ret = %d.\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5498,7 +5471,9 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
|
||||
|
||||
ret = hns_roce_v2_query_qpc(hr_dev, hr_qp->qpn, &context);
|
||||
if (ret) {
|
||||
ibdev_err(ibdev, "failed to query QPC, ret = %d.\n", ret);
|
||||
ibdev_err_ratelimited(ibdev,
|
||||
"failed to query QPC, ret = %d.\n",
|
||||
ret);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -5506,7 +5481,7 @@ static int hns_roce_v2_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
|
||||
state = hr_reg_read(&context, QPC_QP_ST);
|
||||
tmp_qp_state = to_ib_qp_st((enum hns_roce_v2_qp_state)state);
|
||||
if (tmp_qp_state == -1) {
|
||||
ibdev_err(ibdev, "Illegal ib_qp_state\n");
|
||||
ibdev_err_ratelimited(ibdev, "Illegal ib_qp_state\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -5599,9 +5574,9 @@ static int hns_roce_v2_destroy_qp_common(struct hns_roce_dev *hr_dev,
|
||||
ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, NULL, 0,
|
||||
hr_qp->state, IB_QPS_RESET);
|
||||
if (ret)
|
||||
ibdev_err(ibdev,
|
||||
"failed to modify QP to RST, ret = %d.\n",
|
||||
ret);
|
||||
ibdev_err_ratelimited(ibdev,
|
||||
"failed to modify QP to RST, ret = %d.\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
send_cq = hr_qp->ibqp.send_cq ? to_hr_cq(hr_qp->ibqp.send_cq) : NULL;
|
||||
@@ -5637,9 +5612,9 @@ int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
|
||||
|
||||
ret = hns_roce_v2_destroy_qp_common(hr_dev, hr_qp, udata);
|
||||
if (ret)
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"failed to destroy QP, QPN = 0x%06lx, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
ibdev_err_ratelimited(&hr_dev->ib_dev,
|
||||
"failed to destroy QP, QPN = 0x%06lx, ret = %d.\n",
|
||||
hr_qp->qpn, ret);
|
||||
|
||||
hns_roce_qp_destroy(hr_dev, hr_qp, udata);
|
||||
|
||||
@@ -5912,9 +5887,9 @@ static int hns_roce_v2_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
|
||||
HNS_ROCE_CMD_MODIFY_CQC, hr_cq->cqn);
|
||||
hns_roce_free_cmd_mailbox(hr_dev, mailbox);
|
||||
if (ret)
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"failed to process cmd when modifying CQ, ret = %d.\n",
|
||||
ret);
|
||||
ibdev_err_ratelimited(&hr_dev->ib_dev,
|
||||
"failed to process cmd when modifying CQ, ret = %d.\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -5934,9 +5909,9 @@ static int hns_roce_v2_query_cqc(struct hns_roce_dev *hr_dev, u32 cqn,
|
||||
ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma,
|
||||
HNS_ROCE_CMD_QUERY_CQC, cqn);
|
||||
if (ret) {
|
||||
ibdev_err(&hr_dev->ib_dev,
|
||||
"failed to process cmd when querying CQ, ret = %d.\n",
|
||||
ret);
|
||||
ibdev_err_ratelimited(&hr_dev->ib_dev,
|
||||
"failed to process cmd when querying CQ, ret = %d.\n",
|
||||
ret);
|
||||
goto err_mailbox;
|
||||
}
|
||||
|
||||
@@ -5977,11 +5952,10 @@ err_mailbox:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hns_roce_irq_work_handle(struct work_struct *work)
|
||||
static void dump_aeqe_log(struct hns_roce_work *irq_work)
|
||||
{
|
||||
struct hns_roce_work *irq_work =
|
||||
container_of(work, struct hns_roce_work, work);
|
||||
struct ib_device *ibdev = &irq_work->hr_dev->ib_dev;
|
||||
struct hns_roce_dev *hr_dev = irq_work->hr_dev;
|
||||
struct ib_device *ibdev = &hr_dev->ib_dev;
|
||||
|
||||
switch (irq_work->event_type) {
|
||||
case HNS_ROCE_EVENT_TYPE_PATH_MIG:
|
||||
@@ -6025,6 +5999,8 @@ static void hns_roce_irq_work_handle(struct work_struct *work)
|
||||
case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
|
||||
ibdev_warn(ibdev, "DB overflow.\n");
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_MB:
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_FLR:
|
||||
ibdev_warn(ibdev, "function level reset.\n");
|
||||
break;
|
||||
@@ -6035,8 +6011,46 @@ static void hns_roce_irq_work_handle(struct work_struct *work)
|
||||
ibdev_err(ibdev, "invalid xrceth error.\n");
|
||||
break;
|
||||
default:
|
||||
ibdev_info(ibdev, "Undefined event %d.\n",
|
||||
irq_work->event_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void hns_roce_irq_work_handle(struct work_struct *work)
|
||||
{
|
||||
struct hns_roce_work *irq_work =
|
||||
container_of(work, struct hns_roce_work, work);
|
||||
struct hns_roce_dev *hr_dev = irq_work->hr_dev;
|
||||
int event_type = irq_work->event_type;
|
||||
u32 queue_num = irq_work->queue_num;
|
||||
|
||||
switch (event_type) {
|
||||
case HNS_ROCE_EVENT_TYPE_PATH_MIG:
|
||||
case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
|
||||
case HNS_ROCE_EVENT_TYPE_COMM_EST:
|
||||
case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
|
||||
case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
|
||||
case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION:
|
||||
case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
|
||||
hns_roce_qp_event(hr_dev, queue_num, event_type);
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
|
||||
case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
|
||||
hns_roce_srq_event(hr_dev, queue_num, event_type);
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
|
||||
hns_roce_cq_event(hr_dev, queue_num, event_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
dump_aeqe_log(irq_work);
|
||||
|
||||
kfree(irq_work);
|
||||
}
|
||||
@@ -6097,14 +6111,14 @@ static struct hns_roce_aeqe *next_aeqe_sw_v2(struct hns_roce_eq *eq)
|
||||
static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
|
||||
struct hns_roce_eq *eq)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_aeqe *aeqe = next_aeqe_sw_v2(eq);
|
||||
irqreturn_t aeqe_found = IRQ_NONE;
|
||||
int num_aeqes = 0;
|
||||
int event_type;
|
||||
u32 queue_num;
|
||||
int sub_type;
|
||||
|
||||
while (aeqe) {
|
||||
while (aeqe && num_aeqes < HNS_AEQ_POLLING_BUDGET) {
|
||||
/* Make sure we read AEQ entry after we have checked the
|
||||
* ownership bit
|
||||
*/
|
||||
@@ -6115,25 +6129,12 @@ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
|
||||
queue_num = hr_reg_read(aeqe, AEQE_EVENT_QUEUE_NUM);
|
||||
|
||||
switch (event_type) {
|
||||
case HNS_ROCE_EVENT_TYPE_PATH_MIG:
|
||||
case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
|
||||
case HNS_ROCE_EVENT_TYPE_COMM_EST:
|
||||
case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
|
||||
case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
|
||||
case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION:
|
||||
case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
|
||||
hns_roce_qp_event(hr_dev, queue_num, event_type);
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
|
||||
case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
|
||||
hns_roce_srq_event(hr_dev, queue_num, event_type);
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
|
||||
case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
|
||||
hns_roce_cq_event(hr_dev, queue_num, event_type);
|
||||
hns_roce_flush_cqe(hr_dev, queue_num);
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_MB:
|
||||
hns_roce_cmd_event(hr_dev,
|
||||
@@ -6141,12 +6142,7 @@ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
|
||||
aeqe->event.cmd.status,
|
||||
le64_to_cpu(aeqe->event.cmd.out_param));
|
||||
break;
|
||||
case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
|
||||
case HNS_ROCE_EVENT_TYPE_FLR:
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "unhandled event %d on EQ %d at idx %u.\n",
|
||||
event_type, eq->eqn, eq->cons_index);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6158,6 +6154,7 @@ static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
|
||||
hns_roce_v2_init_irq_work(hr_dev, eq, queue_num);
|
||||
|
||||
aeqe = next_aeqe_sw_v2(eq);
|
||||
++num_aeqes;
|
||||
}
|
||||
|
||||
update_eq_db(eq);
|
||||
@@ -6687,6 +6684,9 @@ static int hns_roce_v2_init_eq_table(struct hns_roce_dev *hr_dev)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (hr_dev->caps.aeqe_depth < HNS_AEQ_POLLING_BUDGET)
|
||||
return -EINVAL;
|
||||
|
||||
other_num = hr_dev->caps.num_other_vectors;
|
||||
comp_num = hr_dev->caps.num_comp_vectors;
|
||||
aeq_num = hr_dev->caps.num_aeq_vectors;
|
||||
|
||||
@@ -114,6 +114,11 @@
|
||||
|
||||
#define HNS_ROCE_V2_TABLE_CHUNK_SIZE (1 << 18)
|
||||
|
||||
/* budget must be smaller than aeqe_depth to guarantee that we update
|
||||
* the ci before we polled all the entries in the EQ.
|
||||
*/
|
||||
#define HNS_AEQ_POLLING_BUDGET 64
|
||||
|
||||
enum {
|
||||
HNS_ROCE_CMD_FLAG_IN = BIT(0),
|
||||
HNS_ROCE_CMD_FLAG_OUT = BIT(1),
|
||||
|
||||
@@ -130,8 +130,8 @@ static void hns_roce_mr_free(struct hns_roce_dev *hr_dev, struct hns_roce_mr *mr
|
||||
key_to_hw_index(mr->key) &
|
||||
(hr_dev->caps.num_mtpts - 1));
|
||||
if (ret)
|
||||
ibdev_warn(ibdev, "failed to destroy mpt, ret = %d.\n",
|
||||
ret);
|
||||
ibdev_warn_ratelimited(ibdev, "failed to destroy mpt, ret = %d.\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
free_mr_pbl(hr_dev, mr);
|
||||
|
||||
@@ -39,6 +39,25 @@
|
||||
#include "hns_roce_device.h"
|
||||
#include "hns_roce_hem.h"
|
||||
|
||||
static struct hns_roce_qp *hns_roce_qp_lookup(struct hns_roce_dev *hr_dev,
|
||||
u32 qpn)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_qp *qp;
|
||||
unsigned long flags;
|
||||
|
||||
xa_lock_irqsave(&hr_dev->qp_table_xa, flags);
|
||||
qp = __hns_roce_qp_lookup(hr_dev, qpn);
|
||||
if (qp)
|
||||
refcount_inc(&qp->refcount);
|
||||
xa_unlock_irqrestore(&hr_dev->qp_table_xa, flags);
|
||||
|
||||
if (!qp)
|
||||
dev_warn(dev, "async event for bogus QP %08x\n", qpn);
|
||||
|
||||
return qp;
|
||||
}
|
||||
|
||||
static void flush_work_handle(struct work_struct *work)
|
||||
{
|
||||
struct hns_roce_work *flush_work = container_of(work,
|
||||
@@ -95,29 +114,11 @@ void flush_cqe(struct hns_roce_dev *dev, struct hns_roce_qp *qp)
|
||||
|
||||
void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
|
||||
{
|
||||
struct device *dev = hr_dev->dev;
|
||||
struct hns_roce_qp *qp;
|
||||
|
||||
xa_lock(&hr_dev->qp_table_xa);
|
||||
qp = __hns_roce_qp_lookup(hr_dev, qpn);
|
||||
if (qp)
|
||||
refcount_inc(&qp->refcount);
|
||||
xa_unlock(&hr_dev->qp_table_xa);
|
||||
|
||||
if (!qp) {
|
||||
dev_warn(dev, "async event for bogus QP %08x\n", qpn);
|
||||
qp = hns_roce_qp_lookup(hr_dev, qpn);
|
||||
if (!qp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (event_type == HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR ||
|
||||
event_type == HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR ||
|
||||
event_type == HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR ||
|
||||
event_type == HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION ||
|
||||
event_type == HNS_ROCE_EVENT_TYPE_INVALID_XRCETH) {
|
||||
qp->state = IB_QPS_ERR;
|
||||
|
||||
flush_cqe(hr_dev, qp);
|
||||
}
|
||||
|
||||
qp->event(qp, (enum hns_roce_event)event_type);
|
||||
|
||||
@@ -125,6 +126,21 @@ void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
|
||||
complete(&qp->free);
|
||||
}
|
||||
|
||||
void hns_roce_flush_cqe(struct hns_roce_dev *hr_dev, u32 qpn)
|
||||
{
|
||||
struct hns_roce_qp *qp;
|
||||
|
||||
qp = hns_roce_qp_lookup(hr_dev, qpn);
|
||||
if (!qp)
|
||||
return;
|
||||
|
||||
qp->state = IB_QPS_ERR;
|
||||
flush_cqe(hr_dev, qp);
|
||||
|
||||
if (refcount_dec_and_test(&qp->refcount))
|
||||
complete(&qp->free);
|
||||
}
|
||||
|
||||
static void hns_roce_ib_qp_event(struct hns_roce_qp *hr_qp,
|
||||
enum hns_roce_event type)
|
||||
{
|
||||
|
||||
@@ -150,8 +150,8 @@ static void free_srqc(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
|
||||
ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_SRQ,
|
||||
srq->srqn);
|
||||
if (ret)
|
||||
dev_err(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n",
|
||||
ret, srq->srqn);
|
||||
dev_err_ratelimited(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n",
|
||||
ret, srq->srqn);
|
||||
|
||||
xa_erase_irq(&srq_table->xa, srq->srqn);
|
||||
|
||||
|
||||
@@ -831,14 +831,15 @@ static void pgtable_walk(struct intel_iommu *iommu, unsigned long pfn,
|
||||
while (1) {
|
||||
offset = pfn_level_offset(pfn, level);
|
||||
pte = &parent[offset];
|
||||
if (!pte || (dma_pte_superpage(pte) || !dma_pte_present(pte))) {
|
||||
pr_info("PTE not present at level %d\n", level);
|
||||
break;
|
||||
}
|
||||
|
||||
pr_info("pte level: %d, pte value: 0x%016llx\n", level, pte->val);
|
||||
|
||||
if (level == 1)
|
||||
if (!dma_pte_present(pte)) {
|
||||
pr_info("page table not present at level %d\n", level - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (level == 1 || dma_pte_superpage(pte))
|
||||
break;
|
||||
|
||||
parent = phys_to_virt(dma_pte_addr(pte));
|
||||
@@ -861,11 +862,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
|
||||
pr_info("Dump %s table entries for IOVA 0x%llx\n", iommu->name, addr);
|
||||
|
||||
/* root entry dump */
|
||||
rt_entry = &iommu->root_entry[bus];
|
||||
if (!rt_entry) {
|
||||
pr_info("root table entry is not present\n");
|
||||
if (!iommu->root_entry) {
|
||||
pr_info("root table is not present\n");
|
||||
return;
|
||||
}
|
||||
rt_entry = &iommu->root_entry[bus];
|
||||
|
||||
if (sm_supported(iommu))
|
||||
pr_info("scalable mode root entry: hi 0x%016llx, low 0x%016llx\n",
|
||||
@@ -876,7 +877,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
|
||||
/* context entry dump */
|
||||
ctx_entry = iommu_context_addr(iommu, bus, devfn, 0);
|
||||
if (!ctx_entry) {
|
||||
pr_info("context table entry is not present\n");
|
||||
pr_info("context table is not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -885,17 +886,23 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
|
||||
|
||||
/* legacy mode does not require PASID entries */
|
||||
if (!sm_supported(iommu)) {
|
||||
if (!context_present(ctx_entry)) {
|
||||
pr_info("legacy mode page table is not present\n");
|
||||
return;
|
||||
}
|
||||
level = agaw_to_level(ctx_entry->hi & 7);
|
||||
pgtable = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
|
||||
goto pgtable_walk;
|
||||
}
|
||||
|
||||
/* get the pointer to pasid directory entry */
|
||||
dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
|
||||
if (!dir) {
|
||||
pr_info("pasid directory entry is not present\n");
|
||||
if (!context_present(ctx_entry)) {
|
||||
pr_info("pasid directory table is not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the pointer to pasid directory entry */
|
||||
dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
|
||||
|
||||
/* For request-without-pasid, get the pasid from context entry */
|
||||
if (intel_iommu_sm && pasid == INVALID_IOASID)
|
||||
pasid = PASID_RID2PASID;
|
||||
@@ -907,7 +914,7 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
|
||||
/* get the pointer to the pasid table entry */
|
||||
entries = get_pasid_table_from_pde(pde);
|
||||
if (!entries) {
|
||||
pr_info("pasid table entry is not present\n");
|
||||
pr_info("pasid table is not present\n");
|
||||
return;
|
||||
}
|
||||
index = pasid & PASID_PTE_MASK;
|
||||
@@ -915,6 +922,11 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 source_id,
|
||||
for (i = 0; i < ARRAY_SIZE(pte->val); i++)
|
||||
pr_info("pasid table entry[%d]: 0x%016llx\n", i, pte->val[i]);
|
||||
|
||||
if (!pasid_pte_is_present(pte)) {
|
||||
pr_info("scalable mode page table is not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pasid_pte_get_pgtt(pte) == PASID_ENTRY_PGTT_FL_ONLY) {
|
||||
level = pte->val[2] & BIT_ULL(2) ? 5 : 4;
|
||||
pgtable = phys_to_virt(pte->val[2] & VTD_PAGE_MASK);
|
||||
|
||||
@@ -299,16 +299,17 @@ static void rpcif_rzg2l_timing_adjust_sdr(struct rpcif_priv *rpc)
|
||||
regmap_write(rpc->regmap, RPCIF_PHYADD, 0x80000032);
|
||||
}
|
||||
|
||||
int rpcif_hw_init(struct rpcif *rpcif, bool hyperflash)
|
||||
int rpcif_hw_init(struct device *dev, bool hyperflash)
|
||||
{
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(dev);
|
||||
u32 dummy;
|
||||
int ret;
|
||||
|
||||
pm_runtime_get_sync(rpc->dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (rpc->type == RPCIF_RZ_G2L) {
|
||||
int ret;
|
||||
|
||||
ret = reset_control_reset(rpc->rstc);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -354,7 +355,7 @@ int rpcif_hw_init(struct rpcif *rpcif, bool hyperflash)
|
||||
regmap_write(rpc->regmap, RPCIF_SSLDR, RPCIF_SSLDR_SPNDL(7) |
|
||||
RPCIF_SSLDR_SLNDL(7) | RPCIF_SSLDR_SCKDL(7));
|
||||
|
||||
pm_runtime_put(rpc->dev);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
rpc->bus_size = hyperflash ? 2 : 1;
|
||||
|
||||
@@ -384,10 +385,10 @@ static u8 rpcif_bit_size(u8 buswidth)
|
||||
return buswidth > 4 ? 2 : ilog2(buswidth);
|
||||
}
|
||||
|
||||
void rpcif_prepare(struct rpcif *rpcif, const struct rpcif_op *op, u64 *offs,
|
||||
void rpcif_prepare(struct device *dev, const struct rpcif_op *op, u64 *offs,
|
||||
size_t *len)
|
||||
{
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(dev);
|
||||
|
||||
rpc->smcr = 0;
|
||||
rpc->smadr = 0;
|
||||
@@ -472,13 +473,15 @@ void rpcif_prepare(struct rpcif *rpcif, const struct rpcif_op *op, u64 *offs,
|
||||
}
|
||||
EXPORT_SYMBOL(rpcif_prepare);
|
||||
|
||||
int rpcif_manual_xfer(struct rpcif *rpcif)
|
||||
int rpcif_manual_xfer(struct device *dev)
|
||||
{
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(dev);
|
||||
u32 smenr, smcr, pos = 0, max = rpc->bus_size == 2 ? 8 : 4;
|
||||
int ret = 0;
|
||||
|
||||
pm_runtime_get_sync(rpc->dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
regmap_update_bits(rpc->regmap, RPCIF_PHYCNT,
|
||||
RPCIF_PHYCNT_CAL, RPCIF_PHYCNT_CAL);
|
||||
@@ -588,13 +591,13 @@ int rpcif_manual_xfer(struct rpcif *rpcif)
|
||||
}
|
||||
|
||||
exit:
|
||||
pm_runtime_put(rpc->dev);
|
||||
pm_runtime_put(dev);
|
||||
return ret;
|
||||
|
||||
err_out:
|
||||
if (reset_control_reset(rpc->rstc))
|
||||
dev_err(rpc->dev, "Failed to reset HW\n");
|
||||
rpcif_hw_init(rpcif, rpc->bus_size == 2);
|
||||
dev_err(dev, "Failed to reset HW\n");
|
||||
rpcif_hw_init(dev, rpc->bus_size == 2);
|
||||
goto exit;
|
||||
}
|
||||
EXPORT_SYMBOL(rpcif_manual_xfer);
|
||||
@@ -641,16 +644,19 @@ static void memcpy_fromio_readw(void *to,
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t rpcif_dirmap_read(struct rpcif *rpcif, u64 offs, size_t len, void *buf)
|
||||
ssize_t rpcif_dirmap_read(struct device *dev, u64 offs, size_t len, void *buf)
|
||||
{
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(rpcif->dev);
|
||||
struct rpcif_priv *rpc = dev_get_drvdata(dev);
|
||||
loff_t from = offs & (rpc->size - 1);
|
||||
size_t size = rpc->size - from;
|
||||
int ret;
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
pm_runtime_get_sync(rpc->dev);
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
regmap_update_bits(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_MD, 0);
|
||||
regmap_write(rpc->regmap, RPCIF_DRCR, 0);
|
||||
@@ -668,7 +674,7 @@ ssize_t rpcif_dirmap_read(struct rpcif *rpcif, u64 offs, size_t len, void *buf)
|
||||
else
|
||||
memcpy_fromio(buf, rpc->dirmap + from, len);
|
||||
|
||||
pm_runtime_put(rpc->dev);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -4234,10 +4234,8 @@ mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num,
|
||||
static void
|
||||
mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
sdev->no_uld_attach = data ? 1 : 0;
|
||||
rc = scsi_device_reprobe(sdev);
|
||||
WARN_ON(scsi_device_reprobe(sdev));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -37,7 +37,7 @@ static int da9052_spi_probe(struct spi_device *spi)
|
||||
spi_set_drvdata(spi, da9052);
|
||||
|
||||
config = da9052_regmap_config;
|
||||
config.read_flag_mask = 1;
|
||||
config.write_flag_mask = 1;
|
||||
config.reg_bits = 7;
|
||||
config.pad_bits = 1;
|
||||
config.val_bits = 8;
|
||||
|
||||
@@ -231,16 +231,46 @@ static const struct resource tmu_resources[] = {
|
||||
};
|
||||
|
||||
static struct mfd_cell bxt_wc_dev[] = {
|
||||
{
|
||||
.name = "bxt_wcove_gpadc",
|
||||
.num_resources = ARRAY_SIZE(adc_resources),
|
||||
.resources = adc_resources,
|
||||
},
|
||||
{
|
||||
.name = "bxt_wcove_thermal",
|
||||
.num_resources = ARRAY_SIZE(thermal_resources),
|
||||
.resources = thermal_resources,
|
||||
},
|
||||
{
|
||||
.name = "bxt_wcove_gpio",
|
||||
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||
.resources = gpio_resources,
|
||||
},
|
||||
{
|
||||
.name = "bxt_wcove_region",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell bxt_wc_tmu_dev[] = {
|
||||
{
|
||||
.name = "bxt_wcove_tmu",
|
||||
.num_resources = ARRAY_SIZE(tmu_resources),
|
||||
.resources = tmu_resources,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell bxt_wc_bcu_dev[] = {
|
||||
{
|
||||
.name = "bxt_wcove_bcu",
|
||||
.num_resources = ARRAY_SIZE(bcu_resources),
|
||||
.resources = bcu_resources,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell bxt_wc_adc_dev[] = {
|
||||
{
|
||||
.name = "bxt_wcove_gpadc",
|
||||
.num_resources = ARRAY_SIZE(adc_resources),
|
||||
.resources = adc_resources,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell bxt_wc_chgr_dev[] = {
|
||||
{
|
||||
.name = "bxt_wcove_usbc",
|
||||
.num_resources = ARRAY_SIZE(usbc_resources),
|
||||
@@ -251,25 +281,6 @@ static struct mfd_cell bxt_wc_dev[] = {
|
||||
.num_resources = ARRAY_SIZE(charger_resources),
|
||||
.resources = charger_resources,
|
||||
},
|
||||
{
|
||||
.name = "bxt_wcove_bcu",
|
||||
.num_resources = ARRAY_SIZE(bcu_resources),
|
||||
.resources = bcu_resources,
|
||||
},
|
||||
{
|
||||
.name = "bxt_wcove_tmu",
|
||||
.num_resources = ARRAY_SIZE(tmu_resources),
|
||||
.resources = tmu_resources,
|
||||
},
|
||||
|
||||
{
|
||||
.name = "bxt_wcove_gpio",
|
||||
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||
.resources = gpio_resources,
|
||||
},
|
||||
{
|
||||
.name = "bxt_wcove_region",
|
||||
},
|
||||
};
|
||||
|
||||
static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
|
||||
@@ -426,6 +437,26 @@ static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
|
||||
0, chip, data);
|
||||
}
|
||||
|
||||
static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic,
|
||||
const struct mfd_cell *cells, int n_devs,
|
||||
struct regmap_irq_chip_data *pdata,
|
||||
int pirq, int irq_flags,
|
||||
const struct regmap_irq_chip *chip,
|
||||
struct regmap_irq_chip_data **data)
|
||||
{
|
||||
struct device *dev = pmic->dev;
|
||||
struct irq_domain *domain;
|
||||
int ret;
|
||||
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
|
||||
|
||||
domain = regmap_irq_get_domain(*data);
|
||||
|
||||
return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain);
|
||||
}
|
||||
|
||||
static int bxtwc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -467,6 +498,15 @@ static int bxtwc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
|
||||
|
||||
ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev),
|
||||
pmic->irq_chip_data,
|
||||
BXTWC_TMU_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_tmu,
|
||||
&pmic->irq_chip_data_tmu);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_PWRBTN_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
@@ -475,40 +515,32 @@ static int bxtwc_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
|
||||
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_TMU_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_tmu,
|
||||
&pmic->irq_chip_data_tmu);
|
||||
ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev),
|
||||
pmic->irq_chip_data,
|
||||
BXTWC_BCU_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_bcu,
|
||||
&pmic->irq_chip_data_bcu);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
|
||||
return ret;
|
||||
|
||||
/* Add chained IRQ handler for BCU IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_BCU_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_bcu,
|
||||
&pmic->irq_chip_data_bcu);
|
||||
ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev),
|
||||
pmic->irq_chip_data,
|
||||
BXTWC_ADC_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_adc,
|
||||
&pmic->irq_chip_data_adc);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
|
||||
return ret;
|
||||
|
||||
/* Add chained IRQ handler for ADC IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_ADC_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_adc,
|
||||
&pmic->irq_chip_data_adc);
|
||||
ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev),
|
||||
pmic->irq_chip_data,
|
||||
BXTWC_CHGR_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_chgr,
|
||||
&pmic->irq_chip_data_chgr);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
|
||||
|
||||
/* Add chained IRQ handler for CHGR IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
BXTWC_CHGR_LVL1_IRQ,
|
||||
IRQF_ONESHOT,
|
||||
&bxtwc_regmap_irq_chip_chgr,
|
||||
&pmic->irq_chip_data_chgr);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
|
||||
return ret;
|
||||
|
||||
/* Add chained IRQ handler for CRIT IRQs */
|
||||
ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
|
||||
|
||||
@@ -82,8 +82,8 @@ static int rt5033_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id);
|
||||
|
||||
ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap,
|
||||
rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
0, &rt5033_irq_chip, &rt5033->irq_data);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
|
||||
|
||||
@@ -548,17 +548,13 @@ static int tps65010_probe(struct i2c_client *client,
|
||||
*/
|
||||
if (client->irq > 0) {
|
||||
status = request_irq(client->irq, tps65010_irq,
|
||||
IRQF_TRIGGER_FALLING, DRIVER_NAME, tps);
|
||||
IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
|
||||
DRIVER_NAME, tps);
|
||||
if (status < 0) {
|
||||
dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
|
||||
client->irq, status);
|
||||
return status;
|
||||
}
|
||||
/* annoying race here, ideally we'd have an option
|
||||
* to claim the irq now and enable it later.
|
||||
* FIXME genirq IRQF_NOAUTOEN now solves that ...
|
||||
*/
|
||||
disable_irq(client->irq);
|
||||
set_bit(FLAG_IRQ_ENABLE, &tps->flags);
|
||||
} else
|
||||
dev_warn(&client->dev, "IRQ not configured!\n");
|
||||
|
||||
@@ -56,7 +56,7 @@ static void rpcif_hb_prepare_read(struct rpcif *rpc, void *to,
|
||||
op.data.nbytes = len;
|
||||
op.data.buf.in = to;
|
||||
|
||||
rpcif_prepare(rpc, &op, NULL, NULL);
|
||||
rpcif_prepare(rpc->dev, &op, NULL, NULL);
|
||||
}
|
||||
|
||||
static void rpcif_hb_prepare_write(struct rpcif *rpc, unsigned long to,
|
||||
@@ -70,7 +70,7 @@ static void rpcif_hb_prepare_write(struct rpcif *rpc, unsigned long to,
|
||||
op.data.nbytes = len;
|
||||
op.data.buf.out = from;
|
||||
|
||||
rpcif_prepare(rpc, &op, NULL, NULL);
|
||||
rpcif_prepare(rpc->dev, &op, NULL, NULL);
|
||||
}
|
||||
|
||||
static u16 rpcif_hb_read16(struct hyperbus_device *hbdev, unsigned long addr)
|
||||
@@ -81,7 +81,7 @@ static u16 rpcif_hb_read16(struct hyperbus_device *hbdev, unsigned long addr)
|
||||
|
||||
rpcif_hb_prepare_read(&hyperbus->rpc, &data, addr, 2);
|
||||
|
||||
rpcif_manual_xfer(&hyperbus->rpc);
|
||||
rpcif_manual_xfer(hyperbus->rpc.dev);
|
||||
|
||||
return data.x[0];
|
||||
}
|
||||
@@ -94,7 +94,7 @@ static void rpcif_hb_write16(struct hyperbus_device *hbdev, unsigned long addr,
|
||||
|
||||
rpcif_hb_prepare_write(&hyperbus->rpc, addr, &data, 2);
|
||||
|
||||
rpcif_manual_xfer(&hyperbus->rpc);
|
||||
rpcif_manual_xfer(hyperbus->rpc.dev);
|
||||
}
|
||||
|
||||
static void rpcif_hb_copy_from(struct hyperbus_device *hbdev, void *to,
|
||||
@@ -105,7 +105,7 @@ static void rpcif_hb_copy_from(struct hyperbus_device *hbdev, void *to,
|
||||
|
||||
rpcif_hb_prepare_read(&hyperbus->rpc, to, from, len);
|
||||
|
||||
rpcif_dirmap_read(&hyperbus->rpc, from, len, to);
|
||||
rpcif_dirmap_read(hyperbus->rpc.dev, from, len, to);
|
||||
}
|
||||
|
||||
static const struct hyperbus_ops rpcif_hb_ops = {
|
||||
@@ -130,9 +130,9 @@ static int rpcif_hb_probe(struct platform_device *pdev)
|
||||
|
||||
platform_set_drvdata(pdev, hyperbus);
|
||||
|
||||
rpcif_enable_rpm(&hyperbus->rpc);
|
||||
pm_runtime_enable(hyperbus->rpc.dev);
|
||||
|
||||
error = rpcif_hw_init(&hyperbus->rpc, true);
|
||||
error = rpcif_hw_init(hyperbus->rpc.dev, true);
|
||||
if (error)
|
||||
goto out_disable_rpm;
|
||||
|
||||
@@ -150,24 +150,29 @@ static int rpcif_hb_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
out_disable_rpm:
|
||||
rpcif_disable_rpm(&hyperbus->rpc);
|
||||
pm_runtime_disable(hyperbus->rpc.dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int rpcif_hb_remove(struct platform_device *pdev)
|
||||
static void rpcif_hb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct rpcif_hyperbus *hyperbus = platform_get_drvdata(pdev);
|
||||
|
||||
hyperbus_unregister_device(&hyperbus->hbdev);
|
||||
|
||||
rpcif_disable_rpm(&hyperbus->rpc);
|
||||
|
||||
return 0;
|
||||
pm_runtime_disable(hyperbus->rpc.dev);
|
||||
}
|
||||
|
||||
static const struct platform_device_id rpc_if_hyperflash_id_table[] = {
|
||||
{ .name = "rpc-if-hyperflash" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, rpc_if_hyperflash_id_table);
|
||||
|
||||
static struct platform_driver rpcif_platform_driver = {
|
||||
.probe = rpcif_hb_probe,
|
||||
.remove = rpcif_hb_remove,
|
||||
.remove_new = rpcif_hb_remove,
|
||||
.id_table = rpc_if_hyperflash_id_table,
|
||||
.driver = {
|
||||
.name = "rpc-if-hyperflash",
|
||||
},
|
||||
|
||||
@@ -362,7 +362,7 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
size = ALIGN(size, sizeof(s32));
|
||||
size += (req->ecc.strength + 1) * sizeof(s32) * 3;
|
||||
|
||||
user = kzalloc(size, GFP_KERNEL);
|
||||
user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL);
|
||||
if (!user)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -408,12 +408,6 @@ atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_pmecc_create_user);
|
||||
|
||||
void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user)
|
||||
{
|
||||
kfree(user);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user);
|
||||
|
||||
static int get_strength(struct atmel_pmecc_user *user)
|
||||
{
|
||||
const int *strengths = user->pmecc->caps->strengths;
|
||||
|
||||
@@ -55,8 +55,6 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);
|
||||
struct atmel_pmecc_user *
|
||||
atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
|
||||
struct atmel_pmecc_user_req *req);
|
||||
void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
|
||||
|
||||
void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
|
||||
int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
|
||||
void atmel_pmecc_disable(struct atmel_pmecc_user *user);
|
||||
|
||||
@@ -201,6 +201,11 @@ int cn10k_alloc_leaf_profile(struct otx2_nic *pfvf, u16 *leaf)
|
||||
|
||||
rsp = (struct nix_bandprof_alloc_rsp *)
|
||||
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
rc = PTR_ERR(rsp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rsp->prof_count[BAND_PROF_LEAF_LAYER]) {
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
|
||||
@@ -1786,6 +1786,10 @@ u16 otx2_get_max_mtu(struct otx2_nic *pfvf)
|
||||
if (!rc) {
|
||||
rsp = (struct nix_hw_info *)
|
||||
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
rc = PTR_ERR(rsp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* HW counts VLAN insertion bytes (8 for double tag)
|
||||
* irrespective of whether SQE is requesting to insert VLAN
|
||||
|
||||
@@ -311,6 +311,11 @@ int otx2_config_priority_flow_ctrl(struct otx2_nic *pfvf)
|
||||
if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
|
||||
rsp = (struct cgx_pfc_rsp *)
|
||||
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
err = PTR_ERR(rsp);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (req->rx_pause != rsp->rx_pause || req->tx_pause != rsp->tx_pause) {
|
||||
dev_warn(pfvf->dev,
|
||||
"Failed to config PFC\n");
|
||||
|
||||
@@ -28,6 +28,11 @@ static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
|
||||
if (!err) {
|
||||
rsp = (struct cgx_mac_addr_add_rsp *)
|
||||
otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
mutex_unlock(&pf->mbox.lock);
|
||||
return PTR_ERR(rsp);
|
||||
}
|
||||
|
||||
*dmac_index = rsp->index;
|
||||
}
|
||||
|
||||
@@ -200,6 +205,10 @@ int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u32 bit_pos)
|
||||
|
||||
rsp = (struct cgx_mac_addr_update_rsp *)
|
||||
otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
rc = PTR_ERR(rsp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pf->flow_cfg->bmap_to_dmacindex[bit_pos] = rsp->index;
|
||||
|
||||
|
||||
@@ -333,6 +333,11 @@ static void otx2_get_pauseparam(struct net_device *netdev,
|
||||
if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
|
||||
rsp = (struct cgx_pause_frm_cfg *)
|
||||
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
mutex_unlock(&pfvf->mbox.lock);
|
||||
return;
|
||||
}
|
||||
|
||||
pause->rx_pause = rsp->rx_pause;
|
||||
pause->tx_pause = rsp->tx_pause;
|
||||
}
|
||||
@@ -1072,6 +1077,11 @@ static int otx2_set_fecparam(struct net_device *netdev,
|
||||
|
||||
rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
|
||||
0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
err = PTR_ERR(rsp);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rsp->fec >= 0)
|
||||
pfvf->linfo.fec = rsp->fec;
|
||||
else
|
||||
|
||||
@@ -121,6 +121,8 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count)
|
||||
|
||||
rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
|
||||
(&pfvf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp))
|
||||
goto exit;
|
||||
|
||||
for (ent = 0; ent < rsp->count; ent++)
|
||||
flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];
|
||||
@@ -199,6 +201,10 @@ static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
|
||||
|
||||
rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
|
||||
(&pfvf->mbox.mbox, 0, &req->hdr);
|
||||
if (IS_ERR(rsp)) {
|
||||
mutex_unlock(&pfvf->mbox.lock);
|
||||
return PTR_ERR(rsp);
|
||||
}
|
||||
|
||||
if (rsp->count != req->count) {
|
||||
netdev_info(pfvf->netdev,
|
||||
@@ -234,6 +240,10 @@ static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
|
||||
|
||||
frsp = (struct npc_get_field_status_rsp *)otx2_mbox_get_rsp
|
||||
(&pfvf->mbox.mbox, 0, &freq->hdr);
|
||||
if (IS_ERR(frsp)) {
|
||||
mutex_unlock(&pfvf->mbox.lock);
|
||||
return PTR_ERR(frsp);
|
||||
}
|
||||
|
||||
if (frsp->enable) {
|
||||
pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
|
||||
|
||||
@@ -171,14 +171,13 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
|
||||
if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN)
|
||||
sa.rx = true;
|
||||
|
||||
if (xs->props.family == AF_INET6)
|
||||
memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
|
||||
else
|
||||
memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
|
||||
}
|
||||
if (xs->props.family == AF_INET6)
|
||||
memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
|
||||
else
|
||||
memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
|
||||
|
||||
/* the preparations worked, so save the info */
|
||||
memcpy(&ipsec->sa[sa_idx], &sa, sizeof(sa));
|
||||
|
||||
@@ -9120,7 +9120,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss1[
|
||||
{6, {2633, 2925}, {1215, 1350}, {585, 650} },
|
||||
{7, {2925, 3250}, {1350, 1500}, {650, 722} },
|
||||
{8, {3510, 3900}, {1620, 1800}, {780, 867} },
|
||||
{9, {3900, 4333}, {1800, 2000}, {780, 867} }
|
||||
{9, {3900, 4333}, {1800, 2000}, {865, 960} }
|
||||
};
|
||||
|
||||
/*MCS parameters with Nss = 2 */
|
||||
@@ -9135,7 +9135,7 @@ static const struct ath10k_index_vht_data_rate_type supported_vht_mcs_rate_nss2[
|
||||
{6, {5265, 5850}, {2430, 2700}, {1170, 1300} },
|
||||
{7, {5850, 6500}, {2700, 3000}, {1300, 1444} },
|
||||
{8, {7020, 7800}, {3240, 3600}, {1560, 1733} },
|
||||
{9, {7800, 8667}, {3600, 4000}, {1560, 1733} }
|
||||
{9, {7800, 8667}, {3600, 4000}, {1730, 1920} }
|
||||
};
|
||||
|
||||
static void ath10k_mac_get_rate_flags_ht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs,
|
||||
|
||||
@@ -294,6 +294,9 @@ int htc_connect_service(struct htc_target *target,
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (target->conn_rsp_epid < 0 || target->conn_rsp_epid >= ENDPOINT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
*conn_rsp_epid = target->conn_rsp_epid;
|
||||
return 0;
|
||||
err:
|
||||
|
||||
@@ -623,7 +623,7 @@ static int p54spi_probe(struct spi_device *spi)
|
||||
gpio_direction_input(p54spi_gpio_irq);
|
||||
|
||||
ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
|
||||
p54spi_interrupt, 0, "p54spi",
|
||||
p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
|
||||
priv->spi);
|
||||
if (ret < 0) {
|
||||
dev_err(&priv->spi->dev, "request_irq() failed");
|
||||
@@ -632,8 +632,6 @@ static int p54spi_probe(struct spi_device *spi)
|
||||
|
||||
irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
|
||||
|
||||
disable_irq(gpio_to_irq(p54spi_gpio_irq));
|
||||
|
||||
INIT_WORK(&priv->work, p54spi_work);
|
||||
init_completion(&priv->fw_comp);
|
||||
INIT_LIST_HEAD(&priv->tx_pending);
|
||||
|
||||
@@ -842,7 +842,7 @@ struct mwifiex_ietypes_chanstats {
|
||||
struct mwifiex_ie_types_wildcard_ssid_params {
|
||||
struct mwifiex_ie_types_header header;
|
||||
u8 max_ssid_length;
|
||||
u8 ssid[1];
|
||||
u8 ssid[];
|
||||
} __packed;
|
||||
|
||||
#define TSF_DATA_SIZE 8
|
||||
|
||||
@@ -1638,7 +1638,8 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
|
||||
}
|
||||
|
||||
ret = devm_request_irq(dev, adapter->irq_wakeup,
|
||||
mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW,
|
||||
mwifiex_irq_wakeup_handler,
|
||||
IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
|
||||
"wifi_wake", adapter);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to request irq_wakeup %d (%d)\n",
|
||||
@@ -1646,7 +1647,6 @@ static void mwifiex_probe_of(struct mwifiex_adapter *adapter)
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
disable_irq(adapter->irq_wakeup);
|
||||
if (device_init_wakeup(dev, true)) {
|
||||
dev_err(dev, "fail to init wakeup for mwifiex\n");
|
||||
goto err_exit;
|
||||
|
||||
@@ -479,10 +479,23 @@ static int __init wfx_core_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SPI))
|
||||
if (IS_ENABLED(CONFIG_SPI)) {
|
||||
ret = spi_register_driver(&wfx_spi_driver);
|
||||
if (IS_ENABLED(CONFIG_MMC) && !ret)
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_MMC)) {
|
||||
ret = sdio_register_driver(&wfx_sdio_driver);
|
||||
if (ret)
|
||||
goto unregister_spi;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_spi:
|
||||
if (IS_ENABLED(CONFIG_SPI))
|
||||
spi_unregister_driver(&wfx_spi_driver);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
module_init(wfx_core_init);
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
* @name: Name of the pin mux function
|
||||
* @groups: List of pin groups for this function
|
||||
* @ngroups: Number of entries in @groups
|
||||
* @node: Firmware node matching with the function
|
||||
*
|
||||
* This structure holds information about pin control function
|
||||
* and function group names supporting that function.
|
||||
|
||||
@@ -48,9 +48,8 @@ static irqreturn_t bxt_wcove_tmu_irq_handler(int irq, void *data)
|
||||
static int bxt_wcove_tmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regmap_irq_chip_data *regmap_irq_chip;
|
||||
struct wcove_tmu *wctmu;
|
||||
int ret, virq, irq;
|
||||
int ret;
|
||||
|
||||
wctmu = devm_kzalloc(&pdev->dev, sizeof(*wctmu), GFP_KERNEL);
|
||||
if (!wctmu)
|
||||
@@ -59,27 +58,18 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev)
|
||||
wctmu->dev = &pdev->dev;
|
||||
wctmu->regmap = pmic->regmap;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
wctmu->irq = platform_get_irq(pdev, 0);
|
||||
if (wctmu->irq < 0)
|
||||
return wctmu->irq;
|
||||
|
||||
regmap_irq_chip = pmic->irq_chip_data_tmu;
|
||||
virq = regmap_irq_get_virq(regmap_irq_chip, irq);
|
||||
if (virq < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get virtual interrupt=%d\n", irq);
|
||||
return virq;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(&pdev->dev, virq,
|
||||
ret = devm_request_threaded_irq(&pdev->dev, wctmu->irq,
|
||||
NULL, bxt_wcove_tmu_irq_handler,
|
||||
IRQF_ONESHOT, "bxt_wcove_tmu", wctmu);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n",
|
||||
ret, virq);
|
||||
ret, wctmu->irq);
|
||||
return ret;
|
||||
}
|
||||
wctmu->irq = virq;
|
||||
|
||||
/* Unmask TMU second level Wake & System alarm */
|
||||
regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG,
|
||||
|
||||
@@ -1699,9 +1699,8 @@ bfad_init(void)
|
||||
|
||||
error = bfad_im_module_init();
|
||||
if (error) {
|
||||
error = -ENOMEM;
|
||||
printk(KERN_WARNING "bfad_im_module_init failure\n");
|
||||
goto ext;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (strcmp(FCPI_NAME, " fcpim") == 0)
|
||||
|
||||
@@ -2739,6 +2739,7 @@ static int qedf_alloc_and_init_sb(struct qedf_ctx *qedf,
|
||||
sb_id, QED_SB_TYPE_STORAGE);
|
||||
|
||||
if (ret) {
|
||||
dma_free_coherent(&qedf->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys);
|
||||
QEDF_ERR(&qedf->dbg_ctx,
|
||||
"Status block initialization failed (0x%x) for id = %d.\n",
|
||||
ret, sb_id);
|
||||
|
||||
@@ -369,6 +369,7 @@ static int qedi_alloc_and_init_sb(struct qedi_ctx *qedi,
|
||||
ret = qedi_ops->common->sb_init(qedi->cdev, sb_info, sb_virt, sb_phys,
|
||||
sb_id, QED_SB_TYPE_STORAGE);
|
||||
if (ret) {
|
||||
dma_free_coherent(&qedi->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys);
|
||||
QEDI_ERR(&qedi->dbg_ctx,
|
||||
"Status block initialization failed for id = %d.\n",
|
||||
sb_id);
|
||||
|
||||
@@ -58,7 +58,7 @@ static void rpcif_spi_mem_prepare(struct spi_device *spi_dev,
|
||||
rpc_op.data.dir = RPCIF_NO_DATA;
|
||||
}
|
||||
|
||||
rpcif_prepare(rpc, &rpc_op, offs, len);
|
||||
rpcif_prepare(rpc->dev, &rpc_op, offs, len);
|
||||
}
|
||||
|
||||
static bool rpcif_spi_mem_supports_op(struct spi_mem *mem,
|
||||
@@ -86,7 +86,7 @@ static ssize_t rpcif_spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc,
|
||||
|
||||
rpcif_spi_mem_prepare(desc->mem->spi, &desc->info.op_tmpl, &offs, &len);
|
||||
|
||||
return rpcif_dirmap_read(rpc, offs, len, buf);
|
||||
return rpcif_dirmap_read(rpc->dev, offs, len, buf);
|
||||
}
|
||||
|
||||
static int rpcif_spi_mem_dirmap_create(struct spi_mem_dirmap_desc *desc)
|
||||
@@ -117,7 +117,7 @@ static int rpcif_spi_mem_exec_op(struct spi_mem *mem,
|
||||
|
||||
rpcif_spi_mem_prepare(mem->spi, op, NULL, NULL);
|
||||
|
||||
return rpcif_manual_xfer(rpc);
|
||||
return rpcif_manual_xfer(rpc->dev);
|
||||
}
|
||||
|
||||
static const struct spi_controller_mem_ops rpcif_spi_mem_ops = {
|
||||
@@ -147,7 +147,7 @@ static int rpcif_spi_probe(struct platform_device *pdev)
|
||||
|
||||
ctlr->dev.of_node = parent->of_node;
|
||||
|
||||
rpcif_enable_rpm(rpc);
|
||||
pm_runtime_enable(rpc->dev);
|
||||
|
||||
ctlr->num_chipselect = 1;
|
||||
ctlr->mem_ops = &rpcif_spi_mem_ops;
|
||||
@@ -156,7 +156,7 @@ static int rpcif_spi_probe(struct platform_device *pdev)
|
||||
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_QUAD | SPI_RX_QUAD;
|
||||
ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
|
||||
|
||||
error = rpcif_hw_init(rpc, false);
|
||||
error = rpcif_hw_init(rpc->dev, false);
|
||||
if (error)
|
||||
goto out_disable_rpm;
|
||||
|
||||
@@ -169,7 +169,7 @@ static int rpcif_spi_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
out_disable_rpm:
|
||||
rpcif_disable_rpm(rpc);
|
||||
pm_runtime_disable(rpc->dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ static int rpcif_spi_remove(struct platform_device *pdev)
|
||||
struct rpcif *rpc = spi_controller_get_devdata(ctlr);
|
||||
|
||||
spi_unregister_controller(ctlr);
|
||||
rpcif_disable_rpm(rpc);
|
||||
pm_runtime_disable(rpc->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -621,10 +621,6 @@ static int wcove_typec_probe(struct platform_device *pdev)
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
irq = regmap_irq_get_virq(pmic->irq_chip_data_chgr, irq);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
||||
ret = guid_parse(WCOVE_DSM_UUID, &wcove->guid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -496,13 +496,13 @@ read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
|
||||
* the previous entry, search for a matching entry.
|
||||
*/
|
||||
if (!m || start < m->addr || start >= m->addr + m->size) {
|
||||
struct kcore_list *iter;
|
||||
struct kcore_list *pos;
|
||||
|
||||
m = NULL;
|
||||
list_for_each_entry(iter, &kclist_head, list) {
|
||||
if (start >= iter->addr &&
|
||||
start < iter->addr + iter->size) {
|
||||
m = iter;
|
||||
list_for_each_entry(pos, &kclist_head, list) {
|
||||
if (start >= pos->addr &&
|
||||
start < pos->addr + pos->size) {
|
||||
m = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ struct unicode_map *utf8_load(unsigned int version)
|
||||
return um;
|
||||
|
||||
out_symbol_put:
|
||||
symbol_put(um->tables);
|
||||
symbol_put(utf8_data_table);
|
||||
out_free_um:
|
||||
kfree(um);
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
@@ -71,7 +71,7 @@ static inline void *netpoll_poll_lock(struct napi_struct *napi)
|
||||
{
|
||||
struct net_device *dev = napi->dev;
|
||||
|
||||
if (dev && dev->npinfo) {
|
||||
if (dev && rcu_access_pointer(dev->npinfo)) {
|
||||
int owner = smp_processor_id();
|
||||
|
||||
while (cmpxchg(&napi->poll_owner, -1, owner) != -1)
|
||||
|
||||
@@ -13,6 +13,7 @@ struct nlmsghdr;
|
||||
struct sock;
|
||||
|
||||
struct sock_diag_handler {
|
||||
struct module *owner;
|
||||
__u8 family;
|
||||
int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh);
|
||||
int (*get_info)(struct sk_buff *skb, struct sock *sk);
|
||||
@@ -22,8 +23,13 @@ struct sock_diag_handler {
|
||||
int sock_diag_register(const struct sock_diag_handler *h);
|
||||
void sock_diag_unregister(const struct sock_diag_handler *h);
|
||||
|
||||
void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
|
||||
void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
|
||||
struct sock_diag_inet_compat {
|
||||
struct module *owner;
|
||||
int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh);
|
||||
};
|
||||
|
||||
void sock_diag_register_inet_compat(const struct sock_diag_inet_compat *ptr);
|
||||
void sock_diag_unregister_inet_compat(const struct sock_diag_inet_compat *ptr);
|
||||
|
||||
u64 __sock_gen_cookie(struct sock *sk);
|
||||
|
||||
|
||||
@@ -69,20 +69,10 @@ struct rpcif {
|
||||
};
|
||||
|
||||
int rpcif_sw_init(struct rpcif *rpc, struct device *dev);
|
||||
int rpcif_hw_init(struct rpcif *rpc, bool hyperflash);
|
||||
void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
|
||||
int rpcif_hw_init(struct device *dev, bool hyperflash);
|
||||
void rpcif_prepare(struct device *dev, const struct rpcif_op *op, u64 *offs,
|
||||
size_t *len);
|
||||
int rpcif_manual_xfer(struct rpcif *rpc);
|
||||
ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf);
|
||||
|
||||
static inline void rpcif_enable_rpm(struct rpcif *rpc)
|
||||
{
|
||||
pm_runtime_enable(rpc->dev);
|
||||
}
|
||||
|
||||
static inline void rpcif_disable_rpm(struct rpcif *rpc)
|
||||
{
|
||||
pm_runtime_disable(rpc->dev);
|
||||
}
|
||||
int rpcif_manual_xfer(struct device *dev);
|
||||
ssize_t rpcif_dirmap_read(struct device *dev, u64 offs, size_t len, void *buf);
|
||||
|
||||
#endif // __RENESAS_RPC_IF_H
|
||||
|
||||
@@ -2269,7 +2269,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst)
|
||||
|
||||
sk_tx_queue_clear(sk);
|
||||
WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
|
||||
old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst);
|
||||
old_dst = unrcu_pointer(xchg(&sk->sk_dst_cache, RCU_INITIALIZER(dst)));
|
||||
dst_release(old_dst);
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ enum {
|
||||
#define RTM_GETLINKPROP RTM_GETLINKPROP
|
||||
|
||||
RTM_NEWVLAN = 112,
|
||||
#define RTM_NEWNVLAN RTM_NEWVLAN
|
||||
#define RTM_NEWVLAN RTM_NEWVLAN
|
||||
RTM_DELVLAN,
|
||||
#define RTM_DELVLAN RTM_DELVLAN
|
||||
RTM_GETVLAN,
|
||||
|
||||
@@ -356,10 +356,16 @@ void perf_uprobe_destroy(struct perf_event *p_event)
|
||||
int perf_trace_add(struct perf_event *p_event, int flags)
|
||||
{
|
||||
struct trace_event_call *tp_event = p_event->tp_event;
|
||||
struct hw_perf_event *hwc = &p_event->hw;
|
||||
|
||||
if (!(flags & PERF_EF_START))
|
||||
p_event->hw.state = PERF_HES_STOPPED;
|
||||
|
||||
if (is_sampling_event(p_event)) {
|
||||
hwc->last_period = hwc->sample_period;
|
||||
perf_swevent_set_period(p_event);
|
||||
}
|
||||
|
||||
/*
|
||||
* If TRACE_REG_PERF_ADD returns false; no custom action was performed
|
||||
* and we need to take the default action of enqueueing our event on
|
||||
|
||||
@@ -19,16 +19,6 @@ static const struct device_type bt_link = {
|
||||
.release = bt_link_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* The rfcomm tty device will possibly retain even when conn
|
||||
* is down, and sysfs doesn't support move zombie device,
|
||||
* so we should move the device before conn device is destroyed.
|
||||
*/
|
||||
static int __match_tty(struct device *dev, void *data)
|
||||
{
|
||||
return !strncmp(dev_name(dev), "rfcomm", 6);
|
||||
}
|
||||
|
||||
void hci_conn_init_sysfs(struct hci_conn *conn)
|
||||
{
|
||||
struct hci_dev *hdev = conn->hdev;
|
||||
@@ -71,10 +61,13 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there are devices using the connection as parent reset it to NULL
|
||||
* before unregistering the device.
|
||||
*/
|
||||
while (1) {
|
||||
struct device *dev;
|
||||
|
||||
dev = device_find_child(&conn->dev, NULL, __match_tty);
|
||||
dev = device_find_any_child(&conn->dev);
|
||||
if (!dev)
|
||||
break;
|
||||
device_move(dev, NULL, DPM_ORDER_DEV_LAST);
|
||||
|
||||
@@ -2594,18 +2594,16 @@ BPF_CALL_2(bpf_msg_cork_bytes, struct sk_msg *, msg, u32, bytes)
|
||||
|
||||
static void sk_msg_reset_curr(struct sk_msg *msg)
|
||||
{
|
||||
u32 i = msg->sg.start;
|
||||
u32 len = 0;
|
||||
if (!msg->sg.size) {
|
||||
msg->sg.curr = msg->sg.start;
|
||||
msg->sg.copybreak = 0;
|
||||
} else {
|
||||
u32 i = msg->sg.end;
|
||||
|
||||
do {
|
||||
len += sk_msg_elem(msg, i)->length;
|
||||
sk_msg_iter_var_next(i);
|
||||
if (len >= msg->sg.size)
|
||||
break;
|
||||
} while (i != msg->sg.end);
|
||||
|
||||
msg->sg.curr = i;
|
||||
msg->sg.copybreak = 0;
|
||||
sk_msg_iter_var_prev(i);
|
||||
msg->sg.curr = i;
|
||||
msg->sg.copybreak = msg->sg.data[i].length;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct bpf_func_proto bpf_msg_cork_bytes_proto = {
|
||||
@@ -2768,7 +2766,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
sk_msg_iter_var_next(i);
|
||||
} while (i != msg->sg.end);
|
||||
|
||||
if (start >= offset + l)
|
||||
if (start > offset + l)
|
||||
return -EINVAL;
|
||||
|
||||
space = MAX_MSG_FRAGS - sk_msg_elem_used(msg);
|
||||
@@ -2793,6 +2791,8 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
|
||||
raw = page_address(page);
|
||||
|
||||
if (i == msg->sg.end)
|
||||
sk_msg_iter_var_prev(i);
|
||||
psge = sk_msg_elem(msg, i);
|
||||
front = start - offset;
|
||||
back = psge->length - front;
|
||||
@@ -2809,7 +2809,13 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
}
|
||||
|
||||
put_page(sg_page(psge));
|
||||
} else if (start - offset) {
|
||||
new = i;
|
||||
goto place_new;
|
||||
}
|
||||
|
||||
if (start - offset) {
|
||||
if (i == msg->sg.end)
|
||||
sk_msg_iter_var_prev(i);
|
||||
psge = sk_msg_elem(msg, i);
|
||||
rsge = sk_msg_elem_cpy(msg, i);
|
||||
|
||||
@@ -2820,39 +2826,44 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start,
|
||||
sk_msg_iter_var_next(i);
|
||||
sg_unmark_end(psge);
|
||||
sg_unmark_end(&rsge);
|
||||
sk_msg_iter_next(msg, end);
|
||||
}
|
||||
|
||||
/* Slot(s) to place newly allocated data */
|
||||
sk_msg_iter_next(msg, end);
|
||||
new = i;
|
||||
sk_msg_iter_var_next(i);
|
||||
|
||||
if (i == msg->sg.end) {
|
||||
if (!rsge.length)
|
||||
goto place_new;
|
||||
sk_msg_iter_next(msg, end);
|
||||
goto place_new;
|
||||
}
|
||||
|
||||
/* Shift one or two slots as needed */
|
||||
if (!copy) {
|
||||
sge = sk_msg_elem_cpy(msg, i);
|
||||
sge = sk_msg_elem_cpy(msg, new);
|
||||
sg_unmark_end(&sge);
|
||||
|
||||
nsge = sk_msg_elem_cpy(msg, i);
|
||||
if (rsge.length) {
|
||||
sk_msg_iter_var_next(i);
|
||||
sg_unmark_end(&sge);
|
||||
nnsge = sk_msg_elem_cpy(msg, i);
|
||||
sk_msg_iter_next(msg, end);
|
||||
}
|
||||
|
||||
nsge = sk_msg_elem_cpy(msg, i);
|
||||
while (i != msg->sg.end) {
|
||||
msg->sg.data[i] = sge;
|
||||
sge = nsge;
|
||||
sk_msg_iter_var_next(i);
|
||||
if (rsge.length) {
|
||||
sk_msg_iter_var_next(i);
|
||||
nsge = nnsge;
|
||||
nnsge = sk_msg_elem_cpy(msg, i);
|
||||
}
|
||||
|
||||
while (i != msg->sg.end) {
|
||||
msg->sg.data[i] = sge;
|
||||
sge = nsge;
|
||||
sk_msg_iter_var_next(i);
|
||||
if (rsge.length) {
|
||||
nsge = nnsge;
|
||||
nnsge = sk_msg_elem_cpy(msg, i);
|
||||
} else {
|
||||
nsge = sk_msg_elem_cpy(msg, i);
|
||||
}
|
||||
} else {
|
||||
nsge = sk_msg_elem_cpy(msg, i);
|
||||
}
|
||||
}
|
||||
|
||||
place_new:
|
||||
/* Place newly allocated data buffer */
|
||||
sk_mem_charge(msg->sk, len);
|
||||
msg->sg.size += len;
|
||||
@@ -2881,8 +2892,10 @@ static const struct bpf_func_proto bpf_msg_push_data_proto = {
|
||||
|
||||
static void sk_msg_shift_left(struct sk_msg *msg, int i)
|
||||
{
|
||||
struct scatterlist *sge = sk_msg_elem(msg, i);
|
||||
int prev;
|
||||
|
||||
put_page(sg_page(sge));
|
||||
do {
|
||||
prev = i;
|
||||
sk_msg_iter_var_next(i);
|
||||
@@ -2919,6 +2932,9 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
if (unlikely(flags))
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(len == 0))
|
||||
return 0;
|
||||
|
||||
/* First find the starting scatterlist element */
|
||||
i = msg->sg.start;
|
||||
do {
|
||||
@@ -2931,7 +2947,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
} while (i != msg->sg.end);
|
||||
|
||||
/* Bounds checks: start and pop must be inside message */
|
||||
if (start >= offset + l || last >= msg->sg.size)
|
||||
if (start >= offset + l || last > msg->sg.size)
|
||||
return -EINVAL;
|
||||
|
||||
space = MAX_MSG_FRAGS - sk_msg_elem_used(msg);
|
||||
@@ -2960,12 +2976,12 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
*/
|
||||
if (start != offset) {
|
||||
struct scatterlist *nsge, *sge = sk_msg_elem(msg, i);
|
||||
int a = start;
|
||||
int a = start - offset;
|
||||
int b = sge->length - pop - a;
|
||||
|
||||
sk_msg_iter_var_next(i);
|
||||
|
||||
if (pop < sge->length - a) {
|
||||
if (b > 0) {
|
||||
if (space) {
|
||||
sge->length = a;
|
||||
sk_msg_shift_right(msg, i);
|
||||
@@ -2984,7 +3000,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
if (unlikely(!page))
|
||||
return -ENOMEM;
|
||||
|
||||
sge->length = a;
|
||||
orig = sg_page(sge);
|
||||
from = sg_virt(sge);
|
||||
to = page_address(page);
|
||||
@@ -2994,7 +3009,7 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
put_page(orig);
|
||||
}
|
||||
pop = 0;
|
||||
} else if (pop >= sge->length - a) {
|
||||
} else {
|
||||
pop -= (sge->length - a);
|
||||
sge->length = a;
|
||||
}
|
||||
@@ -3028,7 +3043,6 @@ BPF_CALL_4(bpf_msg_pop_data, struct sk_msg *, msg, u32, start,
|
||||
pop -= sge->length;
|
||||
sk_msg_shift_left(msg, i);
|
||||
}
|
||||
sk_msg_iter_var_next(i);
|
||||
}
|
||||
|
||||
sk_mem_uncharge(msg->sk, len - pop);
|
||||
|
||||
@@ -206,7 +206,7 @@ void gen_kill_estimator(struct net_rate_estimator __rcu **rate_est)
|
||||
{
|
||||
struct net_rate_estimator *est;
|
||||
|
||||
est = xchg((__force struct net_rate_estimator **)rate_est, NULL);
|
||||
est = unrcu_pointer(xchg(rate_est, NULL));
|
||||
if (est) {
|
||||
del_timer_sync(&est->timer);
|
||||
kfree_rcu(est, rcu);
|
||||
|
||||
@@ -1112,9 +1112,9 @@ static void sk_psock_strp_data_ready(struct sock *sk)
|
||||
if (tls_sw_has_ctx_rx(sk)) {
|
||||
psock->saved_data_ready(sk);
|
||||
} else {
|
||||
write_lock_bh(&sk->sk_callback_lock);
|
||||
read_lock_bh(&sk->sk_callback_lock);
|
||||
strp_data_ready(&psock->strp);
|
||||
write_unlock_bh(&sk->sk_callback_lock);
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user