Merge 5.15.81 into android14-5.15

Changes in 5.15.81
	ASoC: fsl_sai: use local device pointer
	ASoC: fsl_asrc fsl_esai fsl_sai: allow CONFIG_PM=N
	serial: Add rs485_supported to uart_port
	serial: fsl_lpuart: Fill in rs485_supported
	tty: serial: fsl_lpuart: don't break the on-going transfer when global reset
	sctp: remove the unnecessary sinfo_stream check in sctp_prsctp_prune_unsent
	sctp: clear out_curr if all frag chunks of current msg are pruned
	cifs: introduce new helper for cifs_reconnect()
	cifs: split out dfs code from cifs_reconnect()
	cifs: support nested dfs links over reconnect
	cifs: Fix connections leak when tlink setup failed
	ata: libata-scsi: simplify __ata_scsi_queuecmd()
	ata: libata-core: do not issue non-internal commands once EH is pending
	drm/display: Don't assume dual mode adaptors support i2c sub-addressing
	nvme: add a bogus subsystem NQN quirk for Micron MTFDKBA2T0TFH
	nvme-pci: add NVME_QUIRK_BOGUS_NID for Micron Nitro
	nvme-pci: disable namespace identifiers for the MAXIO MAP1001
	nvme-pci: disable write zeroes on various Kingston SSD
	nvme-pci: add NVME_QUIRK_BOGUS_NID for Netac NV7000
	iio: ms5611: Simplify IO callback parameters
	iio: pressure: ms5611: fixed value compensation bug
	ceph: do not update snapshot context when there is no new snapshot
	ceph: avoid putting the realm twice when decoding snaps fails
	x86/sgx: Create utility to validate user provided offset and length
	x86/sgx: Add overflow check in sgx_validate_offset_length()
	binder: validate alloc->mm in ->mmap() handler
	ceph: Use kcalloc for allocating multiple elements
	ceph: fix NULL pointer dereference for req->r_session
	wifi: mac80211: fix memory free error when registering wiphy fail
	wifi: mac80211_hwsim: fix debugfs attribute ps with rc table support
	riscv: dts: sifive unleashed: Add PWM controlled LEDs
	audit: fix undefined behavior in bit shift for AUDIT_BIT
	wifi: airo: do not assign -1 to unsigned char
	wifi: mac80211: Fix ack frame idr leak when mesh has no route
	wifi: ath11k: Fix QCN9074 firmware boot on x86
	spi: stm32: fix stm32_spi_prepare_mbr() that halves spi clk for every run
	selftests/bpf: Add verifier test for release_reference()
	Revert "net: macsec: report real_dev features when HW offloading is enabled"
	platform/x86: ideapad-laptop: Disable touchpad_switch
	platform/x86: touchscreen_dmi: Add info for the RCA Cambio W101 v2 2-in-1
	platform/x86/intel/pmt: Sapphire Rapids PMT errata fix
	platform/x86/intel/hid: Add some ACPI device IDs
	scsi: ibmvfc: Avoid path failures during live migration
	scsi: scsi_debug: Make the READ CAPACITY response compliant with ZBC
	drm: panel-orientation-quirks: Add quirk for Acer Switch V 10 (SW5-017)
	block, bfq: fix null pointer dereference in bfq_bio_bfqg()
	arm64/syscall: Include asm/ptrace.h in syscall_wrapper header.
	nvmet: fix memory leak in nvmet_subsys_attr_model_store_locked
	Revert "drm/amdgpu: Revert "drm/amdgpu: getting fan speed pwm for vega10 properly""
	ALSA: usb-audio: add quirk to fix Hamedal C20 disconnect issue
	RISC-V: vdso: Do not add missing symbols to version section in linker script
	MIPS: pic32: treat port as signed integer
	xfrm: fix "disable_policy" on ipv4 early demux
	xfrm: replay: Fix ESN wrap around for GSO
	af_key: Fix send_acquire race with pfkey_register
	ARM: dts: am335x-pcm-953: Define fixed regulators in root node
	ASoC: hdac_hda: fix hda pcm buffer overflow issue
	ASoC: sgtl5000: Reset the CHIP_CLK_CTRL reg on remove
	ASoC: soc-pcm: Don't zero TDM masks in __soc_pcm_open()
	x86/hyperv: Restore VP assist page after cpu offlining/onlining
	scsi: storvsc: Fix handling of srb_status and capacity change events
	ASoC: max98373: Add checks for devm_kcalloc
	regulator: core: fix kobject release warning and memory leak in regulator_register()
	spi: dw-dma: decrease reference count in dw_spi_dma_init_mfld()
	regulator: core: fix UAF in destroy_regulator()
	bus: sunxi-rsb: Remove the shutdown callback
	bus: sunxi-rsb: Support atomic transfers
	tee: optee: fix possible memory leak in optee_register_device()
	ARM: dts: at91: sam9g20ek: enable udc vbus gpio pinctrl
	selftests: mptcp: more stable simult_flows tests
	selftests: mptcp: fix mibit vs mbit mix up
	net: liquidio: simplify if expression
	rxrpc: Allow list of in-use local UDP endpoints to be viewed in /proc
	rxrpc: Use refcount_t rather than atomic_t
	rxrpc: Fix race between conn bundle lookup and bundle removal [ZDI-CAN-15975]
	net: dsa: sja1105: disallow C45 transactions on the BASE-TX MDIO bus
	nfc/nci: fix race with opening and closing
	net: pch_gbe: fix potential memleak in pch_gbe_tx_queue()
	9p/fd: fix issue of list_del corruption in p9_fd_cancel()
	netfilter: conntrack: Fix data-races around ct mark
	netfilter: nf_tables: do not set up extensions for end interval
	iavf: Fix a crash during reset task
	iavf: Do not restart Tx queues after reset task failure
	iavf: Fix race condition between iavf_shutdown and iavf_remove
	ARM: mxs: fix memory leak in mxs_machine_init()
	ARM: dts: imx6q-prti6q: Fix ref/tcxo-clock-frequency properties
	net: ethernet: mtk_eth_soc: fix error handling in mtk_open()
	net/mlx4: Check retval of mlx4_bitmap_init
	net: mvpp2: fix possible invalid pointer dereference
	net/qla3xxx: fix potential memleak in ql3xxx_send()
	octeontx2-af: debugsfs: fix pci device refcount leak
	net: pch_gbe: fix pci device refcount leak while module exiting
	nfp: fill splittable of devlink_port_attrs correctly
	nfp: add port from netdev validation for EEPROM access
	macsec: Fix invalid error code set
	Drivers: hv: vmbus: fix double free in the error path of vmbus_add_channel_work()
	Drivers: hv: vmbus: fix possible memory leak in vmbus_device_register()
	netfilter: ipset: regression in ip_set_hash_ip.c
	net/mlx5: Do not query pci info while pci disabled
	net/mlx5: Fix FW tracer timestamp calculation
	net/mlx5: Fix handling of entry refcount when command is not issued to FW
	tipc: set con sock in tipc_conn_alloc
	tipc: add an extra conn_get in tipc_conn_alloc
	tipc: check skb_linearize() return value in tipc_disc_rcv()
	xfrm: Fix oops in __xfrm_state_delete()
	xfrm: Fix ignored return value in xfrm6_init()
	net: wwan: iosm: use ACPI_FREE() but not kfree() in ipc_pcie_read_bios_cfg()
	sfc: fix potential memleak in __ef100_hard_start_xmit()
	net: sparx5: fix error handling in sparx5_port_open()
	net: sched: allow act_ct to be built without NF_NAT
	NFC: nci: fix memory leak in nci_rx_data_packet()
	regulator: twl6030: re-add TWL6032_SUBCLASS
	bnx2x: fix pci device refcount leak in bnx2x_vf_is_pcie_pending()
	dma-buf: fix racing conflict of dma_heap_add()
	netfilter: ipset: restore allowing 64 clashing elements in hash:net,iface
	netfilter: flowtable_offload: add missing locking
	fs: do not update freeing inode i_io_list
	dccp/tcp: Reset saddr on failure after inet6?_hash_connect().
	ipv4: Fix error return code in fib_table_insert()
	arcnet: fix potential memory leak in com20020_probe()
	s390/dasd: fix no record found for raw_track_access
	nfc: st-nci: fix incorrect validating logic in EVT_TRANSACTION
	nfc: st-nci: fix memory leaks in EVT_TRANSACTION
	nfc: st-nci: fix incorrect sizing calculations in EVT_TRANSACTION
	net: enetc: manage ENETC_F_QBV in priv->active_offloads only when enabled
	net: enetc: cache accesses to &priv->si->hw
	net: enetc: preserve TX ring priority across reconfiguration
	octeontx2-pf: Add check for devm_kcalloc
	octeontx2-af: Fix reference count issue in rvu_sdp_init()
	net: thunderx: Fix the ACPI memory leak
	s390/crashdump: fix TOD programmable field size
	lib/vdso: use "grep -E" instead of "egrep"
	init/Kconfig: fix CC_HAS_ASM_GOTO_TIED_OUTPUT test with dash
	nios2: add FORCE for vmlinuz.gz
	mmc: sdhci-brcmstb: Re-organize flags
	mmc: sdhci-brcmstb: Enable Clock Gating to save power
	mmc: sdhci-brcmstb: Fix SDHCI_RESET_ALL for CQHCI
	KVM: arm64: pkvm: Fixup boot mode to reflect that the kernel resumes from EL1
	usb: dwc3: exynos: Fix remove() function
	usb: cdnsp: Fix issue with Clear Feature Halt Endpoint
	usb: cdnsp: fix issue with ZLP - added TD_SIZE = 1
	ext4: fix use-after-free in ext4_ext_shift_extents
	arm64: dts: rockchip: lower rk3399-puma-haikou SD controller clock frequency
	iio: light: apds9960: fix wrong register for gesture gain
	iio: core: Fix entry not deleted when iio_register_sw_trigger_type() fails
	bus: ixp4xx: Don't touch bit 7 on IXP42x
	usb: dwc3: gadget: conditionally remove requests
	usb: dwc3: gadget: Return -ESHUTDOWN on ep disable
	usb: dwc3: gadget: Clear ep descriptor last
	nilfs2: fix nilfs_sufile_mark_dirty() not set segment usage as dirty
	gcov: clang: fix the buffer overflow issue
	mm: vmscan: fix extreme overreclaim and swap floods
	KVM: x86: nSVM: leave nested mode on vCPU free
	KVM: x86: forcibly leave nested mode on vCPU reset
	KVM: x86: nSVM: harden svm_free_nested against freeing vmcb02 while still in use
	KVM: x86: add kvm_leave_nested
	KVM: x86: remove exit_int_info warning in svm_handle_exit
	x86/tsx: Add a feature bit for TSX control MSR support
	x86/pm: Add enumeration check before spec MSRs save/restore setup
	x86/ioremap: Fix page aligned size calculation in __ioremap_caller()
	Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode
	ASoC: Intel: bytcht_es8316: Add quirk for the Nanote UMPC-01
	tools: iio: iio_generic_buffer: Fix read size
	serial: 8250: 8250_omap: Avoid RS485 RTS glitch on ->set_termios()
	Input: goodix - try resetting the controller when no config is set
	Input: soc_button_array - add use_low_level_irq module parameter
	Input: soc_button_array - add Acer Switch V 10 to dmi_use_low_level_irq[]
	Input: i8042 - apply probe defer to more ASUS ZenBook models
	ASoC: stm32: dfsdm: manage cb buffers cleanup
	xen-pciback: Allow setting PCI_MSIX_FLAGS_MASKALL too
	xen/platform-pci: add missing free_irq() in error path
	platform/x86: asus-wmi: add missing pci_dev_put() in asus_wmi_set_xusb2pr()
	platform/x86: acer-wmi: Enable SW_TABLET_MODE on Switch V 10 (SW5-017)
	drm/amdgpu: disable BACO support on more cards
	zonefs: fix zone report size in __zonefs_io_error()
	platform/x86: hp-wmi: Ignore Smart Experience App event
	platform/x86: ideapad-laptop: Fix interrupt storm on fn-lock toggle on some Yoga laptops
	tcp: configurable source port perturb table size
	net: usb: qmi_wwan: add Telit 0x103a composition
	scsi: iscsi: Fix possible memory leak when device_register() failed
	gpu: host1x: Avoid trying to use GART on Tegra20
	dm integrity: flush the journal on suspend
	dm integrity: clear the journal on suspend
	fuse: lock inode unconditionally in fuse_fallocate()
	wifi: wilc1000: validate pairwise and authentication suite offsets
	wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_OPER_CHANNEL attribute
	wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST attribute
	wifi: wilc1000: validate number of channels
	genirq/msi: Shutdown managed interrupts with unsatifiable affinities
	genirq: Always limit the affinity to online CPUs
	irqchip/gic-v3: Always trust the managed affinity provided by the core code
	genirq: Take the proposed affinity at face value if force==true
	btrfs: free btrfs_path before copying root refs to userspace
	btrfs: free btrfs_path before copying fspath to userspace
	btrfs: free btrfs_path before copying subvol info to userspace
	btrfs: zoned: fix missing endianness conversion in sb_write_pointer
	btrfs: use kvcalloc in btrfs_get_dev_zone_info
	btrfs: sysfs: normalize the error handling branch in btrfs_init_sysfs()
	drm/amd/dc/dce120: Fix audio register mapping, stop triggering KASAN
	drm/amd/display: No display after resume from WB/CB
	drm/amdgpu: Enable Aldebaran devices to report CU Occupancy
	drm/amdgpu: always register an MMU notifier for userptr
	drm/i915: fix TLB invalidation for Gen12 video and compute engines
	cifs: fix missed refcounting of ipc tcon
	Linux 5.15.81

Change-Id: I9fe677a5bc83d3484f86aebbe20dd129c7ca3a42
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2022-12-04 12:02:10 +00:00
214 changed files with 2715 additions and 1829 deletions

View File

@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 15 PATCHLEVEL = 15
SUBLEVEL = 80 SUBLEVEL = 81
EXTRAVERSION = EXTRAVERSION =
NAME = Trick or Treat NAME = Trick or Treat

View File

@@ -12,22 +12,20 @@
compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx"; compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx";
/* Power */ /* Power */
regulators { vcc3v3: fixedregulator1 {
vcc3v3: fixedregulator@1 { compatible = "regulator-fixed";
compatible = "regulator-fixed"; regulator-name = "vcc3v3";
regulator-name = "vcc3v3"; regulator-min-microvolt = <3300000>;
regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>;
regulator-max-microvolt = <3300000>; regulator-boot-on;
regulator-boot-on; };
};
vcc1v8: fixedregulator@2 { vcc1v8: fixedregulator2 {
compatible = "regulator-fixed"; compatible = "regulator-fixed";
regulator-name = "vcc1v8"; regulator-name = "vcc1v8";
regulator-min-microvolt = <1800000>; regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>; regulator-max-microvolt = <1800000>;
regulator-boot-on; regulator-boot-on;
};
}; };
/* User IO */ /* User IO */

View File

@@ -39,6 +39,13 @@
}; };
usb1 {
pinctrl_usb1_vbus_gpio: usb1_vbus_gpio {
atmel,pins =
<AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PC5 GPIO */
};
};
mmc0_slot1 { mmc0_slot1 {
pinctrl_board_mmc0_slot1: mmc0_slot1-board { pinctrl_board_mmc0_slot1: mmc0_slot1-board {
atmel,pins = atmel,pins =
@@ -84,6 +91,8 @@
}; };
usb1: gadget@fffa4000 { usb1: gadget@fffa4000 {
pinctrl-0 = <&pinctrl_usb1_vbus_gpio>;
pinctrl-names = "default";
atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
status = "okay"; status = "okay";
}; };

View File

@@ -364,8 +364,8 @@
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&pinctrl_wifi>; pinctrl-0 = <&pinctrl_wifi>;
interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>; interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>;
ref-clock-frequency = "38400000"; ref-clock-frequency = <38400000>;
tcxo-clock-frequency = "19200000"; tcxo-clock-frequency = <19200000>;
}; };
}; };

View File

@@ -393,8 +393,10 @@ static void __init mxs_machine_init(void)
root = of_find_node_by_path("/"); root = of_find_node_by_path("/");
ret = of_property_read_string(root, "model", &soc_dev_attr->machine); ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
if (ret) if (ret) {
kfree(soc_dev_attr);
return; return;
}
soc_dev_attr->family = "Freescale MXS Family"; soc_dev_attr->family = "Freescale MXS Family";
soc_dev_attr->soc_id = mxs_get_soc_id(); soc_dev_attr->soc_id = mxs_get_soc_id();

View File

@@ -207,7 +207,7 @@
cap-sd-highspeed; cap-sd-highspeed;
cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
disable-wp; disable-wp;
max-frequency = <150000000>; max-frequency = <40000000>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
vmmc-supply = <&vcc3v3_baseboard>; vmmc-supply = <&vcc3v3_baseboard>;

View File

