Merge branch 'perf/urgent' into perf/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
6856b8e536
|
@ -14,3 +14,11 @@ Description:
|
|||
Show or set the gain boost of the amp, from 0-31 range.
|
||||
18 = indoors (default)
|
||||
14 = outdoors
|
||||
|
||||
What /sys/bus/iio/devices/iio:deviceX/noise_level_tripped
|
||||
Date: May 2017
|
||||
KernelVersion: 4.13
|
||||
Contact: Matt Ranostay <matt.ranostay@konsulko.com>
|
||||
Description:
|
||||
When 1 the noise level is over the trip level and not reporting
|
||||
valid data
|
||||
|
|
|
@ -16,6 +16,10 @@ Optional properties:
|
|||
- ams,tuning-capacitor-pf: Calibration tuning capacitor stepping
|
||||
value 0 - 120pF. This will require using the calibration data from
|
||||
the manufacturer.
|
||||
- ams,nflwdth: Set the noise and watchdog threshold register on
|
||||
startup. This will need to set according to the noise from the
|
||||
MCU board, and possibly the local environment. Refer to the
|
||||
datasheet for the threshold settings.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -27,4 +31,5 @@ as3935@0 {
|
|||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <16 1>;
|
||||
ams,tuning-capacitor-pf = <80>;
|
||||
ams,nflwdth = <0x44>;
|
||||
};
|
||||
|
|
|
@ -99,7 +99,7 @@ Examples:
|
|||
compatible = "arm,gic-v3-its";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
reg = <0x0 0x2c200000 0 0x200000>;
|
||||
reg = <0x0 0x2c200000 0 0x20000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -124,14 +124,14 @@ Examples:
|
|||
compatible = "arm,gic-v3-its";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
reg = <0x0 0x2c200000 0 0x200000>;
|
||||
reg = <0x0 0x2c200000 0 0x20000>;
|
||||
};
|
||||
|
||||
gic-its@2c400000 {
|
||||
compatible = "arm,gic-v3-its";
|
||||
msi-controller;
|
||||
#msi-cells = <1>;
|
||||
reg = <0x0 0x2c400000 0 0x200000>;
|
||||
reg = <0x0 0x2c400000 0 0x20000>;
|
||||
};
|
||||
|
||||
ppi-partitions {
|
||||
|
|
|
@ -9213,7 +9213,6 @@ F: include/linux/isicom.h
|
|||
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
|
||||
M: Bin Liu <b-liu@ti.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
|
||||
S: Maintained
|
||||
F: drivers/usb/musb/
|
||||
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 14
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Fearless Coyote
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -131,7 +131,7 @@ endif
|
|||
KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
|
||||
KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
|
||||
|
||||
CHECKFLAGS += -D__arm__
|
||||
CHECKFLAGS += -D__arm__ -m32
|
||||
|
||||
#Default value
|
||||
head-y := arch/arm/kernel/head$(MMUEXT).o
|
||||
|
|
|
@ -23,7 +23,11 @@ ENTRY(putc)
|
|||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
THUMB( bkpt #0xab )
|
||||
#else
|
||||
THUMB( svc #0xab )
|
||||
#endif
|
||||
mov pc, lr
|
||||
.align 2
|
||||
1: .word _GLOBAL_OFFSET_TABLE_ - .
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
};
|
||||
|
||||
i2c0: i2c@11000 {
|
||||
compatible = "marvell,mv64xxx-i2c";
|
||||
compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c";
|
||||
reg = <0x11000 0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -189,7 +189,7 @@
|
|||
};
|
||||
|
||||
i2c1: i2c@11100 {
|
||||
compatible = "marvell,mv64xxx-i2c";
|
||||
compatible = "marvell,mv78230-a0-i2c", "marvell,mv64xxx-i2c";
|
||||
reg = <0x11100 0x20>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
@ -67,8 +67,8 @@
|
|||
pinctrl-0 = <&pinctrl_macb0_default>;
|
||||
phy-mode = "rmii";
|
||||
|
||||
ethernet-phy@1 {
|
||||
reg = <0x1>;
|
||||
ethernet-phy@0 {
|
||||
reg = <0x0>;
|
||||
interrupt-parent = <&pioA>;
|
||||
interrupts = <PIN_PD31 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
|
|
|
@ -309,7 +309,7 @@
|
|||
vddana-supply = <&vdd_3v3_lp_reg>;
|
||||
vref-supply = <&vdd_3v3_lp_reg>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_adc_default>;
|
||||
pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
@ -340,6 +340,20 @@
|
|||
bias-disable;
|
||||
};
|
||||
|
||||
/*
|
||||
* The ADTRG pin can work on any edge type.
|
||||
* In here it's being pulled up, so need to
|
||||
* connect it to ground to get an edge e.g.
|
||||
* Trigger can be configured on falling, rise
|
||||
* or any edge, and the pull-up can be changed
|
||||
* to pull-down or left floating according to
|
||||
* needs.
|
||||
*/
|
||||
pinctrl_adtrg_default: adtrg_default {
|
||||
pinmux = <PIN_PD31__ADTRG>;
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
pinctrl_charger_chglev: charger_chglev {
|
||||
pinmux = <PIN_PA12__GPIO>;
|
||||
bias-disable;
|
||||
|
|
|
@ -18,12 +18,9 @@
|
|||
compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
|
||||
model = "Raspberry Pi Zero W";
|
||||
|
||||
/* Needed by firmware to properly init UARTs */
|
||||
aliases {
|
||||
uart0 = "/soc/serial@7e201000";
|
||||
uart1 = "/soc/serial@7e215040";
|
||||
serial0 = "/soc/serial@7e201000";
|
||||
serial1 = "/soc/serial@7e215040";
|
||||
chosen {
|
||||
/* 8250 auxiliary UART instead of pl011 */
|
||||
stdout-path = "serial1:115200n8";
|
||||
};
|
||||
|
||||
leds {
|
||||
|
|
|
@ -8,6 +8,11 @@
|
|||
compatible = "raspberrypi,3-model-b", "brcm,bcm2837";
|
||||
model = "Raspberry Pi 3 Model B";
|
||||
|
||||
chosen {
|
||||
/* 8250 auxiliary UART instead of pl011 */
|
||||
stdout-path = "serial1:115200n8";
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = <0 0x40000000>;
|
||||
};
|
||||
|
|
|
@ -20,8 +20,13 @@
|
|||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
serial1 = &uart1;
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "earlyprintk console=ttyAMA0";
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
|
|
|
@ -145,11 +145,12 @@
|
|||
};
|
||||
|
||||
watchdog@41000000 {
|
||||
compatible = "cortina,gemini-watchdog";
|
||||
compatible = "cortina,gemini-watchdog", "faraday,ftwdt010";
|
||||
reg = <0x41000000 0x1000>;
|
||||
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&syscon GEMINI_RESET_WDOG>;
|
||||
clocks = <&syscon GEMINI_CLK_APB>;
|
||||
clock-names = "PCLK";
|
||||
};
|
||||
|
||||
uart0: serial@42000000 {
|
||||
|
|
|
@ -144,10 +144,10 @@
|
|||
interrupt-names = "msi";
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
|
||||
<&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
|
||||
<&clks IMX7D_PCIE_PHY_ROOT_CLK>;
|
||||
|
|
|
@ -87,9 +87,10 @@
|
|||
};
|
||||
|
||||
watchdog: watchdog@98500000 {
|
||||
compatible = "moxa,moxart-watchdog";
|
||||
compatible = "moxa,moxart-watchdog", "faraday,ftwdt010";
|
||||
reg = <0x98500000 0x10>;
|
||||
clocks = <&clk_apb>;
|
||||
clock-names = "PCLK";
|
||||
};
|
||||
|
||||
sdhci: sdhci@98e00000 {
|
||||
|
|
|
@ -1430,6 +1430,7 @@
|
|||
atmel,min-sample-rate-hz = <200000>;
|
||||
atmel,max-sample-rate-hz = <20000000>;
|
||||
atmel,startup-time-ms = <4>;
|
||||
atmel,trigger-edge-type = <IRQ_TYPE_EDGE_RISING>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -311,8 +311,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
tcon1_in_drc1: endpoint@0 {
|
||||
reg = <0>;
|
||||
tcon1_in_drc1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&drc1_out_tcon1>;
|
||||
};
|
||||
};
|
||||
|
@ -1012,8 +1012,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
be1_out_drc1: endpoint@0 {
|
||||
reg = <0>;
|
||||
be1_out_drc1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&drc1_in_be1>;
|
||||
};
|
||||
};
|
||||
|
@ -1042,8 +1042,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
|
||||
drc1_in_be1: endpoint@0 {
|
||||
reg = <0>;
|
||||
drc1_in_be1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&be1_out_drc1>;
|
||||
};
|
||||
};
|
||||
|
@ -1053,8 +1053,8 @@
|
|||
#size-cells = <0>;
|
||||
reg = <1>;
|
||||
|
||||
drc1_out_tcon1: endpoint@0 {
|
||||
reg = <0>;
|
||||
drc1_out_tcon1: endpoint@1 {
|
||||
reg = <1>;
|
||||
remote-endpoint = <&tcon1_in_drc1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -115,7 +115,11 @@ ENTRY(printascii)
|
|||
mov r1, r0
|
||||
mov r0, #0x04 @ SYS_WRITE0
|
||||
ARM( svc #0x123456 )
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
THUMB( bkpt #0xab )
|
||||
#else
|
||||
THUMB( svc #0xab )
|
||||
#endif
|
||||
ret lr
|
||||
ENDPROC(printascii)
|
||||
|
||||
|
@ -124,7 +128,11 @@ ENTRY(printch)
|
|||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
#ifdef CONFIG_CPU_V7M
|
||||
THUMB( bkpt #0xab )
|
||||
#else
|
||||
THUMB( svc #0xab )
|
||||
#endif
|
||||
ret lr
|
||||
ENDPROC(printch)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <asm/mach/arch.h>
|
||||
|
||||
#include "db8500-regs.h"
|
||||
#include "pm_domains.h"
|
||||
|
||||
static int __init ux500_l2x0_unlock(void)
|
||||
{
|
||||
|
@ -157,6 +158,9 @@ static const struct of_device_id u8500_local_bus_nodes[] = {
|
|||
|
||||
static void __init u8500_init_machine(void)
|
||||
{
|
||||
/* Initialize ux500 power domains */
|
||||
ux500_pm_domains_init();
|
||||
|
||||
/* automatically probe child nodes of dbx5x0 devices */
|
||||
if (of_machine_is_compatible("st-ericsson,u8540"))
|
||||
of_platform_populate(NULL, u8500_local_bus_nodes,
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/of_address.h>
|
||||
|
||||
#include "db8500-regs.h"
|
||||
#include "pm_domains.h"
|
||||
|
||||
/* ARM WFI Standby signal register */
|
||||
#define PRCM_ARM_WFI_STANDBY (prcmu_base + 0x130)
|
||||
|
@ -203,7 +202,4 @@ void __init ux500_pm_init(u32 phy_base, u32 size)
|
|||
|
||||
/* Set up ux500 suspend callbacks. */
|
||||
suspend_set_ops(UX500_SUSPEND_OPS);
|
||||
|
||||
/* Initialize ux500 power domains */
|
||||
ux500_pm_domains_init();
|
||||
}
|
||||
|
|
|
@ -344,6 +344,11 @@ void __init arm_mm_memblock_reserve(void)
|
|||
* reserved here.
|
||||
*/
|
||||
#endif
|
||||
/*
|
||||
* In any case, always ensure address 0 is never used as many things
|
||||
* get very confused if 0 is returned as a legitimate address.
|
||||
*/
|
||||
memblock_reserve(0, 1);
|
||||
}
|
||||
|
||||
void __init adjust_lowmem_bounds(void)
|
||||
|
|
|
@ -61,13 +61,6 @@
|
|||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
reg_vcc3v3: vcc3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
};
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
|
@ -91,7 +84,7 @@
|
|||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
vmmc-supply = <®_vcc3v3>;
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
|
||||
cd-inverted;
|
||||
disable-wp;
|
||||
|
|
|
@ -336,7 +336,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cpm_clk 1 13>;
|
||||
|
@ -362,7 +362,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf7000000 0 0xf7000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
@ -389,7 +389,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xf8000000 0 0xf8000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu 0 ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cpm_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
|
|
@ -335,7 +335,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 22 IRQ_TYPE_LEVEL_HIGH>;
|
||||
num-lanes = <1>;
|
||||
clocks = <&cps_clk 1 13>;
|
||||
|
@ -361,7 +361,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 24 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
@ -388,7 +388,7 @@
|
|||
/* non-prefetchable memory */
|
||||
0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>;
|
||||
interrupt-map-mask = <0 0 0 0>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu 0 ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-map = <0 0 0 0 &cps_icu ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts = <ICU_GRP_NSR 23 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
num-lanes = <1>;
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
brightness-levels = <256 128 64 16 8 4 0>;
|
||||
default-brightness-level = <6>;
|
||||
|
||||
power-supply = <®_12v>;
|
||||
enable-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
|
@ -83,6 +84,15 @@
|
|||
regulator-always-on;
|
||||
};
|
||||
|
||||
reg_12v: regulator2 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "fixed-12V";
|
||||
regulator-min-microvolt = <12000000>;
|
||||
regulator-max-microvolt = <12000000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
rsnd_ak4613: sound {
|
||||
compatible = "simple-audio-card";
|
||||
|
||||
|
|
|
@ -582,7 +582,7 @@
|
|||
vop_mmu: iommu@ff373f00 {
|
||||
compatible = "rockchip,iommu";
|
||||
reg = <0x0 0xff373f00 0x0 0x100>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "vop_mmu";
|
||||
#iommu-cells = <0>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -740,7 +740,7 @@
|
|||
iep_mmu: iommu@ff900800 {
|
||||
compatible = "rockchip,iommu";
|
||||
reg = <0x0 0xff900800 0x0 0x100>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH 0>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "iep_mmu";
|
||||
#iommu-cells = <0>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -371,10 +371,10 @@
|
|||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -325,12 +325,12 @@
|
|||
vcc_sd: LDO_REG4 {
|
||||
regulator-name = "vcc_sd";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -315,10 +315,10 @@
|
|||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-state-mem {
|
||||
regulator-on-in-suspend;
|
||||
regulator-suspend-microvolt = <3300000>;
|
||||
regulator-suspend-microvolt = <3000000>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -546,9 +546,6 @@ static int bts_event_init(struct perf_event *event)
|
|||
if (event->attr.type != bts_pmu.type)
|
||||
return -ENOENT;
|
||||
|
||||
if (x86_add_exclusive(x86_lbr_exclusive_bts))
|
||||
return -EBUSY;
|
||||
|
||||
/*
|
||||
* BTS leaks kernel addresses even when CPL0 tracing is
|
||||
* disabled, so disallow intel_bts driver for unprivileged
|
||||
|
@ -562,6 +559,9 @@ static int bts_event_init(struct perf_event *event)
|
|||
!capable(CAP_SYS_ADMIN))
|
||||
return -EACCES;
|
||||
|
||||
if (x86_add_exclusive(x86_lbr_exclusive_bts))
|
||||
return -EBUSY;
|
||||
|
||||
ret = x86_reserve_hardware();
|
||||
if (ret) {
|
||||
x86_del_exclusive(x86_lbr_exclusive_bts);
|
||||
|
|
|
@ -110,6 +110,10 @@ build_mmio_write(__writeq, "q", unsigned long, "r", )
|
|||
|
||||
#endif
|
||||
|
||||
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
|
||||
extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
|
||||
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
|
||||
|
||||
/**
|
||||
* virt_to_phys - map virtual addresses to physical
|
||||
* @address: address to remap
|
||||
|
|
|
@ -82,12 +82,21 @@ static inline u64 inc_mm_tlb_gen(struct mm_struct *mm)
|
|||
#define __flush_tlb_single(addr) __native_flush_tlb_single(addr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If tlb_use_lazy_mode is true, then we try to avoid switching CR3 to point
|
||||
* to init_mm when we switch to a kernel thread (e.g. the idle thread). If
|
||||
* it's false, then we immediately switch CR3 when entering a kernel thread.
|
||||
*/
|
||||
DECLARE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
|
||||
static inline bool tlb_defer_switch_to_init_mm(void)
|
||||
{
|
||||
/*
|
||||
* If we have PCID, then switching to init_mm is reasonably
|
||||
* fast. If we don't have PCID, then switching to init_mm is
|
||||
* quite slow, so we try to defer it in the hopes that we can
|
||||
* avoid it entirely. The latter approach runs the risk of
|
||||
* receiving otherwise unnecessary IPIs.
|
||||
*
|
||||
* This choice is just a heuristic. The tlb code can handle this
|
||||
* function returning true or false regardless of whether we have
|
||||
* PCID.
|
||||
*/
|
||||
return !static_cpu_has(X86_FEATURE_PCID);
|
||||
}
|
||||
|
||||
/*
|
||||
* 6 because 6 should be plenty and struct tlb_state will fit in
|
||||
|
|
|
@ -831,7 +831,6 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index,
|
|||
} else if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
|
||||
unsigned int apicid, nshared, first, last;
|
||||
|
||||
this_leaf = this_cpu_ci->info_list + index;
|
||||
nshared = base->eax.split.num_threads_sharing + 1;
|
||||
apicid = cpu_data(cpu).apicid;
|
||||
first = apicid - (apicid % nshared);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/microcode_intel.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/setup.h>
|
||||
|
@ -918,6 +919,18 @@ static int get_ucode_fw(void *to, const void *from, size_t n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_blacklisted(unsigned int cpu)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
if (c->x86 == 6 && c->x86_model == INTEL_FAM6_BROADWELL_X) {
|
||||
pr_err_once("late loading on model 79 is disabled.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum ucode_state request_microcode_fw(int cpu, struct device *device,
|
||||
bool refresh_fw)
|
||||
{
|
||||
|
@ -926,6 +939,9 @@ static enum ucode_state request_microcode_fw(int cpu, struct device *device,
|
|||
const struct firmware *firmware;
|
||||
enum ucode_state ret;
|
||||
|
||||
if (is_blacklisted(cpu))
|
||||
return UCODE_NFOUND;
|
||||
|
||||
sprintf(name, "intel-ucode/%02x-%02x-%02x",
|
||||
c->x86, c->x86_model, c->x86_mask);
|
||||
|
||||
|
@ -950,6 +966,9 @@ static int get_ucode_user(void *to, const void *from, size_t n)
|
|||
static enum ucode_state
|
||||
request_microcode_user(int cpu, const void __user *buf, size_t size)
|
||||
{
|
||||
if (is_blacklisted(cpu))
|
||||
return UCODE_NFOUND;
|
||||
|
||||
return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,11 @@ static void __init i386_default_early_setup(void)
|
|||
|
||||
asmlinkage __visible void __init i386_start_kernel(void)
|
||||
{
|
||||
cr4_init_shadow();
|
||||
|
||||
/* Make sure IDT is set up before any exception happens */
|
||||
idt_setup_early_handler();
|
||||
|
||||
cr4_init_shadow();
|
||||
|
||||
sanitize_boot_params(&boot_params);
|
||||
|
||||
x86_early_init_platform_quirks();
|
||||
|
|
|
@ -174,3 +174,15 @@ const char *arch_vma_name(struct vm_area_struct *vma)
|
|||
return "[mpx]";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int valid_phys_addr_range(phys_addr_t addr, size_t count)
|
||||
{
|
||||
return addr + count <= __pa(high_memory);
|
||||
}
|
||||
|
||||
int valid_mmap_phys_addr_range(unsigned long pfn, size_t count)
|
||||
{
|
||||
phys_addr_t addr = (phys_addr_t)pfn << PAGE_SHIFT;
|
||||
|
||||
return valid_phys_addr_range(addr, count);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1);
|
||||
|
||||
DEFINE_STATIC_KEY_TRUE(tlb_use_lazy_mode);
|
||||
|
||||
static void choose_new_asid(struct mm_struct *next, u64 next_tlb_gen,
|
||||
u16 *new_asid, bool *need_flush)
|
||||
|
@ -147,8 +146,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
|||
this_cpu_write(cpu_tlbstate.is_lazy, false);
|
||||
|
||||
if (real_prev == next) {
|
||||
VM_BUG_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
|
||||
next->context.ctx_id);
|
||||
VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
|
||||
next->context.ctx_id);
|
||||
|
||||
/*
|
||||
* We don't currently support having a real mm loaded without
|
||||
|
@ -213,6 +212,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
|||
}
|
||||
|
||||
/*
|
||||
* Please ignore the name of this function. It should be called
|
||||
* switch_to_kernel_thread().
|
||||
*
|
||||
* enter_lazy_tlb() is a hint from the scheduler that we are entering a
|
||||
* kernel thread or other context without an mm. Acceptable implementations
|
||||
* include doing nothing whatsoever, switching to init_mm, or various clever
|
||||
|
@ -227,7 +229,7 @@ void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
|
|||
if (this_cpu_read(cpu_tlbstate.loaded_mm) == &init_mm)
|
||||
return;
|
||||
|
||||
if (static_branch_unlikely(&tlb_use_lazy_mode)) {
|
||||
if (tlb_defer_switch_to_init_mm()) {
|
||||
/*
|
||||
* There's a significant optimization that may be possible
|
||||
* here. We have accurate enough TLB flush tracking that we
|
||||
|
@ -626,57 +628,3 @@ static int __init create_tlb_single_page_flush_ceiling(void)
|
|||
return 0;
|
||||
}
|
||||
late_initcall(create_tlb_single_page_flush_ceiling);
|
||||
|
||||
static ssize_t tlblazy_read_file(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
buf[0] = static_branch_likely(&tlb_use_lazy_mode) ? '1' : '0';
|
||||
buf[1] = '\n';
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
|
||||
}
|
||||
|
||||
static ssize_t tlblazy_write_file(struct file *file,
|
||||
const char __user *user_buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
bool val;
|
||||
|
||||
if (kstrtobool_from_user(user_buf, count, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
static_branch_enable(&tlb_use_lazy_mode);
|
||||
else
|
||||
static_branch_disable(&tlb_use_lazy_mode);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tlblazy = {
|
||||
.read = tlblazy_read_file,
|
||||
.write = tlblazy_write_file,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int __init init_tlb_use_lazy_mode(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_PCID)) {
|
||||
/*
|
||||
* Heuristic: with PCID on, switching to and from
|
||||
* init_mm is reasonably fast, but remote flush IPIs
|
||||
* as expensive as ever, so turn off lazy TLB mode.
|
||||
*
|
||||
* We can't do this in setup_pcid() because static keys
|
||||
* haven't been initialized yet, and it would blow up
|
||||
* badly.
|
||||
*/
|
||||
static_branch_disable(&tlb_use_lazy_mode);
|
||||
}
|
||||
|
||||
debugfs_create_file("tlb_use_lazy_mode", S_IRUSR | S_IWUSR,
|
||||
arch_debugfs_dir, NULL, &fops_tlblazy);
|
||||
return 0;
|
||||
}
|
||||
late_initcall(init_tlb_use_lazy_mode);
|
||||
|
|
|
@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring,
|
|||
char *req, *p;
|
||||
int len;
|
||||
|
||||
BUG_ON(!id_0 && !id_1);
|
||||
|
||||
if (id_0) {
|
||||
lookup = id_0->data;
|
||||
len = id_0->len;
|
||||
|
@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring,
|
|||
if (id_0 && id_1) {
|
||||
const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
|
||||
|
||||
if (!kids->id[0]) {
|
||||
if (!kids->id[1]) {
|
||||
pr_debug("First ID matches, but second is missing\n");
|
||||
goto reject;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
|
|||
bool want = false;
|
||||
|
||||
sinfo = msg->signed_infos;
|
||||
if (!sinfo)
|
||||
goto inconsistent;
|
||||
|
||||
if (sinfo->authattrs) {
|
||||
want = true;
|
||||
msg->have_authattrs = true;
|
||||
|
|
|
@ -3662,12 +3662,6 @@ static void binder_stat_br(struct binder_proc *proc,
|
|||
}
|
||||
}
|
||||
|
||||
static int binder_has_thread_work(struct binder_thread *thread)
|
||||
{
|
||||
return !binder_worklist_empty(thread->proc, &thread->todo) ||
|
||||
thread->looper_need_return;
|
||||
}
|
||||
|
||||
static int binder_put_node_cmd(struct binder_proc *proc,
|
||||
struct binder_thread *thread,
|
||||
void __user **ptrp,
|
||||
|
@ -4297,12 +4291,9 @@ static unsigned int binder_poll(struct file *filp,
|
|||
|
||||
binder_inner_proc_unlock(thread->proc);
|
||||
|
||||
if (binder_has_work(thread, wait_for_proc_work))
|
||||
return POLLIN;
|
||||
|
||||
poll_wait(filp, &thread->wait, wait);
|
||||
|
||||
if (binder_has_thread_work(thread))
|
||||
if (binder_has_work(thread, wait_for_proc_work))
|
||||
return POLLIN;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -215,17 +215,12 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate,
|
|||
}
|
||||
}
|
||||
|
||||
if (!vma && need_mm)
|
||||
mm = get_task_mm(alloc->tsk);
|
||||
if (!vma && need_mm && mmget_not_zero(alloc->vma_vm_mm))
|
||||
mm = alloc->vma_vm_mm;
|
||||
|
||||
if (mm) {
|
||||
down_write(&mm->mmap_sem);
|
||||
vma = alloc->vma;
|
||||
if (vma && mm != alloc->vma_vm_mm) {
|
||||
pr_err("%d: vma mm and task mm mismatch\n",
|
||||
alloc->pid);
|
||||
vma = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vma && need_mm) {
|
||||
|
@ -565,7 +560,7 @@ static void binder_delete_free_buffer(struct binder_alloc *alloc,
|
|||
binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC,
|
||||
"%d: merge free, buffer %pK do not share page with %pK or %pK\n",
|
||||
alloc->pid, buffer->data,
|
||||
prev->data, next->data);
|
||||
prev->data, next ? next->data : NULL);
|
||||
binder_update_page_range(alloc, 0, buffer_start_page(buffer),
|
||||
buffer_start_page(buffer) + PAGE_SIZE,
|
||||
NULL);
|
||||
|
@ -720,6 +715,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
|
|||
barrier();
|
||||
alloc->vma = vma;
|
||||
alloc->vma_vm_mm = vma->vm_mm;
|
||||
mmgrab(alloc->vma_vm_mm);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -795,6 +791,8 @@ void binder_alloc_deferred_release(struct binder_alloc *alloc)
|
|||
vfree(alloc->buffer);
|
||||
}
|
||||
mutex_unlock(&alloc->mutex);
|
||||
if (alloc->vma_vm_mm)
|
||||
mmdrop(alloc->vma_vm_mm);
|
||||
|
||||
binder_alloc_debug(BINDER_DEBUG_OPEN_CLOSE,
|
||||
"%s: %d buffers %d, pages %d\n",
|
||||
|
@ -889,7 +887,6 @@ int binder_alloc_get_allocated_count(struct binder_alloc *alloc)
|
|||
void binder_alloc_vma_close(struct binder_alloc *alloc)
|
||||
{
|
||||
WRITE_ONCE(alloc->vma, NULL);
|
||||
WRITE_ONCE(alloc->vma_vm_mm, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -926,9 +923,9 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
|||
page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
|
||||
vma = alloc->vma;
|
||||
if (vma) {
|
||||
mm = get_task_mm(alloc->tsk);
|
||||
if (!mm)
|
||||
goto err_get_task_mm_failed;
|
||||
if (!mmget_not_zero(alloc->vma_vm_mm))
|
||||
goto err_mmget;
|
||||
mm = alloc->vma_vm_mm;
|
||||
if (!down_write_trylock(&mm->mmap_sem))
|
||||
goto err_down_write_mmap_sem_failed;
|
||||
}
|
||||
|
@ -963,7 +960,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
|||
|
||||
err_down_write_mmap_sem_failed:
|
||||
mmput_async(mm);
|
||||
err_get_task_mm_failed:
|
||||
err_mmget:
|
||||
err_page_already_freed:
|
||||
mutex_unlock(&alloc->mutex);
|
||||
err_get_alloc_mutex_failed:
|
||||
|
@ -1002,7 +999,6 @@ struct shrinker binder_shrinker = {
|
|||
*/
|
||||
void binder_alloc_init(struct binder_alloc *alloc)
|
||||
{
|
||||
alloc->tsk = current->group_leader;
|
||||
alloc->pid = current->group_leader->pid;
|
||||
mutex_init(&alloc->mutex);
|
||||
INIT_LIST_HEAD(&alloc->buffers);
|
||||
|
|
|
@ -100,7 +100,6 @@ struct binder_lru_page {
|
|||
*/
|
||||
struct binder_alloc {
|
||||
struct mutex mutex;
|
||||
struct task_struct *tsk;
|
||||
struct vm_area_struct *vma;
|
||||
struct mm_struct *vma_vm_mm;
|
||||
void *buffer;
|
||||
|
|
|
@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
|
|||
if (mbus->hw_io_coherency)
|
||||
w->mbus_attr |= ATTR_HW_COHERENCY;
|
||||
w->base = base & DDR_BASE_CS_LOW_MASK;
|
||||
w->size = (size | ~DDR_SIZE_MASK) + 1;
|
||||
w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
|
||||
}
|
||||
}
|
||||
mvebu_mbus_dram_info.num_cs = cs;
|
||||
|
|
|
@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
|
|||
/* Turn off the clock (and clear the event) */
|
||||
disable_timer(cs5535_event_clock);
|
||||
|
||||
if (clockevent_state_shutdown(&cs5535_clockevent))
|
||||
if (clockevent_state_detached(&cs5535_clockevent) ||
|
||||
clockevent_state_shutdown(&cs5535_clockevent))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
/* Clear the counter */
|
||||
|
|
|
@ -344,7 +344,7 @@ msgdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,
|
|||
|
||||
spin_lock_irqsave(&mdev->lock, irqflags);
|
||||
if (desc_cnt > mdev->desc_free_cnt) {
|
||||
spin_unlock_bh(&mdev->lock);
|
||||
spin_unlock_irqrestore(&mdev->lock, irqflags);
|
||||
dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -407,7 +407,7 @@ msgdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
|
|||
|
||||
spin_lock_irqsave(&mdev->lock, irqflags);
|
||||
if (desc_cnt > mdev->desc_free_cnt) {
|
||||
spin_unlock_bh(&mdev->lock);
|
||||
spin_unlock_irqrestore(&mdev->lock, irqflags);
|
||||
dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -205,32 +205,17 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
|
|||
struct amd_sched_entity *entity)
|
||||
{
|
||||
struct amd_sched_rq *rq = entity->rq;
|
||||
int r;
|
||||
|
||||
if (!amd_sched_entity_is_initialized(sched, entity))
|
||||
return;
|
||||
|
||||
/**
|
||||
* The client will not queue more IBs during this fini, consume existing
|
||||
* queued IBs or discard them on SIGKILL
|
||||
* queued IBs
|
||||
*/
|
||||
if ((current->flags & PF_SIGNALED) && current->exit_code == SIGKILL)
|
||||
r = -ERESTARTSYS;
|
||||
else
|
||||
r = wait_event_killable(sched->job_scheduled,
|
||||
amd_sched_entity_is_idle(entity));
|
||||
wait_event(sched->job_scheduled, amd_sched_entity_is_idle(entity));
|
||||
|
||||
amd_sched_rq_remove_entity(rq, entity);
|
||||
if (r) {
|
||||
struct amd_sched_job *job;
|
||||
|
||||
/* Park the kernel for a moment to make sure it isn't processing
|
||||
* our enity.
|
||||
*/
|
||||
kthread_park(sched->thread);
|
||||
kthread_unpark(sched->thread);
|
||||
while (kfifo_out(&entity->job_queue, &job, sizeof(job)))
|
||||
sched->ops->free_job(job);
|
||||
|
||||
}
|
||||
kfifo_free(&entity->job_queue);
|
||||
}
|
||||
|
||||
|
|
|
@ -168,11 +168,13 @@ static struct drm_driver exynos_drm_driver = {
|
|||
static int exynos_drm_suspend(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||
struct exynos_drm_private *private;
|
||||
|
||||
if (pm_runtime_suspended(dev) || !drm_dev)
|
||||
return 0;
|
||||
|
||||
private = drm_dev->dev_private;
|
||||
|
||||
drm_kms_helper_poll_disable(drm_dev);
|
||||
exynos_drm_fbdev_suspend(drm_dev);
|
||||
private->suspend_state = drm_atomic_helper_suspend(drm_dev);
|
||||
|
@ -188,11 +190,12 @@ static int exynos_drm_suspend(struct device *dev)
|
|||
static int exynos_drm_resume(struct device *dev)
|
||||
{
|
||||
struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
struct exynos_drm_private *private = drm_dev->dev_private;
|
||||
struct exynos_drm_private *private;
|
||||
|
||||
if (pm_runtime_suspended(dev) || !drm_dev)
|
||||
return 0;
|
||||
|
||||
private = drm_dev->dev_private;
|
||||
drm_atomic_helper_resume(drm_dev, private->suspend_state);
|
||||
exynos_drm_fbdev_resume(drm_dev);
|
||||
drm_kms_helper_poll_enable(drm_dev);
|
||||
|
@ -427,6 +430,7 @@ static void exynos_drm_unbind(struct device *dev)
|
|||
|
||||
kfree(drm->dev_private);
|
||||
drm->dev_private = NULL;
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
drm_dev_unref(drm);
|
||||
}
|
||||
|
|
|
@ -308,20 +308,8 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu)
|
|||
|
||||
static void tbs_sched_clean_vgpu(struct intel_vgpu *vgpu)
|
||||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler = &vgpu->gvt->scheduler;
|
||||
int ring_id;
|
||||
|
||||
kfree(vgpu->sched_data);
|
||||
vgpu->sched_data = NULL;
|
||||
|
||||
spin_lock_bh(&scheduler->mmio_context_lock);
|
||||
for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
|
||||
if (scheduler->engine_owner[ring_id] == vgpu) {
|
||||
intel_gvt_switch_mmio(vgpu, NULL, ring_id);
|
||||
scheduler->engine_owner[ring_id] = NULL;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&scheduler->mmio_context_lock);
|
||||
}
|
||||
|
||||
static void tbs_sched_start_schedule(struct intel_vgpu *vgpu)
|
||||
|
@ -388,6 +376,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
|
|||
{
|
||||
struct intel_gvt_workload_scheduler *scheduler =
|
||||
&vgpu->gvt->scheduler;
|
||||
int ring_id;
|
||||
|
||||
gvt_dbg_core("vgpu%d: stop schedule\n", vgpu->id);
|
||||
|
||||
|
@ -401,4 +390,13 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu)
|
|||
scheduler->need_reschedule = true;
|
||||
scheduler->current_vgpu = NULL;
|
||||
}
|
||||
|
||||
spin_lock_bh(&scheduler->mmio_context_lock);
|
||||
for (ring_id = 0; ring_id < I915_NUM_ENGINES; ring_id++) {
|
||||
if (scheduler->engine_owner[ring_id] == vgpu) {
|
||||
intel_gvt_switch_mmio(vgpu, NULL, ring_id);
|
||||
scheduler->engine_owner[ring_id] = NULL;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&scheduler->mmio_context_lock);
|
||||
}
|
||||
|
|
|
@ -2657,6 +2657,9 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
|
|||
if (READ_ONCE(obj->mm.pages))
|
||||
return -ENODEV;
|
||||
|
||||
if (obj->mm.madv != I915_MADV_WILLNEED)
|
||||
return -EFAULT;
|
||||
|
||||
/* Before the pages are instantiated the object is treated as being
|
||||
* in the CPU domain. The pages will be clflushed as required before
|
||||
* use, and we can freely write into the pages directly. If userspace
|
||||
|
|
|
@ -33,21 +33,20 @@
|
|||
#include "intel_drv.h"
|
||||
#include "i915_trace.h"
|
||||
|
||||
static bool ggtt_is_idle(struct drm_i915_private *dev_priv)
|
||||
static bool ggtt_is_idle(struct drm_i915_private *i915)
|
||||
{
|
||||
struct i915_ggtt *ggtt = &dev_priv->ggtt;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
struct intel_engine_cs *engine;
|
||||
enum intel_engine_id id;
|
||||
|
||||
for_each_engine(engine, dev_priv, id) {
|
||||
struct intel_timeline *tl;
|
||||
if (i915->gt.active_requests)
|
||||
return false;
|
||||
|
||||
tl = &ggtt->base.timeline.engine[engine->id];
|
||||
if (i915_gem_active_isset(&tl->last_request))
|
||||
return false;
|
||||
}
|
||||
for_each_engine(engine, i915, id) {
|
||||
if (engine->last_retired_context != i915->kernel_context)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ggtt_flush(struct drm_i915_private *i915)
|
||||
|
@ -157,7 +156,8 @@ i915_gem_evict_something(struct i915_address_space *vm,
|
|||
min_size, alignment, cache_level,
|
||||
start, end, mode);
|
||||
|
||||
/* Retire before we search the active list. Although we have
|
||||
/*
|
||||
* Retire before we search the active list. Although we have
|
||||
* reasonable accuracy in our retirement lists, we may have
|
||||
* a stray pin (preventing eviction) that can only be resolved by
|
||||
* retiring.
|
||||
|
@ -182,7 +182,8 @@ search_again:
|
|||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
/* Can we unpin some objects such as idle hw contents,
|
||||
/*
|
||||
* Can we unpin some objects such as idle hw contents,
|
||||
* or pending flips? But since only the GGTT has global entries
|
||||
* such as scanouts, rinbuffers and contexts, we can skip the
|
||||
* purge when inspecting per-process local address spaces.
|
||||
|
@ -190,19 +191,33 @@ search_again:
|
|||
if (!i915_is_ggtt(vm) || flags & PIN_NONBLOCK)
|
||||
return -ENOSPC;
|
||||
|
||||
if (ggtt_is_idle(dev_priv)) {
|
||||
/* If we still have pending pageflip completions, drop
|
||||
* back to userspace to give our workqueues time to
|
||||
* acquire our locks and unpin the old scanouts.
|
||||
*/
|
||||
return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
|
||||
/*
|
||||
* Not everything in the GGTT is tracked via VMA using
|
||||
* i915_vma_move_to_active(), otherwise we could evict as required
|
||||
* with minimal stalling. Instead we are forced to idle the GPU and
|
||||
* explicitly retire outstanding requests which will then remove
|
||||
* the pinning for active objects such as contexts and ring,
|
||||
* enabling us to evict them on the next iteration.
|
||||
*
|
||||
* To ensure that all user contexts are evictable, we perform
|
||||
* a switch to the perma-pinned kernel context. This all also gives
|
||||
* us a termination condition, when the last retired context is
|
||||
* the kernel's there is no more we can evict.
|
||||
*/
|
||||
if (!ggtt_is_idle(dev_priv)) {
|
||||
ret = ggtt_flush(dev_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
goto search_again;
|
||||
}
|
||||
|
||||
ret = ggtt_flush(dev_priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
goto search_again;
|
||||
/*
|
||||
* If we still have pending pageflip completions, drop
|
||||
* back to userspace to give our workqueues time to
|
||||
* acquire our locks and unpin the old scanouts.
|
||||
*/
|
||||
return intel_has_pending_fb_unpin(dev_priv) ? -EAGAIN : -ENOSPC;
|
||||
|
||||
found:
|
||||
/* drm_mm doesn't allow any other other operations while
|
||||
|
|
|
@ -6998,6 +6998,7 @@ enum {
|
|||
*/
|
||||
#define L3_GENERAL_PRIO_CREDITS(x) (((x) >> 1) << 19)
|
||||
#define L3_HIGH_PRIO_CREDITS(x) (((x) >> 1) << 14)
|
||||
#define L3_PRIO_CREDITS_MASK ((0x1f << 19) | (0x1f << 14))
|
||||
|
||||
#define GEN7_L3CNTLREG1 _MMIO(0xB01C)
|
||||
#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C47FF8C
|
||||
|
|
|
@ -664,8 +664,8 @@ intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
|
|||
int *n_entries)
|
||||
{
|
||||
if (IS_BROADWELL(dev_priv)) {
|
||||
*n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
|
||||
return hsw_ddi_translations_fdi;
|
||||
*n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi);
|
||||
return bdw_ddi_translations_fdi;
|
||||
} else if (IS_HASWELL(dev_priv)) {
|
||||
*n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
|
||||
return hsw_ddi_translations_fdi;
|
||||
|
@ -2102,8 +2102,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
|
|||
* register writes.
|
||||
*/
|
||||
val = I915_READ(DPCLKA_CFGCR0);
|
||||
val &= ~(DPCLKA_CFGCR0_DDI_CLK_OFF(port) |
|
||||
DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port));
|
||||
val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
|
||||
I915_WRITE(DPCLKA_CFGCR0, val);
|
||||
} else if (IS_GEN9_BC(dev_priv)) {
|
||||
/* DDI -> PLL mapping */
|
||||
|
|
|
@ -1996,7 +1996,7 @@ static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
|
|||
|
||||
/* 3. Configure DPLL_CFGCR0 */
|
||||
/* Avoid touch CFGCR1 if HDMI mode is not enabled */
|
||||
if (pll->state.hw_state.cfgcr0 & DPLL_CTRL1_HDMI_MODE(pll->id)) {
|
||||
if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
|
||||
val = pll->state.hw_state.cfgcr1;
|
||||
I915_WRITE(CNL_DPLL_CFGCR1(pll->id), val);
|
||||
/* 4. Reab back to ensure writes completed */
|
||||
|
|
|
@ -1048,9 +1048,12 @@ static int bxt_init_workarounds(struct intel_engine_cs *engine)
|
|||
}
|
||||
|
||||
/* WaProgramL3SqcReg1DefaultForPerf:bxt */
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
|
||||
I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
|
||||
L3_HIGH_PRIO_CREDITS(2));
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
|
||||
u32 val = I915_READ(GEN8_L3SQCREG1);
|
||||
val &= ~L3_PRIO_CREDITS_MASK;
|
||||
val |= L3_GENERAL_PRIO_CREDITS(62) | L3_HIGH_PRIO_CREDITS(2);
|
||||
I915_WRITE(GEN8_L3SQCREG1, val);
|
||||
}
|
||||
|
||||
/* WaToEnableHwFixForPushConstHWBug:bxt */
|
||||
if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
|
||||
|
|
|
@ -8245,14 +8245,17 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
|
|||
int high_prio_credits)
|
||||
{
|
||||
u32 misccpctl;
|
||||
u32 val;
|
||||
|
||||
/* WaTempDisableDOPClkGating:bdw */
|
||||
misccpctl = I915_READ(GEN7_MISCCPCTL);
|
||||
I915_WRITE(GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
|
||||
|
||||
I915_WRITE(GEN8_L3SQCREG1,
|
||||
L3_GENERAL_PRIO_CREDITS(general_prio_credits) |
|
||||
L3_HIGH_PRIO_CREDITS(high_prio_credits));
|
||||
val = I915_READ(GEN8_L3SQCREG1);
|
||||
val &= ~L3_PRIO_CREDITS_MASK;
|
||||
val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits);
|
||||
val |= L3_HIGH_PRIO_CREDITS(high_prio_credits);
|
||||
I915_WRITE(GEN8_L3SQCREG1, val);
|
||||
|
||||
/*
|
||||
* Wait at least 100 clocks before re-enabling clock gating.
|
||||
|
|
|
@ -223,7 +223,7 @@ void
|
|||
nouveau_fbcon_accel_save_disable(struct drm_device *dev)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
if (drm->fbcon) {
|
||||
if (drm->fbcon && drm->fbcon->helper.fbdev) {
|
||||
drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags;
|
||||
drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ void
|
|||
nouveau_fbcon_accel_restore(struct drm_device *dev)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
if (drm->fbcon) {
|
||||
if (drm->fbcon && drm->fbcon->helper.fbdev) {
|
||||
drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags;
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +245,8 @@ nouveau_fbcon_accel_fini(struct drm_device *dev)
|
|||
struct nouveau_fbdev *fbcon = drm->fbcon;
|
||||
if (fbcon && drm->channel) {
|
||||
console_lock();
|
||||
fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
if (fbcon->helper.fbdev)
|
||||
fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED;
|
||||
console_unlock();
|
||||
nouveau_channel_idle(drm->channel);
|
||||
nvif_object_fini(&fbcon->twod);
|
||||
|
|
|
@ -3265,11 +3265,14 @@ nv50_mstm = {
|
|||
void
|
||||
nv50_mstm_service(struct nv50_mstm *mstm)
|
||||
{
|
||||
struct drm_dp_aux *aux = mstm->mgr.aux;
|
||||
struct drm_dp_aux *aux = mstm ? mstm->mgr.aux : NULL;
|
||||
bool handled = true;
|
||||
int ret;
|
||||
u8 esi[8] = {};
|
||||
|
||||
if (!aux)
|
||||
return;
|
||||
|
||||
while (handled) {
|
||||
ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8);
|
||||
if (ret != 8) {
|
||||
|
|
|
@ -39,5 +39,5 @@ int
|
|||
g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
|
||||
{
|
||||
return nvkm_xtensa_new_(&g84_bsp, device, index,
|
||||
true, 0x103000, pengine);
|
||||
device->chipset != 0x92, 0x103000, pengine);
|
||||
}
|
||||
|
|
|
@ -241,6 +241,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde)
|
|||
mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem);
|
||||
}
|
||||
|
||||
mmu->func->flush(vm);
|
||||
|
||||
nvkm_memory_del(&pgt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel *channel)
|
|||
{
|
||||
BUG_ON(!is_hvsock_channel(channel));
|
||||
|
||||
channel->rescind = true;
|
||||
/* We always get a rescind msg when a connection is closed. */
|
||||
while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind))
|
||||
msleep(1);
|
||||
|
||||
vmbus_device_unregister(channel->device_obj);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
|
||||
|
|
|
@ -1021,7 +1021,7 @@ static int i2c_imx_init_recovery_info(struct imx_i2c_struct *i2c_imx,
|
|||
}
|
||||
|
||||
dev_dbg(&pdev->dev, "using scl-gpio %d and sda-gpio %d for recovery\n",
|
||||
rinfo->sda_gpio, rinfo->scl_gpio);
|
||||
rinfo->scl_gpio, rinfo->sda_gpio);
|
||||
|
||||
rinfo->prepare_recovery = i2c_imx_prepare_recovery;
|
||||
rinfo->unprepare_recovery = i2c_imx_unprepare_recovery;
|
||||
|
@ -1100,7 +1100,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
/* Request IRQ */
|
||||
ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, 0,
|
||||
ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED,
|
||||
pdev->name, i2c_imx);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "can't claim irq %d\n", irq);
|
||||
|
|
|
@ -340,12 +340,15 @@ static int ismt_process_desc(const struct ismt_desc *desc,
|
|||
data->word = dma_buffer[0] | (dma_buffer[1] << 8);
|
||||
break;
|
||||
case I2C_SMBUS_BLOCK_DATA:
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
if (desc->rxbytes != dma_buffer[0] + 1)
|
||||
return -EMSGSIZE;
|
||||
|
||||
memcpy(data->block, dma_buffer, desc->rxbytes);
|
||||
break;
|
||||
case I2C_SMBUS_I2C_BLOCK_DATA:
|
||||
memcpy(&data->block[1], dma_buffer, desc->rxbytes);
|
||||
data->block[0] = desc->rxbytes;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -360,6 +360,7 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
|
|||
unsigned long fclk_rate = 12000000;
|
||||
unsigned long internal_clk = 0;
|
||||
struct clk *fclk;
|
||||
int error;
|
||||
|
||||
if (omap->rev >= OMAP_I2C_REV_ON_3430_3530) {
|
||||
/*
|
||||
|
@ -378,6 +379,13 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
|
|||
* do this bit unconditionally.
|
||||
*/
|
||||
fclk = clk_get(omap->dev, "fck");
|
||||
if (IS_ERR(fclk)) {
|
||||
error = PTR_ERR(fclk);
|
||||
dev_err(omap->dev, "could not get fck: %i\n", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
fclk_rate = clk_get_rate(fclk);
|
||||
clk_put(fclk);
|
||||
|
||||
|
@ -410,6 +418,12 @@ static int omap_i2c_init(struct omap_i2c_dev *omap)
|
|||
else
|
||||
internal_clk = 4000;
|
||||
fclk = clk_get(omap->dev, "fck");
|
||||
if (IS_ERR(fclk)) {
|
||||
error = PTR_ERR(fclk);
|
||||
dev_err(omap->dev, "could not get fck: %i\n", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
fclk_rate = clk_get_rate(fclk) / 1000;
|
||||
clk_put(fclk);
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@
|
|||
/* SB800 constants */
|
||||
#define SB800_PIIX4_SMB_IDX 0xcd6
|
||||
|
||||
#define KERNCZ_IMC_IDX 0x3e
|
||||
#define KERNCZ_IMC_DATA 0x3f
|
||||
|
||||
/*
|
||||
* SB800 port is selected by bits 2:1 of the smb_en register (0x2c)
|
||||
* or the smb_sel register (0x2e), depending on bit 0 of register 0x2f.
|
||||
|
@ -94,6 +97,12 @@
|
|||
#define SB800_PIIX4_PORT_IDX_ALT 0x2e
|
||||
#define SB800_PIIX4_PORT_IDX_SEL 0x2f
|
||||
#define SB800_PIIX4_PORT_IDX_MASK 0x06
|
||||
#define SB800_PIIX4_PORT_IDX_SHIFT 1
|
||||
|
||||
/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
|
||||
#define SB800_PIIX4_PORT_IDX_KERNCZ 0x02
|
||||
#define SB800_PIIX4_PORT_IDX_MASK_KERNCZ 0x18
|
||||
#define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ 3
|
||||
|
||||
/* insmod parameters */
|
||||
|
||||
|
@ -149,6 +158,8 @@ static const struct dmi_system_id piix4_dmi_ibm[] = {
|
|||
*/
|
||||
static DEFINE_MUTEX(piix4_mutex_sb800);
|
||||
static u8 piix4_port_sel_sb800;
|
||||
static u8 piix4_port_mask_sb800;
|
||||
static u8 piix4_port_shift_sb800;
|
||||
static const char *piix4_main_port_names_sb800[PIIX4_MAX_ADAPTERS] = {
|
||||
" port 0", " port 2", " port 3", " port 4"
|
||||
};
|
||||
|
@ -159,6 +170,7 @@ struct i2c_piix4_adapdata {
|
|||
|
||||
/* SB800 */
|
||||
bool sb800_main;
|
||||
bool notify_imc;
|
||||
u8 port; /* Port number, shifted */
|
||||
};
|
||||
|
||||
|
@ -347,7 +359,19 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|||
|
||||
/* Find which register is used for port selection */
|
||||
if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD) {
|
||||
piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
|
||||
switch (PIIX4_dev->device) {
|
||||
case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS:
|
||||
piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ;
|
||||
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ;
|
||||
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ;
|
||||
break;
|
||||
case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS:
|
||||
default:
|
||||
piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
|
||||
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
|
||||
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
mutex_lock(&piix4_mutex_sb800);
|
||||
outb_p(SB800_PIIX4_PORT_IDX_SEL, SB800_PIIX4_SMB_IDX);
|
||||
|
@ -355,6 +379,8 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
|
|||
piix4_port_sel_sb800 = (port_sel & 0x01) ?
|
||||
SB800_PIIX4_PORT_IDX_ALT :
|
||||
SB800_PIIX4_PORT_IDX;
|
||||
piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
|
||||
piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
|
||||
mutex_unlock(&piix4_mutex_sb800);
|
||||
}
|
||||
|
||||
|
@ -572,6 +598,67 @@ static s32 piix4_access(struct i2c_adapter * adap, u16 addr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t piix4_imc_read(uint8_t idx)
|
||||
{
|
||||
outb_p(idx, KERNCZ_IMC_IDX);
|
||||
return inb_p(KERNCZ_IMC_DATA);
|
||||
}
|
||||
|
||||
static void piix4_imc_write(uint8_t idx, uint8_t value)
|
||||
{
|
||||
outb_p(idx, KERNCZ_IMC_IDX);
|
||||
outb_p(value, KERNCZ_IMC_DATA);
|
||||
}
|
||||
|
||||
static int piix4_imc_sleep(void)
|
||||
{
|
||||
int timeout = MAX_TIMEOUT;
|
||||
|
||||
if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
|
||||
return -EBUSY;
|
||||
|
||||
/* clear response register */
|
||||
piix4_imc_write(0x82, 0x00);
|
||||
/* request ownership flag */
|
||||
piix4_imc_write(0x83, 0xB4);
|
||||
/* kick off IMC Mailbox command 96 */
|
||||
piix4_imc_write(0x80, 0x96);
|
||||
|
||||
while (timeout--) {
|
||||
if (piix4_imc_read(0x82) == 0xfa) {
|
||||
release_region(KERNCZ_IMC_IDX, 2);
|
||||
return 0;
|
||||
}
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
release_region(KERNCZ_IMC_IDX, 2);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void piix4_imc_wakeup(void)
|
||||
{
|
||||
int timeout = MAX_TIMEOUT;
|
||||
|
||||
if (!request_muxed_region(KERNCZ_IMC_IDX, 2, "smbus_kerncz_imc"))
|
||||
return;
|
||||
|
||||
/* clear response register */
|
||||
piix4_imc_write(0x82, 0x00);
|
||||
/* release ownership flag */
|
||||
piix4_imc_write(0x83, 0xB5);
|
||||
/* kick off IMC Mailbox command 96 */
|
||||
piix4_imc_write(0x80, 0x96);
|
||||
|
||||
while (timeout--) {
|
||||
if (piix4_imc_read(0x82) == 0xfa)
|
||||
break;
|
||||
usleep_range(1000, 2000);
|
||||
}
|
||||
|
||||
release_region(KERNCZ_IMC_IDX, 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles access to multiple SMBus ports on the SB800.
|
||||
* The port is selected by bits 2:1 of the smb_en register (0x2c).
|
||||
|
@ -612,12 +699,47 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the IMC (Integrated Micro Controller) if required.
|
||||
* Among other responsibilities, the IMC is in charge of monitoring
|
||||
* the System fans and temperature sensors, and act accordingly.
|
||||
* All this is done through SMBus and can/will collide
|
||||
* with our transactions if they are long (BLOCK_DATA).
|
||||
* Therefore we need to request the ownership flag during those
|
||||
* transactions.
|
||||
*/
|
||||
if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc) {
|
||||
int ret;
|
||||
|
||||
ret = piix4_imc_sleep();
|
||||
switch (ret) {
|
||||
case -EBUSY:
|
||||
dev_warn(&adap->dev,
|
||||
"IMC base address index region 0x%x already in use.\n",
|
||||
KERNCZ_IMC_IDX);
|
||||
break;
|
||||
case -ETIMEDOUT:
|
||||
dev_warn(&adap->dev,
|
||||
"Failed to communicate with the IMC.\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* If IMC communication fails do not retry */
|
||||
if (ret) {
|
||||
dev_warn(&adap->dev,
|
||||
"Continuing without IMC notification.\n");
|
||||
adapdata->notify_imc = false;
|
||||
}
|
||||
}
|
||||
|
||||
outb_p(piix4_port_sel_sb800, SB800_PIIX4_SMB_IDX);
|
||||
smba_en_lo = inb_p(SB800_PIIX4_SMB_IDX + 1);
|
||||
|
||||
port = adapdata->port;
|
||||
if ((smba_en_lo & SB800_PIIX4_PORT_IDX_MASK) != port)
|
||||
outb_p((smba_en_lo & ~SB800_PIIX4_PORT_IDX_MASK) | port,
|
||||
if ((smba_en_lo & piix4_port_mask_sb800) != port)
|
||||
outb_p((smba_en_lo & ~piix4_port_mask_sb800) | port,
|
||||
SB800_PIIX4_SMB_IDX + 1);
|
||||
|
||||
retval = piix4_access(adap, addr, flags, read_write,
|
||||
|
@ -628,6 +750,9 @@ static s32 piix4_access_sb800(struct i2c_adapter *adap, u16 addr,
|
|||
/* Release the semaphore */
|
||||
outb_p(smbslvcnt | 0x20, SMBSLVCNT);
|
||||
|
||||
if ((size == I2C_SMBUS_BLOCK_DATA) && adapdata->notify_imc)
|
||||
piix4_imc_wakeup();
|
||||
|
||||
mutex_unlock(&piix4_mutex_sb800);
|
||||
|
||||
return retval;
|
||||
|
@ -679,7 +804,7 @@ static struct i2c_adapter *piix4_main_adapters[PIIX4_MAX_ADAPTERS];
|
|||
static struct i2c_adapter *piix4_aux_adapter;
|
||||
|
||||
static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
|
||||
bool sb800_main, u8 port,
|
||||
bool sb800_main, u8 port, bool notify_imc,
|
||||
const char *name, struct i2c_adapter **padap)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
|
@ -706,7 +831,8 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
|
|||
|
||||
adapdata->smba = smba;
|
||||
adapdata->sb800_main = sb800_main;
|
||||
adapdata->port = port << 1;
|
||||
adapdata->port = port << piix4_port_shift_sb800;
|
||||
adapdata->notify_imc = notify_imc;
|
||||
|
||||
/* set up the sysfs linkage to our parent device */
|
||||
adap->dev.parent = &dev->dev;
|
||||
|
@ -728,14 +854,15 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba)
|
||||
static int piix4_add_adapters_sb800(struct pci_dev *dev, unsigned short smba,
|
||||
bool notify_imc)
|
||||
{
|
||||
struct i2c_piix4_adapdata *adapdata;
|
||||
int port;
|
||||
int retval;
|
||||
|
||||
for (port = 0; port < PIIX4_MAX_ADAPTERS; port++) {
|
||||
retval = piix4_add_adapter(dev, smba, true, port,
|
||||
retval = piix4_add_adapter(dev, smba, true, port, notify_imc,
|
||||
piix4_main_port_names_sb800[port],
|
||||
&piix4_main_adapters[port]);
|
||||
if (retval < 0)
|
||||
|
@ -769,6 +896,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
|
||||
dev->revision >= 0x40) ||
|
||||
dev->vendor == PCI_VENDOR_ID_AMD) {
|
||||
bool notify_imc = false;
|
||||
is_sb800 = true;
|
||||
|
||||
if (!request_region(SB800_PIIX4_SMB_IDX, 2, "smba_idx")) {
|
||||
|
@ -778,6 +906,20 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (dev->vendor == PCI_VENDOR_ID_AMD &&
|
||||
dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS) {
|
||||
u8 imc;
|
||||
|
||||
/*
|
||||
* Detect if IMC is active or not, this method is
|
||||
* described on coreboot's AMD IMC notes
|
||||
*/
|
||||
pci_bus_read_config_byte(dev->bus, PCI_DEVFN(0x14, 3),
|
||||
0x40, &imc);
|
||||
if (imc & 0x80)
|
||||
notify_imc = true;
|
||||
}
|
||||
|
||||
/* base address location etc changed in SB800 */
|
||||
retval = piix4_setup_sb800(dev, id, 0);
|
||||
if (retval < 0) {
|
||||
|
@ -789,7 +931,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
* Try to register multiplexed main SMBus adapter,
|
||||
* give up if we can't
|
||||
*/
|
||||
retval = piix4_add_adapters_sb800(dev, retval);
|
||||
retval = piix4_add_adapters_sb800(dev, retval, notify_imc);
|
||||
if (retval < 0) {
|
||||
release_region(SB800_PIIX4_SMB_IDX, 2);
|
||||
return retval;
|
||||
|
@ -800,7 +942,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
return retval;
|
||||
|
||||
/* Try to register main SMBus adapter, give up if we can't */
|
||||
retval = piix4_add_adapter(dev, retval, false, 0, "",
|
||||
retval = piix4_add_adapter(dev, retval, false, 0, false, "",
|
||||
&piix4_main_adapters[0]);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
@ -827,7 +969,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
if (retval > 0) {
|
||||
/* Try to add the aux adapter if it exists,
|
||||
* piix4_add_adapter will clean up if this fails */
|
||||
piix4_add_adapter(dev, retval, false, 0,
|
||||
piix4_add_adapter(dev, retval, false, 0, false,
|
||||
is_sb800 ? piix4_aux_port_name_sb800 : "",
|
||||
&piix4_aux_adapter);
|
||||
}
|
||||
|
|
|
@ -243,6 +243,8 @@ config DA9150_GPADC
|
|||
config DLN2_ADC
|
||||
tristate "Diolan DLN-2 ADC driver support"
|
||||
depends on MFD_DLN2
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
Say yes here to build support for Diolan DLN-2 ADC.
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ struct at91_adc_trigger {
|
|||
char *name;
|
||||
unsigned int trgmod_value;
|
||||
unsigned int edge_type;
|
||||
bool hw_trig;
|
||||
};
|
||||
|
||||
struct at91_adc_state {
|
||||
|
@ -254,16 +255,25 @@ static const struct at91_adc_trigger at91_adc_trigger_list[] = {
|
|||
.name = "external_rising",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_RISE,
|
||||
.edge_type = IRQ_TYPE_EDGE_RISING,
|
||||
.hw_trig = true,
|
||||
},
|
||||
{
|
||||
.name = "external_falling",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_FALL,
|
||||
.edge_type = IRQ_TYPE_EDGE_FALLING,
|
||||
.hw_trig = true,
|
||||
},
|
||||
{
|
||||
.name = "external_any",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_EXT_TRIG_ANY,
|
||||
.edge_type = IRQ_TYPE_EDGE_BOTH,
|
||||
.hw_trig = true,
|
||||
},
|
||||
{
|
||||
.name = "software",
|
||||
.trgmod_value = AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER,
|
||||
.edge_type = IRQ_TYPE_NONE,
|
||||
.hw_trig = false,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -597,7 +607,7 @@ static int at91_adc_probe(struct platform_device *pdev)
|
|||
struct at91_adc_state *st;
|
||||
struct resource *res;
|
||||
int ret, i;
|
||||
u32 edge_type;
|
||||
u32 edge_type = IRQ_TYPE_NONE;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
|
||||
if (!indio_dev)
|
||||
|
@ -641,14 +651,14 @@ static int at91_adc_probe(struct platform_device *pdev)
|
|||
ret = of_property_read_u32(pdev->dev.of_node,
|
||||
"atmel,trigger-edge-type", &edge_type);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"invalid or missing value for atmel,trigger-edge-type\n");
|
||||
return ret;
|
||||
dev_dbg(&pdev->dev,
|
||||
"atmel,trigger-edge-type not specified, only software trigger available\n");
|
||||
}
|
||||
|
||||
st->selected_trig = NULL;
|
||||
|
||||
for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT; i++)
|
||||
/* find the right trigger, or no trigger at all */
|
||||
for (i = 0; i < AT91_SAMA5D2_HW_TRIG_CNT + 1; i++)
|
||||
if (at91_adc_trigger_list[i].edge_type == edge_type) {
|
||||
st->selected_trig = &at91_adc_trigger_list[i];
|
||||
break;
|
||||
|
@ -717,24 +727,27 @@ static int at91_adc_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
ret = at91_adc_buffer_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
}
|
||||
if (st->selected_trig->hw_trig) {
|
||||
ret = at91_adc_buffer_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't initialize the buffer.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
}
|
||||
|
||||
ret = at91_adc_trigger_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't setup the triggers.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
ret = at91_adc_trigger_init(indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "couldn't setup the triggers.\n");
|
||||
goto per_clk_disable_unprepare;
|
||||
}
|
||||
}
|
||||
|
||||
ret = iio_device_register(indio_dev);
|
||||
if (ret < 0)
|
||||
goto per_clk_disable_unprepare;
|
||||
|
||||
dev_info(&pdev->dev, "setting up trigger as %s\n",
|
||||
st->selected_trig->name);
|
||||
if (st->selected_trig->hw_trig)
|
||||
dev_info(&pdev->dev, "setting up trigger as %s\n",
|
||||
st->selected_trig->name);
|
||||
|
||||
dev_info(&pdev->dev, "version: %x\n",
|
||||
readl_relaxed(st->base + AT91_SAMA5D2_VERSION));
|
||||
|
|
|
@ -72,6 +72,7 @@ int iio_simple_dummy_write_event_config(struct iio_dev *indio_dev,
|
|||
st->event_en = state;
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -865,7 +865,6 @@ complete:
|
|||
static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
|
||||
struct zpa2326_private *private)
|
||||
{
|
||||
int ret;
|
||||
unsigned int val;
|
||||
long timeout;
|
||||
|
||||
|
@ -887,14 +886,11 @@ static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev,
|
|||
/* Timed out. */
|
||||
zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)",
|
||||
timeout);
|
||||
ret = -ETIME;
|
||||
} else if (timeout < 0) {
|
||||
zpa2326_warn(indio_dev,
|
||||
"wait for one shot interrupt cancelled");
|
||||
ret = -ERESTARTSYS;
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return ret;
|
||||
zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled");
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
static int zpa2326_init_managed_irq(struct device *parent,
|
||||
|
|
|
@ -39,8 +39,12 @@
|
|||
#define AS3935_AFE_GAIN_MAX 0x1F
|
||||
#define AS3935_AFE_PWR_BIT BIT(0)
|
||||
|
||||
#define AS3935_NFLWDTH 0x01
|
||||
#define AS3935_NFLWDTH_MASK 0x7f
|
||||
|
||||
#define AS3935_INT 0x03
|
||||
#define AS3935_INT_MASK 0x0f
|
||||
#define AS3935_DISTURB_INT BIT(2)
|
||||
#define AS3935_EVENT_INT BIT(3)
|
||||
#define AS3935_NOISE_INT BIT(0)
|
||||
|
||||
|
@ -48,6 +52,7 @@
|
|||
#define AS3935_DATA_MASK 0x3F
|
||||
|
||||
#define AS3935_TUNE_CAP 0x08
|
||||
#define AS3935_DEFAULTS 0x3C
|
||||
#define AS3935_CALIBRATE 0x3D
|
||||
|
||||
#define AS3935_READ_DATA BIT(14)
|
||||
|
@ -62,7 +67,9 @@ struct as3935_state {
|
|||
struct mutex lock;
|
||||
struct delayed_work work;
|
||||
|
||||
unsigned long noise_tripped;
|
||||
u32 tune_cap;
|
||||
u32 nflwdth_reg;
|
||||
u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
|
||||
u8 buf[2] ____cacheline_aligned;
|
||||
};
|
||||
|
@ -145,12 +152,29 @@ static ssize_t as3935_sensor_sensitivity_store(struct device *dev,
|
|||
return len;
|
||||
}
|
||||
|
||||
static ssize_t as3935_noise_level_tripped_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||
int ret;
|
||||
|
||||
mutex_lock(&st->lock);
|
||||
ret = sprintf(buf, "%d\n", !time_after(jiffies, st->noise_tripped + HZ));
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
|
||||
as3935_sensor_sensitivity_show, as3935_sensor_sensitivity_store, 0);
|
||||
|
||||
static IIO_DEVICE_ATTR(noise_level_tripped, S_IRUGO,
|
||||
as3935_noise_level_tripped_show, NULL, 0);
|
||||
|
||||
static struct attribute *as3935_attributes[] = {
|
||||
&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
|
||||
&iio_dev_attr_noise_level_tripped.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -246,7 +270,11 @@ static void as3935_event_work(struct work_struct *work)
|
|||
case AS3935_EVENT_INT:
|
||||
iio_trigger_poll_chained(st->trig);
|
||||
break;
|
||||
case AS3935_DISTURB_INT:
|
||||
case AS3935_NOISE_INT:
|
||||
mutex_lock(&st->lock);
|
||||
st->noise_tripped = jiffies;
|
||||
mutex_unlock(&st->lock);
|
||||
dev_warn(&st->spi->dev, "noise level is too high\n");
|
||||
break;
|
||||
}
|
||||
|
@ -269,15 +297,14 @@ static irqreturn_t as3935_interrupt_handler(int irq, void *private)
|
|||
|
||||
static void calibrate_as3935(struct as3935_state *st)
|
||||
{
|
||||
/* mask disturber interrupt bit */
|
||||
as3935_write(st, AS3935_INT, BIT(5));
|
||||
|
||||
as3935_write(st, AS3935_DEFAULTS, 0x96);
|
||||
as3935_write(st, AS3935_CALIBRATE, 0x96);
|
||||
as3935_write(st, AS3935_TUNE_CAP,
|
||||
BIT(5) | (st->tune_cap / TUNE_CAP_DIV));
|
||||
|
||||
mdelay(2);
|
||||
as3935_write(st, AS3935_TUNE_CAP, (st->tune_cap / TUNE_CAP_DIV));
|
||||
as3935_write(st, AS3935_NFLWDTH, st->nflwdth_reg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -370,6 +397,15 @@ static int as3935_probe(struct spi_device *spi)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np,
|
||||
"ams,nflwdth", &st->nflwdth_reg);
|
||||
if (!ret && st->nflwdth_reg > AS3935_NFLWDTH_MASK) {
|
||||
dev_err(&spi->dev,
|
||||
"invalid nflwdth setting of %d\n",
|
||||
st->nflwdth_reg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
indio_dev->dev.parent = &spi->dev;
|
||||
indio_dev->name = spi_get_device_id(spi)->name;
|
||||
indio_dev->channels = as3935_channels;
|
||||
|
@ -384,6 +420,7 @@ static int as3935_probe(struct spi_device *spi)
|
|||
return -ENOMEM;
|
||||
|
||||
st->trig = trig;
|
||||
st->noise_tripped = jiffies - HZ;
|
||||
trig->dev.parent = indio_dev->dev.parent;
|
||||
iio_trigger_set_drvdata(trig, indio_dev);
|
||||
trig->ops = &iio_interrupt_trigger_ops;
|
||||
|
|
|
@ -933,58 +933,52 @@ int input_set_keycode(struct input_dev *dev,
|
|||
}
|
||||
EXPORT_SYMBOL(input_set_keycode);
|
||||
|
||||
bool input_match_device_id(const struct input_dev *dev,
|
||||
const struct input_device_id *id)
|
||||
{
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
|
||||
if (id->bustype != dev->id.bustype)
|
||||
return false;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
|
||||
if (id->vendor != dev->id.vendor)
|
||||
return false;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
|
||||
if (id->product != dev->id.product)
|
||||
return false;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
|
||||
if (id->version != dev->id.version)
|
||||
return false;
|
||||
|
||||
if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX) ||
|
||||
!bitmap_subset(id->keybit, dev->keybit, KEY_MAX) ||
|
||||
!bitmap_subset(id->relbit, dev->relbit, REL_MAX) ||
|
||||
!bitmap_subset(id->absbit, dev->absbit, ABS_MAX) ||
|
||||
!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX) ||
|
||||
!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX) ||
|
||||
!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX) ||
|
||||
!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX) ||
|
||||
!bitmap_subset(id->swbit, dev->swbit, SW_MAX) ||
|
||||
!bitmap_subset(id->propbit, dev->propbit, INPUT_PROP_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(input_match_device_id);
|
||||
|
||||
static const struct input_device_id *input_match_device(struct input_handler *handler,
|
||||
struct input_dev *dev)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
|
||||
for (id = handler->id_table; id->flags || id->driver_info; id++) {
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
|
||||
if (id->bustype != dev->id.bustype)
|
||||
continue;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VENDOR)
|
||||
if (id->vendor != dev->id.vendor)
|
||||
continue;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT)
|
||||
if (id->product != dev->id.product)
|
||||
continue;
|
||||
|
||||
if (id->flags & INPUT_DEVICE_ID_MATCH_VERSION)
|
||||
if (id->version != dev->id.version)
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX))
|
||||
continue;
|
||||
|
||||
if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX))
|
||||
continue;
|
||||
|
||||
if (!handler->match || handler->match(handler, dev))
|
||||
if (input_match_device_id(dev, id) &&
|
||||
(!handler->match || handler->match(handler, dev))) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -747,6 +747,68 @@ static void joydev_cleanup(struct joydev *joydev)
|
|||
input_close_device(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* These codes are copied from from hid-ids.h, unfortunately there is no common
|
||||
* usb_ids/bt_ids.h header.
|
||||
*/
|
||||
#define USB_VENDOR_ID_SONY 0x054c
|
||||
#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
|
||||
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER 0x05c4
|
||||
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc
|
||||
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0
|
||||
|
||||
#define USB_VENDOR_ID_THQ 0x20d6
|
||||
#define USB_DEVICE_ID_THQ_PS3_UDRAW 0xcb17
|
||||
|
||||
#define ACCEL_DEV(vnd, prd) \
|
||||
{ \
|
||||
.flags = INPUT_DEVICE_ID_MATCH_VENDOR | \
|
||||
INPUT_DEVICE_ID_MATCH_PRODUCT | \
|
||||
INPUT_DEVICE_ID_MATCH_PROPBIT, \
|
||||
.vendor = (vnd), \
|
||||
.product = (prd), \
|
||||
.propbit = { BIT_MASK(INPUT_PROP_ACCELEROMETER) }, \
|
||||
}
|
||||
|
||||
static const struct input_device_id joydev_blacklist[] = {
|
||||
/* Avoid touchpads and touchscreens */
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_KEYBIT,
|
||||
.evbit = { BIT_MASK(EV_KEY) },
|
||||
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
|
||||
},
|
||||
/* Avoid tablets, digitisers and similar devices */
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
INPUT_DEVICE_ID_MATCH_KEYBIT,
|
||||
.evbit = { BIT_MASK(EV_KEY) },
|
||||
.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
|
||||
},
|
||||
/* Disable accelerometers on composite devices */
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER),
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2),
|
||||
ACCEL_DEV(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE),
|
||||
ACCEL_DEV(USB_VENDOR_ID_THQ, USB_DEVICE_ID_THQ_PS3_UDRAW),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static bool joydev_dev_is_blacklisted(struct input_dev *dev)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
|
||||
for (id = joydev_blacklist; id->flags; id++) {
|
||||
if (input_match_device_id(dev, id)) {
|
||||
dev_dbg(&dev->dev,
|
||||
"joydev: blacklisting '%s'\n", dev->name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
|
||||
{
|
||||
DECLARE_BITMAP(jd_scratch, KEY_CNT);
|
||||
|
@ -807,12 +869,8 @@ static bool joydev_dev_is_absolute_mouse(struct input_dev *dev)
|
|||
|
||||
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
|
||||
{
|
||||
/* Avoid touchpads and touchscreens */
|
||||
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
|
||||
return false;
|
||||
|
||||
/* Avoid tablets, digitisers and similar devices */
|
||||
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
|
||||
/* Disable blacklisted devices */
|
||||
if (joydev_dev_is_blacklisted(dev))
|
||||
return false;
|
||||
|
||||
/* Avoid absolute mice */
|
||||
|
|
|
@ -234,14 +234,7 @@ static irqreturn_t tca8418_irq_handler(int irq, void *dev_id)
|
|||
static int tca8418_configure(struct tca8418_keypad *keypad_data,
|
||||
u32 rows, u32 cols)
|
||||
{
|
||||
int reg, error;
|
||||
|
||||
/* Write config register, if this fails assume device not present */
|
||||
error = tca8418_write_byte(keypad_data, REG_CFG,
|
||||
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
|
||||
if (error < 0)
|
||||
return -ENODEV;
|
||||
|
||||
int reg, error = 0;
|
||||
|
||||
/* Assemble a mask for row and column registers */
|
||||
reg = ~(~0 << rows);
|
||||
|
@ -257,6 +250,12 @@ static int tca8418_configure(struct tca8418_keypad *keypad_data,
|
|||
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS2, reg >> 8);
|
||||
error |= tca8418_write_byte(keypad_data, REG_DEBOUNCE_DIS3, reg >> 16);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = tca8418_write_byte(keypad_data, REG_CFG,
|
||||
CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -268,6 +267,7 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||
struct input_dev *input;
|
||||
u32 rows = 0, cols = 0;
|
||||
int error, row_shift, max_keys;
|
||||
u8 reg;
|
||||
|
||||
/* Check i2c driver capabilities */
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
|
||||
|
@ -301,10 +301,10 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||
keypad_data->client = client;
|
||||
keypad_data->row_shift = row_shift;
|
||||
|
||||
/* Initialize the chip or fail if chip isn't present */
|
||||
error = tca8418_configure(keypad_data, rows, cols);
|
||||
if (error < 0)
|
||||
return error;
|
||||
/* Read key lock register, if this fails assume device not present */
|
||||
error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, ®);
|
||||
if (error)
|
||||
return -ENODEV;
|
||||
|
||||
/* Configure input device */
|
||||
input = devm_input_allocate_device(dev);
|
||||
|
@ -340,6 +340,11 @@ static int tca8418_keypad_probe(struct i2c_client *client,
|
|||
return error;
|
||||
}
|
||||
|
||||
/* Initialize the chip */
|
||||
error = tca8418_configure(keypad_data, rows, cols);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(dev, "Unable to register input device, error: %d\n",
|
||||
|
|
|
@ -403,6 +403,7 @@ static const struct platform_device_id axp_pek_id_match[] = {
|
|||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, axp_pek_id_match);
|
||||
|
||||
static struct platform_driver axp20x_pek_driver = {
|
||||
.probe = axp20x_pek_probe,
|
||||
|
@ -417,4 +418,3 @@ module_platform_driver(axp20x_pek_driver);
|
|||
MODULE_DESCRIPTION("axp20x Power Button");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:axp20x-pek");
|
||||
|
|
|
@ -1635,13 +1635,25 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
while (buflen > 0) {
|
||||
while (buflen >= sizeof(*union_desc)) {
|
||||
union_desc = (struct usb_cdc_union_desc *)buf;
|
||||
|
||||
if (union_desc->bLength > buflen) {
|
||||
dev_err(&intf->dev, "Too large descriptor\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (union_desc->bDescriptorType == USB_DT_CS_INTERFACE &&
|
||||
union_desc->bDescriptorSubType == USB_CDC_UNION_TYPE) {
|
||||
dev_dbg(&intf->dev, "Found union header\n");
|
||||
return union_desc;
|
||||
|
||||
if (union_desc->bLength >= sizeof(*union_desc))
|
||||
return union_desc;
|
||||
|
||||
dev_err(&intf->dev,
|
||||
"Union descriptor to short (%d vs %zd\n)",
|
||||
union_desc->bLength, sizeof(*union_desc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buflen -= union_desc->bLength;
|
||||
|
|
|
@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse,
|
|||
.sensor_pdata = {
|
||||
.sensor_type = rmi_sensor_touchpad,
|
||||
.axis_align.flip_y = true,
|
||||
/* to prevent cursors jumps: */
|
||||
.kernel_tracking = true,
|
||||
.kernel_tracking = false,
|
||||
.topbuttonpad = topbuttonpad,
|
||||
},
|
||||
.f30_data = {
|
||||
|
|
|
@ -72,6 +72,9 @@ struct goodix_ts_data {
|
|||
#define GOODIX_REG_CONFIG_DATA 0x8047
|
||||
#define GOODIX_REG_ID 0x8140
|
||||
|
||||
#define GOODIX_BUFFER_STATUS_READY BIT(7)
|
||||
#define GOODIX_BUFFER_STATUS_TIMEOUT 20
|
||||
|
||||
#define RESOLUTION_LOC 1
|
||||
#define MAX_CONTACTS_LOC 5
|
||||
#define TRIGGER_LOC 6
|
||||
|
@ -195,35 +198,53 @@ static int goodix_get_cfg_len(u16 id)
|
|||
|
||||
static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
|
||||
{
|
||||
unsigned long max_timeout;
|
||||
int touch_num;
|
||||
int error;
|
||||
|
||||
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, data,
|
||||
GOODIX_CONTACT_SIZE + 1);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev, "I2C transfer error: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!(data[0] & 0x80))
|
||||
return -EAGAIN;
|
||||
|
||||
touch_num = data[0] & 0x0f;
|
||||
if (touch_num > ts->max_touch_num)
|
||||
return -EPROTO;
|
||||
|
||||
if (touch_num > 1) {
|
||||
data += 1 + GOODIX_CONTACT_SIZE;
|
||||
error = goodix_i2c_read(ts->client,
|
||||
GOODIX_READ_COOR_ADDR +
|
||||
1 + GOODIX_CONTACT_SIZE,
|
||||
data,
|
||||
GOODIX_CONTACT_SIZE * (touch_num - 1));
|
||||
if (error)
|
||||
/*
|
||||
* The 'buffer status' bit, which indicates that the data is valid, is
|
||||
* not set as soon as the interrupt is raised, but slightly after.
|
||||
* This takes around 10 ms to happen, so we poll for 20 ms.
|
||||
*/
|
||||
max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT);
|
||||
do {
|
||||
error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR,
|
||||
data, GOODIX_CONTACT_SIZE + 1);
|
||||
if (error) {
|
||||
dev_err(&ts->client->dev, "I2C transfer error: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return touch_num;
|
||||
if (data[0] & GOODIX_BUFFER_STATUS_READY) {
|
||||
touch_num = data[0] & 0x0f;
|
||||
if (touch_num > ts->max_touch_num)
|
||||
return -EPROTO;
|
||||
|
||||
if (touch_num > 1) {
|
||||
data += 1 + GOODIX_CONTACT_SIZE;
|
||||
error = goodix_i2c_read(ts->client,
|
||||
GOODIX_READ_COOR_ADDR +
|
||||
1 + GOODIX_CONTACT_SIZE,
|
||||
data,
|
||||
GOODIX_CONTACT_SIZE *
|
||||
(touch_num - 1));
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return touch_num;
|
||||
}
|
||||
|
||||
usleep_range(1000, 2000); /* Poll every 1 - 2 ms */
|
||||
} while (time_before(jiffies, max_timeout));
|
||||
|
||||
/*
|
||||
* The Goodix panel will send spurious interrupts after a
|
||||
* 'finger up' event, which will always cause a timeout.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data)
|
||||
|
|
|
@ -663,12 +663,10 @@ static int stmfts_probe(struct i2c_client *client,
|
|||
sdata->input->open = stmfts_input_open;
|
||||
sdata->input->close = stmfts_input_close;
|
||||
|
||||
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
|
||||
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
|
||||
touchscreen_parse_properties(sdata->input, true, &sdata->prop);
|
||||
|
||||
input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0,
|
||||
sdata->prop.max_x, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0,
|
||||
sdata->prop.max_y, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
|
||||
input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
|
||||
|
|
|
@ -161,7 +161,7 @@ static void titsc_step_config(struct titsc *ts_dev)
|
|||
break;
|
||||
case 5:
|
||||
config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 |
|
||||
ts_dev->bit_xn | ts_dev->bit_yp;
|
||||
STEPCONFIG_XNP | STEPCONFIG_YPN;
|
||||
break;
|
||||
case 8:
|
||||
config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp);
|
||||
|
|
|
@ -107,6 +107,10 @@ struct its_node {
|
|||
|
||||
#define ITS_ITT_ALIGN SZ_256
|
||||
|
||||
/* The maximum number of VPEID bits supported by VLPI commands */
|
||||
#define ITS_MAX_VPEID_BITS (16)
|
||||
#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS))
|
||||
|
||||
/* Convert page order to size in bytes */
|
||||
#define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o))
|
||||
|
||||
|
@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
|
|||
|
||||
static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
|
||||
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
|
||||
}
|
||||
|
||||
static void its_encode_valid(struct its_cmd_block *cmd, int valid)
|
||||
|
@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
|
|||
|
||||
static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
|
||||
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
|
||||
}
|
||||
|
||||
static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
|
||||
|
@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
|
|||
|
||||
static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
|
||||
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
|
||||
}
|
||||
|
||||
static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
|
||||
|
@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
|||
u64 val = its_read_baser(its, baser);
|
||||
u64 esz = GITS_BASER_ENTRY_SIZE(val);
|
||||
u64 type = GITS_BASER_TYPE(val);
|
||||
u64 baser_phys, tmp;
|
||||
u32 alloc_pages;
|
||||
void *base;
|
||||
u64 tmp;
|
||||
|
||||
retry_alloc_baser:
|
||||
alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
|
||||
|
@ -1496,8 +1500,24 @@ retry_alloc_baser:
|
|||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
baser_phys = virt_to_phys(base);
|
||||
|
||||
/* Check if the physical address of the memory is above 48bits */
|
||||
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
|
||||
|
||||
/* 52bit PA is supported only when PageSize=64K */
|
||||
if (psz != SZ_64K) {
|
||||
pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
|
||||
free_pages((unsigned long)base, order);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Convert 52bit PA to 48bit field */
|
||||
baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
|
||||
}
|
||||
|
||||
retry_baser:
|
||||
val = (virt_to_phys(base) |
|
||||
val = (baser_phys |
|
||||
(type << GITS_BASER_TYPE_SHIFT) |
|
||||
((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
|
||||
((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) |
|
||||
|
@ -1582,13 +1602,12 @@ retry_baser:
|
|||
|
||||
static bool its_parse_indirect_baser(struct its_node *its,
|
||||
struct its_baser *baser,
|
||||
u32 psz, u32 *order)
|
||||
u32 psz, u32 *order, u32 ids)
|
||||
{
|
||||
u64 tmp = its_read_baser(its, baser);
|
||||
u64 type = GITS_BASER_TYPE(tmp);
|
||||
u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
|
||||
u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
|
||||
u32 ids = its->device_ids;
|
||||
u32 new_order = *order;
|
||||
bool indirect = false;
|
||||
|
||||
|
@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its)
|
|||
continue;
|
||||
|
||||
case GITS_BASER_TYPE_DEVICE:
|
||||
indirect = its_parse_indirect_baser(its, baser,
|
||||
psz, &order,
|
||||
its->device_ids);
|
||||
case GITS_BASER_TYPE_VCPU:
|
||||
indirect = its_parse_indirect_baser(its, baser,
|
||||
psz, &order);
|
||||
psz, &order,
|
||||
ITS_MAX_VPEID_BITS);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = {
|
|||
|
||||
static int its_vpe_id_alloc(void)
|
||||
{
|
||||
return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL);
|
||||
return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void its_vpe_id_free(u16 id)
|
||||
|
@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
BUG_ON(entries != vpe_proxy.dev->nr_ites);
|
||||
BUG_ON(entries > vpe_proxy.dev->nr_ites);
|
||||
|
||||
raw_spin_lock_init(&vpe_proxy.lock);
|
||||
vpe_proxy.next_victim = 0;
|
||||
|
|
|
@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc,
|
|||
for (i = 0; i < 2; i++) {
|
||||
ct[i].chip.irq_ack = irq_gc_ack_set_bit;
|
||||
ct[i].chip.irq_mask = irq_gc_mask_disable_reg;
|
||||
ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack;
|
||||
ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set;
|
||||
ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg;
|
||||
ct[i].chip.irq_set_type = tangox_irq_set_type;
|
||||
ct[i].chip.name = gc->domain->name;
|
||||
|
|
|
@ -448,6 +448,8 @@ static void intel_dsm_init(struct intel_host *intel_host, struct device *dev,
|
|||
int err;
|
||||
u32 val;
|
||||
|
||||
intel_host->d3_retune = true;
|
||||
|
||||
err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns);
|
||||
if (err) {
|
||||
pr_debug("%s: DSM not supported, error %d\n",
|
||||
|
|
|
@ -182,22 +182,23 @@
|
|||
/* FLEXCAN hardware feature flags
|
||||
*
|
||||
* Below is some version info we got:
|
||||
* SOC Version IP-Version Glitch- [TR]WRN_INT Memory err RTR re-
|
||||
* Filter? connected? detection ception in MB
|
||||
* MX25 FlexCAN2 03.00.00.00 no no no no
|
||||
* MX28 FlexCAN2 03.00.04.00 yes yes no no
|
||||
* MX35 FlexCAN2 03.00.00.00 no no no no
|
||||
* MX53 FlexCAN2 03.00.00.00 yes no no no
|
||||
* MX6s FlexCAN3 10.00.12.00 yes yes no yes
|
||||
* VF610 FlexCAN3 ? no yes yes yes?
|
||||
* SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re-
|
||||
* Filter? connected? Passive detection ception in MB
|
||||
* MX25 FlexCAN2 03.00.00.00 no no ? no no
|
||||
* MX28 FlexCAN2 03.00.04.00 yes yes no no no
|
||||
* MX35 FlexCAN2 03.00.00.00 no no ? no no
|
||||
* MX53 FlexCAN2 03.00.00.00 yes no no no no
|
||||
* MX6s FlexCAN3 10.00.12.00 yes yes no no yes
|
||||
* VF610 FlexCAN3 ? no yes ? yes yes?
|
||||
*
|
||||
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
|
||||
*/
|
||||
#define FLEXCAN_QUIRK_BROKEN_ERR_STATE BIT(1) /* [TR]WRN_INT not connected */
|
||||
#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */
|
||||
#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */
|
||||
#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */
|
||||
#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */
|
||||
#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */
|
||||
#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */
|
||||
|
||||
/* Structure of the message buffer */
|
||||
struct flexcan_mb {
|
||||
|
@ -281,14 +282,17 @@ struct flexcan_priv {
|
|||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_p1010_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE,
|
||||
.quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE |
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_imx28_devtype_data;
|
||||
static const struct flexcan_devtype_data fsl_imx28_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_imx6q_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP,
|
||||
FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
|
||||
|
@ -335,6 +339,22 @@ static inline void flexcan_write(u32 val, void __iomem *addr)
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
|
||||
{
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK);
|
||||
|
||||
flexcan_write(reg_ctrl, ®s->ctrl);
|
||||
}
|
||||
|
||||
static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv)
|
||||
{
|
||||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK);
|
||||
|
||||
flexcan_write(reg_ctrl, ®s->ctrl);
|
||||
}
|
||||
|
||||
static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv)
|
||||
{
|
||||
if (!priv->reg_xceiver)
|
||||
|
@ -713,6 +733,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
|||
struct flexcan_regs __iomem *regs = priv->regs;
|
||||
irqreturn_t handled = IRQ_NONE;
|
||||
u32 reg_iflag1, reg_esr;
|
||||
enum can_state last_state = priv->can.state;
|
||||
|
||||
reg_iflag1 = flexcan_read(®s->iflag1);
|
||||
|
||||
|
@ -765,8 +786,10 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
|||
flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr);
|
||||
}
|
||||
|
||||
/* state change interrupt */
|
||||
if (reg_esr & FLEXCAN_ESR_ERR_STATE)
|
||||
/* state change interrupt or broken error state quirk fix is enabled */
|
||||
if ((reg_esr & FLEXCAN_ESR_ERR_STATE) ||
|
||||
(priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE |
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE)))
|
||||
flexcan_irq_state(dev, reg_esr);
|
||||
|
||||
/* bus error IRQ - handle if bus error reporting is activated */
|
||||
|
@ -774,6 +797,44 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id)
|
|||
(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
|
||||
flexcan_irq_bus_err(dev, reg_esr);
|
||||
|
||||
/* availability of error interrupt among state transitions in case
|
||||
* bus error reporting is de-activated and
|
||||
* FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled:
|
||||
* +--------------------------------------------------------------+
|
||||
* | +----------------------------------------------+ [stopped / |
|
||||
* | | | sleeping] -+
|
||||
* +-+-> active <-> warning <-> passive -> bus off -+
|
||||
* ___________^^^^^^^^^^^^_______________________________
|
||||
* disabled(1) enabled disabled
|
||||
*
|
||||
* (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled
|
||||
*/
|
||||
if ((last_state != priv->can.state) &&
|
||||
(priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) &&
|
||||
!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) {
|
||||
switch (priv->can.state) {
|
||||
case CAN_STATE_ERROR_ACTIVE:
|
||||
if (priv->devtype_data->quirks &
|
||||
FLEXCAN_QUIRK_BROKEN_WERR_STATE)
|
||||
flexcan_error_irq_enable(priv);
|
||||
else
|
||||
flexcan_error_irq_disable(priv);
|
||||
break;
|
||||
|
||||
case CAN_STATE_ERROR_WARNING:
|
||||
flexcan_error_irq_enable(priv);
|
||||
break;
|
||||
|
||||
case CAN_STATE_ERROR_PASSIVE:
|
||||
case CAN_STATE_BUS_OFF:
|
||||
flexcan_error_irq_disable(priv);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
@ -887,7 +948,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
|||
* on most Flexcan cores, too. Otherwise we don't get
|
||||
* any error warning or passive interrupts.
|
||||
*/
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE ||
|
||||
if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE ||
|
||||
priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
|
||||
reg_ctrl |= FLEXCAN_CTRL_ERR_MSK;
|
||||
else
|
||||
|
|
|
@ -333,7 +333,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
|
|||
}
|
||||
|
||||
cf->can_id = id & ESD_IDMASK;
|
||||
cf->can_dlc = get_can_dlc(msg->msg.rx.dlc);
|
||||
cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR);
|
||||
|
||||
if (id & ESD_EXTID)
|
||||
cf->can_id |= CAN_EFF_FLAG;
|
||||
|
|
|
@ -375,6 +375,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
|
|||
|
||||
gs_free_tx_context(txc);
|
||||
|
||||
atomic_dec(&dev->active_tx_urbs);
|
||||
|
||||
netif_wake_queue(netdev);
|
||||
}
|
||||
|
||||
|
@ -463,14 +465,6 @@ static void gs_usb_xmit_callback(struct urb *urb)
|
|||
urb->transfer_buffer_length,
|
||||
urb->transfer_buffer,
|
||||
urb->transfer_dma);
|
||||
|
||||
atomic_dec(&dev->active_tx_urbs);
|
||||
|
||||
if (!netif_device_present(netdev))
|
||||
return;
|
||||
|
||||
if (netif_queue_stopped(netdev))
|
||||
netif_wake_queue(netdev);
|
||||
}
|
||||
|
||||
static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
|
||||
|
|
|
@ -214,8 +214,14 @@ static int mv88e6060_setup(struct dsa_switch *ds)
|
|||
|
||||
static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr)
|
||||
{
|
||||
/* Use the same MAC Address as FD Pause frames for all ports */
|
||||
REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, (addr[0] << 9) | addr[1]);
|
||||
u16 val = addr[0] << 8 | addr[1];
|
||||
|
||||
/* The multicast bit is always transmitted as a zero, so the switch uses
|
||||
* bit 8 for "DiffAddr", where 0 means all ports transmit the same SA.
|
||||
*/
|
||||
val &= 0xfeff;
|
||||
|
||||
REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val);
|
||||
REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]);
|
||||
REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]);
|
||||
|
||||
|
|
|
@ -742,8 +742,8 @@ static void ena_get_channels(struct net_device *netdev,
|
|||
{
|
||||
struct ena_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
channels->max_rx = ENA_MAX_NUM_IO_QUEUES;
|
||||
channels->max_tx = ENA_MAX_NUM_IO_QUEUES;
|
||||
channels->max_rx = adapter->num_queues;
|
||||
channels->max_tx = adapter->num_queues;
|
||||
channels->max_other = 0;
|
||||
channels->max_combined = 0;
|
||||
channels->rx_count = adapter->num_queues;
|
||||
|
|
|
@ -966,7 +966,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring,
|
|||
u64_stats_update_begin(&rx_ring->syncp);
|
||||
rx_ring->rx_stats.bad_csum++;
|
||||
u64_stats_update_end(&rx_ring->syncp);
|
||||
netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
|
||||
netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
|
||||
"RX IPv4 header checksum error\n");
|
||||
return;
|
||||
}
|
||||
|
@ -979,7 +979,7 @@ static inline void ena_rx_checksum(struct ena_ring *rx_ring,
|
|||
u64_stats_update_begin(&rx_ring->syncp);
|
||||
rx_ring->rx_stats.bad_csum++;
|
||||
u64_stats_update_end(&rx_ring->syncp);
|
||||
netif_err(rx_ring->adapter, rx_err, rx_ring->netdev,
|
||||
netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev,
|
||||
"RX L4 checksum error\n");
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
return;
|
||||
|
@ -3064,7 +3064,8 @@ static void ena_release_bars(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
|
|||
if (ena_dev->mem_bar)
|
||||
devm_iounmap(&pdev->dev, ena_dev->mem_bar);
|
||||
|
||||
devm_iounmap(&pdev->dev, ena_dev->reg_bar);
|
||||
if (ena_dev->reg_bar)
|
||||
devm_iounmap(&pdev->dev, ena_dev->reg_bar);
|
||||
|
||||
release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK;
|
||||
pci_release_selected_regions(pdev, release_bars);
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
|
||||
#define AQ_CFG_FORCE_LEGACY_INT 0U
|
||||
|
||||
#define AQ_CFG_IS_INTERRUPT_MODERATION_DEF 1U
|
||||
#define AQ_CFG_INTERRUPT_MODERATION_RATE_DEF 0xFFFFU
|
||||
#define AQ_CFG_INTERRUPT_MODERATION_OFF 0
|
||||
#define AQ_CFG_INTERRUPT_MODERATION_ON 1
|
||||
#define AQ_CFG_INTERRUPT_MODERATION_AUTO 0xFFFFU
|
||||
|
||||
#define AQ_CFG_INTERRUPT_MODERATION_USEC_MAX (0x1FF * 2)
|
||||
|
||||
#define AQ_CFG_IRQ_MASK 0x1FFU
|
||||
|
||||
#define AQ_CFG_VECS_MAX 8U
|
||||
|
|
|
@ -56,10 +56,6 @@ aq_ethtool_set_link_ksettings(struct net_device *ndev,
|
|||
return aq_nic_set_link_ksettings(aq_nic, cmd);
|
||||
}
|
||||
|
||||
/* there "5U" is number of queue[#] stats lines (InPackets+...+InErrors) */
|
||||
static const unsigned int aq_ethtool_stat_queue_lines = 5U;
|
||||
static const unsigned int aq_ethtool_stat_queue_chars =
|
||||
5U * ETH_GSTRING_LEN;
|
||||
static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
|
||||
"InPackets",
|
||||
"InUCast",
|
||||
|
@ -83,56 +79,26 @@ static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
|
|||
"InOctetsDma",
|
||||
"OutOctetsDma",
|
||||
"InDroppedDma",
|
||||
"Queue[0] InPackets",
|
||||
"Queue[0] OutPackets",
|
||||
"Queue[0] InJumboPackets",
|
||||
"Queue[0] InLroPackets",
|
||||
"Queue[0] InErrors",
|
||||
"Queue[1] InPackets",
|
||||
"Queue[1] OutPackets",
|
||||
"Queue[1] InJumboPackets",
|
||||
"Queue[1] InLroPackets",
|
||||
"Queue[1] InErrors",
|
||||
"Queue[2] InPackets",
|
||||
"Queue[2] OutPackets",
|
||||
"Queue[2] InJumboPackets",
|
||||
"Queue[2] InLroPackets",
|
||||
"Queue[2] InErrors",
|
||||
"Queue[3] InPackets",
|
||||
"Queue[3] OutPackets",
|
||||
"Queue[3] InJumboPackets",
|
||||
"Queue[3] InLroPackets",
|
||||
"Queue[3] InErrors",
|
||||
"Queue[4] InPackets",
|
||||
"Queue[4] OutPackets",
|
||||
"Queue[4] InJumboPackets",
|
||||
"Queue[4] InLroPackets",
|
||||
"Queue[4] InErrors",
|
||||
"Queue[5] InPackets",
|
||||
"Queue[5] OutPackets",
|
||||
"Queue[5] InJumboPackets",
|
||||
"Queue[5] InLroPackets",
|
||||
"Queue[5] InErrors",
|
||||
"Queue[6] InPackets",
|
||||
"Queue[6] OutPackets",
|
||||
"Queue[6] InJumboPackets",
|
||||
"Queue[6] InLroPackets",
|
||||
"Queue[6] InErrors",
|
||||
"Queue[7] InPackets",
|
||||
"Queue[7] OutPackets",
|
||||
"Queue[7] InJumboPackets",
|
||||
"Queue[7] InLroPackets",
|
||||
"Queue[7] InErrors",
|
||||
};
|
||||
|
||||
static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
|
||||
"Queue[%d] InPackets",
|
||||
"Queue[%d] OutPackets",
|
||||
"Queue[%d] Restarts",
|
||||
"Queue[%d] InJumboPackets",
|
||||
"Queue[%d] InLroPackets",
|
||||
"Queue[%d] InErrors",
|
||||
};
|
||||
|
||||
static void aq_ethtool_stats(struct net_device *ndev,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
||||
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
|
||||
|
||||
/* ASSERT: Need add lines to aq_ethtool_stat_names if AQ_CFG_VECS_MAX > 8 */
|
||||
BUILD_BUG_ON(AQ_CFG_VECS_MAX > 8);
|
||||
memset(data, 0, ARRAY_SIZE(aq_ethtool_stat_names) * sizeof(u64));
|
||||
memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
|
||||
ARRAY_SIZE(aq_ethtool_queue_stat_names) *
|
||||
cfg->vecs) * sizeof(u64));
|
||||
aq_nic_get_stats(aq_nic, data);
|
||||
}
|
||||
|
||||
|
@ -154,8 +120,8 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
|
|||
|
||||
strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
|
||||
sizeof(drvinfo->bus_info));
|
||||
drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) -
|
||||
(AQ_CFG_VECS_MAX - cfg->vecs) * aq_ethtool_stat_queue_lines;
|
||||
drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
|
||||
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
|
||||
drvinfo->testinfo_len = 0;
|
||||
drvinfo->regdump_len = regs_count;
|
||||
drvinfo->eedump_len = 0;
|
||||
|
@ -164,14 +130,25 @@ static void aq_ethtool_get_drvinfo(struct net_device *ndev,
|
|||
static void aq_ethtool_get_strings(struct net_device *ndev,
|
||||
u32 stringset, u8 *data)
|
||||
{
|
||||
int i, si;
|
||||
struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
||||
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
|
||||
u8 *p = data;
|
||||
|
||||
if (stringset == ETH_SS_STATS)
|
||||
memcpy(data, *aq_ethtool_stat_names,
|
||||
sizeof(aq_ethtool_stat_names) -
|
||||
(AQ_CFG_VECS_MAX - cfg->vecs) *
|
||||
aq_ethtool_stat_queue_chars);
|
||||
if (stringset == ETH_SS_STATS) {
|
||||
memcpy(p, *aq_ethtool_stat_names,
|
||||
sizeof(aq_ethtool_stat_names));
|
||||
p = p + sizeof(aq_ethtool_stat_names);
|
||||
for (i = 0; i < cfg->vecs; i++) {
|
||||
for (si = 0;
|
||||
si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
|
||||
si++) {
|
||||
snprintf(p, ETH_GSTRING_LEN,
|
||||
aq_ethtool_queue_stat_names[si], i);
|
||||
p += ETH_GSTRING_LEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
|
||||
|
@ -182,9 +159,8 @@ static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
|
|||
|
||||
switch (stringset) {
|
||||
case ETH_SS_STATS:
|
||||
ret = ARRAY_SIZE(aq_ethtool_stat_names) -
|
||||
(AQ_CFG_VECS_MAX - cfg->vecs) *
|
||||
aq_ethtool_stat_queue_lines;
|
||||
ret = ARRAY_SIZE(aq_ethtool_stat_names) +
|
||||
cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
|
@ -245,6 +221,69 @@ static int aq_ethtool_get_rxnfc(struct net_device *ndev,
|
|||
return err;
|
||||
}
|
||||
|
||||
int aq_ethtool_get_coalesce(struct net_device *ndev,
|
||||
struct ethtool_coalesce *coal)
|
||||
{
|
||||
struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
||||
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
|
||||
|
||||
if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
|
||||
cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
|
||||
coal->rx_coalesce_usecs = cfg->rx_itr;
|
||||
coal->tx_coalesce_usecs = cfg->tx_itr;
|
||||
coal->rx_max_coalesced_frames = 0;
|
||||
coal->tx_max_coalesced_frames = 0;
|
||||
} else {
|
||||
coal->rx_coalesce_usecs = 0;
|
||||
coal->tx_coalesce_usecs = 0;
|
||||
coal->rx_max_coalesced_frames = 1;
|
||||
coal->tx_max_coalesced_frames = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aq_ethtool_set_coalesce(struct net_device *ndev,
|
||||
struct ethtool_coalesce *coal)
|
||||
{
|
||||
struct aq_nic_s *aq_nic = netdev_priv(ndev);
|
||||
struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
|
||||
|
||||
/* This is not yet supported
|
||||
*/
|
||||
if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Atlantic only supports timing based coalescing
|
||||
*/
|
||||
if (coal->rx_max_coalesced_frames > 1 ||
|
||||
coal->rx_coalesce_usecs_irq ||
|
||||
coal->rx_max_coalesced_frames_irq)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (coal->tx_max_coalesced_frames > 1 ||
|
||||
coal->tx_coalesce_usecs_irq ||
|
||||
coal->tx_max_coalesced_frames_irq)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* We do not support frame counting. Check this
|
||||
*/
|
||||
if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
|
||||
return -EOPNOTSUPP;
|
||||
if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
|
||||
coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
|
||||
|
||||
cfg->rx_itr = coal->rx_coalesce_usecs;
|
||||
cfg->tx_itr = coal->tx_coalesce_usecs;
|
||||
|
||||
return aq_nic_update_interrupt_moderation_settings(aq_nic);
|
||||
}
|
||||
|
||||
const struct ethtool_ops aq_ethtool_ops = {
|
||||
.get_link = aq_ethtool_get_link,
|
||||
.get_regs_len = aq_ethtool_get_regs_len,
|
||||
|
@ -259,4 +298,6 @@ const struct ethtool_ops aq_ethtool_ops = {
|
|||
.get_ethtool_stats = aq_ethtool_stats,
|
||||
.get_link_ksettings = aq_ethtool_get_link_ksettings,
|
||||
.set_link_ksettings = aq_ethtool_set_link_ksettings,
|
||||
.get_coalesce = aq_ethtool_get_coalesce,
|
||||
.set_coalesce = aq_ethtool_set_coalesce,
|
||||
};
|
||||
|
|
|
@ -151,8 +151,7 @@ struct aq_hw_ops {
|
|||
[ETH_ALEN],
|
||||
u32 count);
|
||||
|
||||
int (*hw_interrupt_moderation_set)(struct aq_hw_s *self,
|
||||
bool itr_enabled);
|
||||
int (*hw_interrupt_moderation_set)(struct aq_hw_s *self);
|
||||
|
||||
int (*hw_rss_set)(struct aq_hw_s *self,
|
||||
struct aq_rss_parameters *rss_params);
|
||||
|
@ -163,6 +162,8 @@ struct aq_hw_ops {
|
|||
int (*hw_get_regs)(struct aq_hw_s *self,
|
||||
struct aq_hw_caps_s *aq_hw_caps, u32 *regs_buff);
|
||||
|
||||
int (*hw_update_stats)(struct aq_hw_s *self);
|
||||
|
||||
int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data,
|
||||
unsigned int *p_count);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "aq_pci_func.h"
|
||||
#include "aq_nic_internal.h"
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/timer.h>
|
||||
|
@ -24,6 +25,18 @@
|
|||
#include <linux/tcp.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO;
|
||||
module_param_named(aq_itr, aq_itr, uint, 0644);
|
||||
MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode");
|
||||
|
||||
static unsigned int aq_itr_tx;
|
||||
module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644);
|
||||
MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate");
|
||||
|
||||
static unsigned int aq_itr_rx;
|
||||
module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644);
|
||||
MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate");
|
||||
|
||||
static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues)
|
||||
{
|
||||
struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg;
|
||||
|
@ -61,9 +74,9 @@ static void aq_nic_cfg_init_defaults(struct aq_nic_s *self)
|
|||
|
||||
cfg->is_polling = AQ_CFG_IS_POLLING_DEF;
|
||||
|
||||
cfg->is_interrupt_moderation = AQ_CFG_IS_INTERRUPT_MODERATION_DEF;
|
||||
cfg->itr = cfg->is_interrupt_moderation ?
|
||||
AQ_CFG_INTERRUPT_MODERATION_RATE_DEF : 0U;
|
||||
cfg->itr = aq_itr;
|
||||
cfg->tx_itr = aq_itr_tx;
|
||||
cfg->rx_itr = aq_itr_rx;
|
||||
|
||||
cfg->is_rss = AQ_CFG_IS_RSS_DEF;
|
||||
cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF;
|
||||
|
@ -126,10 +139,12 @@ static int aq_nic_update_link_status(struct aq_nic_s *self)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps)
|
||||
if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) {
|
||||
pr_info("%s: link change old %d new %d\n",
|
||||
AQ_CFG_DRV_NAME, self->link_status.mbps,
|
||||
self->aq_hw->aq_link_status.mbps);
|
||||
aq_nic_update_interrupt_moderation_settings(self);
|
||||
}
|
||||
|
||||
self->link_status = self->aq_hw->aq_link_status;
|
||||
if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) {
|
||||
|
@ -164,8 +179,8 @@ static void aq_nic_service_timer_cb(unsigned long param)
|
|||
if (err)
|
||||
goto err_exit;
|
||||
|
||||
self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
|
||||
self->aq_nic_cfg.is_interrupt_moderation);
|
||||
if (self->aq_hw_ops.hw_update_stats)
|
||||
self->aq_hw_ops.hw_update_stats(self->aq_hw);
|
||||
|
||||
memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
|
||||
memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
|
||||
|
@ -334,6 +349,7 @@ struct aq_nic_s *aq_nic_alloc_hot(struct net_device *ndev)
|
|||
}
|
||||
if (netif_running(ndev))
|
||||
netif_tx_disable(ndev);
|
||||
netif_carrier_off(self->ndev);
|
||||
|
||||
for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs;
|
||||
self->aq_vecs++) {
|
||||
|
@ -421,9 +437,8 @@ int aq_nic_start(struct aq_nic_s *self)
|
|||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
err = self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
|
||||
self->aq_nic_cfg.is_interrupt_moderation);
|
||||
if (err < 0)
|
||||
err = aq_nic_update_interrupt_moderation_settings(self);
|
||||
if (err)
|
||||
goto err_exit;
|
||||
setup_timer(&self->service_timer, &aq_nic_service_timer_cb,
|
||||
(unsigned long)self);
|
||||
|
@ -645,6 +660,11 @@ err_exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self)
|
||||
{
|
||||
return self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw);
|
||||
}
|
||||
|
||||
int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -899,6 +919,7 @@ int aq_nic_stop(struct aq_nic_s *self)
|
|||
unsigned int i = 0U;
|
||||
|
||||
netif_tx_disable(self->ndev);
|
||||
netif_carrier_off(self->ndev);
|
||||
|
||||
del_timer_sync(&self->service_timer);
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ struct aq_nic_cfg_s {
|
|||
u32 vecs; /* vecs==allocated irqs */
|
||||
u32 irq_type;
|
||||
u32 itr;
|
||||
u16 rx_itr;
|
||||
u16 tx_itr;
|
||||
u32 num_rss_queues;
|
||||
u32 mtu;
|
||||
u32 ucp_0x364;
|
||||
|
@ -49,7 +51,6 @@ struct aq_nic_cfg_s {
|
|||
u16 is_mc_list_enabled;
|
||||
u16 mc_list_count;
|
||||
bool is_autoneg;
|
||||
bool is_interrupt_moderation;
|
||||
bool is_polling;
|
||||
bool is_rss;
|
||||
bool is_lro;
|
||||
|
@ -104,5 +105,6 @@ int aq_nic_set_link_ksettings(struct aq_nic_s *self,
|
|||
struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self);
|
||||
u32 aq_nic_get_fw_version(struct aq_nic_s *self);
|
||||
int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg);
|
||||
int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self);
|
||||
|
||||
#endif /* AQ_NIC_H */
|
||||
|
|
|
@ -85,6 +85,7 @@ int aq_pci_func_init(struct aq_pci_func_s *self)
|
|||
int err = 0;
|
||||
unsigned int bar = 0U;
|
||||
unsigned int port = 0U;
|
||||
unsigned int numvecs = 0U;
|
||||
|
||||
err = pci_enable_device(self->pdev);
|
||||
if (err < 0)
|
||||
|
@ -142,10 +143,12 @@ int aq_pci_func_init(struct aq_pci_func_s *self)
|
|||
}
|
||||
}
|
||||
|
||||
/*enable interrupts */
|
||||
numvecs = min((u8)AQ_CFG_VECS_DEF, self->aq_hw_caps.msix_irqs);
|
||||
numvecs = min(numvecs, num_online_cpus());
|
||||
|
||||
/* enable interrupts */
|
||||
#if !AQ_CFG_FORCE_LEGACY_INT
|
||||
err = pci_alloc_irq_vectors(self->pdev, self->aq_hw_caps.msix_irqs,
|
||||
self->aq_hw_caps.msix_irqs, PCI_IRQ_MSIX);
|
||||
err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs, PCI_IRQ_MSIX);
|
||||
|
||||
if (err < 0) {
|
||||
err = pci_alloc_irq_vectors(self->pdev, 1, 1,
|
||||
|
@ -153,7 +156,7 @@ int aq_pci_func_init(struct aq_pci_func_s *self)
|
|||
if (err < 0)
|
||||
goto err_exit;
|
||||
}
|
||||
#endif
|
||||
#endif /* AQ_CFG_FORCE_LEGACY_INT */
|
||||
|
||||
/* net device init */
|
||||
for (port = 0; port < self->ports; ++port) {
|
||||
|
@ -265,6 +268,9 @@ void aq_pci_func_free(struct aq_pci_func_s *self)
|
|||
aq_nic_ndev_free(self->port[port]);
|
||||
}
|
||||
|
||||
if (self->mmio)
|
||||
iounmap(self->mmio);
|
||||
|
||||
kfree(self);
|
||||
|
||||
err_exit:;
|
||||
|
|
|
@ -373,8 +373,11 @@ int aq_vec_get_sw_stats(struct aq_vec_s *self, u64 *data, unsigned int *p_count)
|
|||
memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
|
||||
aq_vec_add_stats(self, &stats_rx, &stats_tx);
|
||||
|
||||
/* This data should mimic aq_ethtool_queue_stat_names structure
|
||||
*/
|
||||
data[count] += stats_rx.packets;
|
||||
data[++count] += stats_tx.packets;
|
||||
data[++count] += stats_tx.queue_restarts;
|
||||
data[++count] += stats_rx.jumbo_packets;
|
||||
data[++count] += stats_rx.lro_packets;
|
||||
data[++count] += stats_rx.errors;
|
||||
|
|
|
@ -765,24 +765,23 @@ err_exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self,
|
||||
bool itr_enabled)
|
||||
static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self)
|
||||
{
|
||||
unsigned int i = 0U;
|
||||
u32 itr_rx;
|
||||
|
||||
if (itr_enabled && self->aq_nic_cfg->itr) {
|
||||
if (self->aq_nic_cfg->itr != 0xFFFFU) {
|
||||
if (self->aq_nic_cfg->itr) {
|
||||
if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) {
|
||||
u32 itr_ = (self->aq_nic_cfg->itr >> 1);
|
||||
|
||||
itr_ = min(AQ_CFG_IRQ_MASK, itr_);
|
||||
|
||||
PHAL_ATLANTIC_A0->itr_rx = 0x80000000U |
|
||||
(itr_ << 0x10);
|
||||
itr_rx = 0x80000000U | (itr_ << 0x10);
|
||||
} else {
|
||||
u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U);
|
||||
|
||||
if (n < self->aq_link_status.mbps) {
|
||||
PHAL_ATLANTIC_A0->itr_rx = 0U;
|
||||
itr_rx = 0U;
|
||||
} else {
|
||||
static unsigned int hw_timers_tbl_[] = {
|
||||
0x01CU, /* 10Gbit */
|
||||
|
@ -797,8 +796,7 @@ static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self,
|
|||
hw_atl_utils_mbps_2_speed_index(
|
||||
self->aq_link_status.mbps);
|
||||
|
||||
PHAL_ATLANTIC_A0->itr_rx =
|
||||
0x80000000U |
|
||||
itr_rx = 0x80000000U |
|
||||
(hw_timers_tbl_[speed_index] << 0x10U);
|
||||
}
|
||||
|
||||
|
@ -806,11 +804,11 @@ static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self,
|
|||
aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U);
|
||||
}
|
||||
} else {
|
||||
PHAL_ATLANTIC_A0->itr_rx = 0U;
|
||||
itr_rx = 0U;
|
||||
}
|
||||
|
||||
for (i = HW_ATL_A0_RINGS_MAX; i--;)
|
||||
reg_irq_thr_set(self, PHAL_ATLANTIC_A0->itr_rx, i);
|
||||
reg_irq_thr_set(self, itr_rx, i);
|
||||
|
||||
return aq_hw_err_from_flags(self);
|
||||
}
|
||||
|
@ -885,6 +883,7 @@ static struct aq_hw_ops hw_atl_ops_ = {
|
|||
.hw_rss_set = hw_atl_a0_hw_rss_set,
|
||||
.hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set,
|
||||
.hw_get_regs = hw_atl_utils_hw_get_regs,
|
||||
.hw_update_stats = hw_atl_utils_update_stats,
|
||||
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
|
||||
.hw_get_fw_version = hw_atl_utils_get_fw_version,
|
||||
};
|
||||
|
|
|
@ -788,39 +788,45 @@ err_exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self,
|
||||
bool itr_enabled)
|
||||
static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self)
|
||||
{
|
||||
unsigned int i = 0U;
|
||||
u32 itr_tx = 2U;
|
||||
u32 itr_rx = 2U;
|
||||
|
||||
if (itr_enabled && self->aq_nic_cfg->itr) {
|
||||
switch (self->aq_nic_cfg->itr) {
|
||||
case AQ_CFG_INTERRUPT_MODERATION_ON:
|
||||
case AQ_CFG_INTERRUPT_MODERATION_AUTO:
|
||||
tdm_tx_desc_wr_wb_irq_en_set(self, 0U);
|
||||
tdm_tdm_intr_moder_en_set(self, 1U);
|
||||
rdm_rx_desc_wr_wb_irq_en_set(self, 0U);
|
||||
rdm_rdm_intr_moder_en_set(self, 1U);
|
||||
|
||||
PHAL_ATLANTIC_B0->itr_tx = 2U;
|
||||
PHAL_ATLANTIC_B0->itr_rx = 2U;
|
||||
if (self->aq_nic_cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON) {
|
||||
/* HW timers are in 2us units */
|
||||
int tx_max_timer = self->aq_nic_cfg->tx_itr / 2;
|
||||
int tx_min_timer = tx_max_timer / 2;
|
||||
|
||||
if (self->aq_nic_cfg->itr != 0xFFFFU) {
|
||||
unsigned int max_timer = self->aq_nic_cfg->itr / 2U;
|
||||
unsigned int min_timer = self->aq_nic_cfg->itr / 32U;
|
||||
int rx_max_timer = self->aq_nic_cfg->rx_itr / 2;
|
||||
int rx_min_timer = rx_max_timer / 2;
|
||||
|
||||
max_timer = min(0x1FFU, max_timer);
|
||||
min_timer = min(0xFFU, min_timer);
|
||||
tx_max_timer = min(HW_ATL_INTR_MODER_MAX, tx_max_timer);
|
||||
tx_min_timer = min(HW_ATL_INTR_MODER_MIN, tx_min_timer);
|
||||
rx_max_timer = min(HW_ATL_INTR_MODER_MAX, rx_max_timer);
|
||||
rx_min_timer = min(HW_ATL_INTR_MODER_MIN, rx_min_timer);
|
||||
|
||||
PHAL_ATLANTIC_B0->itr_tx |= min_timer << 0x8U;
|
||||
PHAL_ATLANTIC_B0->itr_tx |= max_timer << 0x10U;
|
||||
PHAL_ATLANTIC_B0->itr_rx |= min_timer << 0x8U;
|
||||
PHAL_ATLANTIC_B0->itr_rx |= max_timer << 0x10U;
|
||||
itr_tx |= tx_min_timer << 0x8U;
|
||||
itr_tx |= tx_max_timer << 0x10U;
|
||||
itr_rx |= rx_min_timer << 0x8U;
|
||||
itr_rx |= rx_max_timer << 0x10U;
|
||||
} else {
|
||||
static unsigned int hw_atl_b0_timers_table_tx_[][2] = {
|
||||
{0xffU, 0xffU}, /* 10Gbit */
|
||||
{0xffU, 0x1ffU}, /* 5Gbit */
|
||||
{0xffU, 0x1ffU}, /* 5Gbit 5GS */
|
||||
{0xffU, 0x1ffU}, /* 2.5Gbit */
|
||||
{0xffU, 0x1ffU}, /* 1Gbit */
|
||||
{0xffU, 0x1ffU}, /* 100Mbit */
|
||||
{0xfU, 0xffU}, /* 10Gbit */
|
||||
{0xfU, 0x1ffU}, /* 5Gbit */
|
||||
{0xfU, 0x1ffU}, /* 5Gbit 5GS */
|
||||
{0xfU, 0x1ffU}, /* 2.5Gbit */
|
||||
{0xfU, 0x1ffU}, /* 1Gbit */
|
||||
{0xfU, 0x1ffU}, /* 100Mbit */
|
||||
};
|
||||
|
||||
static unsigned int hw_atl_b0_timers_table_rx_[][2] = {
|
||||
|
@ -836,34 +842,36 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self,
|
|||
hw_atl_utils_mbps_2_speed_index(
|
||||
self->aq_link_status.mbps);
|
||||
|
||||
PHAL_ATLANTIC_B0->itr_tx |=
|
||||
hw_atl_b0_timers_table_tx_[speed_index]
|
||||
[0] << 0x8U; /* set min timer value */
|
||||
PHAL_ATLANTIC_B0->itr_tx |=
|
||||
hw_atl_b0_timers_table_tx_[speed_index]
|
||||
[1] << 0x10U; /* set max timer value */
|
||||
/* Update user visible ITR settings */
|
||||
self->aq_nic_cfg->tx_itr = hw_atl_b0_timers_table_tx_
|
||||
[speed_index][1] * 2;
|
||||
self->aq_nic_cfg->rx_itr = hw_atl_b0_timers_table_rx_
|
||||
[speed_index][1] * 2;
|
||||
|
||||
PHAL_ATLANTIC_B0->itr_rx |=
|
||||
hw_atl_b0_timers_table_rx_[speed_index]
|
||||
[0] << 0x8U; /* set min timer value */
|
||||
PHAL_ATLANTIC_B0->itr_rx |=
|
||||
hw_atl_b0_timers_table_rx_[speed_index]
|
||||
[1] << 0x10U; /* set max timer value */
|
||||
itr_tx |= hw_atl_b0_timers_table_tx_
|
||||
[speed_index][0] << 0x8U;
|
||||
itr_tx |= hw_atl_b0_timers_table_tx_
|
||||
[speed_index][1] << 0x10U;
|
||||
|
||||
itr_rx |= hw_atl_b0_timers_table_rx_
|
||||
[speed_index][0] << 0x8U;
|
||||
itr_rx |= hw_atl_b0_timers_table_rx_
|
||||
[speed_index][1] << 0x10U;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
case AQ_CFG_INTERRUPT_MODERATION_OFF:
|
||||
tdm_tx_desc_wr_wb_irq_en_set(self, 1U);
|
||||
tdm_tdm_intr_moder_en_set(self, 0U);
|
||||
rdm_rx_desc_wr_wb_irq_en_set(self, 1U);
|
||||
rdm_rdm_intr_moder_en_set(self, 0U);
|
||||
PHAL_ATLANTIC_B0->itr_tx = 0U;
|
||||
PHAL_ATLANTIC_B0->itr_rx = 0U;
|
||||
itr_tx = 0U;
|
||||
itr_rx = 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = HW_ATL_B0_RINGS_MAX; i--;) {
|
||||
reg_tx_intr_moder_ctrl_set(self,
|
||||
PHAL_ATLANTIC_B0->itr_tx, i);
|
||||
reg_rx_intr_moder_ctrl_set(self,
|
||||
PHAL_ATLANTIC_B0->itr_rx, i);
|
||||
reg_tx_intr_moder_ctrl_set(self, itr_tx, i);
|
||||
reg_rx_intr_moder_ctrl_set(self, itr_rx, i);
|
||||
}
|
||||
|
||||
return aq_hw_err_from_flags(self);
|
||||
|
@ -939,6 +947,7 @@ static struct aq_hw_ops hw_atl_ops_ = {
|
|||
.hw_rss_set = hw_atl_b0_hw_rss_set,
|
||||
.hw_rss_hash_set = hw_atl_b0_hw_rss_hash_set,
|
||||
.hw_get_regs = hw_atl_utils_hw_get_regs,
|
||||
.hw_update_stats = hw_atl_utils_update_stats,
|
||||
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
|
||||
.hw_get_fw_version = hw_atl_utils_get_fw_version,
|
||||
};
|
||||
|
|
|
@ -139,6 +139,9 @@
|
|||
|
||||
#define HW_ATL_B0_FW_VER_EXPECTED 0x01050006U
|
||||
|
||||
#define HW_ATL_INTR_MODER_MAX 0x1FF
|
||||
#define HW_ATL_INTR_MODER_MIN 0xFF
|
||||
|
||||
/* Hardware tx descriptor */
|
||||
struct __packed hw_atl_txd_s {
|
||||
u64 buf_addr;
|
||||
|
|
|
@ -255,6 +255,15 @@ err_exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
|
||||
struct hw_aq_atl_utils_mbox_header *pmbox)
|
||||
{
|
||||
return hw_atl_utils_fw_downld_dwords(self,
|
||||
PHAL_ATLANTIC->mbox_addr,
|
||||
(u32 *)(void *)pmbox,
|
||||
sizeof(*pmbox) / sizeof(u32));
|
||||
}
|
||||
|
||||
void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
|
||||
struct hw_aq_atl_utils_mbox *pmbox)
|
||||
{
|
||||
|
@ -267,9 +276,6 @@ void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
|
|||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
if (pmbox != &PHAL_ATLANTIC->mbox)
|
||||
memcpy(pmbox, &PHAL_ATLANTIC->mbox, sizeof(*pmbox));
|
||||
|
||||
if (IS_CHIP_FEATURE(REVISION_A0)) {
|
||||
unsigned int mtu = self->aq_nic_cfg ?
|
||||
self->aq_nic_cfg->mtu : 1514U;
|
||||
|
@ -299,17 +305,17 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
|
|||
{
|
||||
int err = 0;
|
||||
u32 transaction_id = 0;
|
||||
struct hw_aq_atl_utils_mbox_header mbox;
|
||||
|
||||
if (state == MPI_RESET) {
|
||||
hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox);
|
||||
hw_atl_utils_mpi_read_mbox(self, &mbox);
|
||||
|
||||
transaction_id = PHAL_ATLANTIC->mbox.transaction_id;
|
||||
transaction_id = mbox.transaction_id;
|
||||
|
||||
AQ_HW_WAIT_FOR(transaction_id !=
|
||||
(hw_atl_utils_mpi_read_stats
|
||||
(self, &PHAL_ATLANTIC->mbox),
|
||||
PHAL_ATLANTIC->mbox.transaction_id),
|
||||
1000U, 100U);
|
||||
(hw_atl_utils_mpi_read_mbox(self, &mbox),
|
||||
mbox.transaction_id),
|
||||
1000U, 100U);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
}
|
||||
|
@ -492,16 +498,51 @@ int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int hw_atl_utils_update_stats(struct aq_hw_s *self)
|
||||
{
|
||||
struct hw_atl_s *hw_self = PHAL_ATLANTIC;
|
||||
struct hw_aq_atl_utils_mbox mbox;
|
||||
|
||||
if (!self->aq_link_status.mbps)
|
||||
return 0;
|
||||
|
||||
hw_atl_utils_mpi_read_stats(self, &mbox);
|
||||
|
||||
#define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
|
||||
mbox.stats._N_ - hw_self->last_stats._N_)
|
||||
|
||||
AQ_SDELTA(uprc);
|
||||
AQ_SDELTA(mprc);
|
||||
AQ_SDELTA(bprc);
|
||||
AQ_SDELTA(erpt);
|
||||
|
||||
AQ_SDELTA(uptc);
|
||||
AQ_SDELTA(mptc);
|
||||
AQ_SDELTA(bptc);
|
||||
AQ_SDELTA(erpr);
|
||||
|
||||
AQ_SDELTA(ubrc);
|
||||
AQ_SDELTA(ubtc);
|
||||
AQ_SDELTA(mbrc);
|
||||
AQ_SDELTA(mbtc);
|
||||
AQ_SDELTA(bbrc);
|
||||
AQ_SDELTA(bbtc);
|
||||
AQ_SDELTA(dpc);
|
||||
|
||||
#undef AQ_SDELTA
|
||||
|
||||
memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
|
||||
u64 *data, unsigned int *p_count)
|
||||
{
|
||||
struct hw_atl_stats_s *stats = NULL;
|
||||
struct hw_atl_s *hw_self = PHAL_ATLANTIC;
|
||||
struct hw_atl_stats_s *stats = &hw_self->curr_stats;
|
||||
int i = 0;
|
||||
|
||||
hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox);
|
||||
|
||||
stats = &PHAL_ATLANTIC->mbox.stats;
|
||||
|
||||
data[i] = stats->uprc + stats->mprc + stats->bprc;
|
||||
data[++i] = stats->uprc;
|
||||
data[++i] = stats->mprc;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue