mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
Merge tag 'v5.4-rc7' into android-mainline
Linux 5.4-rc7 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I505207a0a6f68ccc3519d7f190d8faf25d9d479a
This commit is contained in:
4
.mailmap
4
.mailmap
@@ -108,6 +108,10 @@ Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
|
||||
Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
|
||||
Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
|
||||
<javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jayachandranc@netlogicmicro.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jchandra@broadcom.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com>
|
||||
Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com>
|
||||
Jean Tourrilhes <jt@hpl.hp.com>
|
||||
<jean-philippe@linaro.org> <jean-philippe.brucker@arm.com>
|
||||
Jeff Garzik <jgarzik@pretzel.yyz.us>
|
||||
|
||||
@@ -436,6 +436,10 @@ by the driver:
|
||||
encryption.
|
||||
* ``tx_tls_ooo`` - number of TX packets which were part of a TLS stream
|
||||
but did not arrive in the expected order.
|
||||
* ``tx_tls_skip_no_sync_data`` - number of TX packets which were part of
|
||||
a TLS stream and arrived out-of-order, but skipped the HW offload routine
|
||||
and went to the regular transmit flow as they were retransmissions of the
|
||||
connection handshake.
|
||||
* ``tx_tls_drop_no_sync_data`` - number of TX packets which were part of
|
||||
a TLS stream dropped, because they arrived out of order and associated
|
||||
record could not be found.
|
||||
|
||||
13
MAINTAINERS
13
MAINTAINERS
@@ -3053,6 +3053,7 @@ M: Daniel Borkmann <daniel@iogearbox.net>
|
||||
R: Martin KaFai Lau <kafai@fb.com>
|
||||
R: Song Liu <songliubraving@fb.com>
|
||||
R: Yonghong Song <yhs@fb.com>
|
||||
R: Andrii Nakryiko <andriin@fb.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: bpf@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
|
||||
@@ -3737,7 +3738,6 @@ F: drivers/crypto/cavium/cpt/
|
||||
|
||||
CAVIUM THUNDERX2 ARM64 SOC
|
||||
M: Robert Richter <rrichter@cavium.com>
|
||||
M: Jayachandran C <jnair@caviumnetworks.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: arch/arm64/boot/dts/cavium/thunder2-99xx*
|
||||
@@ -10519,8 +10519,12 @@ F: mm/memblock.c
|
||||
F: Documentation/core-api/boot-time-mm.rst
|
||||
|
||||
MEMORY MANAGEMENT
|
||||
M: Andrew Morton <akpm@linux-foundation.org>
|
||||
L: linux-mm@kvack.org
|
||||
W: http://www.linux-mm.org
|
||||
T: quilt https://ozlabs.org/~akpm/mmotm/
|
||||
T: quilt https://ozlabs.org/~akpm/mmots/
|
||||
T: git git://github.com/hnaz/linux-mm.git
|
||||
S: Maintained
|
||||
F: include/linux/mm.h
|
||||
F: include/linux/gfp.h
|
||||
@@ -17334,6 +17338,12 @@ F: include/linux/vbox_utils.h
|
||||
F: include/uapi/linux/vbox*.h
|
||||
F: drivers/virt/vboxguest/
|
||||
|
||||
VIRTUAL BOX SHARED FOLDER VFS DRIVER:
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: linux-fsdevel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/staging/vboxsf/*
|
||||
|
||||
VIRTUAL SERIO DEVICE DRIVER
|
||||
M: Stephen Chandler Paul <thatslyude@gmail.com>
|
||||
S: Maintained
|
||||
@@ -18034,6 +18044,7 @@ F: Documentation/vm/zsmalloc.rst
|
||||
ZSWAP COMPRESSED SWAP CACHING
|
||||
M: Seth Jennings <sjenning@redhat.com>
|
||||
M: Dan Streetman <ddstreet@ieee.org>
|
||||
M: Vitaly Wool <vitaly.wool@konsulko.com>
|
||||
L: linux-mm@kvack.org
|
||||
S: Maintained
|
||||
F: mm/zswap.c
|
||||
|
||||
2
Makefile
2
Makefile
@@ -2,7 +2,7 @@
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc7
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
||||
@@ -328,6 +328,10 @@
|
||||
pinctrl-0 = <&pinctrl_pwm3>;
|
||||
};
|
||||
|
||||
&snvs_pwrkey {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ssi2 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
@@ -230,6 +230,8 @@
|
||||
accelerometer@1c {
|
||||
compatible = "fsl,mma8451";
|
||||
reg = <0x1c>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mma8451_int>;
|
||||
interrupt-parent = <&gpio6>;
|
||||
interrupts = <31 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
@@ -628,6 +630,12 @@
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_mma8451_int: mma8451intgrp {
|
||||
fsl,pins = <
|
||||
MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0xb0b1
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_pwm3: pwm1grp {
|
||||
fsl,pins = <
|
||||
MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1
|
||||
|
||||
@@ -183,14 +183,12 @@
|
||||
|
||||
ov5640: camera@3c {
|
||||
compatible = "ovti,ov5640";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&ov5640_pins>;
|
||||
reg = <0x3c>;
|
||||
clocks = <&clk_ext_camera>;
|
||||
clock-names = "xclk";
|
||||
DOVDD-supply = <&v2v8>;
|
||||
powerdown-gpios = <&stmfx_pinctrl 18 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&stmfx_pinctrl 19 GPIO_ACTIVE_LOW>;
|
||||
powerdown-gpios = <&stmfx_pinctrl 18 (GPIO_ACTIVE_HIGH | GPIO_PUSH_PULL)>;
|
||||
reset-gpios = <&stmfx_pinctrl 19 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>;
|
||||
rotation = <180>;
|
||||
status = "okay";
|
||||
|
||||
@@ -223,15 +221,8 @@
|
||||
|
||||
joystick_pins: joystick {
|
||||
pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
|
||||
drive-push-pull;
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
ov5640_pins: camera {
|
||||
pins = "agpio2", "agpio3"; /* stmfx pins 18 & 19 */
|
||||
drive-push-pull;
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -932,7 +932,7 @@
|
||||
interrupt-names = "int0", "int1";
|
||||
clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
|
||||
clock-names = "hclk", "cclk";
|
||||
bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
|
||||
bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -945,7 +945,7 @@
|
||||
interrupt-names = "int0", "int1";
|
||||
clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
|
||||
clock-names = "hclk", "cclk";
|
||||
bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
|
||||
bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@
|
||||
vqmmc-supply = <®_dldo1>;
|
||||
non-removable;
|
||||
wakeup-source;
|
||||
keep-power-in-suspend;
|
||||
status = "okay";
|
||||
|
||||
brcmf: wifi@1 {
|
||||
|
||||
@@ -481,14 +481,18 @@ static void sunxi_mc_smp_cpu_die(unsigned int l_cpu)
|
||||
static int sunxi_cpu_powerdown(unsigned int cpu, unsigned int cluster)
|
||||
{
|
||||
u32 reg;
|
||||
int gating_bit = cpu;
|
||||
|
||||
pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu);
|
||||
if (cpu >= SUNXI_CPUS_PER_CLUSTER || cluster >= SUNXI_NR_CLUSTERS)
|
||||
return -EINVAL;
|
||||
|
||||
if (is_a83t && cpu == 0)
|
||||
gating_bit = 4;
|
||||
|
||||
/* gate processor power */
|
||||
reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster));
|
||||
reg |= PRCM_PWROFF_GATING_REG_CORE(cpu);
|
||||
reg |= PRCM_PWROFF_GATING_REG_CORE(gating_bit);
|
||||
writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster));
|
||||
udelay(20);
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
status = "okay";
|
||||
|
||||
i2c-mux@77 {
|
||||
compatible = "nxp,pca9847";
|
||||
compatible = "nxp,pca9547";
|
||||
reg = <0x77>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
@@ -394,7 +394,7 @@
|
||||
};
|
||||
|
||||
sdma2: dma-controller@302c0000 {
|
||||
compatible = "fsl,imx8mm-sdma", "fsl,imx7d-sdma";
|
||||
compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma";
|
||||
reg = <0x302c0000 0x10000>;
|
||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX8MM_CLK_SDMA2_ROOT>,
|
||||
@@ -405,7 +405,7 @@
|
||||
};
|
||||
|
||||
sdma3: dma-controller@302b0000 {
|
||||
compatible = "fsl,imx8mm-sdma", "fsl,imx7d-sdma";
|
||||
compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma";
|
||||
reg = <0x302b0000 0x10000>;
|
||||
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX8MM_CLK_SDMA3_ROOT>,
|
||||
@@ -737,7 +737,7 @@
|
||||
};
|
||||
|
||||
sdma1: dma-controller@30bd0000 {
|
||||
compatible = "fsl,imx8mm-sdma", "fsl,imx7d-sdma";
|
||||
compatible = "fsl,imx8mm-sdma", "fsl,imx8mq-sdma";
|
||||
reg = <0x30bd0000 0x10000>;
|
||||
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX8MM_CLK_SDMA1_ROOT>,
|
||||
|
||||
@@ -288,7 +288,7 @@
|
||||
};
|
||||
|
||||
sdma3: dma-controller@302b0000 {
|
||||
compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
|
||||
compatible = "fsl,imx8mn-sdma", "fsl,imx8mq-sdma";
|
||||
reg = <0x302b0000 0x10000>;
|
||||
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX8MN_CLK_SDMA3_ROOT>,
|
||||
@@ -299,7 +299,7 @@
|
||||
};
|
||||
|
||||
sdma2: dma-controller@302c0000 {
|
||||
compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
|
||||
compatible = "fsl,imx8mn-sdma", "fsl,imx8mq-sdma";
|
||||
reg = <0x302c0000 0x10000>;
|
||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX8MN_CLK_SDMA2_ROOT>,
|
||||
@@ -612,7 +612,7 @@
|
||||
};
|
||||
|
||||
sdma1: dma-controller@30bd0000 {
|
||||
compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
|
||||
compatible = "fsl,imx8mn-sdma", "fsl,imx8mq-sdma";
|
||||
reg = <0x30bd0000 0x10000>;
|
||||
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX8MN_CLK_SDMA1_ROOT>,
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
regulator-name = "0V9_ARM";
|
||||
regulator-min-microvolt = <900000>;
|
||||
regulator-max-microvolt = <1000000>;
|
||||
gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
|
||||
gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
|
||||
states = <1000000 0x1
|
||||
900000 0x0>;
|
||||
regulator-always-on;
|
||||
|
||||
@@ -283,23 +283,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
set_pte(ptep, pte);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTE_SAME
|
||||
static inline int pte_same(pte_t pte_a, pte_t pte_b)
|
||||
{
|
||||
pteval_t lhs, rhs;
|
||||
|
||||
lhs = pte_val(pte_a);
|
||||
rhs = pte_val(pte_b);
|
||||
|
||||
if (pte_present(pte_a))
|
||||
lhs &= ~PTE_RDONLY;
|
||||
|
||||
if (pte_present(pte_b))
|
||||
rhs &= ~PTE_RDONLY;
|
||||
|
||||
return (lhs == rhs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Huge pte definitions.
|
||||
*/
|
||||
|
||||
@@ -30,13 +30,6 @@ int __arm64_get_clock_mode(struct timekeeper *tk)
|
||||
}
|
||||
#define __arch_get_clock_mode __arm64_get_clock_mode
|
||||
|
||||
static __always_inline
|
||||
int __arm64_use_vsyscall(struct vdso_data *vdata)
|
||||
{
|
||||
return !vdata[CS_HRES_COARSE].clock_mode;
|
||||
}
|
||||
#define __arch_use_vsyscall __arm64_use_vsyscall
|
||||
|
||||
static __always_inline
|
||||
void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
|
||||
{
|
||||
|
||||
@@ -28,13 +28,6 @@ int __mips_get_clock_mode(struct timekeeper *tk)
|
||||
}
|
||||
#define __arch_get_clock_mode __mips_get_clock_mode
|
||||
|
||||
static __always_inline
|
||||
int __mips_use_vsyscall(struct vdso_data *vdata)
|
||||
{
|
||||
return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE);
|
||||
}
|
||||
#define __arch_use_vsyscall __mips_use_vsyscall
|
||||
|
||||
/* The asm-generic header needs to be included after the definitions above */
|
||||
#include <asm-generic/vdso/vsyscall.h>
|
||||
|
||||
|
||||
@@ -1141,6 +1141,19 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
|
||||
goto out_addrs;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have seen a tail call, we need a second pass.
|
||||
* This is because bpf_jit_emit_common_epilogue() is called
|
||||
* from bpf_jit_emit_tail_call() with a not yet stable ctx->seen.
|
||||
*/
|
||||
if (cgctx.seen & SEEN_TAILCALL) {
|
||||
cgctx.idx = 0;
|
||||
if (bpf_jit_build_body(fp, 0, &cgctx, addrs, false)) {
|
||||
fp = org_fp;
|
||||
goto out_addrs;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pretend to build prologue, given the features we've seen. This will
|
||||
* update ctgtx.idx as it pretends to output instructions, then we can
|
||||
|
||||
@@ -1586,9 +1586,6 @@ static void setup_local_APIC(void)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
unsigned int value;
|
||||
#ifdef CONFIG_X86_32
|
||||
int logical_apicid, ldr_apicid;
|
||||
#endif
|
||||
|
||||
if (disable_apic) {
|
||||
disable_ioapic_support();
|
||||
@@ -1626,16 +1623,21 @@ static void setup_local_APIC(void)
|
||||
apic->init_apic_ldr();
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* APIC LDR is initialized. If logical_apicid mapping was
|
||||
* initialized during get_smp_config(), make sure it matches the
|
||||
* actual value.
|
||||
*/
|
||||
logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
ldr_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
|
||||
WARN_ON(logical_apicid != BAD_APICID && logical_apicid != ldr_apicid);
|
||||
/* always use the value from LDR */
|
||||
early_per_cpu(x86_cpu_to_logical_apicid, cpu) = ldr_apicid;
|
||||
if (apic->dest_logical) {
|
||||
int logical_apicid, ldr_apicid;
|
||||
|
||||
/*
|
||||
* APIC LDR is initialized. If logical_apicid mapping was
|
||||
* initialized during get_smp_config(), make sure it matches
|
||||
* the actual value.
|
||||
*/
|
||||
logical_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
|
||||
ldr_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR));
|
||||
if (logical_apicid != BAD_APICID)
|
||||
WARN_ON(logical_apicid != ldr_apicid);
|
||||
/* Always use the value from LDR. */
|
||||
early_per_cpu(x86_cpu_to_logical_apicid, cpu) = ldr_apicid;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -522,6 +522,10 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
|
||||
int ret = 0;
|
||||
|
||||
rdtgrp = rdtgroup_kn_lock_live(of->kn);
|
||||
if (!rdtgrp) {
|
||||
ret = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
md.priv = of->kn->priv;
|
||||
resid = md.u.rid;
|
||||
|
||||
@@ -94,6 +94,13 @@ static bool in_exception_stack(unsigned long *stack, struct stack_info *info)
|
||||
BUILD_BUG_ON(N_EXCEPTION_STACKS != 6);
|
||||
|
||||
begin = (unsigned long)__this_cpu_read(cea_exception_stacks);
|
||||
/*
|
||||
* Handle the case where stack trace is collected _before_
|
||||
* cea_exception_stacks had been initialized.
|
||||
*/
|
||||
if (!begin)
|
||||
return false;
|
||||
|
||||
end = begin + sizeof(struct cea_exception_stacks);
|
||||
/* Bail if @stack is outside the exception stack area. */
|
||||
if (stk < begin || stk >= end)
|
||||
|
||||
@@ -1505,6 +1505,9 @@ void __init tsc_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (tsc_clocksource_reliable || no_tsc_watchdog)
|
||||
clocksource_tsc_early.flags &= ~CLOCK_SOURCE_MUST_VERIFY;
|
||||
|
||||
clocksource_register_khz(&clocksource_tsc_early, tsc_khz);
|
||||
detect_art();
|
||||
}
|
||||
|
||||
@@ -934,9 +934,14 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
|
||||
int i;
|
||||
bool has_stats = false;
|
||||
|
||||
spin_lock_irq(&blkg->q->queue_lock);
|
||||
|
||||
if (!blkg->online)
|
||||
goto skip;
|
||||
|
||||
dname = blkg_dev_name(blkg);
|
||||
if (!dname)
|
||||
continue;
|
||||
goto skip;
|
||||
|
||||
/*
|
||||
* Hooray string manipulation, count is the size written NOT
|
||||
@@ -946,8 +951,6 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
|
||||
*/
|
||||
off += scnprintf(buf+off, size-off, "%s ", dname);
|
||||
|
||||
spin_lock_irq(&blkg->q->queue_lock);
|
||||
|
||||
blkg_rwstat_recursive_sum(blkg, NULL,
|
||||
offsetof(struct blkcg_gq, stat_bytes), &rwstat);
|
||||
rbytes = rwstat.cnt[BLKG_RWSTAT_READ];
|
||||
@@ -960,8 +963,6 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
|
||||
wios = rwstat.cnt[BLKG_RWSTAT_WRITE];
|
||||
dios = rwstat.cnt[BLKG_RWSTAT_DISCARD];
|
||||
|
||||
spin_unlock_irq(&blkg->q->queue_lock);
|
||||
|
||||
if (rbytes || wbytes || rios || wios) {
|
||||
has_stats = true;
|
||||
off += scnprintf(buf+off, size-off,
|
||||
@@ -999,6 +1000,8 @@ static int blkcg_print_stat(struct seq_file *sf, void *v)
|
||||
seq_commit(sf, -1);
|
||||
}
|
||||
}
|
||||
skip:
|
||||
spin_unlock_irq(&blkg->q->queue_lock);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
@@ -786,7 +786,6 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm
|
||||
|
||||
if (nc->tentative && connection->agreed_pro_version < 92) {
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&sock->mutex);
|
||||
drbd_err(connection, "--dry-run is not supported by peer");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@@ -297,7 +297,10 @@ static int clk_main_probe_frequency(struct regmap *regmap)
|
||||
regmap_read(regmap, AT91_CKGR_MCFR, &mcfr);
|
||||
if (mcfr & AT91_PMC_MAINRDY)
|
||||
return 0;
|
||||
usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
|
||||
if (system_state < SYSTEM_RUNNING)
|
||||
udelay(MAINF_LOOP_MIN_WAIT);
|
||||
else
|
||||
usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT);
|
||||
} while (time_before(prep_time, timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
|
||||
@@ -43,6 +43,7 @@ static const struct clk_pll_characteristics upll_characteristics = {
|
||||
};
|
||||
|
||||
static const struct clk_programmable_layout sam9x60_programmable_layout = {
|
||||
.pres_mask = 0xff,
|
||||
.pres_shift = 8,
|
||||
.css_mask = 0x1f,
|
||||
.have_slck_mck = 0,
|
||||
|
||||
@@ -76,7 +76,10 @@ static int clk_slow_osc_prepare(struct clk_hw *hw)
|
||||
|
||||
writel(tmp | osc->bits->cr_osc32en, sckcr);
|
||||
|
||||
usleep_range(osc->startup_usec, osc->startup_usec + 1);
|
||||
if (system_state < SYSTEM_RUNNING)
|
||||
udelay(osc->startup_usec);
|
||||
else
|
||||
usleep_range(osc->startup_usec, osc->startup_usec + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -187,7 +190,10 @@ static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
|
||||
|
||||
writel(readl(sckcr) | osc->bits->cr_rcen, sckcr);
|
||||
|
||||
usleep_range(osc->startup_usec, osc->startup_usec + 1);
|
||||
if (system_state < SYSTEM_RUNNING)
|
||||
udelay(osc->startup_usec);
|
||||
else
|
||||
usleep_range(osc->startup_usec, osc->startup_usec + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -288,7 +294,10 @@ static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
|
||||
|
||||
writel(tmp, sckcr);
|
||||
|
||||
usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
|
||||
if (system_state < SYSTEM_RUNNING)
|
||||
udelay(SLOWCK_SW_TIME_USEC);
|
||||
else
|
||||
usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -533,7 +542,10 @@ static int clk_sama5d4_slow_osc_prepare(struct clk_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
usleep_range(osc->startup_usec, osc->startup_usec + 1);
|
||||
if (system_state < SYSTEM_RUNNING)
|
||||
udelay(osc->startup_usec);
|
||||
else
|
||||
usleep_range(osc->startup_usec, osc->startup_usec + 1);
|
||||
osc->prepared = true;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -266,10 +266,11 @@ static int aspeed_g6_clk_enable(struct clk_hw *hw)
|
||||
|
||||
/* Enable clock */
|
||||
if (gate->flags & CLK_GATE_SET_TO_DISABLE) {
|
||||
regmap_write(gate->map, get_clock_reg(gate), clk);
|
||||
} else {
|
||||
/* Use set to clear register */
|
||||
/* Clock is clear to enable, so use set to clear register */
|
||||
regmap_write(gate->map, get_clock_reg(gate) + 0x04, clk);
|
||||
} else {
|
||||
/* Clock is set to enable, so use write to set register */
|
||||
regmap_write(gate->map, get_clock_reg(gate), clk);
|
||||
}
|
||||
|
||||
if (gate->reset_idx >= 0) {
|
||||
|
||||
@@ -638,7 +638,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
||||
clks[IMX8MM_CLK_A53_DIV],
|
||||
clks[IMX8MM_CLK_A53_SRC],
|
||||
clks[IMX8MM_ARM_PLL_OUT],
|
||||
clks[IMX8MM_CLK_24M]);
|
||||
clks[IMX8MM_SYS_PLL1_800M]);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
|
||||
|
||||
@@ -610,7 +610,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
||||
clks[IMX8MN_CLK_A53_DIV],
|
||||
clks[IMX8MN_CLK_A53_SRC],
|
||||
clks[IMX8MN_ARM_PLL_OUT],
|
||||
clks[IMX8MN_CLK_24M]);
|
||||
clks[IMX8MN_SYS_PLL1_800M]);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
|
||||
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
||||
.mask = 0x3,
|
||||
.shift = 0,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk_dyn0_sel",
|
||||
@@ -353,8 +354,7 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
|
||||
{ .hw = &g12a_fclk_div3.hw },
|
||||
},
|
||||
.num_parents = 3,
|
||||
/* This sub-tree is used a parking clock */
|
||||
.flags = CLK_SET_RATE_NO_REPARENT,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -410,6 +410,7 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = {
|
||||
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
||||
.mask = 0x1,
|
||||
.shift = 2,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk_dyn0",
|
||||
@@ -466,6 +467,7 @@ static struct clk_regmap g12a_cpu_clk_dyn = {
|
||||
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
||||
.mask = 0x1,
|
||||
.shift = 10,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk_dyn",
|
||||
@@ -485,6 +487,7 @@ static struct clk_regmap g12a_cpu_clk = {
|
||||
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
||||
.mask = 0x1,
|
||||
.shift = 11,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk",
|
||||
@@ -504,6 +507,7 @@ static struct clk_regmap g12b_cpu_clk = {
|
||||
.offset = HHI_SYS_CPU_CLK_CNTL0,
|
||||
.mask = 0x1,
|
||||
.shift = 11,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk",
|
||||
@@ -523,6 +527,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
|
||||
.offset = HHI_SYS_CPUB_CLK_CNTL,
|
||||
.mask = 0x3,
|
||||
.shift = 0,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpub_clk_dyn0_sel",
|
||||
@@ -533,6 +538,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
|
||||
{ .hw = &g12a_fclk_div3.hw },
|
||||
},
|
||||
.num_parents = 3,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -567,6 +573,7 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = {
|
||||
.offset = HHI_SYS_CPUB_CLK_CNTL,
|
||||
.mask = 0x1,
|
||||
.shift = 2,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpub_clk_dyn0",
|
||||
@@ -644,6 +651,7 @@ static struct clk_regmap g12b_cpub_clk_dyn = {
|
||||
.offset = HHI_SYS_CPUB_CLK_CNTL,
|
||||
.mask = 0x1,
|
||||
.shift = 10,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpub_clk_dyn",
|
||||
@@ -663,6 +671,7 @@ static struct clk_regmap g12b_cpub_clk = {
|
||||
.offset = HHI_SYS_CPUB_CLK_CNTL,
|
||||
.mask = 0x1,
|
||||
.shift = 11,
|
||||
.flags = CLK_MUX_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpub_clk",
|
||||
|
||||
@@ -935,6 +935,7 @@ static struct clk_regmap gxbb_sar_adc_clk_div = {
|
||||
&gxbb_sar_adc_clk_sel.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -165,12 +165,18 @@ static const unsigned long exynos5x_clk_regs[] __initconst = {
|
||||
GATE_BUS_CPU,
|
||||
GATE_SCLK_CPU,
|
||||
CLKOUT_CMU_CPU,
|
||||
CPLL_CON0,
|
||||
DPLL_CON0,
|
||||
EPLL_CON0,
|
||||
EPLL_CON1,
|
||||
EPLL_CON2,
|
||||
RPLL_CON0,
|
||||
RPLL_CON1,
|
||||
RPLL_CON2,
|
||||
IPLL_CON0,
|
||||
SPLL_CON0,
|
||||
VPLL_CON0,
|
||||
MPLL_CON0,
|
||||
SRC_TOP0,
|
||||
SRC_TOP1,
|
||||
SRC_TOP2,
|
||||
@@ -1172,8 +1178,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
|
||||
GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2",
|
||||
GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0),
|
||||
|
||||
GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
|
||||
|
||||
/* CDREX */
|
||||
GATE(CLK_CLKM_PHY0, "clkm_phy0", "dout_sclk_cdrex",
|
||||
GATE_BUS_CDREX0, 0, 0, 0),
|
||||
@@ -1248,6 +1252,15 @@ static struct exynos5_subcmu_reg_dump exynos5x_gsc_suspend_regs[] = {
|
||||
{ DIV2_RATIO0, 0, 0x30 }, /* DIV dout_gscl_blk_300 */
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock exynos5x_g3d_gate_clks[] __initconst = {
|
||||
GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0),
|
||||
};
|
||||
|
||||
static struct exynos5_subcmu_reg_dump exynos5x_g3d_suspend_regs[] = {
|
||||
{ GATE_IP_G3D, 0x3ff, 0x3ff }, /* G3D gates */
|
||||
{ SRC_TOP5, 0, BIT(16) }, /* MUX mout_user_aclk_g3d */
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock exynos5x_mfc_div_clks[] __initconst = {
|
||||
DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2),
|
||||
};
|
||||
@@ -1320,6 +1333,14 @@ static const struct exynos5_subcmu_info exynos5x_gsc_subcmu = {
|
||||
.pd_name = "GSC",
|
||||
};
|
||||
|
||||
static const struct exynos5_subcmu_info exynos5x_g3d_subcmu = {
|
||||
.gate_clks = exynos5x_g3d_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(exynos5x_g3d_gate_clks),
|
||||
.suspend_regs = exynos5x_g3d_suspend_regs,
|
||||
.nr_suspend_regs = ARRAY_SIZE(exynos5x_g3d_suspend_regs),
|
||||
.pd_name = "G3D",
|
||||
};
|
||||
|
||||
static const struct exynos5_subcmu_info exynos5x_mfc_subcmu = {
|
||||
.div_clks = exynos5x_mfc_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(exynos5x_mfc_div_clks),
|
||||
@@ -1351,6 +1372,7 @@ static const struct exynos5_subcmu_info exynos5800_mau_subcmu = {
|
||||
static const struct exynos5_subcmu_info *exynos5x_subcmus[] = {
|
||||
&exynos5x_disp_subcmu,
|
||||
&exynos5x_gsc_subcmu,
|
||||
&exynos5x_g3d_subcmu,
|
||||
&exynos5x_mfc_subcmu,
|
||||
&exynos5x_mscl_subcmu,
|
||||
};
|
||||
@@ -1358,6 +1380,7 @@ static const struct exynos5_subcmu_info *exynos5x_subcmus[] = {
|
||||
static const struct exynos5_subcmu_info *exynos5800_subcmus[] = {
|
||||
&exynos5x_disp_subcmu,
|
||||
&exynos5x_gsc_subcmu,
|
||||
&exynos5x_g3d_subcmu,
|
||||
&exynos5x_mfc_subcmu,
|
||||
&exynos5x_mscl_subcmu,
|
||||
&exynos5800_mau_subcmu,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/exynos5433.h>
|
||||
|
||||
@@ -5584,6 +5585,8 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
|
||||
|
||||
data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs,
|
||||
info->nr_clk_regs);
|
||||
if (!data->clk_save)
|
||||
return -ENOMEM;
|
||||
data->nr_clk_save = info->nr_clk_regs;
|
||||
data->clk_suspend = info->suspend_regs;
|
||||
data->nr_clk_suspend = info->nr_suspend_regs;
|
||||
@@ -5592,12 +5595,19 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
|
||||
if (data->nr_pclks > 0) {
|
||||
data->pclks = devm_kcalloc(dev, sizeof(struct clk *),
|
||||
data->nr_pclks, GFP_KERNEL);
|
||||
|
||||
if (!data->pclks) {
|
||||
kfree(data->clk_save);
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (i = 0; i < data->nr_pclks; i++) {
|
||||
struct clk *clk = of_clk_get(dev->of_node, i);
|
||||
|
||||
if (IS_ERR(clk))
|
||||
if (IS_ERR(clk)) {
|
||||
kfree(data->clk_save);
|
||||
while (--i >= 0)
|
||||
clk_put(data->pclks[i]);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
data->pclks[i] = clk;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1224,7 +1224,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev)
|
||||
|
||||
/* Enforce d1 = 0, d2 = 0 for Audio PLL */
|
||||
val = readl(reg + SUN9I_A80_PLL_AUDIO_REG);
|
||||
val &= (BIT(16) & BIT(18));
|
||||
val &= ~(BIT(16) | BIT(18));
|
||||
writel(val, reg + SUN9I_A80_PLL_AUDIO_REG);
|
||||
|
||||
/* Enforce P = 1 for both CPU cluster PLLs */
|
||||
|
||||
@@ -1080,8 +1080,8 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node,
|
||||
rate_hw, rate_ops,
|
||||
gate_hw, &clk_gate_ops,
|
||||
clkflags |
|
||||
data->div[i].critical ?
|
||||
CLK_IS_CRITICAL : 0);
|
||||
(data->div[i].critical ?
|
||||
CLK_IS_CRITICAL : 0));
|
||||
|
||||
WARN_ON(IS_ERR(clk_data->clks[i]));
|
||||
}
|
||||
|
||||
@@ -174,7 +174,6 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
|
||||
struct clk_init_data init = { NULL };
|
||||
const char **parent_names = NULL;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL);
|
||||
if (!clk_hw) {
|
||||
@@ -207,11 +206,6 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
|
||||
clk = ti_clk_register(NULL, &clk_hw->hw, node->name);
|
||||
|
||||
if (!IS_ERR(clk)) {
|
||||
ret = ti_clk_add_alias(NULL, clk, node->name);
|
||||
if (ret) {
|
||||
clk_unregister(clk);
|
||||
goto cleanup;
|
||||
}
|
||||
of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
kfree(parent_names);
|
||||
return;
|
||||
|
||||
@@ -100,11 +100,12 @@ static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout)
|
||||
* can be from a timer that requires pm_runtime access, which
|
||||
* will eventually bring us here with timekeeping_suspended,
|
||||
* during both suspend entry and resume paths. This happens
|
||||
* at least on am43xx platform.
|
||||
* at least on am43xx platform. Account for flakeyness
|
||||
* with udelay() by multiplying the timeout value by 2.
|
||||
*/
|
||||
if (unlikely(_early_timeout || timekeeping_suspended)) {
|
||||
if (time->cycles++ < timeout) {
|
||||
udelay(1);
|
||||
udelay(1 * 2);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -328,12 +328,13 @@ static int sh_mtu2_register(struct sh_mtu2_channel *ch, const char *name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned int sh_mtu2_channel_offsets[] = {
|
||||
0x300, 0x380, 0x000,
|
||||
};
|
||||
|
||||
static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index,
|
||||
struct sh_mtu2_device *mtu)
|
||||
{
|
||||
static const unsigned int channel_offsets[] = {
|
||||
0x300, 0x380, 0x000,
|
||||
};
|
||||
char name[6];
|
||||
int irq;
|
||||
int ret;
|
||||
@@ -356,7 +357,7 @@ static int sh_mtu2_setup_channel(struct sh_mtu2_channel *ch, unsigned int index,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ch->base = mtu->mapbase + channel_offsets[index];
|
||||
ch->base = mtu->mapbase + sh_mtu2_channel_offsets[index];
|
||||
ch->index = index;
|
||||
|
||||
return sh_mtu2_register(ch, dev_name(&mtu->pdev->dev));
|
||||
@@ -408,7 +409,12 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu,
|
||||
}
|
||||
|
||||
/* Allocate and setup the channels. */
|
||||
mtu->num_channels = 3;
|
||||
ret = platform_irq_count(pdev);
|
||||
if (ret < 0)
|
||||
goto err_unmap;
|
||||
|
||||
mtu->num_channels = min_t(unsigned int, ret,
|
||||
ARRAY_SIZE(sh_mtu2_channel_offsets));
|
||||
|
||||
mtu->channels = kcalloc(mtu->num_channels, sizeof(*mtu->channels),
|
||||
GFP_KERNEL);
|
||||
|
||||
@@ -268,15 +268,12 @@ static int __init mtk_syst_init(struct device_node *node)
|
||||
|
||||
ret = timer_of_init(node, &to);
|
||||
if (ret)
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
|
||||
TIMER_SYNC_TICKS, 0xffffffff);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
timer_of_cleanup(&to);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init mtk_gpt_init(struct device_node *node)
|
||||
@@ -293,7 +290,7 @@ static int __init mtk_gpt_init(struct device_node *node)
|
||||
|
||||
ret = timer_of_init(node, &to);
|
||||
if (ret)
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
/* Configure clock source */
|
||||
mtk_gpt_setup(&to, TIMER_CLK_SRC, GPT_CTRL_OP_FREERUN);
|
||||
@@ -311,9 +308,6 @@ static int __init mtk_gpt_init(struct device_node *node)
|
||||
mtk_gpt_enable_irq(&to, TIMER_CLK_EVT);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
timer_of_cleanup(&to);
|
||||
return ret;
|
||||
}
|
||||
TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
|
||||
TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
|
||||
|
||||
@@ -847,11 +847,9 @@ static void intel_pstate_hwp_force_min_perf(int cpu)
|
||||
value |= HWP_MAX_PERF(min_perf);
|
||||
value |= HWP_MIN_PERF(min_perf);
|
||||
|
||||
/* Set EPP/EPB to min */
|
||||
/* Set EPP to min */
|
||||
if (boot_cpu_has(X86_FEATURE_HWP_EPP))
|
||||
value |= HWP_ENERGY_PERF_PREFERENCE(HWP_EPP_POWERSAVE);
|
||||
else
|
||||
intel_pstate_set_epb(cpu, HWP_EPP_BALANCE_POWERSAVE);
|
||||
|
||||
wrmsrl_on_cpu(cpu, MSR_HWP_REQUEST, value);
|
||||
}
|
||||
|
||||
@@ -362,9 +362,8 @@ static void mrfld_irq_handler(struct irq_desc *desc)
|
||||
chained_irq_exit(irqchip, desc);
|
||||
}
|
||||
|
||||
static int mrfld_irq_init_hw(struct gpio_chip *chip)
|
||||
static void mrfld_irq_init_hw(struct mrfld_gpio *priv)
|
||||
{
|
||||
struct mrfld_gpio *priv = gpiochip_get_data(chip);
|
||||
void __iomem *reg;
|
||||
unsigned int base;
|
||||
|
||||
@@ -376,8 +375,6 @@ static int mrfld_irq_init_hw(struct gpio_chip *chip)
|
||||
reg = gpio_reg(&priv->chip, base, GFER);
|
||||
writel(0, reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv)
|
||||
@@ -400,7 +397,6 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
|
||||
{
|
||||
const struct mrfld_gpio_pinrange *range;
|
||||
const char *pinctrl_dev_name;
|
||||
struct gpio_irq_chip *girq;
|
||||
struct mrfld_gpio *priv;
|
||||
u32 gpio_base, irq_base;
|
||||
void __iomem *base;
|
||||
@@ -448,21 +444,6 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
|
||||
|
||||
raw_spin_lock_init(&priv->lock);
|
||||
|
||||
girq = &priv->chip.irq;
|
||||
girq->chip = &mrfld_irqchip;
|
||||
girq->init_hw = mrfld_irq_init_hw;
|
||||
girq->parent_handler = mrfld_irq_handler;
|
||||
girq->num_parents = 1;
|
||||
girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
|
||||
sizeof(*girq->parents),
|
||||
GFP_KERNEL);
|
||||
if (!girq->parents)
|
||||
return -ENOMEM;
|
||||
girq->parents[0] = pdev->irq;
|
||||
girq->first = irq_base;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_bad_irq;
|
||||
|
||||
pci_set_drvdata(pdev, priv);
|
||||
retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
|
||||
if (retval) {
|
||||
@@ -484,6 +465,18 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
|
||||
}
|
||||
}
|
||||
|
||||
retval = gpiochip_irqchip_add(&priv->chip, &mrfld_irqchip, irq_base,
|
||||
handle_bad_irq, IRQ_TYPE_NONE);
|
||||
if (retval) {
|
||||
dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
mrfld_irq_init_hw(priv);
|
||||
|
||||
gpiochip_set_chained_irqchip(&priv->chip, &mrfld_irqchip, pdev->irq,
|
||||
mrfld_irq_handler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -604,8 +604,11 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_entities; i++)
|
||||
for (i = 0; i < num_entities; i++) {
|
||||
mutex_lock(&ctx->adev->lock_reset);
|
||||
drm_sched_entity_fini(&ctx->entities[0][i].entity);
|
||||
mutex_unlock(&ctx->adev->lock_reset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2885,6 +2885,13 @@ fence_driver_init:
|
||||
DRM_INFO("amdgpu: acceleration disabled, skipping benchmarks\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Register gpu instance before amdgpu_device_enable_mgpu_fan_boost.
|
||||
* Otherwise the mgpu fan boost feature will be skipped due to the
|
||||
* gpu instance is counted less.
|
||||
*/
|
||||
amdgpu_register_gpu_instance(adev);
|
||||
|
||||
/* enable clockgating, etc. after ib tests, etc. since some blocks require
|
||||
* explicit gating rather than handling it automatically.
|
||||
*/
|
||||
|
||||
@@ -1016,6 +1016,7 @@ static const struct pci_device_id pciidlist[] = {
|
||||
{0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x7341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x7347, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
{0x1002, 0x734F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
/* Renoir */
|
||||
{0x1002, 0x1636, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RENOIR|AMD_IS_APU|AMD_EXP_HW_SUPPORT},
|
||||
|
||||
@@ -289,6 +289,7 @@ struct amdgpu_gfx {
|
||||
uint32_t mec2_feature_version;
|
||||
bool mec_fw_write_wait;
|
||||
bool me_fw_write_wait;
|
||||
bool cp_fw_write_wait;
|
||||
struct amdgpu_ring gfx_ring[AMDGPU_MAX_GFX_RINGS];
|
||||
unsigned num_gfx_rings;
|
||||
struct amdgpu_ring compute_ring[AMDGPU_MAX_COMPUTE_RINGS];
|
||||
|
||||
@@ -190,7 +190,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
}
|
||||
|
||||
amdgpu_register_gpu_instance(adev);
|
||||
out:
|
||||
if (r) {
|
||||
/* balance pm_runtime_get_sync in amdgpu_driver_unload_kms */
|
||||
|
||||
@@ -564,6 +564,32 @@ static void gfx_v10_0_free_microcode(struct amdgpu_device *adev)
|
||||
kfree(adev->gfx.rlc.register_list_format);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_check_fw_write_wait(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gfx.cp_fw_write_wait = false;
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_NAVI10:
|
||||
case CHIP_NAVI12:
|
||||
case CHIP_NAVI14:
|
||||
if ((adev->gfx.me_fw_version >= 0x00000046) &&
|
||||
(adev->gfx.me_feature_version >= 27) &&
|
||||
(adev->gfx.pfp_fw_version >= 0x00000068) &&
|
||||
(adev->gfx.pfp_feature_version >= 27) &&
|
||||
(adev->gfx.mec_fw_version >= 0x0000005b) &&
|
||||
(adev->gfx.mec_feature_version >= 27))
|
||||
adev->gfx.cp_fw_write_wait = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (adev->gfx.cp_fw_write_wait == false)
|
||||
DRM_WARN_ONCE("Warning: check cp_fw_version and update it to realize \
|
||||
GRBM requires 1-cycle delay in cp firmware\n");
|
||||
}
|
||||
|
||||
|
||||
static void gfx_v10_0_init_rlc_ext_microcode(struct amdgpu_device *adev)
|
||||
{
|
||||
const struct rlc_firmware_header_v2_1 *rlc_hdr;
|
||||
@@ -832,6 +858,7 @@ static int gfx_v10_0_init_microcode(struct amdgpu_device *adev)
|
||||
}
|
||||
}
|
||||
|
||||
gfx_v10_0_check_fw_write_wait(adev);
|
||||
out:
|
||||
if (err) {
|
||||
dev_err(adev->dev,
|
||||
@@ -4765,6 +4792,24 @@ static void gfx_v10_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
|
||||
gfx_v10_0_wait_reg_mem(ring, 0, 0, 0, reg, 0, val, mask, 0x20);
|
||||
}
|
||||
|
||||
static void gfx_v10_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
|
||||
uint32_t reg0, uint32_t reg1,
|
||||
uint32_t ref, uint32_t mask)
|
||||
{
|
||||
int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
bool fw_version_ok = false;
|
||||
|
||||
fw_version_ok = adev->gfx.cp_fw_write_wait;
|
||||
|
||||
if (fw_version_ok)
|
||||
gfx_v10_0_wait_reg_mem(ring, usepfp, 0, 1, reg0, reg1,
|
||||
ref, mask, 0x20);
|
||||
else
|
||||
amdgpu_ring_emit_reg_write_reg_wait_helper(ring, reg0, reg1,
|
||||
ref, mask);
|
||||
}
|
||||
|
||||
static void
|
||||
gfx_v10_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
|
||||
uint32_t me, uint32_t pipe,
|
||||
@@ -5155,6 +5200,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_gfx = {
|
||||
.emit_tmz = gfx_v10_0_ring_emit_tmz,
|
||||
.emit_wreg = gfx_v10_0_ring_emit_wreg,
|
||||
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
|
||||
@@ -5188,6 +5234,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_compute = {
|
||||
.pad_ib = amdgpu_ring_generic_pad_ib,
|
||||
.emit_wreg = gfx_v10_0_ring_emit_wreg,
|
||||
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
|
||||
};
|
||||
|
||||
static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {
|
||||
@@ -5218,6 +5265,7 @@ static const struct amdgpu_ring_funcs gfx_v10_0_ring_funcs_kiq = {
|
||||
.emit_rreg = gfx_v10_0_ring_emit_rreg,
|
||||
.emit_wreg = gfx_v10_0_ring_emit_wreg,
|
||||
.emit_reg_wait = gfx_v10_0_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = gfx_v10_0_ring_emit_reg_write_reg_wait,
|
||||
};
|
||||
|
||||
static void gfx_v10_0_set_ring_funcs(struct amdgpu_device *adev)
|
||||
|
||||
@@ -973,6 +973,13 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev)
|
||||
adev->gfx.me_fw_write_wait = false;
|
||||
adev->gfx.mec_fw_write_wait = false;
|
||||
|
||||
if ((adev->gfx.mec_fw_version < 0x000001a5) ||
|
||||
(adev->gfx.mec_feature_version < 46) ||
|
||||
(adev->gfx.pfp_fw_version < 0x000000b7) ||
|
||||
(adev->gfx.pfp_feature_version < 46))
|
||||
DRM_WARN_ONCE("Warning: check cp_fw_version and update it to realize \
|
||||
GRBM requires 1-cycle delay in cp firmware\n");
|
||||
|
||||
switch (adev->asic_type) {
|
||||
case CHIP_VEGA10:
|
||||
if ((adev->gfx.me_fw_version >= 0x0000009c) &&
|
||||
@@ -1039,6 +1046,12 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
|
||||
!adev->gfx.rlc.is_rlc_v2_1))
|
||||
adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
|
||||
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS;
|
||||
break;
|
||||
case CHIP_RENOIR:
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
|
||||
@@ -344,11 +344,9 @@ static uint64_t gmc_v10_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring,
|
||||
amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_hi32 + (2 * vmid),
|
||||
upper_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_req + eng, req);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
amdgpu_ring_emit_reg_wait(ring, hub->vm_inv_eng0_ack + eng,
|
||||
1 << vmid, 1 << vmid);
|
||||
amdgpu_ring_emit_reg_write_reg_wait(ring, hub->vm_inv_eng0_req + eng,
|
||||
hub->vm_inv_eng0_ack + eng,
|
||||
req, 1 << vmid);
|
||||
|
||||
return pd_addr;
|
||||
}
|
||||
|
||||
@@ -219,6 +219,15 @@ static void mmhub_v9_4_init_cache_regs(struct amdgpu_device *adev, int hubid)
|
||||
hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp);
|
||||
|
||||
tmp = mmVML2PF0_VM_L2_CNTL3_DEFAULT;
|
||||
if (adev->gmc.translate_further) {
|
||||
tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3, BANK_SELECT, 12);
|
||||
tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3,
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE, 9);
|
||||
} else {
|
||||
tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3, BANK_SELECT, 9);
|
||||
tmp = REG_SET_FIELD(tmp, VML2PF0_VM_L2_CNTL3,
|
||||
L2_CACHE_BIGK_FRAGMENT_SIZE, 6);
|
||||
}
|
||||
WREG32_SOC15_OFFSET(MMHUB, 0, mmVML2PF0_VM_L2_CNTL3,
|
||||
hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp);
|
||||
|
||||
|
||||
@@ -1173,6 +1173,16 @@ static void sdma_v5_0_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
|
||||
SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10));
|
||||
}
|
||||
|
||||
static void sdma_v5_0_ring_emit_reg_write_reg_wait(struct amdgpu_ring *ring,
|
||||
uint32_t reg0, uint32_t reg1,
|
||||
uint32_t ref, uint32_t mask)
|
||||
{
|
||||
amdgpu_ring_emit_wreg(ring, reg0, ref);
|
||||
/* wait for a cycle to reset vm_inv_eng*_ack */
|
||||
amdgpu_ring_emit_reg_wait(ring, reg0, 0, 0);
|
||||
amdgpu_ring_emit_reg_wait(ring, reg1, mask, mask);
|
||||
}
|
||||
|
||||
static int sdma_v5_0_early_init(void *handle)
|
||||
{
|
||||
struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
||||
@@ -1588,7 +1598,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
|
||||
6 + /* sdma_v5_0_ring_emit_pipeline_sync */
|
||||
/* sdma_v5_0_ring_emit_vm_flush */
|
||||
SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 +
|
||||
10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */
|
||||
.emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib = sdma_v5_0_ring_emit_ib,
|
||||
@@ -1602,6 +1612,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
|
||||
.pad_ib = sdma_v5_0_ring_pad_ib,
|
||||
.emit_wreg = sdma_v5_0_ring_emit_wreg,
|
||||
.emit_reg_wait = sdma_v5_0_ring_emit_reg_wait,
|
||||
.emit_reg_write_reg_wait = sdma_v5_0_ring_emit_reg_write_reg_wait,
|
||||
.init_cond_exec = sdma_v5_0_ring_init_cond_exec,
|
||||
.patch_cond_exec = sdma_v5_0_ring_patch_cond_exec,
|
||||
.preempt_ib = sdma_v5_0_ring_preempt_ib,
|
||||
|
||||
@@ -1186,11 +1186,6 @@ static int soc15_common_early_init(void *handle)
|
||||
AMD_PG_SUPPORT_VCN |
|
||||
AMD_PG_SUPPORT_VCN_DPG;
|
||||
adev->external_rev_id = adev->rev_id + 0x91;
|
||||
|
||||
if (adev->pm.pp_feature & PP_GFXOFF_MASK)
|
||||
adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
|
||||
AMD_PG_SUPPORT_CP |
|
||||
AMD_PG_SUPPORT_RLC_SMU_HS;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
|
||||
@@ -2767,15 +2767,6 @@ void core_link_enable_stream(
|
||||
CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
|
||||
COLOR_DEPTH_UNDEFINED);
|
||||
|
||||
/* This second call is needed to reconfigure the DIG
|
||||
* as a workaround for the incorrect value being applied
|
||||
* from transmitter control.
|
||||
*/
|
||||
if (!dc_is_virtual_signal(pipe_ctx->stream->signal))
|
||||
stream->link->link_enc->funcs->setup(
|
||||
stream->link->link_enc,
|
||||
pipe_ctx->stream->signal);
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT
|
||||
if (pipe_ctx->stream->timing.flags.DSC) {
|
||||
if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
|
||||
|
||||
@@ -1107,6 +1107,11 @@ struct stream_encoder *dcn20_stream_encoder_create(
|
||||
if (!enc1)
|
||||
return NULL;
|
||||
|
||||
if (ASICREV_IS_NAVI14_M(ctx->asic_id.hw_internal_rev)) {
|
||||
if (eng_id >= ENGINE_ID_DIGD)
|
||||
eng_id++;
|
||||
}
|
||||
|
||||
dcn20_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id,
|
||||
&stream_enc_regs[eng_id],
|
||||
&se_shift, &se_mask);
|
||||
|
||||
@@ -205,7 +205,7 @@ static struct smu_11_0_cmn2aisc_mapping navi10_workload_map[PP_SMC_POWER_PROFILE
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_CUSTOM_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
|
||||
};
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ static struct smu_11_0_cmn2aisc_mapping vega20_workload_map[PP_SMC_POWER_PROFILE
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_CUSTOM_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
|
||||
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
|
||||
};
|
||||
|
||||
|
||||
@@ -1581,8 +1581,11 @@ static void commit_tail(struct drm_atomic_state *old_state)
|
||||
{
|
||||
struct drm_device *dev = old_state->dev;
|
||||
const struct drm_mode_config_helper_funcs *funcs;
|
||||
struct drm_crtc_state *new_crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
ktime_t start;
|
||||
s64 commit_time_ms;
|
||||
unsigned int i, new_self_refresh_mask = 0;
|
||||
|
||||
funcs = dev->mode_config.helper_private;
|
||||
|
||||
@@ -1602,6 +1605,15 @@ static void commit_tail(struct drm_atomic_state *old_state)
|
||||
|
||||
drm_atomic_helper_wait_for_dependencies(old_state);
|
||||
|
||||
/*
|
||||
* We cannot safely access new_crtc_state after
|
||||
* drm_atomic_helper_commit_hw_done() so figure out which crtc's have
|
||||
* self-refresh active beforehand:
|
||||
*/
|
||||
for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i)
|
||||
if (new_crtc_state->self_refresh_active)
|
||||
new_self_refresh_mask |= BIT(i);
|
||||
|
||||
if (funcs && funcs->atomic_commit_tail)
|
||||
funcs->atomic_commit_tail(old_state);
|
||||
else
|
||||
@@ -1610,7 +1622,8 @@ static void commit_tail(struct drm_atomic_state *old_state)
|
||||
commit_time_ms = ktime_ms_delta(ktime_get(), start);
|
||||
if (commit_time_ms > 0)
|
||||
drm_self_refresh_helper_update_avg_times(old_state,
|
||||
(unsigned long)commit_time_ms);
|
||||
(unsigned long)commit_time_ms,
|
||||
new_self_refresh_mask);
|
||||
|
||||
drm_atomic_helper_commit_cleanup_done(old_state);
|
||||
|
||||
|
||||
@@ -133,29 +133,33 @@ out_drop_locks:
|
||||
* drm_self_refresh_helper_update_avg_times - Updates a crtc's SR time averages
|
||||
* @state: the state which has just been applied to hardware
|
||||
* @commit_time_ms: the amount of time in ms that this commit took to complete
|
||||
* @new_self_refresh_mask: bitmask of crtc's that have self_refresh_active in
|
||||
* new state
|
||||
*
|
||||
* Called after &drm_mode_config_funcs.atomic_commit_tail, this function will
|
||||
* update the average entry/exit self refresh times on self refresh transitions.
|
||||
* These averages will be used when calculating how long to delay before
|
||||
* entering self refresh mode after activity.
|
||||
*/
|
||||
void drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state,
|
||||
unsigned int commit_time_ms)
|
||||
void
|
||||
drm_self_refresh_helper_update_avg_times(struct drm_atomic_state *state,
|
||||
unsigned int commit_time_ms,
|
||||
unsigned int new_self_refresh_mask)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *old_crtc_state, *new_crtc_state;
|
||||
struct drm_crtc_state *old_crtc_state;
|
||||
int i;
|
||||
|
||||
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
|
||||
new_crtc_state, i) {
|
||||
for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
|
||||
bool new_self_refresh_active = new_self_refresh_mask & BIT(i);
|
||||
struct drm_self_refresh_data *sr_data = crtc->self_refresh_data;
|
||||
struct ewma_psr_time *time;
|
||||
|
||||
if (old_crtc_state->self_refresh_active ==
|
||||
new_crtc_state->self_refresh_active)
|
||||
new_self_refresh_active)
|
||||
continue;
|
||||
|
||||
if (new_crtc_state->self_refresh_active)
|
||||
if (new_self_refresh_active)
|
||||
time = &sr_data->entry_avg_ms;
|
||||
else
|
||||
time = &sr_data->exit_avg_ms;
|
||||
|
||||
@@ -864,6 +864,13 @@ load_detect:
|
||||
|
||||
out:
|
||||
intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
|
||||
|
||||
/*
|
||||
* Make sure the refs for power wells enabled during detect are
|
||||
* dropped to avoid a new detect cycle triggered by HPD polling.
|
||||
*/
|
||||
intel_display_power_flush_work(dev_priv);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -1256,6 +1256,9 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
|
||||
u32 unused)
|
||||
{
|
||||
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
|
||||
struct drm_i915_private *i915 =
|
||||
to_i915(intel_dig_port->base.base.dev);
|
||||
enum phy phy = intel_port_to_phy(i915, intel_dig_port->base.port);
|
||||
u32 ret;
|
||||
|
||||
ret = DP_AUX_CH_CTL_SEND_BUSY |
|
||||
@@ -1268,7 +1271,8 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
|
||||
DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) |
|
||||
DP_AUX_CH_CTL_SYNC_PULSE_SKL(32);
|
||||
|
||||
if (intel_dig_port->tc_mode == TC_PORT_TBT_ALT)
|
||||
if (intel_phy_is_tc(i915, phy) &&
|
||||
intel_dig_port->tc_mode == TC_PORT_TBT_ALT)
|
||||
ret |= DP_AUX_CH_CTL_TBT_IO;
|
||||
|
||||
return ret;
|
||||
@@ -5436,6 +5440,12 @@ out:
|
||||
if (status != connector_status_connected && !intel_dp->is_mst)
|
||||
intel_dp_unset_edid(intel_dp);
|
||||
|
||||
/*
|
||||
* Make sure the refs for power wells enabled during detect are
|
||||
* dropped to avoid a new detect cycle triggered by HPD polling.
|
||||
*/
|
||||
intel_display_power_flush_work(dev_priv);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -2565,6 +2565,12 @@ out:
|
||||
if (status != connector_status_connected)
|
||||
cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier);
|
||||
|
||||
/*
|
||||
* Make sure the refs for power wells enabled during detect are
|
||||
* dropped to avoid a new detect cycle triggered by HPD polling.
|
||||
*/
|
||||
intel_display_power_flush_work(dev_priv);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -1958,6 +1958,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev)
|
||||
case 0x682C:
|
||||
si_pi->cac_weights = cac_weights_cape_verde_pro;
|
||||
si_pi->dte_data = dte_data_sun_xt;
|
||||
update_dte_from_pl2 = true;
|
||||
break;
|
||||
case 0x6825:
|
||||
case 0x6827:
|
||||
|
||||
@@ -447,8 +447,12 @@ static int i2c_hid_hwreset(struct i2c_client *client)
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed to reset device.\n");
|
||||
i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
/* At least some SIS devices need this after reset */
|
||||
ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&ihid->reset_lock);
|
||||
return ret;
|
||||
|
||||
@@ -202,6 +202,21 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a signed 32-bit integer to an unsigned n-bit integer. Undoes
|
||||
* the normally-helpful work of 'hid_snto32' for fields that use signed
|
||||
* ranges for questionable reasons.
|
||||
*/
|
||||
static inline __u32 wacom_s32tou(s32 value, __u8 n)
|
||||
{
|
||||
switch (n) {
|
||||
case 8: return ((__u8)value);
|
||||
case 16: return ((__u16)value);
|
||||
case 32: return ((__u32)value);
|
||||
}
|
||||
return value & (1 << (n - 1)) ? value & (~(~0U << n)) : value;
|
||||
}
|
||||
|
||||
extern const struct hid_device_id wacom_ids[];
|
||||
|
||||
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len);
|
||||
|
||||
@@ -2303,7 +2303,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
||||
case HID_DG_TOOLSERIALNUMBER:
|
||||
if (value) {
|
||||
wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
|
||||
wacom_wac->serial[0] |= (__u32)value;
|
||||
wacom_wac->serial[0] |= wacom_s32tou(value, field->report_size);
|
||||
}
|
||||
return;
|
||||
case HID_DG_TWIST:
|
||||
@@ -2319,15 +2319,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
||||
return;
|
||||
case WACOM_HID_WD_SERIALHI:
|
||||
if (value) {
|
||||
__u32 raw_value = wacom_s32tou(value, field->report_size);
|
||||
|
||||
wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
|
||||
wacom_wac->serial[0] |= ((__u64)value) << 32;
|
||||
wacom_wac->serial[0] |= ((__u64)raw_value) << 32;
|
||||
/*
|
||||
* Non-USI EMR devices may contain additional tool type
|
||||
* information here. See WACOM_HID_WD_TOOLTYPE case for
|
||||
* more details.
|
||||
*/
|
||||
if (value >> 20 == 1) {
|
||||
wacom_wac->id[0] |= value & 0xFFFFF;
|
||||
wacom_wac->id[0] |= raw_value & 0xFFFFF;
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -2339,7 +2341,7 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
|
||||
* bitwise OR so the complete value can be built
|
||||
* up over time :(
|
||||
*/
|
||||
wacom_wac->id[0] |= value;
|
||||
wacom_wac->id[0] |= wacom_s32tou(value, field->report_size);
|
||||
return;
|
||||
case WACOM_HID_WD_OFFSETLEFT:
|
||||
if (features->offset_left && value != features->offset_left)
|
||||
|
||||
@@ -626,6 +626,9 @@ static void intel_th_gth_switch(struct intel_th_device *thdev,
|
||||
if (!count)
|
||||
dev_dbg(&thdev->dev, "timeout waiting for CTS Trigger\n");
|
||||
|
||||
/* De-assert the trigger */
|
||||
iowrite32(0, gth->base + REG_CTS_CTL);
|
||||
|
||||
intel_th_gth_stop(gth, output, false);
|
||||
intel_th_gth_start(gth, output);
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ struct msc {
|
||||
};
|
||||
|
||||
static LIST_HEAD(msu_buffer_list);
|
||||
static struct mutex msu_buffer_mutex;
|
||||
static DEFINE_MUTEX(msu_buffer_mutex);
|
||||
|
||||
/**
|
||||
* struct msu_buffer_entry - internal MSU buffer bookkeeping
|
||||
@@ -327,7 +327,7 @@ static size_t msc_win_total_sz(struct msc_window *win)
|
||||
struct msc_block_desc *bdesc = sg_virt(sg);
|
||||
|
||||
if (msc_block_wrapped(bdesc))
|
||||
return win->nr_blocks << PAGE_SHIFT;
|
||||
return (size_t)win->nr_blocks << PAGE_SHIFT;
|
||||
|
||||
size += msc_total_sz(bdesc);
|
||||
if (msc_block_last_written(bdesc))
|
||||
@@ -1848,9 +1848,14 @@ mode_store(struct device *dev, struct device_attribute *attr, const char *buf,
|
||||
len = cp - buf;
|
||||
|
||||
mode = kstrndup(buf, len, GFP_KERNEL);
|
||||
if (!mode)
|
||||
return -ENOMEM;
|
||||
|
||||
i = match_string(msc_mode, ARRAY_SIZE(msc_mode), mode);
|
||||
if (i >= 0)
|
||||
if (i >= 0) {
|
||||
kfree(mode);
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* Buffer sinks only work with a usable IRQ */
|
||||
if (!msc->do_irq) {
|
||||
|
||||
@@ -199,6 +199,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{
|
||||
/* Comet Lake PCH */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6),
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{
|
||||
/* Ice Lake NNPI */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
|
||||
@@ -209,6 +214,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{
|
||||
/* Jasper Lake PCH */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
|
||||
.driver_data = (kernel_ulong_t)&intel_th_2x,
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
||||
@@ -1399,7 +1399,7 @@ static int stm32_adc_dma_start(struct iio_dev *indio_dev)
|
||||
cookie = dmaengine_submit(desc);
|
||||
ret = dma_submit_error(cookie);
|
||||
if (ret) {
|
||||
dmaengine_terminate_all(adc->dma_chan);
|
||||
dmaengine_terminate_sync(adc->dma_chan);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1477,7 +1477,7 @@ static void __stm32_adc_buffer_predisable(struct iio_dev *indio_dev)
|
||||
stm32_adc_conv_irq_disable(adc);
|
||||
|
||||
if (adc->dma_chan)
|
||||
dmaengine_terminate_all(adc->dma_chan);
|
||||
dmaengine_terminate_sync(adc->dma_chan);
|
||||
|
||||
if (stm32_adc_set_trig(indio_dev, NULL))
|
||||
dev_err(&indio_dev->dev, "Can't clear trigger\n");
|
||||
|
||||
@@ -317,8 +317,11 @@ static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2)
|
||||
struct adis16480 *st = iio_priv(indio_dev);
|
||||
unsigned int t, reg;
|
||||
|
||||
if (val < 0 || val2 < 0)
|
||||
return -EINVAL;
|
||||
|
||||
t = val * 1000 + val2 / 1000;
|
||||
if (t <= 0)
|
||||
if (t == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
|
||||
@@ -114,54 +114,63 @@ static const struct inv_mpu6050_hw hw_info[] = {
|
||||
.name = "MPU6050",
|
||||
.reg = ®_set_6050,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 1024,
|
||||
},
|
||||
{
|
||||
.whoami = INV_MPU6500_WHOAMI_VALUE,
|
||||
.name = "MPU6500",
|
||||
.reg = ®_set_6500,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 512,
|
||||
},
|
||||
{
|
||||
.whoami = INV_MPU6515_WHOAMI_VALUE,
|
||||
.name = "MPU6515",
|
||||
.reg = ®_set_6500,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 512,
|
||||
},
|
||||
{
|
||||
.whoami = INV_MPU6000_WHOAMI_VALUE,
|
||||
.name = "MPU6000",
|
||||
.reg = ®_set_6050,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 1024,
|
||||
},
|
||||
{
|
||||
.whoami = INV_MPU9150_WHOAMI_VALUE,
|
||||
.name = "MPU9150",
|
||||
.reg = ®_set_6050,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 1024,
|
||||
},
|
||||
{
|
||||
.whoami = INV_MPU9250_WHOAMI_VALUE,
|
||||
.name = "MPU9250",
|
||||
.reg = ®_set_6500,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 512,
|
||||
},
|
||||
{
|
||||
.whoami = INV_MPU9255_WHOAMI_VALUE,
|
||||
.name = "MPU9255",
|
||||
.reg = ®_set_6500,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 512,
|
||||
},
|
||||
{
|
||||
.whoami = INV_ICM20608_WHOAMI_VALUE,
|
||||
.name = "ICM20608",
|
||||
.reg = ®_set_6500,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 512,
|
||||
},
|
||||
{
|
||||
.whoami = INV_ICM20602_WHOAMI_VALUE,
|
||||
.name = "ICM20602",
|
||||
.reg = ®_set_icm20602,
|
||||
.config = &chip_config_6050,
|
||||
.fifo_size = 1008,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -100,12 +100,14 @@ struct inv_mpu6050_chip_config {
|
||||
* @name: name of the chip.
|
||||
* @reg: register map of the chip.
|
||||
* @config: configuration of the chip.
|
||||
* @fifo_size: size of the FIFO in bytes.
|
||||
*/
|
||||
struct inv_mpu6050_hw {
|
||||
u8 whoami;
|
||||
u8 *name;
|
||||
const struct inv_mpu6050_reg_map *reg;
|
||||
const struct inv_mpu6050_chip_config *config;
|
||||
size_t fifo_size;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -180,9 +180,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
||||
"failed to ack interrupt\n");
|
||||
goto flush_fifo;
|
||||
}
|
||||
/* handle fifo overflow by reseting fifo */
|
||||
if (int_status & INV_MPU6050_BIT_FIFO_OVERFLOW_INT)
|
||||
goto flush_fifo;
|
||||
if (!(int_status & INV_MPU6050_BIT_RAW_DATA_RDY_INT)) {
|
||||
dev_warn(regmap_get_device(st->map),
|
||||
"spurious interrupt with status 0x%x\n", int_status);
|
||||
@@ -211,6 +208,18 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
||||
if (result)
|
||||
goto end_session;
|
||||
fifo_count = get_unaligned_be16(&data[0]);
|
||||
|
||||
/*
|
||||
* Handle fifo overflow by resetting fifo.
|
||||
* Reset if there is only 3 data set free remaining to mitigate
|
||||
* possible delay between reading fifo count and fifo data.
|
||||
*/
|
||||
nb = 3 * bytes_per_datum;
|
||||
if (fifo_count >= st->hw->fifo_size - nb) {
|
||||
dev_warn(regmap_get_device(st->map), "fifo overflow reset\n");
|
||||
goto flush_fifo;
|
||||
}
|
||||
|
||||
/* compute and process all complete datum */
|
||||
nb = fifo_count / bytes_per_datum;
|
||||
inv_mpu6050_update_period(st, pf->timestamp, nb);
|
||||
|
||||
@@ -110,7 +110,7 @@ static int srf04_read(struct srf04_data *data)
|
||||
udelay(data->cfg->trigger_pulse_us);
|
||||
gpiod_set_value(data->gpiod_trig, 0);
|
||||
|
||||
/* it cannot take more than 20 ms */
|
||||
/* it should not take more than 20 ms until echo is rising */
|
||||
ret = wait_for_completion_killable_timeout(&data->rising, HZ/50);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&data->lock);
|
||||
@@ -120,7 +120,8 @@ static int srf04_read(struct srf04_data *data)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
ret = wait_for_completion_killable_timeout(&data->falling, HZ/50);
|
||||
/* it cannot take more than 50 ms until echo is falling */
|
||||
ret = wait_for_completion_killable_timeout(&data->falling, HZ/20);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&data->lock);
|
||||
return ret;
|
||||
@@ -135,19 +136,19 @@ static int srf04_read(struct srf04_data *data)
|
||||
|
||||
dt_ns = ktime_to_ns(ktime_dt);
|
||||
/*
|
||||
* measuring more than 3 meters is beyond the capabilities of
|
||||
* the sensor
|
||||
* measuring more than 6,45 meters is beyond the capabilities of
|
||||
* the supported sensors
|
||||
* ==> filter out invalid results for not measuring echos of
|
||||
* another us sensor
|
||||
*
|
||||
* formula:
|
||||
* distance 3 m
|
||||
* time = ---------- = --------- = 9404389 ns
|
||||
* speed 319 m/s
|
||||
* distance 6,45 * 2 m
|
||||
* time = ---------- = ------------ = 40438871 ns
|
||||
* speed 319 m/s
|
||||
*
|
||||
* using a minimum speed at -20 °C of 319 m/s
|
||||
*/
|
||||
if (dt_ns > 9404389)
|
||||
if (dt_ns > 40438871)
|
||||
return -EIO;
|
||||
|
||||
time_ns = dt_ns;
|
||||
@@ -159,20 +160,20 @@ static int srf04_read(struct srf04_data *data)
|
||||
* with Temp in °C
|
||||
* and speed in m/s
|
||||
*
|
||||
* use 343 m/s as ultrasonic speed at 20 °C here in absence of the
|
||||
* use 343,5 m/s as ultrasonic speed at 20 °C here in absence of the
|
||||
* temperature
|
||||
*
|
||||
* therefore:
|
||||
* time 343
|
||||
* distance = ------ * -----
|
||||
* 10^6 2
|
||||
* time 343,5 time * 106
|
||||
* distance = ------ * ------- = ------------
|
||||
* 10^6 2 617176
|
||||
* with time in ns
|
||||
* and distance in mm (one way)
|
||||
*
|
||||
* because we limit to 3 meters the multiplication with 343 just
|
||||
* because we limit to 6,45 meters the multiplication with 106 just
|
||||
* fits into 32 bit
|
||||
*/
|
||||
distance_mm = time_ns * 343 / 2000000;
|
||||
distance_mm = time_ns * 106 / 617176;
|
||||
|
||||
return distance_mm;
|
||||
}
|
||||
|
||||
@@ -405,8 +405,12 @@ void icc_set_tag(struct icc_path *path, u32 tag)
|
||||
if (!path)
|
||||
return;
|
||||
|
||||
mutex_lock(&icc_lock);
|
||||
|
||||
for (i = 0; i < path->num_nodes; i++)
|
||||
path->reqs[i].tag = tag;
|
||||
|
||||
mutex_unlock(&icc_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(icc_set_tag);
|
||||
|
||||
|
||||
@@ -433,7 +433,8 @@ static int qnoc_probe(struct platform_device *pdev)
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kcalloc(dev, num_nodes, sizeof(*node), GFP_KERNEL);
|
||||
data = devm_kzalloc(dev, struct_size(data, nodes, num_nodes),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -790,7 +790,8 @@ static int qnoc_probe(struct platform_device *pdev)
|
||||
if (!qp)
|
||||
return -ENOMEM;
|
||||
|
||||
data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
|
||||
data = devm_kzalloc(&pdev->dev, struct_size(data, nodes, num_nodes),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -2083,8 +2083,7 @@ static int bond_miimon_inspect(struct bonding *bond)
|
||||
ignore_updelay = !rcu_dereference(bond->curr_active_slave);
|
||||
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
slave->new_link = BOND_LINK_NOCHANGE;
|
||||
slave->link_new_state = slave->link;
|
||||
bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
|
||||
|
||||
link_state = bond_check_dev_link(bond, slave->dev, 0);
|
||||
|
||||
@@ -2118,7 +2117,7 @@ static int bond_miimon_inspect(struct bonding *bond)
|
||||
}
|
||||
|
||||
if (slave->delay <= 0) {
|
||||
slave->new_link = BOND_LINK_DOWN;
|
||||
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||
commit++;
|
||||
continue;
|
||||
}
|
||||
@@ -2155,7 +2154,7 @@ static int bond_miimon_inspect(struct bonding *bond)
|
||||
slave->delay = 0;
|
||||
|
||||
if (slave->delay <= 0) {
|
||||
slave->new_link = BOND_LINK_UP;
|
||||
bond_propose_link_state(slave, BOND_LINK_UP);
|
||||
commit++;
|
||||
ignore_updelay = false;
|
||||
continue;
|
||||
@@ -2193,7 +2192,7 @@ static void bond_miimon_commit(struct bonding *bond)
|
||||
struct slave *slave, *primary;
|
||||
|
||||
bond_for_each_slave(bond, slave, iter) {
|
||||
switch (slave->new_link) {
|
||||
switch (slave->link_new_state) {
|
||||
case BOND_LINK_NOCHANGE:
|
||||
/* For 802.3ad mode, check current slave speed and
|
||||
* duplex again in case its port was disabled after
|
||||
@@ -2265,8 +2264,8 @@ static void bond_miimon_commit(struct bonding *bond)
|
||||
|
||||
default:
|
||||
slave_err(bond->dev, slave->dev, "invalid new link %d on slave\n",
|
||||
slave->new_link);
|
||||
slave->new_link = BOND_LINK_NOCHANGE;
|
||||
slave->link_new_state);
|
||||
bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -2674,13 +2673,13 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
unsigned long trans_start = dev_trans_start(slave->dev);
|
||||
|
||||
slave->new_link = BOND_LINK_NOCHANGE;
|
||||
bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
|
||||
|
||||
if (slave->link != BOND_LINK_UP) {
|
||||
if (bond_time_in_interval(bond, trans_start, 1) &&
|
||||
bond_time_in_interval(bond, slave->last_rx, 1)) {
|
||||
|
||||
slave->new_link = BOND_LINK_UP;
|
||||
bond_propose_link_state(slave, BOND_LINK_UP);
|
||||
slave_state_changed = 1;
|
||||
|
||||
/* primary_slave has no meaning in round-robin
|
||||
@@ -2705,7 +2704,7 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
|
||||
if (!bond_time_in_interval(bond, trans_start, 2) ||
|
||||
!bond_time_in_interval(bond, slave->last_rx, 2)) {
|
||||
|
||||
slave->new_link = BOND_LINK_DOWN;
|
||||
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||
slave_state_changed = 1;
|
||||
|
||||
if (slave->link_failure_count < UINT_MAX)
|
||||
@@ -2736,8 +2735,8 @@ static void bond_loadbalance_arp_mon(struct bonding *bond)
|
||||
goto re_arm;
|
||||
|
||||
bond_for_each_slave(bond, slave, iter) {
|
||||
if (slave->new_link != BOND_LINK_NOCHANGE)
|
||||
slave->link = slave->new_link;
|
||||
if (slave->link_new_state != BOND_LINK_NOCHANGE)
|
||||
slave->link = slave->link_new_state;
|
||||
}
|
||||
|
||||
if (slave_state_changed) {
|
||||
@@ -2760,9 +2759,9 @@ re_arm:
|
||||
}
|
||||
|
||||
/* Called to inspect slaves for active-backup mode ARP monitor link state
|
||||
* changes. Sets new_link in slaves to specify what action should take
|
||||
* place for the slave. Returns 0 if no changes are found, >0 if changes
|
||||
* to link states must be committed.
|
||||
* changes. Sets proposed link state in slaves to specify what action
|
||||
* should take place for the slave. Returns 0 if no changes are found, >0
|
||||
* if changes to link states must be committed.
|
||||
*
|
||||
* Called with rcu_read_lock held.
|
||||
*/
|
||||
@@ -2774,12 +2773,12 @@ static int bond_ab_arp_inspect(struct bonding *bond)
|
||||
int commit = 0;
|
||||
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
slave->new_link = BOND_LINK_NOCHANGE;
|
||||
bond_propose_link_state(slave, BOND_LINK_NOCHANGE);
|
||||
last_rx = slave_last_rx(bond, slave);
|
||||
|
||||
if (slave->link != BOND_LINK_UP) {
|
||||
if (bond_time_in_interval(bond, last_rx, 1)) {
|
||||
slave->new_link = BOND_LINK_UP;
|
||||
bond_propose_link_state(slave, BOND_LINK_UP);
|
||||
commit++;
|
||||
}
|
||||
continue;
|
||||
@@ -2807,7 +2806,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
|
||||
if (!bond_is_active_slave(slave) &&
|
||||
!rcu_access_pointer(bond->current_arp_slave) &&
|
||||
!bond_time_in_interval(bond, last_rx, 3)) {
|
||||
slave->new_link = BOND_LINK_DOWN;
|
||||
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||
commit++;
|
||||
}
|
||||
|
||||
@@ -2820,7 +2819,7 @@ static int bond_ab_arp_inspect(struct bonding *bond)
|
||||
if (bond_is_active_slave(slave) &&
|
||||
(!bond_time_in_interval(bond, trans_start, 2) ||
|
||||
!bond_time_in_interval(bond, last_rx, 2))) {
|
||||
slave->new_link = BOND_LINK_DOWN;
|
||||
bond_propose_link_state(slave, BOND_LINK_DOWN);
|
||||
commit++;
|
||||
}
|
||||
}
|
||||
@@ -2840,7 +2839,7 @@ static void bond_ab_arp_commit(struct bonding *bond)
|
||||
struct slave *slave;
|
||||
|
||||
bond_for_each_slave(bond, slave, iter) {
|
||||
switch (slave->new_link) {
|
||||
switch (slave->link_new_state) {
|
||||
case BOND_LINK_NOCHANGE:
|
||||
continue;
|
||||
|
||||
@@ -2890,8 +2889,9 @@ static void bond_ab_arp_commit(struct bonding *bond)
|
||||
continue;
|
||||
|
||||
default:
|
||||
slave_err(bond->dev, slave->dev, "impossible: new_link %d on slave\n",
|
||||
slave->new_link);
|
||||
slave_err(bond->dev, slave->dev,
|
||||
"impossible: link_new_state %d on slave\n",
|
||||
slave->link_new_state);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#define CONTROL_EX_PDR BIT(8)
|
||||
|
||||
/* control register */
|
||||
#define CONTROL_SWR BIT(15)
|
||||
#define CONTROL_TEST BIT(7)
|
||||
#define CONTROL_CCE BIT(6)
|
||||
#define CONTROL_DISABLE_AR BIT(5)
|
||||
@@ -97,6 +98,9 @@
|
||||
#define BTR_TSEG2_SHIFT 12
|
||||
#define BTR_TSEG2_MASK (0x7 << BTR_TSEG2_SHIFT)
|
||||
|
||||
/* interrupt register */
|
||||
#define INT_STS_PENDING 0x8000
|
||||
|
||||
/* brp extension register */
|
||||
#define BRP_EXT_BRPE_MASK 0x0f
|
||||
#define BRP_EXT_BRPE_SHIFT 0
|
||||
@@ -569,6 +573,26 @@ static void c_can_configure_msg_objects(struct net_device *dev)
|
||||
IF_MCONT_RCV_EOB);
|
||||
}
|
||||
|
||||
static int c_can_software_reset(struct net_device *dev)
|
||||
{
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
int retry = 0;
|
||||
|
||||
if (priv->type != BOSCH_D_CAN)
|
||||
return 0;
|
||||
|
||||
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_SWR | CONTROL_INIT);
|
||||
while (priv->read_reg(priv, C_CAN_CTRL_REG) & CONTROL_SWR) {
|
||||
msleep(20);
|
||||
if (retry++ > 100) {
|
||||
netdev_err(dev, "CCTRL: software reset failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure C_CAN chip:
|
||||
* - enable/disable auto-retransmission
|
||||
@@ -578,6 +602,11 @@ static void c_can_configure_msg_objects(struct net_device *dev)
|
||||
static int c_can_chip_config(struct net_device *dev)
|
||||
{
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
err = c_can_software_reset(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* enable automatic retransmission */
|
||||
priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR);
|
||||
@@ -886,6 +915,9 @@ static int c_can_handle_state_change(struct net_device *dev,
|
||||
struct can_berr_counter bec;
|
||||
|
||||
switch (error_type) {
|
||||
case C_CAN_NO_ERROR:
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
break;
|
||||
case C_CAN_ERROR_WARNING:
|
||||
/* error warning state */
|
||||
priv->can.can_stats.error_warning++;
|
||||
@@ -916,6 +948,13 @@ static int c_can_handle_state_change(struct net_device *dev,
|
||||
ERR_CNT_RP_SHIFT;
|
||||
|
||||
switch (error_type) {
|
||||
case C_CAN_NO_ERROR:
|
||||
/* error warning state */
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
|
||||
cf->data[6] = bec.txerr;
|
||||
cf->data[7] = bec.rxerr;
|
||||
break;
|
||||
case C_CAN_ERROR_WARNING:
|
||||
/* error warning state */
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
@@ -1029,10 +1068,16 @@ static int c_can_poll(struct napi_struct *napi, int quota)
|
||||
u16 curr, last = priv->last_status;
|
||||
int work_done = 0;
|
||||
|
||||
priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
|
||||
/* Ack status on C_CAN. D_CAN is self clearing */
|
||||
if (priv->type != BOSCH_D_CAN)
|
||||
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
|
||||
/* Only read the status register if a status interrupt was pending */
|
||||
if (atomic_xchg(&priv->sie_pending, 0)) {
|
||||
priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG);
|
||||
/* Ack status on C_CAN. D_CAN is self clearing */
|
||||
if (priv->type != BOSCH_D_CAN)
|
||||
priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED);
|
||||
} else {
|
||||
/* no change detected ... */
|
||||
curr = last;
|
||||
}
|
||||
|
||||
/* handle state changes */
|
||||
if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) {
|
||||
@@ -1054,11 +1099,17 @@ static int c_can_poll(struct napi_struct *napi, int quota)
|
||||
/* handle bus recovery events */
|
||||
if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) {
|
||||
netdev_dbg(dev, "left bus off state\n");
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE);
|
||||
}
|
||||
|
||||
if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) {
|
||||
netdev_dbg(dev, "left error passive state\n");
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING);
|
||||
}
|
||||
|
||||
if ((!(curr & STATUS_EWARN)) && (last & STATUS_EWARN)) {
|
||||
netdev_dbg(dev, "left error warning state\n");
|
||||
work_done += c_can_handle_state_change(dev, C_CAN_NO_ERROR);
|
||||
}
|
||||
|
||||
/* handle lec errors on the bus */
|
||||
@@ -1083,10 +1134,16 @@ static irqreturn_t c_can_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
int reg_int;
|
||||
|
||||
if (!priv->read_reg(priv, C_CAN_INT_REG))
|
||||
reg_int = priv->read_reg(priv, C_CAN_INT_REG);
|
||||
if (!reg_int)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* save for later use */
|
||||
if (reg_int & INT_STS_PENDING)
|
||||
atomic_set(&priv->sie_pending, 1);
|
||||
|
||||
/* disable all interrupts and schedule the NAPI */
|
||||
c_can_irq_control(priv, false);
|
||||
napi_schedule(&priv->napi);
|
||||
|
||||
@@ -198,6 +198,7 @@ struct c_can_priv {
|
||||
struct net_device *dev;
|
||||
struct device *device;
|
||||
atomic_t tx_active;
|
||||
atomic_t sie_pending;
|
||||
unsigned long tx_dir;
|
||||
int last_status;
|
||||
u16 (*read_reg) (const struct c_can_priv *priv, enum reg index);
|
||||
|
||||
@@ -848,6 +848,7 @@ void of_can_transceiver(struct net_device *dev)
|
||||
return;
|
||||
|
||||
ret = of_property_read_u32(dn, "max-bitrate", &priv->bitrate_max);
|
||||
of_node_put(dn);
|
||||
if ((ret && ret != -EINVAL) || (!ret && !priv->bitrate_max))
|
||||
netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n");
|
||||
}
|
||||
|
||||
@@ -677,6 +677,7 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
|
||||
struct can_frame *cf;
|
||||
bool rx_errors = false, tx_errors = false;
|
||||
u32 timestamp;
|
||||
int err;
|
||||
|
||||
timestamp = priv->read(®s->timer) << 16;
|
||||
|
||||
@@ -725,7 +726,9 @@ static void flexcan_irq_bus_err(struct net_device *dev, u32 reg_esr)
|
||||
if (tx_errors)
|
||||
dev->stats.tx_errors++;
|
||||
|
||||
can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
if (err)
|
||||
dev->stats.rx_fifo_errors++;
|
||||
}
|
||||
|
||||
static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
|
||||
@@ -738,6 +741,7 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
|
||||
int flt;
|
||||
struct can_berr_counter bec;
|
||||
u32 timestamp;
|
||||
int err;
|
||||
|
||||
timestamp = priv->read(®s->timer) << 16;
|
||||
|
||||
@@ -769,7 +773,9 @@ static void flexcan_irq_state(struct net_device *dev, u32 reg_esr)
|
||||
if (unlikely(new_state == CAN_STATE_BUS_OFF))
|
||||
can_bus_off(dev);
|
||||
|
||||
can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
if (err)
|
||||
dev->stats.rx_fifo_errors++;
|
||||
}
|
||||
|
||||
static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload)
|
||||
@@ -1188,6 +1194,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
||||
reg_mecr = priv->read(®s->mecr);
|
||||
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
|
||||
priv->write(reg_mecr, ®s->mecr);
|
||||
reg_mecr |= FLEXCAN_MECR_ECCDIS;
|
||||
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
|
||||
FLEXCAN_MECR_FANCEI_MSK);
|
||||
priv->write(reg_mecr, ®s->mecr);
|
||||
|
||||
@@ -107,37 +107,95 @@ static int can_rx_offload_compare(struct sk_buff *a, struct sk_buff *b)
|
||||
return cb_b->timestamp - cb_a->timestamp;
|
||||
}
|
||||
|
||||
static struct sk_buff *can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n)
|
||||
/**
|
||||
* can_rx_offload_offload_one() - Read one CAN frame from HW
|
||||
* @offload: pointer to rx_offload context
|
||||
* @n: number of mailbox to read
|
||||
*
|
||||
* The task of this function is to read a CAN frame from mailbox @n
|
||||
* from the device and return the mailbox's content as a struct
|
||||
* sk_buff.
|
||||
*
|
||||
* If the struct can_rx_offload::skb_queue exceeds the maximal queue
|
||||
* length (struct can_rx_offload::skb_queue_len_max) or no skb can be
|
||||
* allocated, the mailbox contents is discarded by reading it into an
|
||||
* overflow buffer. This way the mailbox is marked as free by the
|
||||
* driver.
|
||||
*
|
||||
* Return: A pointer to skb containing the CAN frame on success.
|
||||
*
|
||||
* NULL if the mailbox @n is empty.
|
||||
*
|
||||
* ERR_PTR() in case of an error
|
||||
*/
|
||||
static struct sk_buff *
|
||||
can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n)
|
||||
{
|
||||
struct sk_buff *skb = NULL;
|
||||
struct sk_buff *skb = NULL, *skb_error = NULL;
|
||||
struct can_rx_offload_cb *cb;
|
||||
struct can_frame *cf;
|
||||
int ret;
|
||||
|
||||
/* If queue is full or skb not available, read to discard mailbox */
|
||||
if (likely(skb_queue_len(&offload->skb_queue) <=
|
||||
offload->skb_queue_len_max))
|
||||
if (likely(skb_queue_len(&offload->skb_queue) <
|
||||
offload->skb_queue_len_max)) {
|
||||
skb = alloc_can_skb(offload->dev, &cf);
|
||||
if (unlikely(!skb))
|
||||
skb_error = ERR_PTR(-ENOMEM); /* skb alloc failed */
|
||||
} else {
|
||||
skb_error = ERR_PTR(-ENOBUFS); /* skb_queue is full */
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
/* If queue is full or skb not available, drop by reading into
|
||||
* overflow buffer.
|
||||
*/
|
||||
if (unlikely(skb_error)) {
|
||||
struct can_frame cf_overflow;
|
||||
u32 timestamp;
|
||||
|
||||
ret = offload->mailbox_read(offload, &cf_overflow,
|
||||
×tamp, n);
|
||||
if (ret)
|
||||
offload->dev->stats.rx_dropped++;
|
||||
|
||||
return NULL;
|
||||
/* Mailbox was empty. */
|
||||
if (unlikely(!ret))
|
||||
return NULL;
|
||||
|
||||
/* Mailbox has been read and we're dropping it or
|
||||
* there was a problem reading the mailbox.
|
||||
*
|
||||
* Increment error counters in any case.
|
||||
*/
|
||||
offload->dev->stats.rx_dropped++;
|
||||
offload->dev->stats.rx_fifo_errors++;
|
||||
|
||||
/* There was a problem reading the mailbox, propagate
|
||||
* error value.
|
||||
*/
|
||||
if (unlikely(ret < 0))
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return skb_error;
|
||||
}
|
||||
|
||||
cb = can_rx_offload_get_cb(skb);
|
||||
ret = offload->mailbox_read(offload, cf, &cb->timestamp, n);
|
||||
if (!ret) {
|
||||
|
||||
/* Mailbox was empty. */
|
||||
if (unlikely(!ret)) {
|
||||
kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* There was a problem reading the mailbox, propagate error value. */
|
||||
if (unlikely(ret < 0)) {
|
||||
kfree_skb(skb);
|
||||
|
||||
offload->dev->stats.rx_dropped++;
|
||||
offload->dev->stats.rx_fifo_errors++;
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/* Mailbox was read. */
|
||||
return skb;
|
||||
}
|
||||
|
||||
@@ -157,8 +215,8 @@ int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 pen
|
||||
continue;
|
||||
|
||||
skb = can_rx_offload_offload_one(offload, i);
|
||||
if (!skb)
|
||||
break;
|
||||
if (IS_ERR_OR_NULL(skb))
|
||||
continue;
|
||||
|
||||
__skb_queue_add_sort(&skb_queue, skb, can_rx_offload_compare);
|
||||
}
|
||||
@@ -188,7 +246,13 @@ int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload)
|
||||
struct sk_buff *skb;
|
||||
int received = 0;
|
||||
|
||||
while ((skb = can_rx_offload_offload_one(offload, 0))) {
|
||||
while (1) {
|
||||
skb = can_rx_offload_offload_one(offload, 0);
|
||||
if (IS_ERR(skb))
|
||||
continue;
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
skb_queue_tail(&offload->skb_queue, skb);
|
||||
received++;
|
||||
}
|
||||
@@ -207,8 +271,10 @@ int can_rx_offload_queue_sorted(struct can_rx_offload *offload,
|
||||
unsigned long flags;
|
||||
|
||||
if (skb_queue_len(&offload->skb_queue) >
|
||||
offload->skb_queue_len_max)
|
||||
return -ENOMEM;
|
||||
offload->skb_queue_len_max) {
|
||||
kfree_skb(skb);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
cb = can_rx_offload_get_cb(skb);
|
||||
cb->timestamp = timestamp;
|
||||
@@ -250,8 +316,10 @@ int can_rx_offload_queue_tail(struct can_rx_offload *offload,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
if (skb_queue_len(&offload->skb_queue) >
|
||||
offload->skb_queue_len_max)
|
||||
return -ENOMEM;
|
||||
offload->skb_queue_len_max) {
|
||||
kfree_skb(skb);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
skb_queue_tail(&offload->skb_queue, skb);
|
||||
can_rx_offload_schedule(offload);
|
||||
|
||||
@@ -717,6 +717,7 @@ static void mcp251x_restart_work_handler(struct work_struct *ws)
|
||||
if (priv->after_suspend) {
|
||||
mcp251x_hw_reset(spi);
|
||||
mcp251x_setup(net, spi);
|
||||
priv->force_quit = 0;
|
||||
if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
|
||||
mcp251x_set_normal_mode(spi);
|
||||
} else if (priv->after_suspend & AFTER_SUSPEND_UP) {
|
||||
@@ -728,7 +729,6 @@ static void mcp251x_restart_work_handler(struct work_struct *ws)
|
||||
mcp251x_hw_sleep(spi);
|
||||
}
|
||||
priv->after_suspend = 0;
|
||||
priv->force_quit = 0;
|
||||
}
|
||||
|
||||
if (priv->restart_tx) {
|
||||
|
||||
@@ -73,6 +73,7 @@ MODULE_VERSION(HECC_MODULE_VERSION);
|
||||
*/
|
||||
#define HECC_MAX_RX_MBOX (HECC_MAX_MAILBOXES - HECC_MAX_TX_MBOX)
|
||||
#define HECC_RX_FIRST_MBOX (HECC_MAX_MAILBOXES - 1)
|
||||
#define HECC_RX_LAST_MBOX (HECC_MAX_TX_MBOX)
|
||||
|
||||
/* TI HECC module registers */
|
||||
#define HECC_CANME 0x0 /* Mailbox enable */
|
||||
@@ -82,7 +83,7 @@ MODULE_VERSION(HECC_MODULE_VERSION);
|
||||
#define HECC_CANTA 0x10 /* Transmission acknowledge */
|
||||
#define HECC_CANAA 0x14 /* Abort acknowledge */
|
||||
#define HECC_CANRMP 0x18 /* Receive message pending */
|
||||
#define HECC_CANRML 0x1C /* Remote message lost */
|
||||
#define HECC_CANRML 0x1C /* Receive message lost */
|
||||
#define HECC_CANRFP 0x20 /* Remote frame pending */
|
||||
#define HECC_CANGAM 0x24 /* SECC only:Global acceptance mask */
|
||||
#define HECC_CANMC 0x28 /* Master control */
|
||||
@@ -149,6 +150,8 @@ MODULE_VERSION(HECC_MODULE_VERSION);
|
||||
#define HECC_BUS_ERROR (HECC_CANES_FE | HECC_CANES_BE |\
|
||||
HECC_CANES_CRCE | HECC_CANES_SE |\
|
||||
HECC_CANES_ACKE)
|
||||
#define HECC_CANES_FLAGS (HECC_BUS_ERROR | HECC_CANES_BO |\
|
||||
HECC_CANES_EP | HECC_CANES_EW)
|
||||
|
||||
#define HECC_CANMCF_RTR BIT(4) /* Remote transmit request */
|
||||
|
||||
@@ -382,8 +385,18 @@ static void ti_hecc_start(struct net_device *ndev)
|
||||
hecc_set_bit(priv, HECC_CANMIM, mbx_mask);
|
||||
}
|
||||
|
||||
/* Prevent message over-write & Enable interrupts */
|
||||
hecc_write(priv, HECC_CANOPC, HECC_SET_REG);
|
||||
/* Enable tx interrupts */
|
||||
hecc_set_bit(priv, HECC_CANMIM, BIT(HECC_MAX_TX_MBOX) - 1);
|
||||
|
||||
/* Prevent message over-write to create a rx fifo, but not for
|
||||
* the lowest priority mailbox, since that allows detecting
|
||||
* overflows instead of the hardware silently dropping the
|
||||
* messages.
|
||||
*/
|
||||
mbx_mask = ~BIT(HECC_RX_LAST_MBOX);
|
||||
hecc_write(priv, HECC_CANOPC, mbx_mask);
|
||||
|
||||
/* Enable interrupts */
|
||||
if (priv->use_hecc1int) {
|
||||
hecc_write(priv, HECC_CANMIL, HECC_SET_REG);
|
||||
hecc_write(priv, HECC_CANGIM, HECC_CANGIM_DEF_MASK |
|
||||
@@ -400,6 +413,9 @@ static void ti_hecc_stop(struct net_device *ndev)
|
||||
{
|
||||
struct ti_hecc_priv *priv = netdev_priv(ndev);
|
||||
|
||||
/* Disable the CPK; stop sending, erroring and acking */
|
||||
hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
|
||||
|
||||
/* Disable interrupts and disable mailboxes */
|
||||
hecc_write(priv, HECC_CANGIM, 0);
|
||||
hecc_write(priv, HECC_CANMIM, 0);
|
||||
@@ -508,8 +524,6 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
hecc_set_bit(priv, HECC_CANME, mbx_mask);
|
||||
spin_unlock_irqrestore(&priv->mbx_lock, flags);
|
||||
|
||||
hecc_clear_bit(priv, HECC_CANMD, mbx_mask);
|
||||
hecc_set_bit(priv, HECC_CANMIM, mbx_mask);
|
||||
hecc_write(priv, HECC_CANTRS, mbx_mask);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
@@ -526,8 +540,10 @@ static unsigned int ti_hecc_mailbox_read(struct can_rx_offload *offload,
|
||||
u32 *timestamp, unsigned int mbxno)
|
||||
{
|
||||
struct ti_hecc_priv *priv = rx_offload_to_priv(offload);
|
||||
u32 data;
|
||||
u32 data, mbx_mask;
|
||||
int ret = 1;
|
||||
|
||||
mbx_mask = BIT(mbxno);
|
||||
data = hecc_read_mbx(priv, mbxno, HECC_CANMID);
|
||||
if (data & HECC_CANMID_IDE)
|
||||
cf->can_id = (data & CAN_EFF_MASK) | CAN_EFF_FLAG;
|
||||
@@ -548,7 +564,25 @@ static unsigned int ti_hecc_mailbox_read(struct can_rx_offload *offload,
|
||||
|
||||
*timestamp = hecc_read_stamp(priv, mbxno);
|
||||
|
||||
return 1;
|
||||
/* Check for FIFO overrun.
|
||||
*
|
||||
* All but the last RX mailbox have activated overwrite
|
||||
* protection. So skip check for overrun, if we're not
|
||||
* handling the last RX mailbox.
|
||||
*
|
||||
* As the overwrite protection for the last RX mailbox is
|
||||
* disabled, the CAN core might update while we're reading
|
||||
* it. This means the skb might be inconsistent.
|
||||
*
|
||||
* Return an error to let rx-offload discard this CAN frame.
|
||||
*/
|
||||
if (unlikely(mbxno == HECC_RX_LAST_MBOX &&
|
||||
hecc_read(priv, HECC_CANRML) & mbx_mask))
|
||||
ret = -ENOBUFS;
|
||||
|
||||
hecc_write(priv, HECC_CANRMP, mbx_mask);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ti_hecc_error(struct net_device *ndev, int int_status,
|
||||
@@ -558,90 +592,71 @@ static int ti_hecc_error(struct net_device *ndev, int int_status,
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
u32 timestamp;
|
||||
|
||||
/* propagate the error condition to the can stack */
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (!skb) {
|
||||
if (printk_ratelimit())
|
||||
netdev_err(priv->ndev,
|
||||
"%s: alloc_can_err_skb() failed\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (int_status & HECC_CANGIF_WLIF) { /* warning level int */
|
||||
if ((int_status & HECC_CANGIF_BOIF) == 0) {
|
||||
priv->can.state = CAN_STATE_ERROR_WARNING;
|
||||
++priv->can.can_stats.error_warning;
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
if (hecc_read(priv, HECC_CANTEC) > 96)
|
||||
cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
|
||||
if (hecc_read(priv, HECC_CANREC) > 96)
|
||||
cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
|
||||
}
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_EW);
|
||||
netdev_dbg(priv->ndev, "Error Warning interrupt\n");
|
||||
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
|
||||
}
|
||||
|
||||
if (int_status & HECC_CANGIF_EPIF) { /* error passive int */
|
||||
if ((int_status & HECC_CANGIF_BOIF) == 0) {
|
||||
priv->can.state = CAN_STATE_ERROR_PASSIVE;
|
||||
++priv->can.can_stats.error_passive;
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
if (hecc_read(priv, HECC_CANTEC) > 127)
|
||||
cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE;
|
||||
if (hecc_read(priv, HECC_CANREC) > 127)
|
||||
cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE;
|
||||
}
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_EP);
|
||||
netdev_dbg(priv->ndev, "Error passive interrupt\n");
|
||||
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
|
||||
}
|
||||
|
||||
/* Need to check busoff condition in error status register too to
|
||||
* ensure warning interrupts don't hog the system
|
||||
*/
|
||||
if ((int_status & HECC_CANGIF_BOIF) || (err_status & HECC_CANES_BO)) {
|
||||
priv->can.state = CAN_STATE_BUS_OFF;
|
||||
cf->can_id |= CAN_ERR_BUSOFF;
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_BO);
|
||||
hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR);
|
||||
/* Disable all interrupts in bus-off to avoid int hog */
|
||||
hecc_write(priv, HECC_CANGIM, 0);
|
||||
++priv->can.can_stats.bus_off;
|
||||
can_bus_off(ndev);
|
||||
}
|
||||
int err;
|
||||
|
||||
if (err_status & HECC_BUS_ERROR) {
|
||||
/* propagate the error condition to the can stack */
|
||||
skb = alloc_can_err_skb(ndev, &cf);
|
||||
if (!skb) {
|
||||
if (net_ratelimit())
|
||||
netdev_err(priv->ndev,
|
||||
"%s: alloc_can_err_skb() failed\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
++priv->can.can_stats.bus_error;
|
||||
cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
|
||||
if (err_status & HECC_CANES_FE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_FE);
|
||||
if (err_status & HECC_CANES_FE)
|
||||
cf->data[2] |= CAN_ERR_PROT_FORM;
|
||||
}
|
||||
if (err_status & HECC_CANES_BE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_BE);
|
||||
if (err_status & HECC_CANES_BE)
|
||||
cf->data[2] |= CAN_ERR_PROT_BIT;
|
||||
}
|
||||
if (err_status & HECC_CANES_SE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_SE);
|
||||
if (err_status & HECC_CANES_SE)
|
||||
cf->data[2] |= CAN_ERR_PROT_STUFF;
|
||||
}
|
||||
if (err_status & HECC_CANES_CRCE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_CRCE);
|
||||
if (err_status & HECC_CANES_CRCE)
|
||||
cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
|
||||
}
|
||||
if (err_status & HECC_CANES_ACKE) {
|
||||
hecc_set_bit(priv, HECC_CANES, HECC_CANES_ACKE);
|
||||
if (err_status & HECC_CANES_ACKE)
|
||||
cf->data[3] = CAN_ERR_PROT_LOC_ACK;
|
||||
}
|
||||
|
||||
timestamp = hecc_read(priv, HECC_CANLNT);
|
||||
err = can_rx_offload_queue_sorted(&priv->offload, skb,
|
||||
timestamp);
|
||||
if (err)
|
||||
ndev->stats.rx_fifo_errors++;
|
||||
}
|
||||
|
||||
hecc_write(priv, HECC_CANES, HECC_CANES_FLAGS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ti_hecc_change_state(struct net_device *ndev,
|
||||
enum can_state rx_state,
|
||||
enum can_state tx_state)
|
||||
{
|
||||
struct ti_hecc_priv *priv = netdev_priv(ndev);
|
||||
struct can_frame *cf;
|
||||
struct sk_buff *skb;
|
||||
u32 timestamp;
|
||||
int err;
|
||||
|
||||
skb = alloc_can_err_skb(priv->ndev, &cf);
|
||||
if (unlikely(!skb)) {
|
||||
priv->can.state = max(tx_state, rx_state);
|
||||
return;
|
||||
}
|
||||
|
||||
can_change_state(priv->ndev, cf, tx_state, rx_state);
|
||||
|
||||
if (max(tx_state, rx_state) != CAN_STATE_BUS_OFF) {
|
||||
cf->data[6] = hecc_read(priv, HECC_CANTEC);
|
||||
cf->data[7] = hecc_read(priv, HECC_CANREC);
|
||||
}
|
||||
|
||||
timestamp = hecc_read(priv, HECC_CANLNT);
|
||||
can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
|
||||
return 0;
|
||||
err = can_rx_offload_queue_sorted(&priv->offload, skb, timestamp);
|
||||
if (err)
|
||||
ndev->stats.rx_fifo_errors++;
|
||||
}
|
||||
|
||||
static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
|
||||
@@ -651,6 +666,7 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
|
||||
struct net_device_stats *stats = &ndev->stats;
|
||||
u32 mbxno, mbx_mask, int_status, err_status, stamp;
|
||||
unsigned long flags, rx_pending;
|
||||
u32 handled = 0;
|
||||
|
||||
int_status = hecc_read(priv,
|
||||
priv->use_hecc1int ?
|
||||
@@ -660,17 +676,66 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
|
||||
err_status = hecc_read(priv, HECC_CANES);
|
||||
if (err_status & (HECC_BUS_ERROR | HECC_CANES_BO |
|
||||
HECC_CANES_EP | HECC_CANES_EW))
|
||||
if (unlikely(err_status & HECC_CANES_FLAGS))
|
||||
ti_hecc_error(ndev, int_status, err_status);
|
||||
|
||||
if (unlikely(int_status & HECC_CANGIM_DEF_MASK)) {
|
||||
enum can_state rx_state, tx_state;
|
||||
u32 rec = hecc_read(priv, HECC_CANREC);
|
||||
u32 tec = hecc_read(priv, HECC_CANTEC);
|
||||
|
||||
if (int_status & HECC_CANGIF_WLIF) {
|
||||
handled |= HECC_CANGIF_WLIF;
|
||||
rx_state = rec >= tec ? CAN_STATE_ERROR_WARNING : 0;
|
||||
tx_state = rec <= tec ? CAN_STATE_ERROR_WARNING : 0;
|
||||
netdev_dbg(priv->ndev, "Error Warning interrupt\n");
|
||||
ti_hecc_change_state(ndev, rx_state, tx_state);
|
||||
}
|
||||
|
||||
if (int_status & HECC_CANGIF_EPIF) {
|
||||
handled |= HECC_CANGIF_EPIF;
|
||||
rx_state = rec >= tec ? CAN_STATE_ERROR_PASSIVE : 0;
|
||||
tx_state = rec <= tec ? CAN_STATE_ERROR_PASSIVE : 0;
|
||||
netdev_dbg(priv->ndev, "Error passive interrupt\n");
|
||||
ti_hecc_change_state(ndev, rx_state, tx_state);
|
||||
}
|
||||
|
||||
if (int_status & HECC_CANGIF_BOIF) {
|
||||
handled |= HECC_CANGIF_BOIF;
|
||||
rx_state = CAN_STATE_BUS_OFF;
|
||||
tx_state = CAN_STATE_BUS_OFF;
|
||||
netdev_dbg(priv->ndev, "Bus off interrupt\n");
|
||||
|
||||
/* Disable all interrupts */
|
||||
hecc_write(priv, HECC_CANGIM, 0);
|
||||
can_bus_off(ndev);
|
||||
ti_hecc_change_state(ndev, rx_state, tx_state);
|
||||
}
|
||||
} else if (unlikely(priv->can.state != CAN_STATE_ERROR_ACTIVE)) {
|
||||
enum can_state new_state, tx_state, rx_state;
|
||||
u32 rec = hecc_read(priv, HECC_CANREC);
|
||||
u32 tec = hecc_read(priv, HECC_CANTEC);
|
||||
|
||||
if (rec >= 128 || tec >= 128)
|
||||
new_state = CAN_STATE_ERROR_PASSIVE;
|
||||
else if (rec >= 96 || tec >= 96)
|
||||
new_state = CAN_STATE_ERROR_WARNING;
|
||||
else
|
||||
new_state = CAN_STATE_ERROR_ACTIVE;
|
||||
|
||||
if (new_state < priv->can.state) {
|
||||
rx_state = rec >= tec ? new_state : 0;
|
||||
tx_state = rec <= tec ? new_state : 0;
|
||||
ti_hecc_change_state(ndev, rx_state, tx_state);
|
||||
}
|
||||
}
|
||||
|
||||
if (int_status & HECC_CANGIF_GMIF) {
|
||||
while (priv->tx_tail - priv->tx_head > 0) {
|
||||
mbxno = get_tx_tail_mb(priv);
|
||||
mbx_mask = BIT(mbxno);
|
||||
if (!(mbx_mask & hecc_read(priv, HECC_CANTA)))
|
||||
break;
|
||||
hecc_clear_bit(priv, HECC_CANMIM, mbx_mask);
|
||||
hecc_write(priv, HECC_CANTA, mbx_mask);
|
||||
spin_lock_irqsave(&priv->mbx_lock, flags);
|
||||
hecc_clear_bit(priv, HECC_CANME, mbx_mask);
|
||||
@@ -695,16 +760,15 @@ static irqreturn_t ti_hecc_interrupt(int irq, void *dev_id)
|
||||
while ((rx_pending = hecc_read(priv, HECC_CANRMP))) {
|
||||
can_rx_offload_irq_offload_timestamp(&priv->offload,
|
||||
rx_pending);
|
||||
hecc_write(priv, HECC_CANRMP, rx_pending);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear all interrupt conditions - read back to avoid spurious ints */
|
||||
if (priv->use_hecc1int) {
|
||||
hecc_write(priv, HECC_CANGIF1, HECC_SET_REG);
|
||||
hecc_write(priv, HECC_CANGIF1, handled);
|
||||
int_status = hecc_read(priv, HECC_CANGIF1);
|
||||
} else {
|
||||
hecc_write(priv, HECC_CANGIF0, HECC_SET_REG);
|
||||
hecc_write(priv, HECC_CANGIF0, handled);
|
||||
int_status = hecc_read(priv, HECC_CANGIF0);
|
||||
}
|
||||
|
||||
@@ -877,7 +941,7 @@ static int ti_hecc_probe(struct platform_device *pdev)
|
||||
|
||||
priv->offload.mailbox_read = ti_hecc_mailbox_read;
|
||||
priv->offload.mb_first = HECC_RX_FIRST_MBOX;
|
||||
priv->offload.mb_last = HECC_MAX_TX_MBOX;
|
||||
priv->offload.mb_last = HECC_RX_LAST_MBOX;
|
||||
err = can_rx_offload_add_timestamp(ndev, &priv->offload);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "can_rx_offload_add_timestamp() failed\n");
|
||||
|
||||
@@ -623,6 +623,7 @@ static int gs_can_open(struct net_device *netdev)
|
||||
rc);
|
||||
|
||||
usb_unanchor_urb(urb);
|
||||
usb_free_urb(urb);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -876,9 +876,8 @@ static void mcba_usb_disconnect(struct usb_interface *intf)
|
||||
netdev_info(priv->netdev, "device disconnected\n");
|
||||
|
||||
unregister_candev(priv->netdev);
|
||||
free_candev(priv->netdev);
|
||||
|
||||
mcba_urb_unlink(priv);
|
||||
free_candev(priv->netdev);
|
||||
}
|
||||
|
||||
static struct usb_driver mcba_usb_driver = {
|
||||
|
||||
@@ -100,7 +100,7 @@ struct pcan_usb_msg_context {
|
||||
u8 *end;
|
||||
u8 rec_cnt;
|
||||
u8 rec_idx;
|
||||
u8 rec_data_idx;
|
||||
u8 rec_ts_idx;
|
||||
struct net_device *netdev;
|
||||
struct pcan_usb *pdev;
|
||||
};
|
||||
@@ -436,8 +436,8 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
|
||||
}
|
||||
if ((n & PCAN_USB_ERROR_BUS_LIGHT) == 0) {
|
||||
/* no error (back to active state) */
|
||||
mc->pdev->dev.can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
return 0;
|
||||
new_state = CAN_STATE_ERROR_ACTIVE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -460,9 +460,9 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
|
||||
}
|
||||
|
||||
if ((n & PCAN_USB_ERROR_BUS_HEAVY) == 0) {
|
||||
/* no error (back to active state) */
|
||||
mc->pdev->dev.can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
return 0;
|
||||
/* no error (back to warning state) */
|
||||
new_state = CAN_STATE_ERROR_WARNING;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -501,6 +501,11 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
|
||||
mc->pdev->dev.can.can_stats.error_warning++;
|
||||
break;
|
||||
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
cf->data[1] = CAN_ERR_CRTL_ACTIVE;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* CAN_STATE_MAX (trick to handle other errors) */
|
||||
cf->can_id |= CAN_ERR_CRTL;
|
||||
@@ -547,10 +552,15 @@ static int pcan_usb_decode_status(struct pcan_usb_msg_context *mc,
|
||||
mc->ptr += PCAN_USB_CMD_ARGS;
|
||||
|
||||
if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
|
||||
int err = pcan_usb_decode_ts(mc, !mc->rec_idx);
|
||||
int err = pcan_usb_decode_ts(mc, !mc->rec_ts_idx);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Next packet in the buffer will have a timestamp on a single
|
||||
* byte
|
||||
*/
|
||||
mc->rec_ts_idx++;
|
||||
}
|
||||
|
||||
switch (f) {
|
||||
@@ -632,10 +642,13 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len)
|
||||
|
||||
cf->can_dlc = get_can_dlc(rec_len);
|
||||
|
||||
/* first data packet timestamp is a word */
|
||||
if (pcan_usb_decode_ts(mc, !mc->rec_data_idx))
|
||||
/* Only first packet timestamp is a word */
|
||||
if (pcan_usb_decode_ts(mc, !mc->rec_ts_idx))
|
||||
goto decode_failed;
|
||||
|
||||
/* Next packet in the buffer will have a timestamp on a single byte */
|
||||
mc->rec_ts_idx++;
|
||||
|
||||
/* read data */
|
||||
memset(cf->data, 0x0, sizeof(cf->data));
|
||||
if (status_len & PCAN_USB_STATUSLEN_RTR) {
|
||||
@@ -688,7 +701,6 @@ static int pcan_usb_decode_msg(struct peak_usb_device *dev, u8 *ibuf, u32 lbuf)
|
||||
/* handle normal can frames here */
|
||||
} else {
|
||||
err = pcan_usb_decode_data(&mc, sl);
|
||||
mc.rec_data_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -750,7 +750,7 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
|
||||
dev = netdev_priv(netdev);
|
||||
|
||||
/* allocate a buffer large enough to send commands */
|
||||
dev->cmd_buf = kmalloc(PCAN_USB_MAX_CMD_LEN, GFP_KERNEL);
|
||||
dev->cmd_buf = kzalloc(PCAN_USB_MAX_CMD_LEN, GFP_KERNEL);
|
||||
if (!dev->cmd_buf) {
|
||||
err = -ENOMEM;
|
||||
goto lbl_free_candev;
|
||||
|
||||
@@ -996,9 +996,8 @@ static void usb_8dev_disconnect(struct usb_interface *intf)
|
||||
netdev_info(priv->netdev, "device disconnected\n");
|
||||
|
||||
unregister_netdev(priv->netdev);
|
||||
free_candev(priv->netdev);
|
||||
|
||||
unlink_all_urbs(priv);
|
||||
free_candev(priv->netdev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1599,7 +1599,6 @@ static const struct xcan_devtype_data xcan_zynq_data = {
|
||||
|
||||
static const struct xcan_devtype_data xcan_axi_data = {
|
||||
.cantype = XAXI_CAN,
|
||||
.flags = XCAN_FLAG_TXFEMP,
|
||||
.bittiming_const = &xcan_bittiming_const,
|
||||
.btr_ts2_shift = XCAN_BTR_TS2_SHIFT,
|
||||
.btr_sjw_shift = XCAN_BTR_SJW_SHIFT,
|
||||
|
||||
@@ -1215,10 +1215,10 @@ static int bcm_sf2_sw_remove(struct platform_device *pdev)
|
||||
struct bcm_sf2_priv *priv = platform_get_drvdata(pdev);
|
||||
|
||||
priv->wol_ports_mask = 0;
|
||||
/* Disable interrupts */
|
||||
bcm_sf2_intr_disable(priv);
|
||||
dsa_unregister_switch(priv->dev->ds);
|
||||
bcm_sf2_cfp_exit(priv->dev->ds);
|
||||
/* Disable all ports and interrupts */
|
||||
bcm_sf2_sw_suspend(priv->dev->ds);
|
||||
bcm_sf2_mdio_unregister(priv);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1996,8 +1996,6 @@ static void reset_umac(struct bcmgenet_priv *priv)
|
||||
|
||||
/* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
|
||||
bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD);
|
||||
udelay(2);
|
||||
bcmgenet_umac_writel(priv, 0, UMAC_CMD);
|
||||
}
|
||||
|
||||
static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
|
||||
@@ -2614,8 +2612,10 @@ static void bcmgenet_irq_task(struct work_struct *work)
|
||||
spin_unlock_irq(&priv->lock);
|
||||
|
||||
if (status & UMAC_IRQ_PHY_DET_R &&
|
||||
priv->dev->phydev->autoneg != AUTONEG_ENABLE)
|
||||
priv->dev->phydev->autoneg != AUTONEG_ENABLE) {
|
||||
phy_init_hw(priv->dev->phydev);
|
||||
genphy_config_aneg(priv->dev->phydev);
|
||||
}
|
||||
|
||||
/* Link UP/DOWN event */
|
||||
if (status & UMAC_IRQ_LINK_EVENT)
|
||||
@@ -2879,12 +2879,6 @@ static int bcmgenet_open(struct net_device *dev)
|
||||
if (priv->internal_phy)
|
||||
bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
|
||||
|
||||
ret = bcmgenet_mii_connect(dev);
|
||||
if (ret) {
|
||||
netdev_err(dev, "failed to connect to PHY\n");
|
||||
goto err_clk_disable;
|
||||
}
|
||||
|
||||
/* take MAC out of reset */
|
||||
bcmgenet_umac_reset(priv);
|
||||
|
||||
@@ -2894,12 +2888,6 @@ static int bcmgenet_open(struct net_device *dev)
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);
|
||||
|
||||
ret = bcmgenet_mii_config(dev, true);
|
||||
if (ret) {
|
||||
netdev_err(dev, "unsupported PHY\n");
|
||||
goto err_disconnect_phy;
|
||||
}
|
||||
|
||||
bcmgenet_set_hw_addr(priv, dev->dev_addr);
|
||||
|
||||
if (priv->internal_phy) {
|
||||
@@ -2915,7 +2903,7 @@ static int bcmgenet_open(struct net_device *dev)
|
||||
ret = bcmgenet_init_dma(priv);
|
||||
if (ret) {
|
||||
netdev_err(dev, "failed to initialize DMA\n");
|
||||
goto err_disconnect_phy;
|
||||
goto err_clk_disable;
|
||||
}
|
||||
|
||||
/* Always enable ring 16 - descriptor ring */
|
||||
@@ -2938,19 +2926,25 @@ static int bcmgenet_open(struct net_device *dev)
|
||||
goto err_irq0;
|
||||
}
|
||||
|
||||
ret = bcmgenet_mii_probe(dev);
|
||||
if (ret) {
|
||||
netdev_err(dev, "failed to connect to PHY\n");
|
||||
goto err_irq1;
|
||||
}
|
||||
|
||||
bcmgenet_netif_start(dev);
|
||||
|
||||
netif_tx_start_all_queues(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_irq1:
|
||||
free_irq(priv->irq1, priv);
|
||||
err_irq0:
|
||||
free_irq(priv->irq0, priv);
|
||||
err_fini_dma:
|
||||
bcmgenet_dma_teardown(priv);
|
||||
bcmgenet_fini_dma(priv);
|
||||
err_disconnect_phy:
|
||||
phy_disconnect(dev->phydev);
|
||||
err_clk_disable:
|
||||
if (priv->internal_phy)
|
||||
bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
|
||||
@@ -3631,8 +3625,6 @@ static int bcmgenet_resume(struct device *d)
|
||||
if (priv->internal_phy)
|
||||
bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
|
||||
|
||||
phy_init_hw(dev->phydev);
|
||||
|
||||
bcmgenet_umac_reset(priv);
|
||||
|
||||
init_umac(priv);
|
||||
@@ -3641,7 +3633,10 @@ static int bcmgenet_resume(struct device *d)
|
||||
if (priv->wolopts)
|
||||
clk_disable_unprepare(priv->clk_wol);
|
||||
|
||||
phy_init_hw(dev->phydev);
|
||||
|
||||
/* Speed settings must be restored */
|
||||
genphy_config_aneg(dev->phydev);
|
||||
bcmgenet_mii_config(priv->dev, false);
|
||||
|
||||
bcmgenet_set_hw_addr(priv, dev->dev_addr);
|
||||
|
||||
@@ -720,8 +720,8 @@ GENET_IO_MACRO(rbuf, GENET_RBUF_OFF);
|
||||
|
||||
/* MDIO routines */
|
||||
int bcmgenet_mii_init(struct net_device *dev);
|
||||
int bcmgenet_mii_connect(struct net_device *dev);
|
||||
int bcmgenet_mii_config(struct net_device *dev, bool init);
|
||||
int bcmgenet_mii_probe(struct net_device *dev);
|
||||
void bcmgenet_mii_exit(struct net_device *dev);
|
||||
void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
|
||||
void bcmgenet_mii_setup(struct net_device *dev);
|
||||
|
||||
@@ -173,46 +173,6 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
|
||||
bcmgenet_fixed_phy_link_update);
|
||||
}
|
||||
|
||||
int bcmgenet_mii_connect(struct net_device *dev)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
struct device_node *dn = priv->pdev->dev.of_node;
|
||||
struct phy_device *phydev;
|
||||
u32 phy_flags = 0;
|
||||
int ret;
|
||||
|
||||
/* Communicate the integrated PHY revision */
|
||||
if (priv->internal_phy)
|
||||
phy_flags = priv->gphy_rev;
|
||||
|
||||
/* Initialize link state variables that bcmgenet_mii_setup() uses */
|
||||
priv->old_link = -1;
|
||||
priv->old_speed = -1;
|
||||
priv->old_duplex = -1;
|
||||
priv->old_pause = -1;
|
||||
|
||||
if (dn) {
|
||||
phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup,
|
||||
phy_flags, priv->phy_interface);
|
||||
if (!phydev) {
|
||||
pr_err("could not attach to PHY\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
phydev = dev->phydev;
|
||||
phydev->dev_flags = phy_flags;
|
||||
|
||||
ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
|
||||
priv->phy_interface);
|
||||
if (ret) {
|
||||
pr_err("could not attach to PHY\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcmgenet_mii_config(struct net_device *dev, bool init)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
@@ -221,8 +181,38 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
|
||||
const char *phy_name = NULL;
|
||||
u32 id_mode_dis = 0;
|
||||
u32 port_ctrl;
|
||||
int bmcr = -1;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
/* MAC clocking workaround during reset of umac state machines */
|
||||
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
|
||||
if (reg & CMD_SW_RESET) {
|
||||
/* An MII PHY must be isolated to prevent TXC contention */
|
||||
if (priv->phy_interface == PHY_INTERFACE_MODE_MII) {
|
||||
ret = phy_read(phydev, MII_BMCR);
|
||||
if (ret >= 0) {
|
||||
bmcr = ret;
|
||||
ret = phy_write(phydev, MII_BMCR,
|
||||
bmcr | BMCR_ISOLATE);
|
||||
}
|
||||
if (ret) {
|
||||
netdev_err(dev, "failed to isolate PHY\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/* Switch MAC clocking to RGMII generated clock */
|
||||
bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
|
||||
/* Ensure 5 clks with Rx disabled
|
||||
* followed by 5 clks with Reset asserted
|
||||
*/
|
||||
udelay(4);
|
||||
reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN);
|
||||
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
|
||||
/* Ensure 5 more clocks before Rx is enabled */
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
priv->ext_phy = !priv->internal_phy &&
|
||||
(priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
|
||||
|
||||
@@ -254,6 +244,9 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
|
||||
phy_set_max_speed(phydev, SPEED_100);
|
||||
bcmgenet_sys_writel(priv,
|
||||
PORT_MODE_EXT_EPHY, SYS_PORT_CTRL);
|
||||
/* Restore the MII PHY after isolation */
|
||||
if (bmcr >= 0)
|
||||
phy_write(phydev, MII_BMCR, bmcr);
|
||||
break;
|
||||
|
||||
case PHY_INTERFACE_MODE_REVMII:
|
||||
@@ -306,21 +299,71 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
|
||||
bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
|
||||
}
|
||||
|
||||
if (init) {
|
||||
linkmode_copy(phydev->advertising, phydev->supported);
|
||||
|
||||
/* The internal PHY has its link interrupts routed to the
|
||||
* Ethernet MAC ISRs. On GENETv5 there is a hardware issue
|
||||
* that prevents the signaling of link UP interrupts when
|
||||
* the link operates at 10Mbps, so fallback to polling for
|
||||
* those versions of GENET.
|
||||
*/
|
||||
if (priv->internal_phy && !GENET_IS_V5(priv))
|
||||
phydev->irq = PHY_IGNORE_INTERRUPT;
|
||||
|
||||
if (init)
|
||||
dev_info(kdev, "configuring instance for %s\n", phy_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bcmgenet_mii_probe(struct net_device *dev)
|
||||
{
|
||||
struct bcmgenet_priv *priv = netdev_priv(dev);
|
||||
struct device_node *dn = priv->pdev->dev.of_node;
|
||||
struct phy_device *phydev;
|
||||
u32 phy_flags = 0;
|
||||
int ret;
|
||||
|
||||
/* Communicate the integrated PHY revision */
|
||||
if (priv->internal_phy)
|
||||
phy_flags = priv->gphy_rev;
|
||||
|
||||
/* Initialize link state variables that bcmgenet_mii_setup() uses */
|
||||
priv->old_link = -1;
|
||||
priv->old_speed = -1;
|
||||
priv->old_duplex = -1;
|
||||
priv->old_pause = -1;
|
||||
|
||||
if (dn) {
|
||||
phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup,
|
||||
phy_flags, priv->phy_interface);
|
||||
if (!phydev) {
|
||||
pr_err("could not attach to PHY\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
phydev = dev->phydev;
|
||||
phydev->dev_flags = phy_flags;
|
||||
|
||||
ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
|
||||
priv->phy_interface);
|
||||
if (ret) {
|
||||
pr_err("could not attach to PHY\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure port multiplexer based on what the probed PHY device since
|
||||
* reading the 'max-speed' property determines the maximum supported
|
||||
* PHY speed which is needed for bcmgenet_mii_config() to configure
|
||||
* things appropriately.
|
||||
*/
|
||||
ret = bcmgenet_mii_config(dev, true);
|
||||
if (ret) {
|
||||
phy_disconnect(dev->phydev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
linkmode_copy(phydev->advertising, phydev->supported);
|
||||
|
||||
/* The internal PHY has its link interrupts routed to the
|
||||
* Ethernet MAC ISRs. On GENETv5 there is a hardware issue
|
||||
* that prevents the signaling of link UP interrupts when
|
||||
* the link operates at 10Mbps, so fallback to polling for
|
||||
* those versions of GENET.
|
||||
*/
|
||||
if (priv->internal_phy && !GENET_IS_V5(priv))
|
||||
dev->phydev->irq = PHY_IGNORE_INTERRUPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1499,7 +1499,7 @@ static int octeon_mgmt_probe(struct platform_device *pdev)
|
||||
netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
|
||||
|
||||
netdev->min_mtu = 64 - OCTEON_MGMT_RX_HEADROOM;
|
||||
netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM;
|
||||
netdev->max_mtu = 16383 - OCTEON_MGMT_RX_HEADROOM - VLAN_HLEN;
|
||||
|
||||
mac = of_get_mac_address(pdev->dev.of_node);
|
||||
|
||||
|
||||
@@ -3645,6 +3645,8 @@ fec_drv_remove(struct platform_device *pdev)
|
||||
regulator_disable(fep->reg_phy);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_disable_unprepare(fep->clk_ahb);
|
||||
clk_disable_unprepare(fep->clk_ipg);
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(fep->phy_node);
|
||||
|
||||
@@ -199,7 +199,6 @@ hnae_init_ring(struct hnae_queue *q, struct hnae_ring *ring, int flags)
|
||||
|
||||
ring->q = q;
|
||||
ring->flags = flags;
|
||||
spin_lock_init(&ring->lock);
|
||||
ring->coal_param = q->handle->coal_param;
|
||||
assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
|
||||
|
||||
|
||||
@@ -274,9 +274,6 @@ struct hnae_ring {
|
||||
/* statistic */
|
||||
struct ring_stats stats;
|
||||
|
||||
/* ring lock for poll one */
|
||||
spinlock_t lock;
|
||||
|
||||
dma_addr_t desc_dma_addr;
|
||||
u32 buf_size; /* size for hnae_desc->addr, preset by AE */
|
||||
u16 desc_num; /* total number of desc */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user