@@ -8,7 +8,7 @@
#ifndef __ASM_SYSCALL_WRAPPER_H #ifndef __ASM_SYSCALL_WRAPPER_H
#define __ASM_SYSCALL_WRAPPER_H #define __ASM_SYSCALL_WRAPPER_H
struct pt_regs; #include <asm/ptrace.h>
#define SC_ARM64_REGS_TO_ARGS(x, ...) \ #define SC_ARM64_REGS_TO_ARGS(x, ...) \
__MAP(x,__SC_ARGS \ __MAP(x,__SC_ARGS \

View File

@@ -26,6 +26,6 @@ extern char *fw_getcmdline(void);
extern void fw_meminit(void); extern void fw_meminit(void);
extern char *fw_getenv(char *name); extern char *fw_getenv(char *name);
extern unsigned long fw_getenvl(char *name); extern unsigned long fw_getenvl(char *name);
extern void fw_init_early_console(char port); extern void fw_init_early_console(void);
#endif /* __ASM_FW_H_ */ #endif /* __ASM_FW_H_ */

View File

@@ -27,7 +27,7 @@
#define U_BRG(x) (UART_BASE(x) + 0x40) #define U_BRG(x) (UART_BASE(x) + 0x40)
static void __iomem *uart_base; static void __iomem *uart_base;
static char console_port = -1; static int console_port = -1;
static int __init configure_uart_pins(int port) static int __init configure_uart_pins(int port)
{ {
@@ -47,7 +47,7 @@ static int __init configure_uart_pins(int port)
return 0; return 0;
} }
static void __init configure_uart(char port, int baud) static void __init configure_uart(int port, int baud)
{ {
u32 pbclk; u32 pbclk;
@@ -60,7 +60,7 @@ static void __init configure_uart(char port, int baud)
uart_base + PIC32_SET(U_STA(port))); uart_base + PIC32_SET(U_STA(port)));
} }
static void __init setup_early_console(char port, int baud) static void __init setup_early_console(int port, int baud)
{ {
if (configure_uart_pins(port)) if (configure_uart_pins(port))
return; return;
@@ -130,16 +130,15 @@ _out:
return baud; return baud;
} }
void __init fw_init_early_console(char port) void __init fw_init_early_console(void)
{ {
char *arch_cmdline = pic32_getcmdline(); char *arch_cmdline = pic32_getcmdline();
int baud = -1; int baud, port;
uart_base = ioremap(PIC32_BASE_UART, 0xc00); uart_base = ioremap(PIC32_BASE_UART, 0xc00);
baud = get_baud_from_cmdline(arch_cmdline); baud = get_baud_from_cmdline(arch_cmdline);
if (port == -1) port = get_port_from_cmdline(arch_cmdline);
port = get_port_from_cmdline(arch_cmdline);
if (port == -1) if (port == -1)
port = EARLY_CONSOLE_PORT; port = EARLY_CONSOLE_PORT;

View File

@@ -47,7 +47,7 @@ void __init plat_mem_setup(void)
strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
#ifdef CONFIG_EARLY_PRINTK #ifdef CONFIG_EARLY_PRINTK
fw_init_early_console(-1); fw_init_early_console();
#endif #endif
pic32_config_init(); pic32_config_init();
} }

View File

@@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE
$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip) $(call if_changed,gzip)
$(obj)/vmImage: $(obj)/vmlinux.gz $(obj)/vmImage: $(obj)/vmlinux.gz FORCE
$(call if_changed,uimage) $(call if_changed,uimage)
@$(kecho) 'Kernel: $@ is ready' @$(kecho) 'Kernel: $@ is ready'

View File

@@ -3,6 +3,8 @@
#include "fu540-c000.dtsi" #include "fu540-c000.dtsi"
#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/leds/common.h>
#include <dt-bindings/pwm/pwm.h>
/* Clock frequency (in Hz) of the PCB crystal for rtcclk */ /* Clock frequency (in Hz) of the PCB crystal for rtcclk */
#define RTCCLK_FREQ 1000000 #define RTCCLK_FREQ 1000000
@@ -46,6 +48,42 @@
compatible = "gpio-restart"; compatible = "gpio-restart";
gpios = <&gpio 10 GPIO_ACTIVE_LOW>; gpios = <&gpio 10 GPIO_ACTIVE_LOW>;
}; };
led-controller {
compatible = "pwm-leds";
led-d1 {
pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>;
active-low;
color = <LED_COLOR_ID_GREEN>;
max-brightness = <255>;
label = "d1";
};
led-d2 {
pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>;
active-low;
color = <LED_COLOR_ID_GREEN>;
max-brightness = <255>;
label = "d2";
};
led-d3 {
pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>;
active-low;
color = <LED_COLOR_ID_GREEN>;
max-brightness = <255>;
label = "d3";
};
led-d4 {
pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>;
active-low;
color = <LED_COLOR_ID_GREEN>;
max-brightness = <255>;
label = "d4";
};
};
}; };
&uart0 { &uart0 {

View File

@@ -28,6 +28,9 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
obj-y += vdso.o obj-y += vdso.o
CPPFLAGS_vdso.lds += -P -C -U$(ARCH) CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
ifneq ($(filter vgettimeofday, $(vdso-syms)),)
CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
endif
# Disable -pg to prevent insert call site # Disable -pg to prevent insert call site
CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)

View File

@@ -65,9 +65,11 @@ VERSION
LINUX_4.15 { LINUX_4.15 {
global: global:
__vdso_rt_sigreturn; __vdso_rt_sigreturn;
#ifdef HAS_VGETTIMEOFDAY
__vdso_gettimeofday; __vdso_gettimeofday;
__vdso_clock_gettime; __vdso_clock_gettime;
__vdso_clock_getres; __vdso_clock_getres;
#endif
__vdso_getcpu; __vdso_getcpu;
__vdso_flush_icache; __vdso_flush_icache;
local: *; local: *;

View File

@@ -44,7 +44,7 @@ struct save_area {
u64 fprs[16]; u64 fprs[16];
u32 fpc; u32 fpc;
u32 prefix; u32 prefix;
u64 todpreg; u32 todpreg;
u64 timer; u64 timer;
u64 todcmp; u64 todcmp;
u64 vxrs_low[16]; u64 vxrs_low[16];

View File

@@ -45,7 +45,7 @@ EXPORT_SYMBOL_GPL(hv_vp_assist_page);
static int hv_cpu_init(unsigned int cpu) static int hv_cpu_init(unsigned int cpu)
{ {
union hv_vp_assist_msr_contents msr = { 0 }; union hv_vp_assist_msr_contents msr = { 0 };
struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()]; struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu];
int ret; int ret;
ret = hv_common_cpu_init(cpu); ret = hv_common_cpu_init(cpu);
@@ -55,34 +55,32 @@ static int hv_cpu_init(unsigned int cpu)
if (!hv_vp_assist_page) if (!hv_vp_assist_page)
return 0; return 0;
if (!*hvp) { if (hv_root_partition) {
if (hv_root_partition) { /*
/* * For root partition we get the hypervisor provided VP assist
* For root partition we get the hypervisor provided VP assist * page, instead of allocating a new page.
* page, instead of allocating a new page. */
*/ rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); *hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT,
*hvp = memremap(msr.pfn << PAGE_SIZE, MEMREMAP_WB);
HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT, } else {
PAGE_SIZE, MEMREMAP_WB); /*
} else { * The VP assist page is an "overlay" page (see Hyper-V TLFS's
/* * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed
* The VP assist page is an "overlay" page (see Hyper-V TLFS's * out to make sure we always write the EOI MSR in
* Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed * hv_apic_eoi_write() *after* the EOI optimization is disabled
* out to make sure we always write the EOI MSR in * in hv_cpu_die(), otherwise a CPU may not be stopped in the
* hv_apic_eoi_write() *after* the EOI optimization is disabled * case of CPU offlining and the VM will hang.
* in hv_cpu_die(), otherwise a CPU may not be stopped in the */
* case of CPU offlining and the VM will hang. if (!*hvp)
*/
*hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO); *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO);
if (*hvp) if (*hvp)
msr.pfn = vmalloc_to_pfn(*hvp); msr.pfn = vmalloc_to_pfn(*hvp);
}
WARN_ON(!(*hvp)); }
if (*hvp) { if (!WARN_ON(!(*hvp))) {
msr.enable = 1; msr.enable = 1;
wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64);
}
} }
return 0; return 0;

View File

@@ -303,6 +303,9 @@
#define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */
#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */ #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */
#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */
/* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
#define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
#define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */

View File

@@ -372,6 +372,29 @@ err_out_free:
return ret; return ret;
} }
/*
* Ensure user provided offset and length values are valid for
* an enclave.
*/
static int sgx_validate_offset_length(struct sgx_encl *encl,
unsigned long offset,
unsigned long length)
{
if (!IS_ALIGNED(offset, PAGE_SIZE))
return -EINVAL;
if (!length || !IS_ALIGNED(length, PAGE_SIZE))
return -EINVAL;
if (offset + length < offset)
return -EINVAL;
if (offset + length - PAGE_SIZE >= encl->size)
return -EINVAL;
return 0;
}
/** /**
* sgx_ioc_enclave_add_pages() - The handler for %SGX_IOC_ENCLAVE_ADD_PAGES * sgx_ioc_enclave_add_pages() - The handler for %SGX_IOC_ENCLAVE_ADD_PAGES
* @encl: an enclave pointer * @encl: an enclave pointer
@@ -425,14 +448,10 @@ static long sgx_ioc_enclave_add_pages(struct sgx_encl *encl, void __user *arg)
if (copy_from_user(&add_arg, arg, sizeof(add_arg))) if (copy_from_user(&add_arg, arg, sizeof(add_arg)))
return -EFAULT; return -EFAULT;
if (!IS_ALIGNED(add_arg.offset, PAGE_SIZE) || if (!IS_ALIGNED(add_arg.src, PAGE_SIZE))
!IS_ALIGNED(add_arg.src, PAGE_SIZE))
return -EINVAL; return -EINVAL;
if (!add_arg.length || add_arg.length & (PAGE_SIZE - 1)) if (sgx_validate_offset_length(encl, add_arg.offset, add_arg.length))
return -EINVAL;
if (add_arg.offset + add_arg.length - PAGE_SIZE >= encl->size)
return -EINVAL; return -EINVAL;
if (copy_from_user(&secinfo, (void __user *)add_arg.secinfo, if (copy_from_user(&secinfo, (void __user *)add_arg.secinfo,

View File

@@ -58,24 +58,6 @@ static void tsx_enable(void)
wrmsrl(MSR_IA32_TSX_CTRL, tsx); wrmsrl(MSR_IA32_TSX_CTRL, tsx);
} }
static bool tsx_ctrl_is_supported(void)
{
u64 ia32_cap = x86_read_arch_cap_msr();
/*
* TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this
* MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
*
* TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
* microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
* bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
* MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
* tsx= cmdline requests will do nothing on CPUs without
* MSR_IA32_TSX_CTRL support.
*/
return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
}
static enum tsx_ctrl_states x86_get_tsx_auto_mode(void) static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
{ {
if (boot_cpu_has_bug(X86_BUG_TAA)) if (boot_cpu_has_bug(X86_BUG_TAA))
@@ -135,7 +117,7 @@ static void tsx_clear_cpuid(void)
rdmsrl(MSR_TSX_FORCE_ABORT, msr); rdmsrl(MSR_TSX_FORCE_ABORT, msr);
msr |= MSR_TFA_TSX_CPUID_CLEAR; msr |= MSR_TFA_TSX_CPUID_CLEAR;
wrmsrl(MSR_TSX_FORCE_ABORT, msr); wrmsrl(MSR_TSX_FORCE_ABORT, msr);
} else if (tsx_ctrl_is_supported()) { } else if (cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL)) {
rdmsrl(MSR_IA32_TSX_CTRL, msr); rdmsrl(MSR_IA32_TSX_CTRL, msr);
msr |= TSX_CTRL_CPUID_CLEAR; msr |= TSX_CTRL_CPUID_CLEAR;
wrmsrl(MSR_IA32_TSX_CTRL, msr); wrmsrl(MSR_IA32_TSX_CTRL, msr);
@@ -158,7 +140,8 @@ static void tsx_dev_mode_disable(void)
u64 mcu_opt_ctrl; u64 mcu_opt_ctrl;
/* Check if RTM_ALLOW exists */ /* Check if RTM_ALLOW exists */
if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() || if (!boot_cpu_has_bug(X86_BUG_TAA) ||
!cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL) ||
!cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL)) !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL))
return; return;
@@ -191,7 +174,20 @@ void __init tsx_init(void)
return; return;
} }
if (!tsx_ctrl_is_supported()) { /*
* TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this
* MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES.
*
* TSX control (aka MSR_IA32_TSX_CTRL) is only available after a
* microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES
* bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get
* MSR_IA32_TSX_CTRL support even after a microcode update. Thus,
* tsx= cmdline requests will do nothing on CPUs without
* MSR_IA32_TSX_CTRL support.
*/
if (x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR) {
setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL);
} else {
tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED; tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED;
return; return;
} }

View File

@@ -919,6 +919,9 @@ void svm_free_nested(struct vcpu_svm *svm)
if (!svm->nested.initialized) if (!svm->nested.initialized)
return; return;
if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr))
svm_switch_vmcb(svm, &svm->vmcb01);
svm_vcpu_free_msrpm(svm->nested.msrpm); svm_vcpu_free_msrpm(svm->nested.msrpm);
svm->nested.msrpm = NULL; svm->nested.msrpm = NULL;
@@ -937,9 +940,6 @@ void svm_free_nested(struct vcpu_svm *svm)
svm->nested.initialized = false; svm->nested.initialized = false;
} }
/*
* Forcibly leave nested mode in order to be able to reset the VCPU later on.
*/
void svm_leave_nested(struct kvm_vcpu *vcpu) void svm_leave_nested(struct kvm_vcpu *vcpu)
{ {
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);

View File

@@ -317,12 +317,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer)
return 0; return 0;
} }
static int is_external_interrupt(u32 info)
{
info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
}
static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu) static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu)
{ {
struct vcpu_svm *svm = to_svm(vcpu); struct vcpu_svm *svm = to_svm(vcpu);
@@ -1427,6 +1421,7 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
*/ */
svm_clear_current_vmcb(svm->vmcb); svm_clear_current_vmcb(svm->vmcb);
svm_leave_nested(vcpu);
svm_free_nested(svm); svm_free_nested(svm);
sev_free_vcpu(vcpu); sev_free_vcpu(vcpu);
@@ -3359,15 +3354,6 @@ static int handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
return 0; return 0;
} }
if (is_external_interrupt(svm->vmcb->control.exit_int_info) &&
exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR &&
exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH &&
exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI)
printk(KERN_ERR "%s: unexpected exit_int_info 0x%x "
"exit_code 0x%x\n",
__func__, svm->vmcb->control.exit_int_info,
exit_code);
if (exit_fastpath != EXIT_FASTPATH_NONE) if (exit_fastpath != EXIT_FASTPATH_NONE)
return 1; return 1;

View File

@@ -6276,9 +6276,6 @@ out:
return kvm_state.size; return kvm_state.size;
} }
/*
* Forcibly leave nested mode in order to be able to reset the VCPU later on.
*/
void vmx_leave_nested(struct kvm_vcpu *vcpu) void vmx_leave_nested(struct kvm_vcpu *vcpu)
{ {
if (is_guest_mode(vcpu)) { if (is_guest_mode(vcpu)) {

View File

@@ -608,6 +608,12 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu)
} }
EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload); EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload);
/* Forcibly leave the nested mode in cases like a vCPU reset */
static void kvm_leave_nested(struct kvm_vcpu *vcpu)
{
kvm_x86_ops.nested_ops->leave_nested(vcpu);
}
static void kvm_multiple_exception(struct kvm_vcpu *vcpu, static void kvm_multiple_exception(struct kvm_vcpu *vcpu,
unsigned nr, bool has_error, u32 error_code, unsigned nr, bool has_error, u32 error_code,
bool has_payload, unsigned long payload, bool reinject) bool has_payload, unsigned long payload, bool reinject)
@@ -4774,7 +4780,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
if (events->flags & KVM_VCPUEVENT_VALID_SMM) { if (events->flags & KVM_VCPUEVENT_VALID_SMM) {
if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) { if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) {
kvm_x86_ops.nested_ops->leave_nested(vcpu); kvm_leave_nested(vcpu);
kvm_smm_changed(vcpu, events->smi.smm); kvm_smm_changed(vcpu, events->smi.smm);
} }
@@ -11066,8 +11072,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
unsigned long new_cr0; unsigned long new_cr0;
u32 eax, dummy; u32 eax, dummy;
/*
* SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's
* possible to INIT the vCPU while L2 is active. Force the vCPU back
* into L1 as EFER.SVME is cleared on INIT (along with all other EFER
* bits), i.e. virtualization is disabled.
*/
if (is_guest_mode(vcpu))
kvm_leave_nested(vcpu);
kvm_lapic_reset(vcpu, init_event); kvm_lapic_reset(vcpu, init_event);
WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu));
vcpu->arch.hflags = 0; vcpu->arch.hflags = 0;
vcpu->arch.smi_pending = 0; vcpu->arch.smi_pending = 0;

View File

@@ -216,9 +216,15 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size,
* Mappings have to be page-aligned * Mappings have to be page-aligned
*/ */
offset = phys_addr & ~PAGE_MASK; offset = phys_addr & ~PAGE_MASK;
phys_addr &= PHYSICAL_PAGE_MASK; phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr+1) - phys_addr; size = PAGE_ALIGN(last_addr+1) - phys_addr;
/*
* Mask out any bits not part of the actual physical
* address, like memory encryption bits.
*/
phys_addr &= PHYSICAL_PAGE_MASK;
retval = memtype_reserve(phys_addr, (u64)phys_addr + size, retval = memtype_reserve(phys_addr, (u64)phys_addr + size,
pcm, &new_pcm); pcm, &new_pcm);
if (retval) { if (retval) {

View File

@@ -513,16 +513,23 @@ static int pm_cpu_check(const struct x86_cpu_id *c)
static void pm_save_spec_msr(void) static void pm_save_spec_msr(void)
{ {
u32 spec_msr_id[] = { struct msr_enumeration {
MSR_IA32_SPEC_CTRL, u32 msr_no;
MSR_IA32_TSX_CTRL, u32 feature;
MSR_TSX_FORCE_ABORT, } msr_enum[] = {
MSR_IA32_MCU_OPT_CTRL, { MSR_IA32_SPEC_CTRL, X86_FEATURE_MSR_SPEC_CTRL },
MSR_AMD64_LS_CFG, { MSR_IA32_TSX_CTRL, X86_FEATURE_MSR_TSX_CTRL },
MSR_AMD64_DE_CFG, { MSR_TSX_FORCE_ABORT, X86_FEATURE_TSX_FORCE_ABORT },
{ MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL },
{ MSR_AMD64_LS_CFG, X86_FEATURE_LS_CFG_SSBD },
{ MSR_AMD64_DE_CFG, X86_FEATURE_LFENCE_RDTSC },
}; };
int i;
msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id)); for (i = 0; i < ARRAY_SIZE(msr_enum); i++) {
if (boot_cpu_has(msr_enum[i].feature))
msr_build_context(&msr_enum[i].msr_no, 1);
}
} }
static int pm_check_save_msr(void) static int pm_check_save_msr(void)

View File

@@ -613,6 +613,10 @@ struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio)
struct bfq_group *bfqg; struct bfq_group *bfqg;
while (blkg) { while (blkg) {
if (!blkg->online) {
blkg = blkg->parent;
continue;
}
bfqg = blkg_to_bfqg(blkg); bfqg = blkg_to_bfqg(blkg);
if (bfqg->online) { if (bfqg->online) {
bio_associate_blkg_from_css(bio, &blkg->blkcg->css); bio_associate_blkg_from_css(bio, &blkg->blkcg->css);

View File

@@ -753,6 +753,12 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
const char *failure_string; const char *failure_string;
struct binder_buffer *buffer; struct binder_buffer *buffer;
if (unlikely(vma->vm_mm != alloc->vma_vm_mm)) {
ret = -EINVAL;
failure_string = "invalid vma->vm_mm";
goto err_invalid_mm;
}
mutex_lock(&binder_alloc_mmap_lock); mutex_lock(&binder_alloc_mmap_lock);
if (alloc->buffer_size) { if (alloc->buffer_size) {
ret = -EBUSY; ret = -EBUSY;
@@ -799,6 +805,7 @@ err_alloc_pages_failed:
alloc->buffer_size = 0; alloc->buffer_size = 0;
err_already_mapped: err_already_mapped:
mutex_unlock(&binder_alloc_mmap_lock); mutex_unlock(&binder_alloc_mmap_lock);
err_invalid_mm:
binder_alloc_debug(BINDER_DEBUG_USER_ERROR, binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
"%s: %d %lx-%lx %s failed %d\n", __func__, "%s: %d %lx-%lx %s failed %d\n", __func__,
alloc->pid, vma->vm_start, vma->vm_end, alloc->pid, vma->vm_start, vma->vm_end,

View File

@@ -3988,44 +3988,51 @@ void ata_scsi_dump_cdb(struct ata_port *ap, struct scsi_cmnd *cmd)
int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev)
{ {
struct ata_port *ap = dev->link->ap;
u8 scsi_op = scmd->cmnd[0]; u8 scsi_op = scmd->cmnd[0];
ata_xlat_func_t xlat_func; ata_xlat_func_t xlat_func;
int rc = 0;
/*
* scsi_queue_rq() will defer commands if scsi_host_in_recovery().
* However, this check is done without holding the ap->lock (a libata
* specific lock), so we can have received an error irq since then,
* therefore we must check if EH is pending, while holding ap->lock.
*/
if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS))
return SCSI_MLQUEUE_DEVICE_BUSY;
if (unlikely(!scmd->cmd_len))
goto bad_cdb_len;
if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) { if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) {
if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) if (unlikely(scmd->cmd_len > dev->cdb_len))
goto bad_cdb_len; goto bad_cdb_len;
xlat_func = ata_get_xlat_func(dev, scsi_op); xlat_func = ata_get_xlat_func(dev, scsi_op);
} else { } else if (likely((scsi_op != ATA_16) || !atapi_passthru16)) {
if (unlikely(!scmd->cmd_len)) /* relay SCSI command to ATAPI device */
int len = COMMAND_SIZE(scsi_op);
if (unlikely(len > scmd->cmd_len ||
len > dev->cdb_len ||
scmd->cmd_len > ATAPI_CDB_LEN))
goto bad_cdb_len; goto bad_cdb_len;
xlat_func = NULL; xlat_func = atapi_xlat;
if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { } else {
/* relay SCSI command to ATAPI device */ /* ATA_16 passthru, treat as an ATA command */
int len = COMMAND_SIZE(scsi_op); if (unlikely(scmd->cmd_len > 16))
if (unlikely(len > scmd->cmd_len || goto bad_cdb_len;
len > dev->cdb_len ||
scmd->cmd_len > ATAPI_CDB_LEN))
goto bad_cdb_len;
xlat_func = atapi_xlat; xlat_func = ata_get_xlat_func(dev, scsi_op);
} else {
/* ATA_16 passthru, treat as an ATA command */
if (unlikely(scmd->cmd_len > 16))
goto bad_cdb_len;
xlat_func = ata_get_xlat_func(dev, scsi_op);
}
} }
if (xlat_func) if (xlat_func)
rc = ata_scsi_translate(dev, scmd, xlat_func); return ata_scsi_translate(dev, scmd, xlat_func);
else
ata_scsi_simulate(dev, scmd);
return rc; ata_scsi_simulate(dev, scmd);
return 0;
bad_cdb_len: bad_cdb_len:
DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n", DPRINTK("bad CDB len=%u, scsi_op=0x%02x, max=%u\n",

View File

@@ -49,7 +49,7 @@
#define IXP4XX_EXP_SIZE_SHIFT 10 #define IXP4XX_EXP_SIZE_SHIFT 10
#define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */ #define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */
#define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */ #define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */
#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x */ #define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x, dangerous to touch on IXP42x */
#define IXP4XX_EXP_BYTE_RD16 BIT(6) #define IXP4XX_EXP_BYTE_RD16 BIT(6)
#define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */ #define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */
#define IXP4XX_EXP_MUX_EN BIT(4) #define IXP4XX_EXP_MUX_EN BIT(4)
@@ -57,8 +57,6 @@
#define IXP4XX_EXP_WORD BIT(2) /* Always zero */ #define IXP4XX_EXP_WORD BIT(2) /* Always zero */
#define IXP4XX_EXP_WR_EN BIT(1) #define IXP4XX_EXP_WR_EN BIT(1)
#define IXP4XX_EXP_BYTE_EN BIT(0) #define IXP4XX_EXP_BYTE_EN BIT(0)
#define IXP42X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD)
#define IXP43X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD)
#define IXP4XX_EXP_CNFG0 0x20 #define IXP4XX_EXP_CNFG0 0x20
#define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31) #define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31)
@@ -252,10 +250,9 @@ static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb,
cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT; cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT;
} }
if (eb->is_42x)
cs_cfg &= ~IXP42X_RESERVED;
if (eb->is_43x) { if (eb->is_43x) {
cs_cfg &= ~IXP43X_RESERVED; /* Should always be zero */
cs_cfg &= ~IXP4XX_EXP_WORD;
/* /*
* This bit for Intel strata flash is currently unused, but let's * This bit for Intel strata flash is currently unused, but let's
* report it if we find one. * report it if we find one.

View File

@@ -271,6 +271,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register);
/* common code that starts a transfer */ /* common code that starts a transfer */
static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
{ {
u32 int_mask, status;
bool timeout;
if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) {
dev_dbg(rsb->dev, "RSB transfer still in progress\n"); dev_dbg(rsb->dev, "RSB transfer still in progress\n");
return -EBUSY; return -EBUSY;
@@ -278,13 +281,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
reinit_completion(&rsb->complete); reinit_completion(&rsb->complete);
writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER;
rsb->regs + RSB_INTE); writel(int_mask, rsb->regs + RSB_INTE);
writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB,
rsb->regs + RSB_CTRL); rsb->regs + RSB_CTRL);
if (!wait_for_completion_io_timeout(&rsb->complete, if (irqs_disabled()) {
msecs_to_jiffies(100))) { timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS,
status, (status & int_mask),
10, 100000);
writel(status, rsb->regs + RSB_INTS);
} else {
timeout = !wait_for_completion_io_timeout(&rsb->complete,
msecs_to_jiffies(100));
status = rsb->status;
}
if (timeout) {
dev_dbg(rsb->dev, "RSB timeout\n"); dev_dbg(rsb->dev, "RSB timeout\n");
/* abort the transfer */ /* abort the transfer */
@@ -296,18 +309,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
if (rsb->status & RSB_INTS_LOAD_BSY) { if (status & RSB_INTS_LOAD_BSY) {
dev_dbg(rsb->dev, "RSB busy\n"); dev_dbg(rsb->dev, "RSB busy\n");
return -EBUSY; return -EBUSY;
} }
if (rsb->status & RSB_INTS_TRANS_ERR) { if (status & RSB_INTS_TRANS_ERR) {
if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { if (status & RSB_INTS_TRANS_ERR_ACK) {
dev_dbg(rsb->dev, "RSB slave nack\n"); dev_dbg(rsb->dev, "RSB slave nack\n");
return -EINVAL; return -EINVAL;
} }
if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { if (status & RSB_INTS_TRANS_ERR_DATA) {
dev_dbg(rsb->dev, "RSB transfer data error\n"); dev_dbg(rsb->dev, "RSB transfer data error\n");
return -EIO; return -EIO;
} }
@@ -816,14 +829,6 @@ static int sunxi_rsb_remove(struct platform_device *pdev)
return 0; return 0;
} }
static void sunxi_rsb_shutdown(struct platform_device *pdev)
{
struct sunxi_rsb *rsb = platform_get_drvdata(pdev);
pm_runtime_disable(&pdev->dev);
sunxi_rsb_hw_exit(rsb);
}
static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = { static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = {
SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend, SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend,
sunxi_rsb_runtime_resume, NULL) sunxi_rsb_runtime_resume, NULL)
@@ -839,7 +844,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table);
static struct platform_driver sunxi_rsb_driver = { static struct platform_driver sunxi_rsb_driver = {
.probe = sunxi_rsb_probe, .probe = sunxi_rsb_probe,
.remove = sunxi_rsb_remove, .remove = sunxi_rsb_remove,
.shutdown = sunxi_rsb_shutdown,
.driver = { .driver = {
.name = RSB_CTRL_NAME, .name = RSB_CTRL_NAME,
.of_match_table = sunxi_rsb_of_match_table, .of_match_table = sunxi_rsb_of_match_table,

View File

@@ -297,7 +297,7 @@ EXPORT_SYMBOL_GPL(dma_heap_get_name);
struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
{ {
struct dma_heap *heap, *err_ret; struct dma_heap *heap, *h, *err_ret;
unsigned int minor; unsigned int minor;
int ret; int ret;
@@ -311,15 +311,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
/* check the name is unique */
heap = dma_heap_find(exp_info->name);
if (heap) {
pr_err("dma_heap: Already registered heap named %s\n",
exp_info->name);
dma_heap_put(heap);
return ERR_PTR(-EINVAL);
}
heap = kzalloc(sizeof(*heap), GFP_KERNEL); heap = kzalloc(sizeof(*heap), GFP_KERNEL);
if (!heap) if (!heap)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
@@ -363,13 +354,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
/* Make sure it doesn't disappear on us */ /* Make sure it doesn't disappear on us */
heap->heap_dev = get_device(heap->heap_dev); heap->heap_dev = get_device(heap->heap_dev);
/* Add heap to the list */
mutex_lock(&heap_list_lock); mutex_lock(&heap_list_lock);
/* check the name is unique */
list_for_each_entry(h, &heap_list, list) {
if (!strcmp(h->name, exp_info->name)) {
mutex_unlock(&heap_list_lock);
pr_err("dma_heap: Already registered heap named %s\n",
exp_info->name);
err_ret = ERR_PTR(-EINVAL);
put_device(heap->heap_dev);
goto err3;
}
}
/* Add heap to the list */
list_add(&heap->list, &heap_list); list_add(&heap->list, &heap_list);
mutex_unlock(&heap_list_lock); mutex_unlock(&heap_list_lock);
return heap; return heap;
err3:
device_destroy(dma_heap_class, heap->heap_devt);
err2: err2:
cdev_del(&heap->heap_cdev); cdev_del(&heap->heap_cdev);
err1: err1:

View File

@@ -44,5 +44,6 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = {
.get_atc_vmid_pasid_mapping_info = .get_atc_vmid_pasid_mapping_info =
kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, kgd_gfx_v9_get_atc_vmid_pasid_mapping_info,
.set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base, .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base,
.get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy,
.program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings .program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings
}; };

View File

@@ -419,11 +419,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
if (r) if (r)
goto release_object; goto release_object;
if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { r = amdgpu_mn_register(bo, args->addr);
r = amdgpu_mn_register(bo, args->addr); if (r)
if (r) goto release_object;
goto release_object;
}
if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);

View File

@@ -1374,7 +1374,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
}, },
}, },
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
},
},
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
},
},
{} {}
/* TODO: refactor this from a fixed table to a dynamic option */
}; };
static void retrieve_dmi_info(struct amdgpu_display_manager *dm) static void retrieve_dmi_info(struct amdgpu_display_manager *dm)

View File

@@ -361,7 +361,8 @@ static const struct dce_audio_registers audio_regs[] = {
audio_regs(2), audio_regs(2),
audio_regs(3), audio_regs(3),
audio_regs(4), audio_regs(4),
audio_regs(5) audio_regs(5),
audio_regs(6),
}; };
#define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\

View File

@@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr,
int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr,
uint32_t *speed) uint32_t *speed)
{ {
uint32_t current_rpm; struct amdgpu_device *adev = hwmgr->adev;
uint32_t percent = 0; uint32_t duty100, duty;
uint64_t tmp64;
if (hwmgr->thermal_controller.fanInfo.bNoFan) duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1),
return 0; CG_FDO_CTRL1, FMAX_DUTY100);
duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS),
CG_THERMAL_STATUS, FDO_PWM_DUTY);
if (vega10_get_current_rpm(hwmgr, &current_rpm)) if (!duty100)
return -1; return -EINVAL;
if (hwmgr->thermal_controller. tmp64 = (uint64_t)duty * 255;
advanceFanControlParameters.usMaxFanRPM != 0) do_div(tmp64, duty100);
percent = current_rpm * 255 / *speed = MIN((uint32_t)tmp64, 255);
hwmgr->thermal_controller.
advanceFanControlParameters.usMaxFanRPM;
*speed = MIN(percent, 255);
return 0; return 0;
} }

View File

@@ -368,6 +368,10 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu)
((adev->pdev->device == 0x73BF) && ((adev->pdev->device == 0x73BF) &&
(adev->pdev->revision == 0xCF)) || (adev->pdev->revision == 0xCF)) ||
((adev->pdev->device == 0x7422) && ((adev->pdev->device == 0x7422) &&
(adev->pdev->revision == 0x00)) ||
((adev->pdev->device == 0x73A3) &&
(adev->pdev->revision == 0x00)) ||
((adev->pdev->device == 0x73E3) &&
(adev->pdev->revision == 0x00))) (adev->pdev->revision == 0x00)))
smu_baco->platform_support = false; smu_baco->platform_support = false;

View File

@@ -63,23 +63,45 @@
ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter, ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
u8 offset, void *buffer, size_t size) u8 offset, void *buffer, size_t size)
{ {
u8 zero = 0;
char *tmpbuf = NULL;
/*
* As sub-addressing is not supported by all adaptors,
* always explicitly read from the start and discard
* any bytes that come before the requested offset.
* This way, no matter whether the adaptor supports it
* or not, we'll end up reading the proper data.
*/
struct i2c_msg msgs[] = { struct i2c_msg msgs[] = {
{ {
.addr = DP_DUAL_MODE_SLAVE_ADDRESS, .addr = DP_DUAL_MODE_SLAVE_ADDRESS,
.flags = 0, .flags = 0,
.len = 1, .len = 1,
.buf = &offset, .buf = &zero,
}, },
{ {
.addr = DP_DUAL_MODE_SLAVE_ADDRESS, .addr = DP_DUAL_MODE_SLAVE_ADDRESS,
.flags = I2C_M_RD, .flags = I2C_M_RD,
.len = size, .len = size + offset,
.buf = buffer, .buf = buffer,
}, },
}; };
int ret; int ret;
if (offset) {
tmpbuf = kmalloc(size + offset, GFP_KERNEL);
if (!tmpbuf)
return -ENOMEM;
msgs[1].buf = tmpbuf;
}
ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
if (tmpbuf)
memcpy(buffer, tmpbuf + offset, size);
kfree(tmpbuf);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (ret != ARRAY_SIZE(msgs)) if (ret != ARRAY_SIZE(msgs))
@@ -208,18 +230,6 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev,
if (ret) if (ret)
return DRM_DP_DUAL_MODE_UNKNOWN; return DRM_DP_DUAL_MODE_UNKNOWN;
/*
* Sigh. Some (maybe all?) type 1 adaptors are broken and ack
* the offset but ignore it, and instead they just always return
* data from the start of the HDMI ID buffer. So for a broken
* type 1 HDMI adaptor a single byte read will always give us
* 0x44, and for a type 1 DVI adaptor it should give 0x00
* (assuming it implements any registers). Fortunately neither
* of those values will match the type 2 signature of the
* DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
* the type 2 adaptor detection safely even in the presence
* of broken type 1 adaptors.
*/
ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID, ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
&adaptor_id, sizeof(adaptor_id)); &adaptor_id, sizeof(adaptor_id));
drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret); drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret);
@@ -233,11 +243,10 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev,
return DRM_DP_DUAL_MODE_TYPE2_DVI; return DRM_DP_DUAL_MODE_TYPE2_DVI;
} }
/* /*
* If neither a proper type 1 ID nor a broken type 1 adaptor * If not a proper type 1 ID, still assume type 1, but let
* as described above, assume type 1, but let the user know * the user know that we may have misdetected the type.
* that we may have misdetected the type.
*/ */
if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0]) if (!is_type1_adaptor(adaptor_id))
drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id); drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id);
} }
@@ -343,10 +352,8 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
* @enable: enable (as opposed to disable) the TMDS output buffers * @enable: enable (as opposed to disable) the TMDS output buffers
* *
* Set the state of the TMDS output buffers in the adaptor. For * Set the state of the TMDS output buffers in the adaptor. For
* type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register.
* some type 1 adaptors have problems with registers (see comments * Type1 adaptors do not support any register writes.
* in drm_dp_dual_mode_detect()) we avoid touching the register,
* making this function a no-op on type 1 adaptors.
* *
* Returns: * Returns:
* 0 on success, negative error code on failure * 0 on success, negative error code on failure

View File

@@ -128,6 +128,12 @@ static const struct dmi_system_id orientation_data[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"),
}, },
.driver_data = (void *)&lcd800x1280_rightside_up, .driver_data = (void *)&lcd800x1280_rightside_up,
}, { /* Acer Switch V 10 (SW5-017) */
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
},
.driver_data = (void *)&lcd800x1280_rightside_up,
}, { /* Anbernic Win600 */ }, { /* Anbernic Win600 */
.matches = { .matches = {
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"), DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"),

View File

@@ -982,6 +982,10 @@ void intel_gt_invalidate_tlbs(struct intel_gt *gt)
if (!i915_mmio_reg_offset(rb.reg)) if (!i915_mmio_reg_offset(rb.reg))
continue; continue;
if (GRAPHICS_VER(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS ||
engine->class == VIDEO_ENHANCEMENT_CLASS))
rb.bit = _MASKED_BIT_ENABLE(rb.bit);
intel_uncore_write_fw(uncore, rb.reg, rb.bit); intel_uncore_write_fw(uncore, rb.reg, rb.bit);
} }

View File

@@ -1083,6 +1083,10 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev)
struct host1x *host1x = dev_get_drvdata(dev->dev.parent); struct host1x *host1x = dev_get_drvdata(dev->dev.parent);
struct iommu_domain *domain; struct iommu_domain *domain;
/* Our IOMMU usage policy doesn't currently play well with GART */
if (of_machine_is_compatible("nvidia,tegra20"))
return false;
/* /*
* If the Tegra DRM clients are backed by an IOMMU, push buffers are * If the Tegra DRM clients are backed by an IOMMU, push buffers are
* likely to be allocated beyond the 32-bit boundary if sufficient * likely to be allocated beyond the 32-bit boundary if sufficient

View File

@@ -204,6 +204,10 @@ static void host1x_setup_sid_table(struct host1x *host)
static bool host1x_wants_iommu(struct host1x *host1x) static bool host1x_wants_iommu(struct host1x *host1x)
{ {
/* Our IOMMU usage policy doesn't currently play well with GART */
if (of_machine_is_compatible("nvidia,tegra20"))
return false;
/* /*
* If we support addressing a maximum of 32 bits of physical memory * If we support addressing a maximum of 32 bits of physical memory
* and if the host1x firewall is enabled, there's no need to enable * and if the host1x firewall is enabled, there's no need to enable

View File

@@ -531,13 +531,17 @@ static void vmbus_add_channel_work(struct work_struct *work)
* Add the new device to the bus. This will kick off device-driver * Add the new device to the bus. This will kick off device-driver
* binding which eventually invokes the device driver's AddDevice() * binding which eventually invokes the device driver's AddDevice()
* method. * method.
*
* If vmbus_device_register() fails, the 'device_obj' is freed in
* vmbus_device_release() as called by device_unregister() in the
* error path of vmbus_device_register(). In the outside error
* path, there's no need to free it.
*/ */
ret = vmbus_device_register(newchannel->device_obj); ret = vmbus_device_register(newchannel->device_obj);
if (ret != 0) { if (ret != 0) {
pr_err("unable to add child device object (relid %d)\n", pr_err("unable to add child device object (relid %d)\n",
newchannel->offermsg.child_relid); newchannel->offermsg.child_relid);
kfree(newchannel->device_obj);
goto err_deq_chan; goto err_deq_chan;
} }

View File

@@ -2109,6 +2109,7 @@ int vmbus_device_register(struct hv_device *child_device_obj)
ret = device_register(&child_device_obj->device); ret = device_register(&child_device_obj->device);
if (ret) { if (ret) {
pr_err("Unable to register child device\n"); pr_err("Unable to register child device\n");
put_device(&child_device_obj->device);
return ret; return ret;
} }

View File

@@ -58,8 +58,12 @@ int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t)
t->group = configfs_register_default_group(iio_triggers_group, t->name, t->group = configfs_register_default_group(iio_triggers_group, t->name,
&iio_trigger_type_group_type); &iio_trigger_type_group_type);
if (IS_ERR(t->group)) if (IS_ERR(t->group)) {
mutex_lock(&iio_trigger_types_lock);
list_del(&t->list);
mutex_unlock(&iio_trigger_types_lock);
ret = PTR_ERR(t->group); ret = PTR_ERR(t->group);
}
return ret; return ret;
} }

View File

@@ -54,9 +54,6 @@
#define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2 #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2
#define APDS9960_REG_CONFIG_2 0x90 #define APDS9960_REG_CONFIG_2 0x90
#define APDS9960_REG_CONFIG_2_GGAIN_MASK 0x60
#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT 5
#define APDS9960_REG_ID 0x92 #define APDS9960_REG_ID 0x92
#define APDS9960_REG_STATUS 0x93 #define APDS9960_REG_STATUS 0x93
@@ -77,6 +74,9 @@
#define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6 #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6
#define APDS9960_REG_GCONF_2 0xa3 #define APDS9960_REG_GCONF_2 0xa3
#define APDS9960_REG_GCONF_2_GGAIN_MASK 0x60
#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT 5
#define APDS9960_REG_GOFFSET_U 0xa4 #define APDS9960_REG_GOFFSET_U 0xa4
#define APDS9960_REG_GOFFSET_D 0xa5 #define APDS9960_REG_GOFFSET_D 0xa5
#define APDS9960_REG_GPULSE 0xa6 #define APDS9960_REG_GPULSE 0xa6
@@ -396,9 +396,9 @@ static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
} }
ret = regmap_update_bits(data->regmap, ret = regmap_update_bits(data->regmap,
APDS9960_REG_CONFIG_2, APDS9960_REG_GCONF_2,
APDS9960_REG_CONFIG_2_GGAIN_MASK, APDS9960_REG_GCONF_2_GGAIN_MASK,
idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT); idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT);
if (!ret) if (!ret)
data->pxs_gain = idx; data->pxs_gain = idx;
mutex_unlock(&data->lock); mutex_unlock(&data->lock);

View File

@@ -25,13 +25,6 @@ enum {
MS5607, MS5607,
}; };
struct ms5611_chip_info {
u16 prom[MS5611_PROM_WORDS_NB];
int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info,
s32 *temp, s32 *pressure);
};
/* /*
* OverSampling Rate descriptor. * OverSampling Rate descriptor.
* Warning: cmd MUST be kept aligned on a word boundary (see * Warning: cmd MUST be kept aligned on a word boundary (see
@@ -50,12 +43,15 @@ struct ms5611_state {
const struct ms5611_osr *pressure_osr; const struct ms5611_osr *pressure_osr;
const struct ms5611_osr *temp_osr; const struct ms5611_osr *temp_osr;
int (*reset)(struct device *dev); u16 prom[MS5611_PROM_WORDS_NB];
int (*read_prom_word)(struct device *dev, int index, u16 *word);
int (*read_adc_temp_and_pressure)(struct device *dev, int (*reset)(struct ms5611_state *st);
int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word);
int (*read_adc_temp_and_pressure)(struct ms5611_state *st,
s32 *temp, s32 *pressure); s32 *temp, s32 *pressure);
struct ms5611_chip_info *chip_info; int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp,
s32 *pressure);
struct regulator *vdd; struct regulator *vdd;
}; };

View File

@@ -85,8 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
struct ms5611_state *st = iio_priv(indio_dev); struct ms5611_state *st = iio_priv(indio_dev);
for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { for (i = 0; i < MS5611_PROM_WORDS_NB; i++) {
ret = st->read_prom_word(&indio_dev->dev, ret = st->read_prom_word(st, i, &st->prom[i]);
i, &st->chip_info->prom[i]);
if (ret < 0) { if (ret < 0) {
dev_err(&indio_dev->dev, dev_err(&indio_dev->dev,
"failed to read prom at %d\n", i); "failed to read prom at %d\n", i);
@@ -94,7 +93,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev)
} }
} }
if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) { if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) {
dev_err(&indio_dev->dev, "PROM integrity check failed\n"); dev_err(&indio_dev->dev, "PROM integrity check failed\n");
return -ENODEV; return -ENODEV;
} }
@@ -108,28 +107,27 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev,
int ret; int ret;
struct ms5611_state *st = iio_priv(indio_dev); struct ms5611_state *st = iio_priv(indio_dev);
ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure); ret = st->read_adc_temp_and_pressure(st, temp, pressure);
if (ret < 0) { if (ret < 0) {
dev_err(&indio_dev->dev, dev_err(&indio_dev->dev,
"failed to read temperature and pressure\n"); "failed to read temperature and pressure\n");
return ret; return ret;
} }
return st->chip_info->temp_and_pressure_compensate(st->chip_info, return st->compensate_temp_and_pressure(st, temp, pressure);
temp, pressure);
} }
static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st,
s32 *temp, s32 *pressure) s32 *temp, s32 *pressure)
{ {
s32 t = *temp, p = *pressure; s32 t = *temp, p = *pressure;
s64 off, sens, dt; s64 off, sens, dt;
dt = t - (chip_info->prom[5] << 8); dt = t - (st->prom[5] << 8);
off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7); off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7);
sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8); sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8);
t = 2000 + ((chip_info->prom[6] * dt) >> 23); t = 2000 + ((st->prom[6] * dt) >> 23);
if (t < 2000) { if (t < 2000) {
s64 off2, sens2, t2; s64 off2, sens2, t2;
@@ -155,17 +153,17 @@ static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_inf
return 0; return 0;
} }
static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st,
s32 *temp, s32 *pressure) s32 *temp, s32 *pressure)
{ {
s32 t = *temp, p = *pressure; s32 t = *temp, p = *pressure;
s64 off, sens, dt; s64 off, sens, dt;
dt = t - (chip_info->prom[5] << 8); dt = t - (st->prom[5] << 8);
off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6); off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6);
sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7); sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7);
t = 2000 + ((chip_info->prom[6] * dt) >> 23); t = 2000 + ((st->prom[6] * dt) >> 23);
if (t < 2000) { if (t < 2000) {
s64 off2, sens2, t2, tmp; s64 off2, sens2, t2, tmp;
@@ -196,7 +194,7 @@ static int ms5611_reset(struct iio_dev *indio_dev)
int ret; int ret;
struct ms5611_state *st = iio_priv(indio_dev); struct ms5611_state *st = iio_priv(indio_dev);
ret = st->reset(&indio_dev->dev); ret = st->reset(st);
if (ret < 0) { if (ret < 0) {
dev_err(&indio_dev->dev, "failed to reset device\n"); dev_err(&indio_dev->dev, "failed to reset device\n");
return ret; return ret;
@@ -343,15 +341,6 @@ static int ms5611_write_raw(struct iio_dev *indio_dev,
static const unsigned long ms5611_scan_masks[] = {0x3, 0}; static const unsigned long ms5611_scan_masks[] = {0x3, 0};
static struct ms5611_chip_info chip_info_tbl[] = {
[MS5611] = {
.temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate,
},
[MS5607] = {
.temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate,
}
};
static const struct iio_chan_spec ms5611_channels[] = { static const struct iio_chan_spec ms5611_channels[] = {
{ {
.type = IIO_PRESSURE, .type = IIO_PRESSURE,
@@ -434,7 +423,20 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev,
struct ms5611_state *st = iio_priv(indio_dev); struct ms5611_state *st = iio_priv(indio_dev);
mutex_init(&st->lock); mutex_init(&st->lock);
st->chip_info = &chip_info_tbl[type];
switch (type) {
case MS5611:
st->compensate_temp_and_pressure =
ms5611_temp_and_pressure_compensate;
break;
case MS5607:
st->compensate_temp_and_pressure =
ms5607_temp_and_pressure_compensate;
break;
default:
return -EINVAL;
}
st->temp_osr = st->temp_osr =
&ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1];
st->pressure_osr = st->pressure_osr =

View File

@@ -20,17 +20,15 @@
#include "ms5611.h" #include "ms5611.h"
static int ms5611_i2c_reset(struct device *dev) static int ms5611_i2c_reset(struct ms5611_state *st)
{ {
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
return i2c_smbus_write_byte(st->client, MS5611_RESET); return i2c_smbus_write_byte(st->client, MS5611_RESET);
} }
static int ms5611_i2c_read_prom_word(struct device *dev, int index, u16 *word) static int ms5611_i2c_read_prom_word(struct ms5611_state *st, int index,
u16 *word)
{ {
int ret; int ret;
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
ret = i2c_smbus_read_word_swapped(st->client, ret = i2c_smbus_read_word_swapped(st->client,
MS5611_READ_PROM_WORD + (index << 1)); MS5611_READ_PROM_WORD + (index << 1));
@@ -57,11 +55,10 @@ static int ms5611_i2c_read_adc(struct ms5611_state *st, s32 *val)
return 0; return 0;
} }
static int ms5611_i2c_read_adc_temp_and_pressure(struct device *dev, static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st,
s32 *temp, s32 *pressure) s32 *temp, s32 *pressure)
{ {
int ret; int ret;
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
const struct ms5611_osr *osr = st->temp_osr; const struct ms5611_osr *osr = st->temp_osr;
ret = i2c_smbus_write_byte(st->client, osr->cmd); ret = i2c_smbus_write_byte(st->client, osr->cmd);

View File

@@ -15,18 +15,17 @@
#include "ms5611.h" #include "ms5611.h"
static int ms5611_spi_reset(struct device *dev) static int ms5611_spi_reset(struct ms5611_state *st)
{ {
u8 cmd = MS5611_RESET; u8 cmd = MS5611_RESET;
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
return spi_write_then_read(st->client, &cmd, 1, NULL, 0); return spi_write_then_read(st->client, &cmd, 1, NULL, 0);
} }
static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word) static int ms5611_spi_read_prom_word(struct ms5611_state *st, int index,
u16 *word)
{ {
int ret; int ret;
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
ret = spi_w8r16be(st->client, MS5611_READ_PROM_WORD + (index << 1)); ret = spi_w8r16be(st->client, MS5611_READ_PROM_WORD + (index << 1));
if (ret < 0) if (ret < 0)
@@ -37,11 +36,10 @@ static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word)
return 0; return 0;
} }
static int ms5611_spi_read_adc(struct device *dev, s32 *val) static int ms5611_spi_read_adc(struct ms5611_state *st, s32 *val)
{ {
int ret; int ret;
u8 buf[3] = { MS5611_READ_ADC }; u8 buf[3] = { MS5611_READ_ADC };
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
ret = spi_write_then_read(st->client, buf, 1, buf, 3); ret = spi_write_then_read(st->client, buf, 1, buf, 3);
if (ret < 0) if (ret < 0)
@@ -52,11 +50,10 @@ static int ms5611_spi_read_adc(struct device *dev, s32 *val)
return 0; return 0;
} }
static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, static int ms5611_spi_read_adc_temp_and_pressure(struct ms5611_state *st,
s32 *temp, s32 *pressure) s32 *temp, s32 *pressure)
{ {
int ret; int ret;
struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev));
const struct ms5611_osr *osr = st->temp_osr; const struct ms5611_osr *osr = st->temp_osr;
/* /*
@@ -68,7 +65,7 @@ static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev,
return ret; return ret;
usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL));
ret = ms5611_spi_read_adc(dev, temp); ret = ms5611_spi_read_adc(st, temp);
if (ret < 0) if (ret < 0)
return ret; return ret;
@@ -78,7 +75,7 @@ static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev,
return ret; return ret;
usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL));
return ms5611_spi_read_adc(dev, pressure); return ms5611_spi_read_adc(st, pressure);
} }
static int ms5611_spi_probe(struct spi_device *spi) static int ms5611_spi_probe(struct spi_device *spi)

View File

@@ -18,6 +18,10 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
static bool use_low_level_irq;
module_param(use_low_level_irq, bool, 0444);
MODULE_PARM_DESC(use_low_level_irq, "Use low-level triggered IRQ instead of edge triggered");
struct soc_button_info { struct soc_button_info {
const char *name; const char *name;
int acpi_index; int acpi_index;
@@ -73,6 +77,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
}, },
}, },
{
/* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
},
},
{ {
/* /*
* Acer One S1003. _LID method messes with power-button GPIO * Acer One S1003. _LID method messes with power-button GPIO
@@ -164,7 +175,8 @@ soc_button_device_create(struct platform_device *pdev,
} }
/* See dmi_use_low_level_irq[] comment */ /* See dmi_use_low_level_irq[] comment */
if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) { if (!autorepeat && (use_low_level_irq ||
dmi_check_system(dmi_use_low_level_irq))) {
irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
gpio_keys[n_buttons].irq = irq; gpio_keys[n_buttons].irq = irq;
gpio_keys[n_buttons].gpio = -ENOENT; gpio_keys[n_buttons].gpio = -ENOENT;

View File

@@ -191,6 +191,7 @@ static const char * const smbus_pnp_ids[] = {
"SYN3221", /* HP 15-ay000 */ "SYN3221", /* HP 15-ay000 */
"SYN323d", /* HP Spectre X360 13-w013dx */ "SYN323d", /* HP Spectre X360 13-w013dx */
"SYN3257", /* HP Envy 13-ad105ng */ "SYN3257", /* HP Envy 13-ad105ng */
"SYN3286", /* HP Laptop 15-da3001TU */
NULL NULL
}; };

View File

@@ -114,18 +114,18 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER)
}, },
{ {
/* ASUS ZenBook UX425UA */ /* ASUS ZenBook UX425UA/QA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"), DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"),
}, },
.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
}, },
{ {
/* ASUS ZenBook UM325UA */ /* ASUS ZenBook UM325UA/QA */
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"), DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"),
}, },
.driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER)
}, },

View File

@@ -1039,6 +1039,7 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
retry_read_config:
/* Read configuration and apply touchscreen parameters */ /* Read configuration and apply touchscreen parameters */
goodix_read_config(ts); goodix_read_config(ts);
@@ -1046,6 +1047,16 @@ static int goodix_configure_dev(struct goodix_ts_data *ts)
touchscreen_parse_properties(ts->input_dev, true, &ts->prop); touchscreen_parse_properties(ts->input_dev, true, &ts->prop);
if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) { if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) {
if (!ts->reset_controller_at_probe &&
ts->irq_pin_access_method != IRQ_PIN_ACCESS_NONE) {
dev_info(&ts->client->dev, "Config not set, resetting controller\n");
/* Retry after a controller reset */
ts->reset_controller_at_probe = true;
error = goodix_reset(ts);
if (error)
return error;
goto retry_read_config;
}
dev_err(&ts->client->dev, dev_err(&ts->client->dev,
"Invalid config (%d, %d, %d), using defaults\n", "Invalid config (%d, %d, %d), using defaults\n",
ts->prop.max_x, ts->prop.max_y, ts->max_touch_num); ts->prop.max_x, ts->prop.max_y, ts->max_touch_num);

View File

@@ -1620,7 +1620,7 @@ static int its_select_cpu(struct irq_data *d,
cpu = cpumask_pick_least_loaded(d, tmpmask); cpu = cpumask_pick_least_loaded(d, tmpmask);
} else { } else {
cpumask_and(tmpmask, irq_data_get_affinity_mask(d), cpu_online_mask); cpumask_copy(tmpmask, aff_mask);
/* If we cannot cross sockets, limit the search to that node */ /* If we cannot cross sockets, limit the search to that node */
if ((its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) && if ((its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144) &&

View File

@@ -259,6 +259,7 @@ struct dm_integrity_c {
struct completion crypto_backoff; struct completion crypto_backoff;
bool wrote_to_journal;
bool journal_uptodate; bool journal_uptodate;
bool just_formatted; bool just_formatted;
bool recalculate_flag; bool recalculate_flag;
@@ -2361,6 +2362,8 @@ static void integrity_commit(struct work_struct *w)
if (!commit_sections) if (!commit_sections)
goto release_flush_bios; goto release_flush_bios;
ic->wrote_to_journal = true;
i = commit_start; i = commit_start;
for (n = 0; n < commit_sections; n++) { for (n = 0; n < commit_sections; n++) {
for (j = 0; j < ic->journal_section_entries; j++) { for (j = 0; j < ic->journal_section_entries; j++) {
@@ -2575,10 +2578,6 @@ static void integrity_writer(struct work_struct *w)
unsigned prev_free_sectors; unsigned prev_free_sectors;
/* the following test is not needed, but it tests the replay code */
if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev)
return;
spin_lock_irq(&ic->endio_wait.lock); spin_lock_irq(&ic->endio_wait.lock);
write_start = ic->committed_section; write_start = ic->committed_section;
write_sections = ic->n_committed_sections; write_sections = ic->n_committed_sections;
@@ -3085,10 +3084,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
drain_workqueue(ic->commit_wq); drain_workqueue(ic->commit_wq);
if (ic->mode == 'J') { if (ic->mode == 'J') {
if (ic->meta_dev) queue_work(ic->writer_wq, &ic->writer_work);
queue_work(ic->writer_wq, &ic->writer_work);
drain_workqueue(ic->writer_wq); drain_workqueue(ic->writer_wq);
dm_integrity_flush_buffers(ic, true); dm_integrity_flush_buffers(ic, true);
if (ic->wrote_to_journal) {
init_journal(ic, ic->free_section,
ic->journal_sections - ic->free_section, ic->commit_seq);
if (ic->free_section) {
init_journal(ic, 0, ic->free_section,
next_commit_seq(ic->commit_seq));
}
}
} }
if (ic->mode == 'B') { if (ic->mode == 'B') {
@@ -3116,6 +3122,8 @@ static void dm_integrity_resume(struct dm_target *ti)
DEBUG_print("resume\n"); DEBUG_print("resume\n");
ic->wrote_to_journal = false;
if (ic->provided_data_sectors != old_provided_data_sectors) { if (ic->provided_data_sectors != old_provided_data_sectors) {
if (ic->provided_data_sectors > old_provided_data_sectors && if (ic->provided_data_sectors > old_provided_data_sectors &&
ic->mode == 'B' && ic->mode == 'B' &&

View File

@@ -12,28 +12,55 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h> #include <linux/delay.h>
#include "sdhci-cqhci.h"
#include "sdhci-pltfm.h" #include "sdhci-pltfm.h"
#include "cqhci.h" #include "cqhci.h"
#define SDHCI_VENDOR 0x78 #define SDHCI_VENDOR 0x78
#define SDHCI_VENDOR_ENHANCED_STRB 0x1 #define SDHCI_VENDOR_ENHANCED_STRB 0x1
#define SDHCI_VENDOR_GATE_SDCLK_EN 0x2
#define BRCMSTB_PRIV_FLAGS_NO_64BIT BIT(0) #define BRCMSTB_MATCH_FLAGS_NO_64BIT BIT(0)
#define BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT BIT(1) #define BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT BIT(1)
#define BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE BIT(2)
#define BRCMSTB_PRIV_FLAGS_HAS_CQE BIT(0)
#define BRCMSTB_PRIV_FLAGS_GATE_CLOCK BIT(1)
#define SDHCI_ARASAN_CQE_BASE_ADDR 0x200 #define SDHCI_ARASAN_CQE_BASE_ADDR 0x200
struct sdhci_brcmstb_priv { struct sdhci_brcmstb_priv {
void __iomem *cfg_regs; void __iomem *cfg_regs;
bool has_cqe; unsigned int flags;
}; };
struct brcmstb_match_priv { struct brcmstb_match_priv {
void (*hs400es)(struct mmc_host *mmc, struct mmc_ios *ios); void (*hs400es)(struct mmc_host *mmc, struct mmc_ios *ios);
struct sdhci_ops *ops; struct sdhci_ops *ops;
unsigned int flags; const unsigned int flags;
}; };
static inline void enable_clock_gating(struct sdhci_host *host)
{
u32 reg;
reg = sdhci_readl(host, SDHCI_VENDOR);
reg |= SDHCI_VENDOR_GATE_SDCLK_EN;
sdhci_writel(host, reg, SDHCI_VENDOR);
}
void brcmstb_reset(struct sdhci_host *host, u8 mask)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host);
sdhci_and_cqhci_reset(host, mask);
/* Reset will clear this, so re-enable it */
if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK)
enable_clock_gating(host);
}
static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios) static void sdhci_brcmstb_hs400es(struct mmc_host *mmc, struct mmc_ios *ios)
{ {
struct sdhci_host *host = mmc_priv(mmc); struct sdhci_host *host = mmc_priv(mmc);
@@ -129,22 +156,23 @@ static struct sdhci_ops sdhci_brcmstb_ops = {
static struct sdhci_ops sdhci_brcmstb_ops_7216 = { static struct sdhci_ops sdhci_brcmstb_ops_7216 = {
.set_clock = sdhci_brcmstb_set_clock, .set_clock = sdhci_brcmstb_set_clock,
.set_bus_width = sdhci_set_bus_width, .set_bus_width = sdhci_set_bus_width,
.reset = sdhci_reset, .reset = brcmstb_reset,
.set_uhs_signaling = sdhci_brcmstb_set_uhs_signaling, .set_uhs_signaling = sdhci_brcmstb_set_uhs_signaling,
}; };
static struct brcmstb_match_priv match_priv_7425 = { static struct brcmstb_match_priv match_priv_7425 = {
.flags = BRCMSTB_PRIV_FLAGS_NO_64BIT | .flags = BRCMSTB_MATCH_FLAGS_NO_64BIT |
BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT, BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT,
.ops = &sdhci_brcmstb_ops, .ops = &sdhci_brcmstb_ops,
}; };
static struct brcmstb_match_priv match_priv_7445 = { static struct brcmstb_match_priv match_priv_7445 = {
.flags = BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT, .flags = BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT,
.ops = &sdhci_brcmstb_ops, .ops = &sdhci_brcmstb_ops,
}; };
static const struct brcmstb_match_priv match_priv_7216 = { static const struct brcmstb_match_priv match_priv_7216 = {
.flags = BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE,
.hs400es = sdhci_brcmstb_hs400es, .hs400es = sdhci_brcmstb_hs400es,
.ops = &sdhci_brcmstb_ops_7216, .ops = &sdhci_brcmstb_ops_7216,
}; };
@@ -176,7 +204,7 @@ static int sdhci_brcmstb_add_host(struct sdhci_host *host,
bool dma64; bool dma64;
int ret; int ret;
if (!priv->has_cqe) if ((priv->flags & BRCMSTB_PRIV_FLAGS_HAS_CQE) == 0)
return sdhci_add_host(host); return sdhci_add_host(host);
dev_dbg(mmc_dev(host->mmc), "CQE is enabled\n"); dev_dbg(mmc_dev(host->mmc), "CQE is enabled\n");
@@ -225,7 +253,6 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
struct sdhci_brcmstb_priv *priv; struct sdhci_brcmstb_priv *priv;
struct sdhci_host *host; struct sdhci_host *host;
struct resource *iomem; struct resource *iomem;
bool has_cqe = false;
struct clk *clk; struct clk *clk;
int res; int res;
@@ -244,10 +271,6 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
return res; return res;
memset(&brcmstb_pdata, 0, sizeof(brcmstb_pdata)); memset(&brcmstb_pdata, 0, sizeof(brcmstb_pdata));
if (device_property_read_bool(&pdev->dev, "supports-cqe")) {
has_cqe = true;
match_priv->ops->irq = sdhci_brcmstb_cqhci_irq;
}
brcmstb_pdata.ops = match_priv->ops; brcmstb_pdata.ops = match_priv->ops;
host = sdhci_pltfm_init(pdev, &brcmstb_pdata, host = sdhci_pltfm_init(pdev, &brcmstb_pdata,
sizeof(struct sdhci_brcmstb_priv)); sizeof(struct sdhci_brcmstb_priv));
@@ -258,7 +281,10 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
pltfm_host = sdhci_priv(host); pltfm_host = sdhci_priv(host);
priv = sdhci_pltfm_priv(pltfm_host); priv = sdhci_pltfm_priv(pltfm_host);
priv->has_cqe = has_cqe; if (device_property_read_bool(&pdev->dev, "supports-cqe")) {
priv->flags |= BRCMSTB_PRIV_FLAGS_HAS_CQE;
match_priv->ops->irq = sdhci_brcmstb_cqhci_irq;
}
/* Map in the non-standard CFG registers */ /* Map in the non-standard CFG registers */
iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1); iomem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -273,6 +299,14 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
if (res) if (res)
goto err; goto err;
/*
* Automatic clock gating does not work for SD cards that may
* voltage switch so only enable it for non-removable devices.
*/
if ((match_priv->flags & BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE) &&
(host->mmc->caps & MMC_CAP_NONREMOVABLE))
priv->flags |= BRCMSTB_PRIV_FLAGS_GATE_CLOCK;
/* /*
* If the chip has enhanced strobe and it's enabled, add * If the chip has enhanced strobe and it's enabled, add
* callback * callback
@@ -287,14 +321,14 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
* properties through mmc_of_parse(). * properties through mmc_of_parse().
*/ */
host->caps = sdhci_readl(host, SDHCI_CAPABILITIES); host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
if (match_priv->flags & BRCMSTB_PRIV_FLAGS_NO_64BIT) if (match_priv->flags & BRCMSTB_MATCH_FLAGS_NO_64BIT)
host->caps &= ~SDHCI_CAN_64BIT; host->caps &= ~SDHCI_CAN_64BIT;
host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
SDHCI_SUPPORT_DDR50); SDHCI_SUPPORT_DDR50);
host->quirks |= SDHCI_QUIRK_MISSING_CAPS; host->quirks |= SDHCI_QUIRK_MISSING_CAPS;
if (match_priv->flags & BRCMSTB_PRIV_FLAGS_BROKEN_TIMEOUT) if (match_priv->flags & BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT)
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
res = sdhci_brcmstb_add_host(host, priv); res = sdhci_brcmstb_add_host(host, priv);

View File

@@ -113,6 +113,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
struct com20020_dev *info; struct com20020_dev *info;
struct net_device *dev; struct net_device *dev;
struct arcnet_local *lp; struct arcnet_local *lp;
int ret = -ENOMEM;
dev_dbg(&p_dev->dev, "com20020_attach()\n"); dev_dbg(&p_dev->dev, "com20020_attach()\n");
@@ -142,12 +143,18 @@ static int com20020_probe(struct pcmcia_device *p_dev)
info->dev = dev; info->dev = dev;
p_dev->priv = info; p_dev->priv = info;
return com20020_config(p_dev); ret = com20020_config(p_dev);
if (ret)
goto fail_config;
return 0;
fail_config:
free_arcdev(dev);
fail_alloc_dev: fail_alloc_dev:
kfree(info); kfree(info);
fail_alloc_info: fail_alloc_info:
return -ENOMEM; return ret;
} /* com20020_attach */ } /* com20020_attach */
static void com20020_detach(struct pcmcia_device *link) static void com20020_detach(struct pcmcia_device *link)

View File

@@ -256,6 +256,9 @@ static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg)
u32 tmp; u32 tmp;
int rc; int rc;
if (reg & MII_ADDR_C45)
return -EOPNOTSUPP;
rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg, rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg,
&tmp, NULL); &tmp, NULL);
if (rc < 0) if (rc < 0)
@@ -272,6 +275,9 @@ static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg,
const struct sja1105_regs *regs = priv->info->regs; const struct sja1105_regs *regs = priv->info->regs;
u32 tmp = val; u32 tmp = val;
if (reg & MII_ADDR_C45)
return -EOPNOTSUPP;
return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg, return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg,
&tmp, NULL); &tmp, NULL);
} }

View File

@@ -795,16 +795,20 @@ static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf)
static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
{ {
struct pci_dev *dev;
struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid); struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid);
struct pci_dev *dev;
bool pending;
if (!vf) if (!vf)
return false; return false;
dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn); dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
if (dev) if (!dev)
return bnx2x_is_pcie_pending(dev); return false;
return false; pending = bnx2x_is_pcie_pending(dev);
pci_dev_put(dev);
return pending;
} }
int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)

View File

@@ -1798,7 +1798,7 @@ static int liquidio_open(struct net_device *netdev)
ifstate_set(lio, LIO_IFSTATE_RUNNING); ifstate_set(lio, LIO_IFSTATE_RUNNING);
if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) { if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) {
ret = setup_tx_poll_fn(netdev); ret = setup_tx_poll_fn(netdev);
if (ret) if (ret)
goto err_poll; goto err_poll;
@@ -1828,7 +1828,7 @@ static int liquidio_open(struct net_device *netdev)
return 0; return 0;
err_rx_ctrl: err_rx_ctrl:
if (!OCTEON_CN23XX_PF(oct) || (OCTEON_CN23XX_PF(oct) && !oct->msix_on)) if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on)
cleanup_tx_poll_fn(netdev); cleanup_tx_poll_fn(netdev);
err_poll: err_poll:
if (lio->ptp_clock) { if (lio->ptp_clock) {

View File

@@ -1435,8 +1435,10 @@ static acpi_status bgx_acpi_match_id(acpi_handle handle, u32 lvl,
return AE_OK; return AE_OK;
} }
if (strncmp(string.pointer, bgx_sel, 4)) if (strncmp(string.pointer, bgx_sel, 4)) {
kfree(string.pointer);
return AE_OK; return AE_OK;
}
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
bgx_acpi_register_phy, NULL, bgx, NULL); bgx_acpi_register_phy, NULL, bgx, NULL);

View File

@@ -1768,7 +1768,7 @@ static void enetc_setup_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
/* enable Tx ints by setting pkt thr to 1 */ /* enable Tx ints by setting pkt thr to 1 */
enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1); enetc_txbdr_wr(hw, idx, ENETC_TBICR0, ENETC_TBICR0_ICEN | 0x1);
tbmr = ENETC_TBMR_EN; tbmr = ENETC_TBMR_EN | ENETC_TBMR_SET_PRIO(tx_ring->prio);
if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX) if (tx_ring->ndev->features & NETIF_F_HW_VLAN_CTAG_TX)
tbmr |= ENETC_TBMR_VIH; tbmr |= ENETC_TBMR_VIH;
@@ -1831,13 +1831,14 @@ static void enetc_setup_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
static void enetc_setup_bdrs(struct enetc_ndev_priv *priv) static void enetc_setup_bdrs(struct enetc_ndev_priv *priv)
{ {
struct enetc_hw *hw = &priv->si->hw;
int i; int i;
for (i = 0; i < priv->num_tx_rings; i++) for (i = 0; i < priv->num_tx_rings; i++)
enetc_setup_txbdr(&priv->si->hw, priv->tx_ring[i]); enetc_setup_txbdr(hw, priv->tx_ring[i]);
for (i = 0; i < priv->num_rx_rings; i++) for (i = 0; i < priv->num_rx_rings; i++)
enetc_setup_rxbdr(&priv->si->hw, priv->rx_ring[i]); enetc_setup_rxbdr(hw, priv->rx_ring[i]);
} }
static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) static void enetc_clear_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
@@ -1870,13 +1871,14 @@ static void enetc_clear_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
static void enetc_clear_bdrs(struct enetc_ndev_priv *priv) static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
{ {
struct enetc_hw *hw = &priv->si->hw;
int i; int i;
for (i = 0; i < priv->num_tx_rings; i++) for (i = 0; i < priv->num_tx_rings; i++)
enetc_clear_txbdr(&priv->si->hw, priv->tx_ring[i]); enetc_clear_txbdr(hw, priv->tx_ring[i]);
for (i = 0; i < priv->num_rx_rings; i++) for (i = 0; i < priv->num_rx_rings; i++)
enetc_clear_rxbdr(&priv->si->hw, priv->rx_ring[i]); enetc_clear_rxbdr(hw, priv->rx_ring[i]);
udelay(1); udelay(1);
} }
@@ -1884,13 +1886,13 @@ static void enetc_clear_bdrs(struct enetc_ndev_priv *priv)
static int enetc_setup_irqs(struct enetc_ndev_priv *priv) static int enetc_setup_irqs(struct enetc_ndev_priv *priv)
{ {
struct pci_dev *pdev = priv->si->pdev; struct pci_dev *pdev = priv->si->pdev;
struct enetc_hw *hw = &priv->si->hw;
int i, j, err; int i, j, err;
for (i = 0; i < priv->bdr_int_num; i++) { for (i = 0; i < priv->bdr_int_num; i++) {
int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i); int irq = pci_irq_vector(pdev, ENETC_BDR_INT_BASE_IDX + i);
struct enetc_int_vector *v = priv->int_vector[i]; struct enetc_int_vector *v = priv->int_vector[i];
int entry = ENETC_BDR_INT_BASE_IDX + i; int entry = ENETC_BDR_INT_BASE_IDX + i;
struct enetc_hw *hw = &priv->si->hw;
snprintf(v->name, sizeof(v->name), "%s-rxtx%d", snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
priv->ndev->name, i); priv->ndev->name, i);
@@ -1978,13 +1980,14 @@ static void enetc_setup_interrupts(struct enetc_ndev_priv *priv)
static void enetc_clear_interrupts(struct enetc_ndev_priv *priv) static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
{ {
struct enetc_hw *hw = &priv->si->hw;
int i; int i;
for (i = 0; i < priv->num_tx_rings; i++) for (i = 0; i < priv->num_tx_rings; i++)
enetc_txbdr_wr(&priv->si->hw, i, ENETC_TBIER, 0); enetc_txbdr_wr(hw, i, ENETC_TBIER, 0);
for (i = 0; i < priv->num_rx_rings; i++) for (i = 0; i < priv->num_rx_rings; i++)
enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0); enetc_rxbdr_wr(hw, i, ENETC_RBIER, 0);
} }
static int enetc_phylink_connect(struct net_device *ndev) static int enetc_phylink_connect(struct net_device *ndev)
@@ -2151,6 +2154,7 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
{ {
struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct tc_mqprio_qopt *mqprio = type_data; struct tc_mqprio_qopt *mqprio = type_data;
struct enetc_hw *hw = &priv->si->hw;
struct enetc_bdr *tx_ring; struct enetc_bdr *tx_ring;
int num_stack_tx_queues; int num_stack_tx_queues;
u8 num_tc; u8 num_tc;
@@ -2167,7 +2171,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
/* Reset all ring priorities to 0 */ /* Reset all ring priorities to 0 */
for (i = 0; i < priv->num_tx_rings; i++) { for (i = 0; i < priv->num_tx_rings; i++) {
tx_ring = priv->tx_ring[i]; tx_ring = priv->tx_ring[i];
enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, 0); tx_ring->prio = 0;
enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
} }
return 0; return 0;
@@ -2186,7 +2191,8 @@ int enetc_setup_tc_mqprio(struct net_device *ndev, void *type_data)
*/ */
for (i = 0; i < num_tc; i++) { for (i = 0; i < num_tc; i++) {
tx_ring = priv->tx_ring[i]; tx_ring = priv->tx_ring[i];
enetc_set_bdr_prio(&priv->si->hw, tx_ring->index, i); tx_ring->prio = i;
enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
} }
/* Reset the number of netdev queues based on the TC count */ /* Reset the number of netdev queues based on the TC count */
@@ -2296,19 +2302,21 @@ static int enetc_set_rss(struct net_device *ndev, int en)
static void enetc_enable_rxvlan(struct net_device *ndev, bool en) static void enetc_enable_rxvlan(struct net_device *ndev, bool en)
{ {
struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_hw *hw = &priv->si->hw;
int i; int i;
for (i = 0; i < priv->num_rx_rings; i++) for (i = 0; i < priv->num_rx_rings; i++)
enetc_bdr_enable_rxvlan(&priv->si->hw, i, en); enetc_bdr_enable_rxvlan(hw, i, en);
} }
static void enetc_enable_txvlan(struct net_device *ndev, bool en) static void enetc_enable_txvlan(struct net_device *ndev, bool en)
{ {
struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_hw *hw = &priv->si->hw;
int i; int i;
for (i = 0; i < priv->num_tx_rings; i++) for (i = 0; i < priv->num_tx_rings; i++)
enetc_bdr_enable_txvlan(&priv->si->hw, i, en); enetc_bdr_enable_txvlan(hw, i, en);
} }
void enetc_set_features(struct net_device *ndev, netdev_features_t features) void enetc_set_features(struct net_device *ndev, netdev_features_t features)

View File

@@ -91,6 +91,7 @@ struct enetc_bdr {
void __iomem *rcir; void __iomem *rcir;
}; };
u16 index; u16 index;
u16 prio;
int bd_count; /* # of BDs */ int bd_count; /* # of BDs */
int next_to_use; int next_to_use;
int next_to_clean; int next_to_clean;
@@ -423,19 +424,20 @@ int enetc_set_psfp(struct net_device *ndev, bool en);
static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv) static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
{ {
struct enetc_hw *hw = &priv->si->hw;
u32 reg; u32 reg;
reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR); reg = enetc_port_rd(hw, ENETC_PSIDCAPR);
priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK; priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
/* Port stream filter capability */ /* Port stream filter capability */
reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR); reg = enetc_port_rd(hw, ENETC_PSFCAPR);
priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK; priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
/* Port stream gate capability */ /* Port stream gate capability */
reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR); reg = enetc_port_rd(hw, ENETC_PSGCAPR);
priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK); priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16; priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
/* Port flow meter capability */ /* Port flow meter capability */
reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR); reg = enetc_port_rd(hw, ENETC_PFMCAPR);
priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK; priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
} }

View File

@@ -800,9 +800,6 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
ndev->priv_flags |= IFF_UNICAST_FLT; ndev->priv_flags |= IFF_UNICAST_FLT;
if (si->hw_features & ENETC_SI_F_QBV)
priv->active_offloads |= ENETC_F_QBV;
if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) { if (si->hw_features & ENETC_SI_F_PSFP && !enetc_psfp_enable(priv)) {
priv->active_offloads |= ENETC_F_QCI; priv->active_offloads |= ENETC_F_QCI;
ndev->features |= NETIF_F_HW_TC; ndev->features |= NETIF_F_HW_TC;
@@ -1053,7 +1050,8 @@ static void enetc_pl_mac_link_up(struct phylink_config *config,
int idx; int idx;
priv = netdev_priv(pf->si->ndev); priv = netdev_priv(pf->si->ndev);
if (priv->active_offloads & ENETC_F_QBV)
if (pf->si->hw_features & ENETC_SI_F_QBV)
enetc_sched_speed_set(priv, speed); enetc_sched_speed_set(priv, speed);
if (!phylink_autoneg_inband(mode) && if (!phylink_autoneg_inband(mode) &&

View File

@@ -17,8 +17,9 @@ static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed) void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
{ {
struct enetc_hw *hw = &priv->si->hw;
u32 old_speed = priv->speed; u32 old_speed = priv->speed;
u32 pspeed; u32 pspeed, tmp;
if (speed == old_speed) if (speed == old_speed)
return; return;
@@ -39,10 +40,8 @@ void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
} }
priv->speed = speed; priv->speed = speed;
enetc_port_wr(&priv->si->hw, ENETC_PMR, tmp = enetc_port_rd(hw, ENETC_PMR);
(enetc_port_rd(&priv->si->hw, ENETC_PMR) enetc_port_wr(hw, ENETC_PMR, (tmp & ~ENETC_PMR_PSPEED_MASK) | pspeed);
& (~ENETC_PMR_PSPEED_MASK))
| pspeed);
} }
#define ENETC_QOS_ALIGN 64 #define ENETC_QOS_ALIGN 64
@@ -50,6 +49,7 @@ static int enetc_setup_taprio(struct net_device *ndev,
struct tc_taprio_qopt_offload *admin_conf) struct tc_taprio_qopt_offload *admin_conf)
{ {
struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_hw *hw = &priv->si->hw;
struct enetc_cbd cbd = {.cmd = 0}; struct enetc_cbd cbd = {.cmd = 0};
struct tgs_gcl_conf *gcl_config; struct tgs_gcl_conf *gcl_config;
struct tgs_gcl_data *gcl_data; struct tgs_gcl_data *gcl_data;
@@ -62,15 +62,16 @@ static int enetc_setup_taprio(struct net_device *ndev,
int err; int err;
int i; int i;
if (admin_conf->num_entries > enetc_get_max_gcl_len(&priv->si->hw)) if (admin_conf->num_entries > enetc_get_max_gcl_len(hw))
return -EINVAL; return -EINVAL;
gcl_len = admin_conf->num_entries; gcl_len = admin_conf->num_entries;
tge = enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET); tge = enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET);
if (!admin_conf->enable) { if (!admin_conf->enable) {
enetc_wr(&priv->si->hw, enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
ENETC_QBV_PTGCR_OFFSET,
tge & (~ENETC_QBV_TGE)); priv->active_offloads &= ~ENETC_F_QBV;
return 0; return 0;
} }
@@ -124,18 +125,18 @@ static int enetc_setup_taprio(struct net_device *ndev,
cbd.cls = BDCR_CMD_PORT_GCL; cbd.cls = BDCR_CMD_PORT_GCL;
cbd.status_flags = 0; cbd.status_flags = 0;
enetc_wr(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET, enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge | ENETC_QBV_TGE);
tge | ENETC_QBV_TGE);
err = enetc_send_cmd(priv->si, &cbd); err = enetc_send_cmd(priv->si, &cbd);
if (err) if (err)
enetc_wr(&priv->si->hw, enetc_wr(hw, ENETC_QBV_PTGCR_OFFSET, tge & ~ENETC_QBV_TGE);
ENETC_QBV_PTGCR_OFFSET,
tge & (~ENETC_QBV_TGE));
dma_free_coherent(&priv->si->pdev->dev, data_size + ENETC_QOS_ALIGN, dma_free_coherent(&priv->si->pdev->dev, data_size + ENETC_QOS_ALIGN,
tmp, dma); tmp, dma);
if (!err)
priv->active_offloads |= ENETC_F_QBV;
return err; return err;
} }
@@ -143,6 +144,8 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
{ {
struct tc_taprio_qopt_offload *taprio = type_data; struct tc_taprio_qopt_offload *taprio = type_data;
struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_hw *hw = &priv->si->hw;
struct enetc_bdr *tx_ring;
int err; int err;
int i; int i;
@@ -151,18 +154,20 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data)
if (priv->tx_ring[i]->tsd_enable) if (priv->tx_ring[i]->tsd_enable)
return -EBUSY; return -EBUSY;
for (i = 0; i < priv->num_tx_rings; i++) for (i = 0; i < priv->num_tx_rings; i++) {
enetc_set_bdr_prio(&priv->si->hw, tx_ring = priv->tx_ring[i];
priv->tx_ring[i]->index, tx_ring->prio = taprio->enable ? i : 0;
taprio->enable ? i : 0); enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
}
err = enetc_setup_taprio(ndev, taprio); err = enetc_setup_taprio(ndev, taprio);
if (err) {
if (err) for (i = 0; i < priv->num_tx_rings; i++) {
for (i = 0; i < priv->num_tx_rings; i++) tx_ring = priv->tx_ring[i];
enetc_set_bdr_prio(&priv->si->hw, tx_ring->prio = taprio->enable ? 0 : i;
priv->tx_ring[i]->index, enetc_set_bdr_prio(hw, tx_ring->index, tx_ring->prio);
taprio->enable ? 0 : i); }
}
return err; return err;
} }
@@ -183,7 +188,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
struct tc_cbs_qopt_offload *cbs = type_data; struct tc_cbs_qopt_offload *cbs = type_data;
u32 port_transmit_rate = priv->speed; u32 port_transmit_rate = priv->speed;
u8 tc_nums = netdev_get_num_tc(ndev); u8 tc_nums = netdev_get_num_tc(ndev);
struct enetc_si *si = priv->si; struct enetc_hw *hw = &priv->si->hw;
u32 hi_credit_bit, hi_credit_reg; u32 hi_credit_bit, hi_credit_reg;
u32 max_interference_size; u32 max_interference_size;
u32 port_frame_max_size; u32 port_frame_max_size;
@@ -204,15 +209,15 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
* lower than this TC have been disabled. * lower than this TC have been disabled.
*/ */
if (tc == prio_top && if (tc == prio_top &&
enetc_get_cbs_enable(&si->hw, prio_next)) { enetc_get_cbs_enable(hw, prio_next)) {
dev_err(&ndev->dev, dev_err(&ndev->dev,
"Disable TC%d before disable TC%d\n", "Disable TC%d before disable TC%d\n",
prio_next, tc); prio_next, tc);
return -EINVAL; return -EINVAL;
} }
enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), 0); enetc_port_wr(hw, ENETC_PTCCBSR1(tc), 0);
enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), 0); enetc_port_wr(hw, ENETC_PTCCBSR0(tc), 0);
return 0; return 0;
} }
@@ -229,13 +234,13 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
* higher than this TC have been enabled. * higher than this TC have been enabled.
*/ */
if (tc == prio_next) { if (tc == prio_next) {
if (!enetc_get_cbs_enable(&si->hw, prio_top)) { if (!enetc_get_cbs_enable(hw, prio_top)) {
dev_err(&ndev->dev, dev_err(&ndev->dev,
"Enable TC%d first before enable TC%d\n", "Enable TC%d first before enable TC%d\n",
prio_top, prio_next); prio_top, prio_next);
return -EINVAL; return -EINVAL;
} }
bw_sum += enetc_get_cbs_bw(&si->hw, prio_top); bw_sum += enetc_get_cbs_bw(hw, prio_top);
} }
if (bw_sum + bw >= 100) { if (bw_sum + bw >= 100) {
@@ -244,7 +249,7 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
return -EINVAL; return -EINVAL;
} }
enetc_port_rd(&si->hw, ENETC_PTCMSDUR(tc)); enetc_port_rd(hw, ENETC_PTCMSDUR(tc));
/* For top prio TC, the max_interfrence_size is maxSizedFrame. /* For top prio TC, the max_interfrence_size is maxSizedFrame.
* *
@@ -264,8 +269,8 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
u32 m0, ma, r0, ra; u32 m0, ma, r0, ra;
m0 = port_frame_max_size * 8; m0 = port_frame_max_size * 8;
ma = enetc_port_rd(&si->hw, ENETC_PTCMSDUR(prio_top)) * 8; ma = enetc_port_rd(hw, ENETC_PTCMSDUR(prio_top)) * 8;
ra = enetc_get_cbs_bw(&si->hw, prio_top) * ra = enetc_get_cbs_bw(hw, prio_top) *
port_transmit_rate * 10000ULL; port_transmit_rate * 10000ULL;
r0 = port_transmit_rate * 1000000ULL; r0 = port_transmit_rate * 1000000ULL;
max_interference_size = m0 + ma + max_interference_size = m0 + ma +
@@ -285,10 +290,10 @@ int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data)
hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit, hi_credit_reg = (u32)div_u64((ENETC_CLK * 100ULL) * hi_credit_bit,
port_transmit_rate * 1000000ULL); port_transmit_rate * 1000000ULL);
enetc_port_wr(&si->hw, ENETC_PTCCBSR1(tc), hi_credit_reg); enetc_port_wr(hw, ENETC_PTCCBSR1(tc), hi_credit_reg);
/* Set bw register and enable this traffic class */ /* Set bw register and enable this traffic class */
enetc_port_wr(&si->hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE); enetc_port_wr(hw, ENETC_PTCCBSR0(tc), bw | ENETC_CBSE);
return 0; return 0;
} }
@@ -298,6 +303,7 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
struct enetc_ndev_priv *priv = netdev_priv(ndev); struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct tc_etf_qopt_offload *qopt = type_data; struct tc_etf_qopt_offload *qopt = type_data;
u8 tc_nums = netdev_get_num_tc(ndev); u8 tc_nums = netdev_get_num_tc(ndev);
struct enetc_hw *hw = &priv->si->hw;
int tc; int tc;
if (!tc_nums) if (!tc_nums)
@@ -313,12 +319,11 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data)
return -EBUSY; return -EBUSY;
/* TSD and Qbv are mutually exclusive in hardware */ /* TSD and Qbv are mutually exclusive in hardware */
if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE) if (enetc_rd(hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE)
return -EBUSY; return -EBUSY;
priv->tx_ring[tc]->tsd_enable = qopt->enable; priv->tx_ring[tc]->tsd_enable = qopt->enable;
enetc_port_wr(&priv->si->hw, ENETC_PTCTSDR(tc), enetc_port_wr(hw, ENETC_PTCTSDR(tc), qopt->enable ? ENETC_TSDE : 0);
qopt->enable ? ENETC_TSDE : 0);
return 0; return 0;
} }

View File

@@ -2270,7 +2270,6 @@ static void iavf_disable_vf(struct iavf_adapter *adapter)
iavf_free_queues(adapter); iavf_free_queues(adapter);
memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE);
iavf_shutdown_adminq(&adapter->hw); iavf_shutdown_adminq(&adapter->hw);
adapter->netdev->flags &= ~IFF_UP;
adapter->flags &= ~IAVF_FLAG_RESET_PENDING; adapter->flags &= ~IAVF_FLAG_RESET_PENDING;
iavf_change_state(adapter, __IAVF_DOWN); iavf_change_state(adapter, __IAVF_DOWN);
wake_up(&adapter->down_waitqueue); wake_up(&adapter->down_waitqueue);
@@ -2369,6 +2368,11 @@ static void iavf_reset_task(struct work_struct *work)
iavf_disable_vf(adapter); iavf_disable_vf(adapter);
mutex_unlock(&adapter->client_lock); mutex_unlock(&adapter->client_lock);
mutex_unlock(&adapter->crit_lock); mutex_unlock(&adapter->crit_lock);
if (netif_running(netdev)) {
rtnl_lock();
dev_close(netdev);
rtnl_unlock();
}
return; /* Do not attempt to reinit. It's dead, Jim. */ return; /* Do not attempt to reinit. It's dead, Jim. */
} }
@@ -2381,6 +2385,7 @@ continue_reset:
if (running) { if (running) {
netif_carrier_off(netdev); netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
adapter->link_up = false; adapter->link_up = false;
iavf_napi_disable_all(adapter); iavf_napi_disable_all(adapter);
} }
@@ -2503,6 +2508,16 @@ reset_err:
mutex_unlock(&adapter->client_lock); mutex_unlock(&adapter->client_lock);
mutex_unlock(&adapter->crit_lock); mutex_unlock(&adapter->crit_lock);
if (netif_running(netdev)) {
/* Close device to ensure that Tx queues will not be started
* during netif_device_attach() at the end of the reset task.
*/
rtnl_lock();
dev_close(netdev);
rtnl_unlock();
}
dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n");
reset_finish: reset_finish:
rtnl_lock(); rtnl_lock();
@@ -4174,23 +4189,21 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
static void iavf_remove(struct pci_dev *pdev) static void iavf_remove(struct pci_dev *pdev)
{ {
struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev); struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
struct net_device *netdev = adapter->netdev;
struct iavf_fdir_fltr *fdir, *fdirtmp; struct iavf_fdir_fltr *fdir, *fdirtmp;
struct iavf_vlan_filter *vlf, *vlftmp; struct iavf_vlan_filter *vlf, *vlftmp;
struct iavf_cloud_filter *cf, *cftmp;
struct iavf_adv_rss *rss, *rsstmp; struct iavf_adv_rss *rss, *rsstmp;
struct iavf_mac_filter *f, *ftmp; struct iavf_mac_filter *f, *ftmp;
struct iavf_cloud_filter *cf, *cftmp; struct net_device *netdev;
struct iavf_hw *hw = &adapter->hw; struct iavf_hw *hw;
int err; int err;
/* When reboot/shutdown is in progress no need to do anything netdev = adapter->netdev;
* as the adapter is already REMOVE state that was set during hw = &adapter->hw;
* iavf_shutdown() callback.
*/ if (test_and_set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))
if (adapter->state == __IAVF_REMOVE)
return; return;
set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
/* Wait until port initialization is complete. /* Wait until port initialization is complete.
* There are flows where register/unregister netdev may race. * There are flows where register/unregister netdev may race.
*/ */

View File

@@ -7356,6 +7356,7 @@ static int mvpp2_get_sram(struct platform_device *pdev,
struct mvpp2 *priv) struct mvpp2 *priv)
{ {
struct resource *res; struct resource *res;
void __iomem *base;
res = platform_get_resource(pdev, IORESOURCE_MEM, 2); res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if (!res) { if (!res) {
@@ -7366,9 +7367,12 @@ static int mvpp2_get_sram(struct platform_device *pdev,
return 0; return 0;
} }
priv->cm3_base = devm_ioremap_resource(&pdev->dev, res); base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
return PTR_ERR_OR_ZERO(priv->cm3_base); priv->cm3_base = base;
return 0;
} }
static int mvpp2_probe(struct platform_device *pdev) static int mvpp2_probe(struct platform_device *pdev)

View File

@@ -441,6 +441,8 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
sprintf(lmac, "LMAC%d", lmac_id); sprintf(lmac, "LMAC%d", lmac_id);
seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n", seq_printf(filp, "%s\t0x%x\t\tNIX%d\t\t%s\t%s\n",
dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac); dev_name(&pdev->dev), pcifunc, blkid, cgx, lmac);
pci_dev_put(pdev);
} }
return 0; return 0;
} }
@@ -2127,6 +2129,7 @@ static int cgx_print_dmac_flt(struct seq_file *s, int lmac_id)
} }
} }
pci_dev_put(pdev);
return 0; return 0;
} }

View File

@@ -4832,6 +4832,8 @@ static int nix_setup_ipolicers(struct rvu *rvu,
ipolicer->ref_count = devm_kcalloc(rvu->dev, ipolicer->ref_count = devm_kcalloc(rvu->dev,
ipolicer->band_prof.max, ipolicer->band_prof.max,
sizeof(u16), GFP_KERNEL); sizeof(u16), GFP_KERNEL);
if (!ipolicer->ref_count)
return -ENOMEM;
} }
/* Set policer timeunit to 2us ie (19 + 1) * 100 nsec = 2us */ /* Set policer timeunit to 2us ie (19 + 1) * 100 nsec = 2us */

View File

@@ -62,15 +62,18 @@ int rvu_sdp_init(struct rvu *rvu)
pfvf->sdp_info = devm_kzalloc(rvu->dev, pfvf->sdp_info = devm_kzalloc(rvu->dev,
sizeof(struct sdp_node_info), sizeof(struct sdp_node_info),
GFP_KERNEL); GFP_KERNEL);
if (!pfvf->sdp_info) if (!pfvf->sdp_info) {
pci_dev_put(pdev);
return -ENOMEM; return -ENOMEM;
}
dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]); dev_info(rvu->dev, "SDP PF number:%d\n", sdp_pf_num[i]);
put_device(&pdev->dev);
i++; i++;
} }
pci_dev_put(pdev);
return 0; return 0;
} }

View File

@@ -2327,8 +2327,10 @@ static int mtk_open(struct net_device *dev)
int err; int err;
err = mtk_start_dma(eth); err = mtk_start_dma(eth);
if (err) if (err) {
phylink_disconnect_phy(mac->phylink);
return err; return err;
}
if (eth->soc->offload_version && mtk_ppe_start(&eth->ppe) == 0) if (eth->soc->offload_version && mtk_ppe_start(&eth->ppe) == 0)
gdm_config = MTK_GDMA_TO_PPE; gdm_config = MTK_GDMA_TO_PPE;

View File

@@ -697,7 +697,8 @@ static int mlx4_create_zones(struct mlx4_dev *dev,
err = mlx4_bitmap_init(*bitmap + k, 1, err = mlx4_bitmap_init(*bitmap + k, 1,
MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0, MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0,
0); 0);
mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0); if (!err)
mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0);
} }
if (err) if (err)

View File

@@ -971,6 +971,7 @@ static void cmd_work_handler(struct work_struct *work)
cmd_ent_get(ent); cmd_ent_get(ent);
set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
cmd_ent_get(ent); /* for the _real_ FW event on completion */
/* Skip sending command to fw if internal error */ /* Skip sending command to fw if internal error */
if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) { if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) {
u8 status = 0; u8 status = 0;
@@ -984,7 +985,6 @@ static void cmd_work_handler(struct work_struct *work)
return; return;
} }
cmd_ent_get(ent); /* for the _real_ FW event on completion */
/* ring doorbell after the descriptor is valid */ /* ring doorbell after the descriptor is valid */
mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx); mlx5_core_dbg(dev, "writing 0x%x to command doorbell\n", 1 << ent->idx);
wmb(); wmb();
@@ -1598,8 +1598,8 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
cmd_ent_put(ent); /* timeout work was canceled */ cmd_ent_put(ent); /* timeout work was canceled */
if (!forced || /* Real FW completion */ if (!forced || /* Real FW completion */
pci_channel_offline(dev->pdev) || /* FW is inaccessible */ mlx5_cmd_is_down(dev) || /* No real FW completion is expected */
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) !opcode_allowed(cmd, ent->op))
cmd_ent_put(ent); cmd_ent_put(ent);
ent->ts2 = ktime_get_ns(); ent->ts2 = ktime_get_ns();

View File

@@ -638,7 +638,7 @@ static void mlx5_tracer_handle_timestamp_trace(struct mlx5_fw_tracer *tracer,
trace_timestamp = (timestamp_event.timestamp & MASK_52_7) | trace_timestamp = (timestamp_event.timestamp & MASK_52_7) |
(str_frmt->timestamp & MASK_6_0); (str_frmt->timestamp & MASK_6_0);
else else
trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) | trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) |
(str_frmt->timestamp & MASK_6_0); (str_frmt->timestamp & MASK_6_0);
mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp); mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp);

View File

@@ -1608,7 +1608,8 @@ static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,
res = state == pci_channel_io_perm_failure ? res = state == pci_channel_io_perm_failure ?
PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
mlx5_pci_trace(dev, "Exit, result = %d, %s\n", res, result2str(res)); mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, result = %d, %s\n",
__func__, dev->state, dev->pci_status, res, result2str(res));
return res; return res;
} }
@@ -1647,7 +1648,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
struct mlx5_core_dev *dev = pci_get_drvdata(pdev); struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
int err; int err;
mlx5_pci_trace(dev, "Enter\n"); mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Enter\n",
__func__, dev->state, dev->pci_status);
err = mlx5_pci_enable_device(dev); err = mlx5_pci_enable_device(dev);
if (err) { if (err) {
@@ -1669,7 +1671,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
res = PCI_ERS_RESULT_RECOVERED; res = PCI_ERS_RESULT_RECOVERED;
out: out:
mlx5_pci_trace(dev, "Exit, err = %d, result = %d, %s\n", err, res, result2str(res)); mlx5_core_info(dev, "%s Device state = %d pci_status: %d. Exit, err = %d, result = %d, %s\n",
__func__, dev->state, dev->pci_status, err, res, result2str(res));
return res; return res;
} }

View File

@@ -83,7 +83,7 @@ static int sparx5_port_open(struct net_device *ndev)
err = phylink_of_phy_connect(port->phylink, port->of_node, 0); err = phylink_of_phy_connect(port->phylink, port->of_node, 0);
if (err) { if (err) {
netdev_err(ndev, "Could not attach to PHY\n"); netdev_err(ndev, "Could not attach to PHY\n");
return err; goto err_connect;
} }
phylink_start(port->phylink); phylink_start(port->phylink);
@@ -95,10 +95,20 @@ static int sparx5_port_open(struct net_device *ndev)
err = sparx5_serdes_set(port->sparx5, port, &port->conf); err = sparx5_serdes_set(port->sparx5, port, &port->conf);
else else
err = phy_power_on(port->serdes); err = phy_power_on(port->serdes);
if (err) if (err) {
netdev_err(ndev, "%s failed\n", __func__); netdev_err(ndev, "%s failed\n", __func__);
goto out_power;
}
} }
return 0;
out_power:
phylink_stop(port->phylink);
phylink_disconnect_phy(port->phylink);
err_connect:
sparx5_port_enable(port, false);
return err; return err;
} }

View File

@@ -363,7 +363,7 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
return ret; return ret;
attrs.split = eth_port.is_split; attrs.split = eth_port.is_split;
attrs.splittable = !attrs.split; attrs.splittable = eth_port.port_lanes > 1 && !attrs.split;
attrs.lanes = eth_port.port_lanes; attrs.lanes = eth_port.port_lanes;
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
attrs.phys.port_number = eth_port.label_port; attrs.phys.port_number = eth_port.label_port;

View File

@@ -1219,6 +1219,9 @@ nfp_port_get_module_info(struct net_device *netdev,
u8 data; u8 data;
port = nfp_port_from_netdev(netdev); port = nfp_port_from_netdev(netdev);
if (!port)
return -EOPNOTSUPP;
/* update port state to get latest interface */ /* update port state to get latest interface */
set_bit(NFP_PORT_CHANGED, &port->flags); set_bit(NFP_PORT_CHANGED, &port->flags);
eth_port = nfp_port_get_eth_port(port); eth_port = nfp_port_get_eth_port(port);

View File

@@ -1148,6 +1148,7 @@ static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter,
buffer_info->dma = 0; buffer_info->dma = 0;
buffer_info->time_stamp = 0; buffer_info->time_stamp = 0;
tx_ring->next_to_use = ring_num; tx_ring->next_to_use = ring_num;
dev_kfree_skb_any(skb);
return; return;
} }
buffer_info->mapped = true; buffer_info->mapped = true;
@@ -2464,6 +2465,7 @@ static void pch_gbe_remove(struct pci_dev *pdev)
unregister_netdev(netdev); unregister_netdev(netdev);
pch_gbe_phy_hw_reset(&adapter->hw); pch_gbe_phy_hw_reset(&adapter->hw);
pci_dev_put(adapter->ptp_pdev);
free_netdev(netdev); free_netdev(netdev);
} }
@@ -2539,7 +2541,7 @@ static int pch_gbe_probe(struct pci_dev *pdev,
/* setup the private structure */ /* setup the private structure */
ret = pch_gbe_sw_init(adapter); ret = pch_gbe_sw_init(adapter);
if (ret) if (ret)
goto err_free_netdev; goto err_put_dev;
/* Initialize PHY */ /* Initialize PHY */
ret = pch_gbe_init_phy(adapter); ret = pch_gbe_init_phy(adapter);
@@ -2597,6 +2599,8 @@ static int pch_gbe_probe(struct pci_dev *pdev,
err_free_adapter: err_free_adapter:
pch_gbe_phy_hw_reset(&adapter->hw); pch_gbe_phy_hw_reset(&adapter->hw);
err_put_dev:
pci_dev_put(adapter->ptp_pdev);
err_free_netdev: err_free_netdev:
free_netdev(netdev); free_netdev(netdev);
return ret; return ret;

View File

@@ -2469,6 +2469,7 @@ static netdev_tx_t ql3xxx_send(struct sk_buff *skb,
skb_shinfo(skb)->nr_frags); skb_shinfo(skb)->nr_frags);
if (tx_cb->seg_count == -1) { if (tx_cb->seg_count == -1) {
netdev_err(ndev, "%s: invalid segment count!\n", __func__); netdev_err(ndev, "%s: invalid segment count!\n", __func__);
dev_kfree_skb_any(skb);
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }

View File

@@ -200,6 +200,7 @@ static netdev_tx_t ef100_hard_start_xmit(struct sk_buff *skb,
skb->len, skb->data_len, channel->channel); skb->len, skb->data_len, channel->channel);
if (!efx->n_channels || !efx->n_tx_channels || !channel) { if (!efx->n_channels || !efx->n_tx_channels || !channel) {
netif_stop_queue(net_dev); netif_stop_queue(net_dev);
dev_kfree_skb_any(skb);
goto err; goto err;
} }

View File

@@ -2644,11 +2644,6 @@ static int macsec_upd_offload(struct sk_buff *skb, struct genl_info *info)
if (ret) if (ret)
goto rollback; goto rollback;
/* Force features update, since they are different for SW MACSec and
* HW offloading cases.
*/
netdev_update_features(dev);
rtnl_unlock(); rtnl_unlock();
return 0; return 0;
@@ -3416,16 +3411,9 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
return ret; return ret;
} }
#define SW_MACSEC_FEATURES \ #define MACSEC_FEATURES \
(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST) (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
/* If h/w offloading is enabled, use real device features save for
* VLAN_FEATURES - they require additional ops
* HW_MACSEC - no reason to report it
*/
#define REAL_DEV_FEATURES(dev) \
((dev)->features & ~(NETIF_F_VLAN_FEATURES | NETIF_F_HW_MACSEC))
static int macsec_dev_init(struct net_device *dev) static int macsec_dev_init(struct net_device *dev)
{ {
struct macsec_dev *macsec = macsec_priv(dev); struct macsec_dev *macsec = macsec_priv(dev);
@@ -3442,12 +3430,8 @@ static int macsec_dev_init(struct net_device *dev)
return err; return err;
} }
if (macsec_is_offloaded(macsec)) { dev->features = real_dev->features & MACSEC_FEATURES;
dev->features = REAL_DEV_FEATURES(real_dev); dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
} else {
dev->features = real_dev->features & SW_MACSEC_FEATURES;
dev->features |= NETIF_F_LLTX | NETIF_F_GSO_SOFTWARE;
}
dev->needed_headroom = real_dev->needed_headroom + dev->needed_headroom = real_dev->needed_headroom +
MACSEC_NEEDED_HEADROOM; MACSEC_NEEDED_HEADROOM;
@@ -3476,10 +3460,7 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
struct macsec_dev *macsec = macsec_priv(dev); struct macsec_dev *macsec = macsec_priv(dev);
struct net_device *real_dev = macsec->real_dev; struct net_device *real_dev = macsec->real_dev;
if (macsec_is_offloaded(macsec)) features &= (real_dev->features & MACSEC_FEATURES) |
return REAL_DEV_FEATURES(real_dev);
features &= (real_dev->features & SW_MACSEC_FEATURES) |
NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES; NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
features |= NETIF_F_LLTX; features |= NETIF_F_LLTX;
@@ -3827,7 +3808,6 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
if (macsec_is_offloaded(macsec)) { if (macsec_is_offloaded(macsec)) {
const struct macsec_ops *ops; const struct macsec_ops *ops;
struct macsec_context ctx; struct macsec_context ctx;
int ret;
ops = macsec_get_ops(netdev_priv(dev), &ctx); ops = macsec_get_ops(netdev_priv(dev), &ctx);
if (!ops) { if (!ops) {

View File

@@ -1353,6 +1353,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */
{QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */

View File

@@ -27,7 +27,7 @@
#define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52 #define ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01 52
#define ATH11K_QMI_CALDB_SIZE 0x480000 #define ATH11K_QMI_CALDB_SIZE 0x480000
#define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20 #define ATH11K_QMI_BDF_EXT_STR_LENGTH 0x20
#define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 3 #define ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT 5
#define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035 #define QMI_WLFW_REQUEST_MEM_IND_V01 0x0035
#define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037 #define QMI_WLFW_FW_MEM_READY_IND_V01 0x0037

View File

@@ -5233,7 +5233,7 @@ static int get_wep_tx_idx(struct airo_info *ai)
return -1; return -1;
} }
static int set_wep_key(struct airo_info *ai, u16 index, const char *key, static int set_wep_key(struct airo_info *ai, u16 index, const u8 *key,
u16 keylen, int perm, int lock) u16 keylen, int perm, int lock)
{ {
static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 }; static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
@@ -5284,7 +5284,7 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
struct net_device *dev = PDE_DATA(inode); struct net_device *dev = PDE_DATA(inode);
struct airo_info *ai = dev->ml_priv; struct airo_info *ai = dev->ml_priv;
int i, rc; int i, rc;
char key[16]; u8 key[16];
u16 index = 0; u16 index = 0;
int j = 0; int j = 0;
@@ -5312,12 +5312,22 @@ static void proc_wepkey_on_close(struct inode *inode, struct file *file)
} }
for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) { for (i = 0; i < 16*3 && data->wbuffer[i+j]; i++) {
int val;
if (i % 3 == 2)
continue;
val = hex_to_bin(data->wbuffer[i+j]);
if (val < 0) {
airo_print_err(ai->dev->name, "WebKey passed invalid key hex");
return;
}
switch(i%3) { switch(i%3) {
case 0: case 0:
key[i/3] = hex_to_bin(data->wbuffer[i+j])<<4; key[i/3] = (u8)val << 4;
break; break;
case 1: case 1:
key[i/3] |= hex_to_bin(data->wbuffer[i+j]); key[i/3] |= (u8)val;
break; break;
} }
} }

View File

@@ -880,6 +880,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
struct sk_buff *skb; struct sk_buff *skb;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *cb;
if (!vp->assoc) if (!vp->assoc)
return; return;
@@ -901,6 +902,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
memcpy(hdr->addr2, mac, ETH_ALEN); memcpy(hdr->addr2, mac, ETH_ALEN);
memcpy(hdr->addr3, vp->bssid, ETH_ALEN); memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
cb = IEEE80211_SKB_CB(skb);
cb->control.rates[0].count = 1;
cb->control.rates[1].idx = -1;
rcu_read_lock(); rcu_read_lock();
mac80211_hwsim_tx_frame(data->hw, skb, mac80211_hwsim_tx_frame(data->hw, skb,
rcu_dereference(vif->chanctx_conf)->def.chan); rcu_dereference(vif->chanctx_conf)->def.chan);

View File

@@ -939,30 +939,52 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
return; return;
while (index + sizeof(*e) <= len) { while (index + sizeof(*e) <= len) {
u16 attr_size;
e = (struct wilc_attr_entry *)&buf[index]; e = (struct wilc_attr_entry *)&buf[index];
if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST) attr_size = le16_to_cpu(e->attr_len);
if (index + sizeof(*e) + attr_size > len)
return;
if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
ch_list_idx = index; ch_list_idx = index;
else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL) else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
op_ch_idx = index; op_ch_idx = index;
if (ch_list_idx && op_ch_idx) if (ch_list_idx && op_ch_idx)
break; break;
index += le16_to_cpu(e->attr_len) + sizeof(*e);
index += sizeof(*e) + attr_size;
} }
if (ch_list_idx) { if (ch_list_idx) {
u16 attr_size; unsigned int i;
struct wilc_ch_list_elem *e; u16 elem_size;
int i;
ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx]; ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
attr_size = le16_to_cpu(ch_list->attr_len); /* the number of bytes following the final 'elem' member */
for (i = 0; i < attr_size;) { elem_size = le16_to_cpu(ch_list->attr_len) -
(sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
for (i = 0; i < elem_size;) {
struct wilc_ch_list_elem *e;
e = (struct wilc_ch_list_elem *)(ch_list->elem + i); e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
i += sizeof(*e);
if (i > elem_size)
break;
i += e->no_of_channels;
if (i > elem_size)
break;
if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) { if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
memset(e->ch_list, sta_ch, e->no_of_channels); memset(e->ch_list, sta_ch, e->no_of_channels);
break; break;
} }
i += e->no_of_channels;
} }
} }

View File

@@ -467,14 +467,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len); rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
if (rsn_ie) { if (rsn_ie) {
int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
int offset = 8; int offset = 8;
param->mode_802_11i = 2;
param->rsn_found = true;
/* extract RSN capabilities */ /* extract RSN capabilities */
offset += (rsn_ie[offset] * 4) + 2; if (offset < rsn_ie_len) {
offset += (rsn_ie[offset] * 4) + 2; /* skip over pairwise suites */
memcpy(param->rsn_cap, &rsn_ie[offset], 2); offset += (rsn_ie[offset] * 4) + 2;
if (offset < rsn_ie_len) {
/* skip over authentication suites */
offset += (rsn_ie[offset] * 4) + 2;
if (offset + 1 < rsn_ie_len) {
param->mode_802_11i = 2;
param->rsn_found = true;
memcpy(param->rsn_cap, &rsn_ie[offset], 2);
}
}
}
} }
if (param->rsn_found) { if (param->rsn_found) {

View File

@@ -249,7 +249,7 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
if (object->integer.value == 3) if (object->integer.value == 3)
sleep_state = IPC_PCIE_D3L2; sleep_state = IPC_PCIE_D3L2;
kfree(object); ACPI_FREE(object);
default_ret: default_ret:
return sleep_state; return sleep_state;

View File

@@ -312,6 +312,8 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
int r = 0; int r = 0;
struct device *dev = &ndev->nfc_dev->dev; struct device *dev = &ndev->nfc_dev->dev;
struct nfc_evt_transaction *transaction; struct nfc_evt_transaction *transaction;
u32 aid_len;
u8 params_len;
pr_debug("connectivity gate event: %x\n", event); pr_debug("connectivity gate event: %x\n", event);
@@ -325,26 +327,47 @@ static int st_nci_hci_connectivity_event_received(struct nci_dev *ndev,
* Description Tag Length * Description Tag Length
* AID 81 5 to 16 * AID 81 5 to 16
* PARAMETERS 82 0 to 255 * PARAMETERS 82 0 to 255
*
* The key differences are aid storage length is variably sized
* in the packet, but fixed in nfc_evt_transaction, and that
* the aid_len is u8 in the packet, but u32 in the structure,
* and the tags in the packet are not included in
* nfc_evt_transaction.
*
* size(b): 1 1 5-16 1 1 0-255
* offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4
* mem name: aid_tag(M) aid_len aid params_tag(M) params_len params
* example: 0x81 5-16 X 0x82 0-255 X
*/ */
if (skb->len < NFC_MIN_AID_LENGTH + 2 && if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
return -EPROTO; return -EPROTO;
transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL); aid_len = skb->data[1];
if (skb->len < aid_len + 4 ||
aid_len > sizeof(transaction->aid))
return -EPROTO;
params_len = skb->data[aid_len + 3];
/* Verify PARAMETERS tag is (82), and final check that there is
* enough space in the packet to read everything.
*/
if (skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG ||
skb->len < aid_len + 4 + params_len)
return -EPROTO;
transaction = devm_kzalloc(dev, sizeof(*transaction) +
params_len, GFP_KERNEL);
if (!transaction) if (!transaction)
return -ENOMEM; return -ENOMEM;
transaction->aid_len = skb->data[1]; transaction->aid_len = aid_len;
memcpy(transaction->aid, &skb->data[2], transaction->aid_len); transaction->params_len = params_len;
/* Check next byte is PARAMETERS tag (82) */ memcpy(transaction->aid, &skb->data[2], aid_len);
if (skb->data[transaction->aid_len + 2] != memcpy(transaction->params, &skb->data[aid_len + 4],
NFC_EVT_TRANSACTION_PARAMS_TAG) params_len);
return -EPROTO;
transaction->params_len = skb->data[transaction->aid_len + 3];
memcpy(transaction->params, skb->data +
transaction->aid_len + 4, transaction->params_len);
r = nfc_se_transaction(ndev->nfc_dev, host, transaction); r = nfc_se_transaction(ndev->nfc_dev, host, transaction);
break; break;

View File

@@ -3351,6 +3351,10 @@ static const struct pci_device_id nvme_id_table[] = {
{ PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */
.driver_data = NVME_QUIRK_NO_DEEPEST_PS | .driver_data = NVME_QUIRK_NO_DEEPEST_PS |
NVME_QUIRK_IGNORE_DEV_SUBNQN, }, NVME_QUIRK_IGNORE_DEV_SUBNQN, },
{ PCI_DEVICE(0x1344, 0x5407), /* Micron Technology Inc NVMe SSD */
.driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN },
{ PCI_DEVICE(0x1344, 0x6001), /* Micron Nitro NVMe */
.driver_data = NVME_QUIRK_BOGUS_NID, },
{ PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */ { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */
@@ -3361,6 +3365,20 @@ static const struct pci_device_id nvme_id_table[] = {
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
{ PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */
.driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, .driver_data = NVME_QUIRK_NO_DEEPEST_PS, },
{ PCI_DEVICE(0x2646, 0x5018), /* KINGSTON OM8SFP4xxxxP OS21012 NVMe SSD */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x2646, 0x5016), /* KINGSTON OM3PGP4xxxxP OS21011 NVMe SSD */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x2646, 0x501A), /* KINGSTON OM8PGP4xxxxP OS21005 NVMe SSD */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x2646, 0x501B), /* KINGSTON OM8PGP4xxxxQ OS21005 NVMe SSD */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x2646, 0x501E), /* KINGSTON OM3PGP4xxxxQ OS21011 NVMe SSD */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x1f40, 0x5236), /* Netac Technologies Co. NV7000 NVMe SSD */
.driver_data = NVME_QUIRK_BOGUS_NID, },
{ PCI_DEVICE(0x1e4B, 0x1001), /* MAXIO MAP1001 */
.driver_data = NVME_QUIRK_BOGUS_NID, },
{ PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */ { PCI_DEVICE(0x1e4B, 0x1002), /* MAXIO MAP1002 */
.driver_data = NVME_QUIRK_BOGUS_NID, }, .driver_data = NVME_QUIRK_BOGUS_NID, },
{ PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */ { PCI_DEVICE(0x1e4B, 0x1202), /* MAXIO MAP1202 */

View File

@@ -1189,6 +1189,7 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
const char *page, size_t count) const char *page, size_t count)
{ {
int pos = 0, len; int pos = 0, len;
char *val;
if (subsys->subsys_discovered) { if (subsys->subsys_discovered) {
pr_err("Can't set model number. %s is already assigned\n", pr_err("Can't set model number. %s is already assigned\n",
@@ -1211,9 +1212,11 @@ static ssize_t nvmet_subsys_attr_model_store_locked(struct nvmet_subsys *subsys,
return -EINVAL; return -EINVAL;
} }
subsys->model_number = kmemdup_nul(page, len, GFP_KERNEL); val = kmemdup_nul(page, len, GFP_KERNEL);
if (!subsys->model_number) if (!val)
return -ENOMEM; return -ENOMEM;
kfree(subsys->model_number);
subsys->model_number = val;
return count; return count;
} }

View File

@@ -564,6 +564,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
}, },
.driver_data = (void *)ACER_CAP_KBD_DOCK, .driver_data = (void *)ACER_CAP_KBD_DOCK,
}, },
{
.callback = set_force_caps,
.ident = "Acer Aspire Switch V 10 SW5-017",
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
},
.driver_data = (void *)ACER_CAP_KBD_DOCK,
},
{ {
.callback = set_force_caps, .callback = set_force_caps,
.ident = "Acer One 10 (S1003)", .ident = "Acer One 10 (S1003)",

View File

@@ -1511,6 +1511,8 @@ static void asus_wmi_set_xusb2pr(struct asus_wmi *asus)
pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
cpu_to_le32(ports_available)); cpu_to_le32(ports_available));
pci_dev_put(xhci_pdev);
pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n", pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n",
orig_ports_available, ports_available); orig_ports_available, ports_available);
} }

View File

@@ -64,6 +64,7 @@ enum hp_wmi_event_ids {
HPWMI_PEAKSHIFT_PERIOD = 0x0F, HPWMI_PEAKSHIFT_PERIOD = 0x0F,
HPWMI_BATTERY_CHARGE_PERIOD = 0x10, HPWMI_BATTERY_CHARGE_PERIOD = 0x10,
HPWMI_SANITIZATION_MODE = 0x17, HPWMI_SANITIZATION_MODE = 0x17,
HPWMI_SMART_EXPERIENCE_APP = 0x21,
}; };
struct bios_args { struct bios_args {
@@ -641,6 +642,8 @@ static void hp_wmi_notify(u32 value, void *context)
break; break;
case HPWMI_SANITIZATION_MODE: case HPWMI_SANITIZATION_MODE:
break; break;
case HPWMI_SMART_EXPERIENCE_APP:
break;
default: default:
pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
break; break;

View File

@@ -136,6 +136,7 @@ struct ideapad_private {
bool dytc : 1; bool dytc : 1;
bool fan_mode : 1; bool fan_mode : 1;
bool fn_lock : 1; bool fn_lock : 1;
bool set_fn_lock_led : 1;
bool hw_rfkill_switch : 1; bool hw_rfkill_switch : 1;
bool kbd_bl : 1; bool kbd_bl : 1;
bool touchpad_ctrl_via_ec : 1; bool touchpad_ctrl_via_ec : 1;
@@ -1467,6 +1468,9 @@ static void ideapad_wmi_notify(u32 value, void *context)
ideapad_input_report(priv, value); ideapad_input_report(priv, value);
break; break;
case 208: case 208:
if (!priv->features.set_fn_lock_led)
break;
if (!eval_hals(priv->adev->handle, &result)) { if (!eval_hals(priv->adev->handle, &result)) {
bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result); bool state = test_bit(HALS_FNLOCK_STATE_BIT, &result);
@@ -1480,6 +1484,18 @@ static void ideapad_wmi_notify(u32 value, void *context)
} }
#endif #endif
/* On some models we need to call exec_sals(SALS_FNLOCK_ON/OFF) to set the LED */
static const struct dmi_system_id set_fn_lock_led_list[] = {
{
/* https://bugzilla.kernel.org/show_bug.cgi?id=212671 */
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Legion R7000P2020H"),
}
},
{}
};
/* /*
* Some ideapads have a hardware rfkill switch, but most do not have one. * Some ideapads have a hardware rfkill switch, but most do not have one.
* Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill, * Reading VPCCMD_R_RF always results in 0 on models without a hardware rfkill,
@@ -1499,15 +1515,39 @@ static const struct dmi_system_id hw_rfkill_list[] = {
{} {}
}; };
static const struct dmi_system_id no_touchpad_switch_list[] = {
{
.ident = "Lenovo Yoga 3 Pro 1370",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3"),
},
},
{
.ident = "ZhaoYang K4e-IML",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ZhaoYang K4e-IML"),
},
},
{}
};
static void ideapad_check_features(struct ideapad_private *priv) static void ideapad_check_features(struct ideapad_private *priv)
{ {
acpi_handle handle = priv->adev->handle; acpi_handle handle = priv->adev->handle;
unsigned long val; unsigned long val;
priv->features.set_fn_lock_led = dmi_check_system(set_fn_lock_led_list);
priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list); priv->features.hw_rfkill_switch = dmi_check_system(hw_rfkill_list);
/* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */ /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */
priv->features.touchpad_ctrl_via_ec = !acpi_dev_present("ELAN0634", NULL, -1); if (acpi_dev_present("ELAN0634", NULL, -1))
priv->features.touchpad_ctrl_via_ec = 0;
else if (dmi_check_system(no_touchpad_switch_list))
priv->features.touchpad_ctrl_via_ec = 0;
else
priv->features.touchpad_ctrl_via_ec = 1;
if (!read_ec_data(handle, VPCCMD_R_FAN, &val)) if (!read_ec_data(handle, VPCCMD_R_FAN, &val))
priv->features.fan_mode = true; priv->features.fan_mode = true;

View File

@@ -27,6 +27,9 @@ static const struct acpi_device_id intel_hid_ids[] = {
{"INTC1051", 0}, {"INTC1051", 0},
{"INTC1054", 0}, {"INTC1054", 0},
{"INTC1070", 0}, {"INTC1070", 0},
{"INTC1076", 0},
{"INTC1077", 0},
{"INTC1078", 0},
{"", 0}, {"", 0},
}; };
MODULE_DEVICE_TABLE(acpi, intel_hid_ids); MODULE_DEVICE_TABLE(acpi, intel_hid_ids);

View File

@@ -9,6 +9,7 @@
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/pci.h> #include <linux/pci.h>
@@ -18,6 +19,7 @@
#define PMT_XA_START 0 #define PMT_XA_START 0
#define PMT_XA_MAX INT_MAX #define PMT_XA_MAX INT_MAX
#define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX)
#define GUID_SPR_PUNIT 0x9956f43f
/* /*
* Early implementations of PMT on client platforms have some * Early implementations of PMT on client platforms have some
@@ -41,6 +43,29 @@ bool intel_pmt_is_early_client_hw(struct device *dev)
} }
EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw); EXPORT_SYMBOL_GPL(intel_pmt_is_early_client_hw);
static inline int
pmt_memcpy64_fromio(void *to, const u64 __iomem *from, size_t count)
{
int i, remain;
u64 *buf = to;
if (!IS_ALIGNED((unsigned long)from, 8))
return -EFAULT;
for (i = 0; i < count/8; i++)
buf[i] = readq(&from[i]);
/* Copy any remaining bytes */
remain = count % 8;
if (remain) {
u64 tmp = readq(&from[i]);
memcpy(&buf[i], &tmp, remain);
}
return count;
}
/* /*
* sysfs * sysfs
*/ */
@@ -62,7 +87,11 @@ intel_pmt_read(struct file *filp, struct kobject *kobj,
if (count > entry->size - off) if (count > entry->size - off)
count = entry->size - off; count = entry->size - off;
memcpy_fromio(buf, entry->base + off, count); if (entry->guid == GUID_SPR_PUNIT)
/* PUNIT on SPR only supports aligned 64-bit read */
count = pmt_memcpy64_fromio(buf, entry->base + off, count);
else
memcpy_fromio(buf, entry->base + off, count);
return count; return count;
} }

View File

@@ -773,6 +773,22 @@ static const struct ts_dmi_data predia_basic_data = {
.properties = predia_basic_props, .properties = predia_basic_props,
}; };
static const struct property_entry rca_cambio_w101_v2_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-x", 4),
PROPERTY_ENTRY_U32("touchscreen-min-y", 20),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1644),
PROPERTY_ENTRY_U32("touchscreen-size-y", 874),
PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-rca-cambio-w101-v2.fw"),
PROPERTY_ENTRY_U32("silead,max-fingers", 10),
{ }
};
static const struct ts_dmi_data rca_cambio_w101_v2_data = {
.acpi_name = "MSSL1680:00",
.properties = rca_cambio_w101_v2_props,
};
static const struct property_entry rwc_nanote_p8_props[] = { static const struct property_entry rwc_nanote_p8_props[] = {
PROPERTY_ENTRY_U32("touchscreen-min-y", 46), PROPERTY_ENTRY_U32("touchscreen-min-y", 46),
PROPERTY_ENTRY_U32("touchscreen-size-x", 1728), PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
@@ -1394,6 +1410,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = {
DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"), DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
}, },
}, },
{
/* RCA Cambio W101 v2 */
/* https://github.com/onitake/gsl-firmware/discussions/193 */
.driver_data = (void *)&rca_cambio_w101_v2_data,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "RCA"),
DMI_MATCH(DMI_PRODUCT_NAME, "W101SA23T1"),
},
},
{ {
/* RWC NANOTE P8 */ /* RWC NANOTE P8 */
.driver_data = (void *)&rwc_nanote_p8_data, .driver_data = (void *)&rwc_nanote_p8_data,

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